Skip to content

Commit 036c016

Browse files
authored
Merge pull request #649 from go-mysql-org/add-test-for-ExecuteSelectStreaming
Add test for Conn.ExecuteSelectStreaming
2 parents 958aa76 + 70c2440 commit 036c016

File tree

3 files changed

+157
-23
lines changed

3 files changed

+157
-23
lines changed

client/client_test.go

+1-23
Original file line numberDiff line numberDiff line change
@@ -2,38 +2,16 @@ package client
22

33
import (
44
"encoding/json"
5-
"flag"
65
"fmt"
76
"strings"
8-
"testing"
97

10-
"github.com/go-mysql-org/go-mysql/test_util/test_keys"
118
. "github.com/pingcap/check"
129
"github.com/pingcap/errors"
1310

1411
"github.com/go-mysql-org/go-mysql/mysql"
12+
"github.com/go-mysql-org/go-mysql/test_util/test_keys"
1513
)
1614

17-
var testHost = flag.String("host", "127.0.0.1", "MySQL server host")
18-
19-
// We cover the whole range of MySQL server versions using docker-compose to bind them to different ports for testing.
20-
// MySQL is constantly updating auth plugin to make it secure:
21-
// starting from MySQL 8.0.4, a new auth plugin is introduced, causing plain password auth to fail with error:
22-
// ERROR 1251 (08004): Client does not support authentication protocol requested by server; consider upgrading MySQL client
23-
// Hint: use docker-compose to start corresponding MySQL docker containers and add the their ports here
24-
var testPort = flag.String("port", "3306", "MySQL server port") // choose one or more form 5561,5641,3306,5722,8003,8012,8013, e.g. '3306,5722,8003'
25-
var testUser = flag.String("user", "root", "MySQL user")
26-
var testPassword = flag.String("pass", "", "MySQL password")
27-
var testDB = flag.String("db", "test", "MySQL test database")
28-
29-
func Test(t *testing.T) {
30-
segs := strings.Split(*testPort, ",")
31-
for _, seg := range segs {
32-
Suite(&clientTestSuite{port: seg})
33-
}
34-
TestingT(t)
35-
}
36-
3715
type clientTestSuite struct {
3816
c *Conn
3917
port string

client/common_test.go

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package client
2+
3+
import (
4+
"flag"
5+
"strings"
6+
"testing"
7+
8+
. "github.com/pingcap/check"
9+
)
10+
11+
var testHost = flag.String("host", "127.0.0.1", "MySQL server host")
12+
13+
// We cover the whole range of MySQL server versions using docker-compose to bind them to different ports for testing.
14+
// MySQL is constantly updating auth plugin to make it secure:
15+
// starting from MySQL 8.0.4, a new auth plugin is introduced, causing plain password auth to fail with error:
16+
// ERROR 1251 (08004): Client does not support authentication protocol requested by server; consider upgrading MySQL client
17+
// Hint: use docker-compose to start corresponding MySQL docker containers and add the their ports here
18+
var testPort = flag.String("port", "3306", "MySQL server port") // choose one or more form 5561,5641,3306,5722,8003,8012,8013, e.g. '3306,5722,8003'
19+
var testUser = flag.String("user", "root", "MySQL user")
20+
var testPassword = flag.String("pass", "", "MySQL password")
21+
var testDB = flag.String("db", "test", "MySQL test database")
22+
23+
func Test(t *testing.T) {
24+
segs := strings.Split(*testPort, ",")
25+
for _, seg := range segs {
26+
Suite(&clientTestSuite{port: seg})
27+
Suite(&connTestSuite{port: seg})
28+
}
29+
TestingT(t)
30+
}

client/conn_test.go

+126
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
package client
2+
3+
import (
4+
"fmt"
5+
6+
. "github.com/pingcap/check"
7+
8+
"github.com/go-mysql-org/go-mysql/mysql"
9+
)
10+
11+
type connTestSuite struct {
12+
c *Conn
13+
port string
14+
}
15+
16+
func (s *connTestSuite) SetUpSuite(c *C) {
17+
var err error
18+
addr := fmt.Sprintf("%s:%s", *testHost, s.port)
19+
s.c, err = Connect(addr, *testUser, *testPassword, "")
20+
if err != nil {
21+
c.Fatal(err)
22+
}
23+
24+
_, err = s.c.Execute("CREATE DATABASE IF NOT EXISTS " + *testDB)
25+
c.Assert(err, IsNil)
26+
27+
_, err = s.c.Execute("USE " + *testDB)
28+
c.Assert(err, IsNil)
29+
30+
s.testExecute_CreateTable(c)
31+
}
32+
33+
func (s *connTestSuite) TearDownSuite(c *C) {
34+
if s.c == nil {
35+
return
36+
}
37+
38+
s.testExecute_DropTable(c)
39+
40+
if s.c != nil {
41+
s.c.Close()
42+
}
43+
}
44+
45+
var (
46+
testExecuteSelectStreamingRows = [...]string{"foo", "helloworld", "bar", "", "spam"}
47+
testExecuteSelectStreamingTablename = "execute_plain_table"
48+
)
49+
50+
func (s *connTestSuite) testExecute_CreateTable(c *C) {
51+
str := `CREATE TABLE IF NOT EXISTS ` + testExecuteSelectStreamingTablename + ` (
52+
id INT UNSIGNED NOT NULL,
53+
str VARCHAR(256),
54+
PRIMARY KEY (id)
55+
) ENGINE=InnoDB DEFAULT CHARSET=utf8`
56+
57+
result, err := s.c.Execute(str)
58+
c.Assert(err, IsNil)
59+
result.Close()
60+
61+
result, err = s.c.Execute(`TRUNCATE TABLE ` + testExecuteSelectStreamingTablename)
62+
c.Assert(err, IsNil)
63+
result.Close()
64+
65+
stmt, err := s.c.Prepare(`INSERT INTO ` + testExecuteSelectStreamingTablename + ` (id, str) VALUES (?, ?)`)
66+
c.Assert(err, IsNil)
67+
defer stmt.Close()
68+
69+
for id, str := range testExecuteSelectStreamingRows {
70+
result, err := stmt.Execute(id, str)
71+
c.Assert(err, IsNil)
72+
result.Close()
73+
}
74+
}
75+
76+
func (s *connTestSuite) testExecute_DropTable(c *C) {
77+
_, err := s.c.Execute(`drop table if exists ` + testExecuteSelectStreamingTablename)
78+
c.Assert(err, IsNil)
79+
}
80+
81+
func (s *connTestSuite) TestExecuteSelectStreaming(c *C) {
82+
var (
83+
expectedRowId int64
84+
perResultCallbackCalledTimes int
85+
result mysql.Result
86+
)
87+
88+
const colsInResult = 2 // id, str
89+
90+
err := s.c.ExecuteSelectStreaming(`SELECT id, str FROM `+testExecuteSelectStreamingTablename+` ORDER BY id`,
91+
&result,
92+
func(row []mysql.FieldValue) error {
93+
// Check number of columns
94+
c.Assert(row, HasLen, colsInResult)
95+
// Check type of columns
96+
c.Assert(row[0].Type, Equals, mysql.FieldValueType(mysql.FieldValueTypeUnsigned))
97+
c.Assert(row[1].Type, Equals, mysql.FieldValueType(mysql.FieldValueTypeString))
98+
99+
id := row[0].AsInt64()
100+
str := row[1].AsString()
101+
102+
// Check order of rows
103+
c.Assert(id, Equals, expectedRowId)
104+
// Check string values (protection from incorrect reuse of memory)
105+
c.Assert(string(str), Equals, testExecuteSelectStreamingRows[id])
106+
107+
expectedRowId++
108+
109+
return nil
110+
}, func(result *mysql.Result) error {
111+
// result.Resultset must be defined at this point
112+
c.Assert(result.Resultset, NotNil)
113+
// Check number of columns
114+
c.Assert(result.Resultset.Fields, HasLen, colsInResult)
115+
116+
perResultCallbackCalledTimes++
117+
return nil
118+
})
119+
c.Assert(err, IsNil)
120+
121+
// Check total rows count
122+
c.Assert(expectedRowId, Equals, int64(len(testExecuteSelectStreamingRows)))
123+
124+
// Check perResultCallback call count
125+
c.Assert(perResultCallbackCalledTimes, Equals, 1)
126+
}

0 commit comments

Comments
 (0)