Skip to content

Commit 166d407

Browse files
Tweaks
1 parent e3c72e2 commit 166d407

File tree

10 files changed

+122
-50
lines changed

10 files changed

+122
-50
lines changed

go/cmd/gh-ost-localtests/main.go

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,10 @@ func main() {
2525
var localtestsDir, testName string
2626
var cnf localtests.Config
2727

28-
flag.StringVar(&cnf.Username, "username", "root", "mysql username")
29-
flag.StringVar(&cnf.Password, "password", "", "mysql password")
30-
flag.StringVar(&cnf.Host, "host", "127.0.0.1", "mysql host")
31-
flag.Int64Var(&cnf.Port, "port", 3306, "mysql port")
28+
flag.StringVar(&cnf.Host, "host", localtests.DefaultHost, "mysql host")
29+
flag.Int64Var(&cnf.Port, "port", localtests.DefaultPort, "mysql port")
30+
flag.StringVar(&cnf.Username, "username", localtests.DefaultUsername, "mysql username")
31+
flag.StringVar(&cnf.Password, "password", localtests.DefaultPassword, "mysql password")
3232
flag.StringVar(&localtestsDir, "tests-dir", filepath.Join(pwd, "localtests"), "path to localtests directory")
3333
flag.StringVar(&testName, "test", "", "run a single test by name (default: run all tests)")
3434
flag.BoolVar(&testNoop, "test-noop", false, "run a single noop migration, eg: --alter='ENGINE=InnoDB'")
@@ -53,12 +53,18 @@ func main() {
5353
}
5454
defer db.Close()
5555

56+
if err = localtests.WaitForMySQLAvailable(db); err != nil {
57+
log.Fatalf("Failed to setup database client: %+v", err)
58+
}
59+
5660
var tests []localtests.Test
5761
if testNoop {
5862
tests = []localtests.Test{
5963
{
60-
Name: "noop",
61-
ExtraArgs: `--alter='ENGINE=InnoDB'`,
64+
Name: "noop",
65+
ExtraArgs: []string{
66+
`--alter='ENGINE=InnoDB'`,
67+
},
6268
},
6369
}
6470
} else {

go/localtests/localtests.go

Lines changed: 47 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2,32 +2,37 @@ package localtests
22

33
import (
44
"database/sql"
5+
"errors"
56
"fmt"
67
"io/ioutil"
78
"log"
89
"os"
910
"os/exec"
1011
"path/filepath"
1112
"strings"
13+
"time"
1214

1315
"github.com/google/shlex"
1416
)
1517

1618
const (
17-
testUsername = "gh-ost"
18-
testPassword = "gh-ost"
19-
testDatabase = "test"
20-
testTable = "gh_ost_test"
21-
testSocketFile = "/tmp/gh-ost.test.sock"
22-
throttleFlagFile = "/tmp/gh-ost-test.ghost.throttle.flag"
23-
throttleQuery = "select timestampdiff(second, min(last_update), now()) < 5 from _gh_ost_test_ghc"
19+
PrimaryHost = "primary"
20+
DefaultHost = "replica"
21+
DefaultPort int64 = 3306
22+
DefaultUsername = "gh-ost"
23+
DefaultPassword = "gh-ost"
24+
testDatabase = "test"
25+
testTable = "gh_ost_test"
26+
testSocketFile = "/tmp/gh-ost.test.sock"
27+
throttleFlagFile = "/tmp/gh-ost-test.ghost.throttle.flag"
28+
throttleQuery = "select timestampdiff(second, min(last_update), now()) < 5 from _gh_ost_test_ghc"
2429
)
2530

2631
type Config struct {
27-
Username string
28-
Password string
2932
Host string
3033
Port int64
34+
Username string
35+
Password string
3136
GhostBinary string
3237
MysqlBinary string
3338
}
@@ -36,10 +41,29 @@ type Test struct {
3641
Name string
3742
Path string
3843
CreateSQLFile string
39-
ExtraArgs string
44+
ExtraArgs []string
4045
IgnoreVersions []string
4146
}
4247

48+
func WaitForMySQLAvailable(db *sql.DB) error {
49+
ticker := time.NewTicker(time.Second)
50+
defer ticker.Stop()
51+
52+
for {
53+
select {
54+
case <-time.After(10 * time.Minute):
55+
return errors.New("timed out waiting for mysql")
56+
case <-ticker.C:
57+
if err := db.Ping(); err != nil {
58+
log.Println("Waiting for mysql to become available")
59+
} else {
60+
log.Println("MySQL is available")
61+
return nil
62+
}
63+
}
64+
}
65+
}
66+
4367
// Prepare runs a 'mysql' client/shell command to populate the test schema.
4468
// The create.sql file is read by golang and passed to 'mysql' over stdin.
4569
func (test *Test) Prepare(config Config) error {
@@ -55,7 +79,7 @@ func (test *Test) Prepare(config Config) error {
5579

5680
flags := []string{
5781
fmt.Sprintf("--defaults-file=%s", defaultsFile),
58-
fmt.Sprintf("--host=%s", config.Host),
82+
fmt.Sprintf("--host=%s", PrimaryHost), // TODO: fix this
5983
fmt.Sprintf("--port=%d", config.Port),
6084
"--default-character-set=utf8mb4",
6185
testDatabase,
@@ -84,11 +108,11 @@ func (test *Test) Migrate(db *sql.DB, config Config) error {
84108
log.Printf("[%s] detected MySQL %s host %s:%d", test.Name, mysqlInfo.Version, config.Host, config.Port)
85109

86110
flags := []string{
87-
fmt.Sprintf("--user=%s", testUsername),
88-
fmt.Sprintf("--password=%s", testPassword),
111+
fmt.Sprintf("--user=%s", config.Username),
112+
fmt.Sprintf("--password=%s", config.Password),
89113
fmt.Sprintf("--host=%s", config.Host),
90114
fmt.Sprintf("--port=%d", config.Port),
91-
fmt.Sprintf("--assume-master-host=%s:%d", mysqlInfo.Host, mysqlInfo.Port),
115+
fmt.Sprintf("--assume-master-host=primary:%d", mysqlInfo.Port), // TODO: fix this
92116
fmt.Sprintf("--database=%s", testDatabase),
93117
fmt.Sprintf("--table=%s", testTable),
94118
"--assume-rbr",
@@ -108,14 +132,10 @@ func (test *Test) Migrate(db *sql.DB, config Config) error {
108132
"--stack",
109133
"--verbose",
110134
}
111-
if test.ExtraArgs == "" {
112-
flags = append(flags, "--alter='engine=innodb'")
135+
if len(test.ExtraArgs) > 0 {
136+
flags = append(flags, test.ExtraArgs...)
113137
} else {
114-
extraArgs, err := shlex.Split(test.ExtraArgs)
115-
if err != nil {
116-
return err
117-
}
118-
flags = append(flags, extraArgs...)
138+
flags = append(flags, `--alter='ENGINE=InnoDB'`)
119139
}
120140

121141
log.Printf("[%s] running gh-ost command: %s\n %s", test.Name, config.GhostBinary, strings.Join(flags, "\n "))
@@ -150,7 +170,12 @@ func ReadTests(testsDir string) (tests []Test, err error) {
150170

151171
extraArgsFile := filepath.Join(test.Path, "extra_args")
152172
if _, err = os.Stat(extraArgsFile); err == nil {
153-
if test.ExtraArgs, err = readTestFile(extraArgsFile); err != nil {
173+
extraArgsStr, err := readTestFile(extraArgsFile)
174+
if err != nil {
175+
log.Printf("Failed to read extra_args file %q: %+v", extraArgsFile, err)
176+
return tests, err
177+
}
178+
if test.ExtraArgs, err = shlex.Split(extraArgsStr); err != nil {
154179
log.Printf("Failed to read extra_args file %q: %+v", extraArgsFile, err)
155180
return tests, err
156181
}

go/localtests/utils.go

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,11 @@ type MysqlInfo struct {
1717
Host string
1818
Port int64
1919
Version string
20-
SQLMode string
2120
}
2221

2322
func getMysqlHostInfo(db *sql.DB) (info MysqlInfo, err error) {
24-
res := db.QueryRow("select @@hostname, @@port, @@version, @@sql_mode")
25-
err = res.Scan(&info.Host, &info.Port, &info.Version, &info.SQLMode)
23+
res := db.QueryRow("select @@hostname, @@port, @@version")
24+
err = res.Scan(&info.Host, &info.Port, &info.Version)
2625
return info, err
2726
}
2827

go/sql/parser.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,12 @@ func (this *AlterTableParser) parseAlterToken(alterToken string) {
135135

136136
func (this *AlterTableParser) ParseAlterStatement(alterStatement string) (err error) {
137137
this.alterStatementOptions = alterStatement
138+
for _, trimQuote := range []string{`'`, `"`} {
139+
if strings.HasPrefix(this.alterStatementOptions, trimQuote) && strings.HasSuffix(this.alterStatementOptions, trimQuote) {
140+
this.alterStatementOptions = strings.TrimPrefix(this.alterStatementOptions, trimQuote)
141+
this.alterStatementOptions = strings.TrimSuffix(this.alterStatementOptions, trimQuote)
142+
}
143+
}
138144
for _, alterTableRegexp := range alterTableExplicitSchemaTableRegexps {
139145
if submatch := alterTableRegexp.FindStringSubmatch(this.alterStatementOptions); len(submatch) > 0 {
140146
this.explicitSchema = submatch[1]

go/sql/parser_test.go

Lines changed: 35 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
package sql
77

88
import (
9+
"fmt"
910
"reflect"
1011
"testing"
1112

@@ -18,13 +19,40 @@ func init() {
1819
}
1920

2021
func TestParseAlterStatement(t *testing.T) {
21-
statement := "add column t int, engine=innodb"
22-
parser := NewAlterTableParser()
23-
err := parser.ParseAlterStatement(statement)
24-
test.S(t).ExpectNil(err)
25-
test.S(t).ExpectEquals(parser.alterStatementOptions, statement)
26-
test.S(t).ExpectFalse(parser.HasNonTrivialRenames())
27-
test.S(t).ExpectFalse(parser.IsAutoIncrementDefined())
22+
// plain alter
23+
{
24+
statement := "add column t int, engine=innodb"
25+
parser := NewAlterTableParser()
26+
err := parser.ParseAlterStatement(statement)
27+
test.S(t).ExpectNil(err)
28+
test.S(t).ExpectEquals(parser.alterStatementOptions, statement)
29+
test.S(t).ExpectFalse(parser.HasNonTrivialRenames())
30+
test.S(t).ExpectFalse(parser.IsAutoIncrementDefined())
31+
}
32+
// single-quoted alter
33+
{
34+
statement := "add column t int, engine=innodb"
35+
parser := NewAlterTableParser()
36+
err := parser.ParseAlterStatement(fmt.Sprintf(`'%s'`, statement))
37+
test.S(t).ExpectNil(err)
38+
test.S(t).ExpectEquals(parser.alterStatementOptions, statement)
39+
}
40+
// single-quoted w/comment alter
41+
{
42+
statement := "add column t int 'single-quoted comment'"
43+
parser := NewAlterTableParser()
44+
err := parser.ParseAlterStatement(fmt.Sprintf(`'%s'`, statement))
45+
test.S(t).ExpectNil(err)
46+
test.S(t).ExpectEquals(parser.alterStatementOptions, statement)
47+
}
48+
// double-quoted alter
49+
{
50+
statement := "add column t int, engine=innodb"
51+
parser := NewAlterTableParser()
52+
err := parser.ParseAlterStatement(fmt.Sprintf(`"%s"`, statement))
53+
test.S(t).ExpectNil(err)
54+
test.S(t).ExpectEquals(parser.alterStatementOptions, statement)
55+
}
2856
}
2957

3058
func TestParseAlterStatementTrivialRename(t *testing.T) {

localtests/docker-compose.yml

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,21 +4,23 @@ services:
44
build:
55
context: ../
66
dockerfile: localtests/Dockerfile
7-
command: "--host primary"
87
depends_on:
98
- primary
109
- replica
1110
primary:
12-
image: mysql:${MYSQL_VERSION}
13-
command: "--log-bin --server-id=1 --log-slave-updates"
11+
image: mysql:${MYSQL_TAG}
12+
command: "--enforce-gtid-consistency --gtid-mode=ON --log-bin --log-slave-updates --server-id=1"
1413
environment:
1514
MYSQL_ALLOW_EMPTY_PASSWORD: true
1615
volumes:
17-
- "./init.sql:/docker-entrypoint-initdb.d/init.sql:ro"
16+
- "./init.sql:/docker-entrypoint-initdb.d/01-init.sql:ro"
1817
replica:
19-
image: mysql:${MYSQL_VERSION}
20-
command: "--log-bin --server-id=2 --log-slave-updates --read-only=ON"
18+
image: mysql:${MYSQL_TAG}
19+
command: "--enforce-gtid-consistency --gtid-mode=ON --log-bin --log-slave-updates --read-only=ON --server-id=2"
2120
environment:
2221
MYSQL_ALLOW_EMPTY_PASSWORD: true
22+
ports:
23+
- "3306:3306"
2324
volumes:
24-
- "./init.sql:/docker-entrypoint-initdb.d/init.sql:ro"
25+
- "./init.sql:/docker-entrypoint-initdb.d/01-init.sql:ro"
26+
- "./init-replica.sql:/docker-entrypoint-initdb.d/02-init-replica.sql:ro"

localtests/init-replica.sql

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
STOP SLAVE;
2+
RESET SLAVE;
3+
RESET MASTER;
4+
5+
CHANGE MASTER TO MASTER_HOST='primary', MASTER_USER='gh-ost', MASTER_PASSWORD='gh-ost', MASTER_PORT=3306,
6+
MASTER_AUTO_POSITION=1, MASTER_CONNECT_RETRY=1;
7+
8+
START SLAVE;
9+
SET @@GLOBAL.read_only=ON;

localtests/keyword-column/extra_args

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
--alter='add column `index` int unsigned' \
1+
--alter='add column `index` int unsigned'

localtests/trivial/extra_args

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
--throttle-query='select false' \
1+
--throttle-query='select false'

resources/localtests-init.sql

Lines changed: 0 additions & 3 deletions
This file was deleted.

0 commit comments

Comments
 (0)