diff --git a/go/vt/mysqlctl/mysqld_test.go b/go/vt/mysqlctl/mysqld_test.go index 733b47091a8..3d3112e93d9 100644 --- a/go/vt/mysqlctl/mysqld_test.go +++ b/go/vt/mysqlctl/mysqld_test.go @@ -26,6 +26,8 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "vitess.io/vitess/go/mysql/fakesqldb" + "vitess.io/vitess/go/sqltypes" "vitess.io/vitess/go/vt/dbconfigs" ) @@ -216,19 +218,75 @@ func TestRunMysqlUpgrade(t *testing.T) { err := testMysqld.RunMysqlUpgrade(ctx) assert.NoError(t, err) - // TODO: Look for more tests + // TODO: Add more tests } -// func TestMysqldInit(t *testing.T) { -// os.Remove(MycnfPath) -// testMysqld := NewMysqld(&dbconfigs.GlobalDBConfigs) -// defer testMysqld.Close() +func TestGetDbaConnection(t *testing.T) { + db := fakesqldb.New(t) + defer db.Close() -// ctx := context.Background() -// uid := uint32(11111) -// mycnf := NewMycnf(uid, 0) -// mycnf.Path = MycnfPath -// err := testMysqld.Init(ctx, mycnf, "") + params := db.ConnParams() + cp := *params + dbc := dbconfigs.NewTestDBConfigs(cp, cp, "fakesqldb") -// assert.NoError(t, err) -// } + testMysqld := NewMysqld(dbc) + defer testMysqld.Close() + + ctx := context.Background() + + conn, err := testMysqld.GetDbaConnection(ctx) + assert.NoError(t, err) + assert.NoError(t, conn.Ping()) + defer conn.Close() +} + +func TestGetVersionString(t *testing.T) { + db := fakesqldb.New(t) + defer db.Close() + + params := db.ConnParams() + cp := *params + dbc := dbconfigs.NewTestDBConfigs(cp, cp, "fakesqldb") + + testMysqld := NewMysqld(dbc) + defer testMysqld.Close() + + ctx := context.Background() + str, err := testMysqld.GetVersionString(ctx) + assert.NoError(t, err) + assert.NotEmpty(t, str) + + ver := "test_version" + db.AddQuery("SELECT 1", &sqltypes.Result{}) + db.AddQuery(versionSQLQuery, sqltypes.MakeTestResult(sqltypes.MakeTestFields("test_field", "varchar"), ver)) + + str, err = testMysqld.GetVersionString(ctx) + assert.Equal(t, ver, str) + assert.NoError(t, err) +} + +func TestGetVersionComment(t *testing.T) { + db := fakesqldb.New(t) + defer db.Close() + + params := db.ConnParams() + cp := *params + dbc := dbconfigs.NewTestDBConfigs(cp, cp, "fakesqldb") + + db.AddQuery("SELECT 1", &sqltypes.Result{}) + db.AddQuery("select @@global.version_comment", sqltypes.MakeTestResult(sqltypes.MakeTestFields("@@global.version_comment", "varchar"), "test_version1", "test_version2")) + + testMysqld := NewMysqld(dbc) + defer testMysqld.Close() + + ctx := context.Background() + _, err := testMysqld.GetVersionComment(ctx) + assert.ErrorContains(t, err, "unexpected result length") + + ver := "test_version" + db.AddQuery("select @@global.version_comment", sqltypes.MakeTestResult(sqltypes.MakeTestFields("@@global.version_comment", "varchar"), ver)) + + str, err := testMysqld.GetVersionComment(ctx) + assert.NoError(t, err) + assert.Equal(t, ver, str) +} diff --git a/go/vt/mysqlctl/permissions_test.go b/go/vt/mysqlctl/permissions_test.go new file mode 100644 index 00000000000..5a8954fac15 --- /dev/null +++ b/go/vt/mysqlctl/permissions_test.go @@ -0,0 +1,44 @@ +/* +Copyright 2024 The Vitess Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package mysqlctl + +import ( + "testing" + + "github.com/stretchr/testify/assert" + + "vitess.io/vitess/go/mysql/fakesqldb" + "vitess.io/vitess/go/sqltypes" +) + +func TestGetPermissions(t *testing.T) { + db := fakesqldb.New(t) + defer db.Close() + + testMysqld := NewFakeMysqlDaemon(db) + defer testMysqld.Close() + + testMysqld.FetchSuperQueryMap = map[string]*sqltypes.Result{ + "SELECT * FROM mysql.user ORDER BY host, user": sqltypes.MakeTestResult(sqltypes.MakeTestFields("host|user", "varchar|varchar"), "test_host1|test_user1", "test_host2|test_user2"), + "SELECT * FROM mysql.db ORDER BY host, db, user": sqltypes.MakeTestResult(sqltypes.MakeTestFields("host|user|db", "varchar|varchar|varchar"), "test_host1|test_user1|test_db1", "test_host2|test_user2|test_db2"), + } + + per, err := GetPermissions(testMysqld) + assert.NoError(t, err) + assert.Len(t, per.DbPermissions, 2) + assert.Len(t, per.UserPermissions, 2) +} diff --git a/go/vt/mysqlctl/redo_log_test.go b/go/vt/mysqlctl/redo_log_test.go new file mode 100644 index 00000000000..ae2005bdc51 --- /dev/null +++ b/go/vt/mysqlctl/redo_log_test.go @@ -0,0 +1,52 @@ +/* +Copyright 2024 The Vitess Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package mysqlctl + +import ( + "context" + "testing" + + "github.com/stretchr/testify/assert" + + "vitess.io/vitess/go/mysql/fakesqldb" + "vitess.io/vitess/go/sqltypes" + "vitess.io/vitess/go/vt/dbconfigs" +) + +func TestProcessCanDisableRedoLog(t *testing.T) { + db := fakesqldb.New(t) + defer db.Close() + + params := db.ConnParams() + cp := *params + dbc := dbconfigs.NewTestDBConfigs(cp, cp, "fakesqldb") + + db.AddQuery("SELECT 1", &sqltypes.Result{}) + db.AddQuery("SELECT variable_value FROM performance_schema.global_status WHERE variable_name = 'innodb_redo_log_enabled'", sqltypes.MakeTestResult(sqltypes.MakeTestFields("field1", "varchar"), "val1")) + + testMysqld := NewMysqld(dbc) + defer testMysqld.Close() + + res, err := testMysqld.ProcessCanDisableRedoLog(context.Background()) + assert.NoError(t, err) + assert.True(t, res) + + db.AddQuery("SELECT variable_value FROM performance_schema.global_status WHERE variable_name = 'innodb_redo_log_enabled'", &sqltypes.Result{}) + res, err = testMysqld.ProcessCanDisableRedoLog(context.Background()) + assert.Error(t, err) + assert.False(t, res) +} diff --git a/go/vt/mysqlctl/reparent_test.go b/go/vt/mysqlctl/reparent_test.go index 468ed7200bc..7d43ffe9d30 100644 --- a/go/vt/mysqlctl/reparent_test.go +++ b/go/vt/mysqlctl/reparent_test.go @@ -17,11 +17,15 @@ limitations under the License. package mysqlctl import ( + "context" "testing" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "vitess.io/vitess/go/mysql/fakesqldb" + "vitess.io/vitess/go/sqltypes" + "vitess.io/vitess/go/vt/dbconfigs" "vitess.io/vitess/go/vt/logutil" ) @@ -48,3 +52,44 @@ func TestPopulateReparentJournal(t *testing.T) { want := `INSERT INTO _vt.reparent_journal (time_created_ns, action_name, primary_alias, replication_position) VALUES (1, 'action', 'primaryAlias', 'MySQL56/145e508e-ae54-11e9-8ce6-46824dd1815e:1-3,1e51f8be-ae54-11e9-a7c6-4280a041109b:1-3,47b59de1-b368-11e9-b48b-624401d35560:1-152981,557def0a-b368-11e9-84ed-f6fffd91cc57:1-3,599ef589-ae55-11e9-9688-ca1f44501925:1-14857169,b9ce485d-b36b-11e9-9b17-2a6e0a6011f4:1-371262')` assert.Equal(t, want, res) } + +func TestWaitForReparentJournal(t *testing.T) { + db := fakesqldb.New(t) + defer db.Close() + + params := db.ConnParams() + cp := *params + dbc := dbconfigs.NewTestDBConfigs(cp, cp, "fakesqldb") + + db.AddQuery("SELECT 1", &sqltypes.Result{}) + db.AddQuery("SELECT action_name, primary_alias, replication_position FROM _vt.reparent_journal WHERE time_created_ns=5", sqltypes.MakeTestResult(sqltypes.MakeTestFields("test_field", "varchar"), "test_row")) + + testMysqld := NewMysqld(dbc) + defer testMysqld.Close() + + ctx := context.Background() + err := testMysqld.WaitForReparentJournal(ctx, 5) + assert.NoError(t, err) +} + +func TestPromote(t *testing.T) { + db := fakesqldb.New(t) + defer db.Close() + + params := db.ConnParams() + cp := *params + dbc := dbconfigs.NewTestDBConfigs(cp, cp, "fakesqldb") + + db.AddQuery("SELECT 1", &sqltypes.Result{}) + db.AddQuery("STOP SLAVE", &sqltypes.Result{}) + db.AddQuery("RESET SLAVE ALL", &sqltypes.Result{}) + db.AddQuery("FLUSH BINARY LOGS", &sqltypes.Result{}) + db.AddQuery("SELECT @@global.gtid_executed", sqltypes.MakeTestResult(sqltypes.MakeTestFields("test_field", "varchar"), "8bc65c84-3fe4-11ed-a912-257f0fcdd6c9:1-8,8bc65c84-3fe4-11ed-a912-257f0fcdd6c9:12-17")) + + testMysqld := NewMysqld(dbc) + defer testMysqld.Close() + + pos, err := testMysqld.Promote(map[string]string{}) + assert.NoError(t, err) + assert.Equal(t, "8bc65c84-3fe4-11ed-a912-257f0fcdd6c9:1-8:12-17", pos.String()) +} diff --git a/go/vt/mysqlctl/replication_test.go b/go/vt/mysqlctl/replication_test.go index e7accd77182..d47c51928e3 100644 --- a/go/vt/mysqlctl/replication_test.go +++ b/go/vt/mysqlctl/replication_test.go @@ -17,12 +17,16 @@ limitations under the License. package mysqlctl import ( - "fmt" + "context" + "net" "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "vitess.io/vitess/go/mysql/fakesqldb" + "vitess.io/vitess/go/mysql/replication" + "vitess.io/vitess/go/sqltypes" "vitess.io/vitess/go/vt/dbconfigs" ) @@ -86,7 +90,6 @@ func TestRedactPassword(t *testing.T) { } func TestWaitForReplicationStart(t *testing.T) { - // TODO: Needs more tests db := fakesqldb.New(t) fakemysqld := NewFakeMysqlDaemon(db) @@ -99,25 +102,574 @@ func TestWaitForReplicationStart(t *testing.T) { assert.NoError(t, err) } -func TestStartReplication(t *testing.T) { +func TestGetMysqlPort(t *testing.T) { db := fakesqldb.New(t) + defer db.Close() + + params := db.ConnParams() + cp := *params + dbc := dbconfigs.NewTestDBConfigs(cp, cp, "fakesqldb") + + db.AddQuery("SELECT 1", &sqltypes.Result{}) + db.AddQuery("SHOW VARIABLES LIKE 'port'", sqltypes.MakeTestResult(sqltypes.MakeTestFields("test_field|test_field2", "varchar|uint64"), "test_port|12")) + testMysqld := NewMysqld(dbc) + defer testMysqld.Close() + + res, err := testMysqld.GetMysqlPort() + assert.Equal(t, int32(12), res) + assert.NoError(t, err) + + db.AddQuery("SHOW VARIABLES LIKE 'port'", &sqltypes.Result{}) + res, err = testMysqld.GetMysqlPort() + assert.ErrorContains(t, err, "no port variable in mysql") + assert.Equal(t, int32(0), res) +} + +func TestGetServerID(t *testing.T) { + db := fakesqldb.New(t) + defer db.Close() + + params := db.ConnParams() + cp := *params + dbc := dbconfigs.NewTestDBConfigs(cp, cp, "fakesqldb") + + db.AddQuery("SELECT 1", &sqltypes.Result{}) + db.AddQuery("select @@global.server_id", sqltypes.MakeTestResult(sqltypes.MakeTestFields("test_field", "uint64"), "12")) + testMysqld := NewMysqld(dbc) + defer testMysqld.Close() + + ctx := context.Background() + res, err := testMysqld.GetServerID(ctx) + assert.Equal(t, uint32(12), res) + assert.NoError(t, err) + + db.AddQuery("select @@global.server_id", &sqltypes.Result{}) + res, err = testMysqld.GetServerID(ctx) + assert.ErrorContains(t, err, "no server_id in mysql") + assert.Equal(t, uint32(0), res) +} + +func TestGetServerUUID(t *testing.T) { + db := fakesqldb.New(t) + defer db.Close() + + params := db.ConnParams() + cp := *params + dbc := dbconfigs.NewTestDBConfigs(cp, cp, "fakesqldb") + + db.AddQuery("SELECT 1", &sqltypes.Result{}) + + testMysqld := NewMysqld(dbc) + defer testMysqld.Close() + + uuid := "test_uuid" + db.AddQuery("SELECT @@global.server_uuid", sqltypes.MakeTestResult(sqltypes.MakeTestFields("test_field", "varchar"), uuid)) + + ctx := context.Background() + res, err := testMysqld.GetServerUUID(ctx) + assert.Equal(t, uuid, res) + assert.NoError(t, err) + + db.AddQuery("SELECT @@global.server_uuid", &sqltypes.Result{}) + res, err = testMysqld.GetServerUUID(ctx) + assert.Error(t, err) + assert.Equal(t, "", res) +} + +func TestWaitSourcePos(t *testing.T) { + db := fakesqldb.New(t) + defer db.Close() + + params := db.ConnParams() + cp := *params + dbc := dbconfigs.NewTestDBConfigs(cp, cp, "fakesqldb") + + db.AddQuery("SELECT 1", &sqltypes.Result{}) + db.AddQuery("SELECT @@global.gtid_executed", sqltypes.MakeTestResult(sqltypes.MakeTestFields("test_field", "varchar"), "8bc65c84-3fe4-11ed-a912-257f0fcdd6c9:1-8,8bc65c84-3fe4-11ed-a912-257f0fcdd6c9:12-17")) + + testMysqld := NewMysqld(dbc) + defer testMysqld.Close() + + ctx := context.Background() + err := testMysqld.WaitSourcePos(ctx, replication.Position{GTIDSet: replication.Mysql56GTIDSet{}}) + assert.NoError(t, err) + + db.AddQuery("SELECT @@global.gtid_executed", sqltypes.MakeTestResult(sqltypes.MakeTestFields("test_field", "varchar"), "invalid_id")) + err = testMysqld.WaitSourcePos(ctx, replication.Position{GTIDSet: replication.Mysql56GTIDSet{}}) + assert.ErrorContains(t, err, "invalid MySQL 5.6 GTID set") + + // TODO: Look for more cases +} + +func TestReplicationStatus(t *testing.T) { + db := fakesqldb.New(t) + defer db.Close() + + params := db.ConnParams() + cp := *params + dbc := dbconfigs.NewTestDBConfigs(cp, cp, "fakesqldb") + + db.AddQuery("SELECT 1", &sqltypes.Result{}) + db.AddQuery("SHOW SLAVE STATUS", sqltypes.MakeTestResult(sqltypes.MakeTestFields("test_field", "varchar"), "test_status")) + + testMysqld := NewMysqld(dbc) + defer testMysqld.Close() + + res, err := testMysqld.ReplicationStatus() + assert.NoError(t, err) + assert.True(t, res.ReplicationLagUnknown) + + db.AddQuery("SHOW SLAVE STATUS", &sqltypes.Result{}) + res, err = testMysqld.ReplicationStatus() + assert.Error(t, err) + assert.False(t, res.ReplicationLagUnknown) +} + +func TestPrimaryStatus(t *testing.T) { + db := fakesqldb.New(t) + defer db.Close() + + params := db.ConnParams() + cp := *params + dbc := dbconfigs.NewTestDBConfigs(cp, cp, "fakesqldb") + + db.AddQuery("SELECT 1", &sqltypes.Result{}) + db.AddQuery("SHOW MASTER STATUS", sqltypes.MakeTestResult(sqltypes.MakeTestFields("test_field", "varchar"), "test_status")) + + testMysqld := NewMysqld(dbc) + defer testMysqld.Close() + + ctx := context.Background() + res, err := testMysqld.PrimaryStatus(ctx) + assert.NoError(t, err) + assert.NotNil(t, res) + + db.AddQuery("SHOW MASTER STATUS", &sqltypes.Result{}) + _, err = testMysqld.PrimaryStatus(ctx) + assert.ErrorContains(t, err, "no master status") +} + +func TestGetGTIDPurged(t *testing.T) { + db := fakesqldb.New(t) + defer db.Close() + params := db.ConnParams() cp := *params - dbc := dbconfigs.NewTestDBConfigs(cp, cp, "test_db_name") - // uid := uint32(11111) - // cnf := NewMycnf(uid, 6802) - // // Assigning ServerID to be different from tablet UID to make sure that there are no - // // assumptions in the code that those IDs are the same. - // cnf.ServerID = 22222 + dbc := dbconfigs.NewTestDBConfigs(cp, cp, "fakesqldb") + + db.AddQuery("SELECT 1", &sqltypes.Result{}) + db.AddQuery("SELECT @@global.gtid_purged", sqltypes.MakeTestResult(sqltypes.MakeTestFields("test_field", "varchar"), "8bc65c84-3fe4-11ed-a912-257f0fcdd6c9:1-8,8bc65c84-3fe4-11ed-a912-257f0fcdd6c9:12-17")) + + testMysqld := NewMysqld(dbc) + defer testMysqld.Close() + + ctx := context.Background() + res, err := testMysqld.GetGTIDPurged(ctx) + assert.NoError(t, err) + assert.Equal(t, "8bc65c84-3fe4-11ed-a912-257f0fcdd6c9:1-8:12-17", res.String()) +} + +func TestPrimaryPosition(t *testing.T) { + db := fakesqldb.New(t) + defer db.Close() + + params := db.ConnParams() + cp := *params + dbc := dbconfigs.NewTestDBConfigs(cp, cp, "fakesqldb") + + db.AddQuery("SELECT 1", &sqltypes.Result{}) + db.AddQuery("SELECT @@global.gtid_executed", sqltypes.MakeTestResult(sqltypes.MakeTestFields("test_field", "varchar"), "8bc65c84-3fe4-11ed-a912-257f0fcdd6c9:1-8,8bc65c84-3fe4-11ed-a912-257f0fcdd6c9:12-17")) + + testMysqld := NewMysqld(dbc) + defer testMysqld.Close() + + res, err := testMysqld.PrimaryPosition() + assert.NoError(t, err) + assert.Equal(t, "8bc65c84-3fe4-11ed-a912-257f0fcdd6c9:1-8:12-17", res.String()) +} + +func TestSetReplicationPosition(t *testing.T) { + db := fakesqldb.New(t) + defer db.Close() + + params := db.ConnParams() + cp := *params + dbc := dbconfigs.NewTestDBConfigs(cp, cp, "fakesqldb") + + db.AddQuery("SELECT 1", &sqltypes.Result{}) + db.AddQuery("RESET MASTER", &sqltypes.Result{}) + + testMysqld := NewMysqld(dbc) + defer testMysqld.Close() + + ctx := context.Background() + + pos := replication.Position{GTIDSet: replication.Mysql56GTIDSet{}} + sid := replication.SID{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15} + pos.GTIDSet = pos.GTIDSet.AddGTID(replication.Mysql56GTID{Server: sid, Sequence: 1}) + + err := testMysqld.SetReplicationPosition(ctx, pos) + assert.Error(t, err) + + // We expect this query to be executed + db.AddQuery("SET GLOBAL gtid_purged = '00010203-0405-0607-0809-0a0b0c0d0e0f:1'", &sqltypes.Result{}) + + err = testMysqld.SetReplicationPosition(ctx, pos) + assert.NoError(t, err) +} + +func TestSetReplicationSource(t *testing.T) { + db := fakesqldb.New(t) + defer db.Close() + + params := db.ConnParams() + cp := *params + dbc := dbconfigs.NewTestDBConfigs(cp, cp, "fakesqldb") + + db.AddQuery("SELECT 1", &sqltypes.Result{}) + db.AddQuery("RESET MASTER", &sqltypes.Result{}) + db.AddQuery("STOP SLAVE", &sqltypes.Result{}) + + testMysqld := NewMysqld(dbc) + defer testMysqld.Close() + + ctx := context.Background() + + // We expect query containing passed host and port to be executed + err := testMysqld.SetReplicationSource(ctx, "test_host", 2, true, true) + assert.ErrorContains(t, err, `MASTER_HOST = 'test_host'`) + assert.ErrorContains(t, err, `MASTER_PORT = 2`) + assert.ErrorContains(t, err, `CHANGE MASTER TO`) +} + +func TestResetReplication(t *testing.T) { + db := fakesqldb.New(t) + defer db.Close() + + params := db.ConnParams() + cp := *params + dbc := dbconfigs.NewTestDBConfigs(cp, cp, "fakesqldb") + + db.AddQuery("SELECT 1", &sqltypes.Result{}) + db.AddQuery("SHOW GLOBAL VARIABLES LIKE 'rpl_semi_sync%'", &sqltypes.Result{}) + db.AddQuery("STOP SLAVE", &sqltypes.Result{}) + + testMysqld := NewMysqld(dbc) + defer testMysqld.Close() + + ctx := context.Background() + err := testMysqld.ResetReplication(ctx) + assert.ErrorContains(t, err, "RESET SLAVE ALL") + + // We expect this query to be executed + db.AddQuery("RESET SLAVE ALL", &sqltypes.Result{}) + err = testMysqld.ResetReplication(ctx) + assert.ErrorContains(t, err, "RESET MASTER") + + // We expect this query to be executed + db.AddQuery("RESET MASTER", &sqltypes.Result{}) + err = testMysqld.ResetReplication(ctx) + assert.NoError(t, err) +} + +func TestResetReplicationParameters(t *testing.T) { + db := fakesqldb.New(t) + defer db.Close() + + params := db.ConnParams() + cp := *params + dbc := dbconfigs.NewTestDBConfigs(cp, cp, "fakesqldb") + + db.AddQuery("SELECT 1", &sqltypes.Result{}) + db.AddQuery("SHOW GLOBAL VARIABLES LIKE 'rpl_semi_sync%'", &sqltypes.Result{}) + db.AddQuery("STOP SLAVE", &sqltypes.Result{}) + + testMysqld := NewMysqld(dbc) + defer testMysqld.Close() + + ctx := context.Background() + err := testMysqld.ResetReplicationParameters(ctx) + assert.ErrorContains(t, err, "RESET SLAVE ALL") + + // We expect this query to be executed + db.AddQuery("RESET SLAVE ALL", &sqltypes.Result{}) + err = testMysqld.ResetReplicationParameters(ctx) + assert.NoError(t, err) +} + +func TestFindReplicas(t *testing.T) { + db := fakesqldb.New(t) + fakemysqld := NewFakeMysqlDaemon(db) - // dbconfigs.GlobalDBConfigs.InitWithSocket(cnf.SocketFile, collations.MySQL8()) - mysqld := NewMysqld(dbc) defer func() { db.Close() - mysqld.Close() + fakemysqld.Close() }() - // servenv.OnClose(mysqld.Close) - err := mysqld.StartReplication(map[string]string{}) - fmt.Println("Error: ", err) + fakemysqld.FetchSuperQueryMap = map[string]*sqltypes.Result{ + "SHOW PROCESSLIST": sqltypes.MakeTestResult(sqltypes.MakeTestFields("Id|User|Host|db|Command|Time|State|Info", "varchar|varchar|varchar|varchar|varchar|varchar|varchar|varchar"), "1|user1|localhost:12|db1|Binlog Dump|54|Has sent all binlog to slave|NULL"), + } + + res, err := FindReplicas(fakemysqld) + assert.NoError(t, err) + + want, err := net.LookupHost("localhost") + require.NoError(t, err) + + assert.Equal(t, want, res) +} + +func TestGetBinlogInformation(t *testing.T) { + db := fakesqldb.New(t) + defer db.Close() + + params := db.ConnParams() + cp := *params + dbc := dbconfigs.NewTestDBConfigs(cp, cp, "fakesqldb") + + db.AddQuery("SELECT 1", &sqltypes.Result{}) + db.AddQuery("SELECT @@global.binlog_format, @@global.log_bin, @@global.log_slave_updates, @@global.binlog_row_image", sqltypes.MakeTestResult(sqltypes.MakeTestFields("@@global.binlog_format|@@global.log_bin|@@global.log_slave_updates|@@global.binlog_row_image", "varchar|int64|int64|varchar"), "binlog|1|2|row_image")) + + testMysqld := NewMysqld(dbc) + defer testMysqld.Close() + + ctx := context.Background() + bin, logBin, slaveUpdate, rowImage, err := testMysqld.GetBinlogInformation(ctx) + assert.NoError(t, err) + assert.Equal(t, "binlog", bin) + assert.Equal(t, "row_image", rowImage) + assert.True(t, logBin) + assert.False(t, slaveUpdate) +} + +func TestGetGTIDMode(t *testing.T) { + db := fakesqldb.New(t) + defer db.Close() + + params := db.ConnParams() + cp := *params + dbc := dbconfigs.NewTestDBConfigs(cp, cp, "fakesqldb") + + in := "8bc65c84-3fe4-11ed-a912-257f0fcdd6c9:1-8,8bc65c84-3fe4-11ed-a912-257f0fcdd6c9:12-17" + db.AddQuery("SELECT 1", &sqltypes.Result{}) + db.AddQuery("select @@global.gtid_mode", sqltypes.MakeTestResult(sqltypes.MakeTestFields("test_field", "varchar"), in)) + + testMysqld := NewMysqld(dbc) + defer testMysqld.Close() + + ctx := context.Background() + res, err := testMysqld.GetGTIDMode(ctx) + assert.NoError(t, err) + assert.Equal(t, in, res) +} + +func TestFlushBinaryLogs(t *testing.T) { + db := fakesqldb.New(t) + defer db.Close() + + params := db.ConnParams() + cp := *params + dbc := dbconfigs.NewTestDBConfigs(cp, cp, "fakesqldb") + + db.AddQuery("SELECT 1", &sqltypes.Result{}) + + testMysqld := NewMysqld(dbc) + defer testMysqld.Close() + + // We expect this query to be executed + err := testMysqld.SetSemiSyncEnabled(true, true) + assert.ErrorContains(t, err, "FLUSH BINARY LOGS") +} + +func TestGetBinaryLogs(t *testing.T) { + db := fakesqldb.New(t) + defer db.Close() + + params := db.ConnParams() + cp := *params + dbc := dbconfigs.NewTestDBConfigs(cp, cp, "fakesqldb") + + db.AddQuery("SELECT 1", &sqltypes.Result{}) + + testMysqld := NewMysqld(dbc) + defer testMysqld.Close() + + db.AddQuery("SHOW BINARY LOGS", sqltypes.MakeTestResult(sqltypes.MakeTestFields("field", "varchar"), "binlog1", "binlog2")) + + res, err := testMysqld.GetBinaryLogs(context.Background()) + assert.NoError(t, err) + assert.Len(t, res, 2) + assert.Contains(t, res, "binlog1") + assert.Contains(t, res, "binlog2") +} + +func TestGetPreviousGTIDs(t *testing.T) { + db := fakesqldb.New(t) + defer db.Close() + + params := db.ConnParams() + cp := *params + dbc := dbconfigs.NewTestDBConfigs(cp, cp, "fakesqldb") + + db.AddQuery("SELECT 1", &sqltypes.Result{}) + db.AddQuery("SHOW BINLOG EVENTS IN 'binlog' LIMIT 2", sqltypes.MakeTestResult(sqltypes.MakeTestFields("Event_type|Info", "varchar|varchar"), "Previous_gtids|8bc65c84-3fe4-11ed-a912-257f0fcdd6c9:1-8")) + + testMysqld := NewMysqld(dbc) + defer testMysqld.Close() + + ctx := context.Background() + res, err := testMysqld.GetPreviousGTIDs(ctx, "binlog") + assert.NoError(t, err) + assert.Equal(t, "8bc65c84-3fe4-11ed-a912-257f0fcdd6c9:1-8", res) +} + +func TestSetSemiSyncEnabled(t *testing.T) { + db := fakesqldb.New(t) + defer db.Close() + + params := db.ConnParams() + cp := *params + dbc := dbconfigs.NewTestDBConfigs(cp, cp, "fakesqldb") + + db.AddQuery("SELECT 1", &sqltypes.Result{}) + + testMysqld := NewMysqld(dbc) + defer testMysqld.Close() + + // We expect this query to be executed + err := testMysqld.SetSemiSyncEnabled(true, true) + assert.ErrorContains(t, err, "SET GLOBAL rpl_semi_sync_master_enabled = 1, GLOBAL rpl_semi_sync_slave_enabled = 1") + + // We expect this query to be executed + err = testMysqld.SetSemiSyncEnabled(true, false) + assert.ErrorContains(t, err, "SET GLOBAL rpl_semi_sync_master_enabled = 1, GLOBAL rpl_semi_sync_slave_enabled = 0") + + // We expect this query to be executed + err = testMysqld.SetSemiSyncEnabled(false, true) + assert.ErrorContains(t, err, "SET GLOBAL rpl_semi_sync_master_enabled = 0, GLOBAL rpl_semi_sync_slave_enabled = 1") +} + +func TestSemiSyncEnabled(t *testing.T) { + db := fakesqldb.New(t) + defer db.Close() + + params := db.ConnParams() + cp := *params + dbc := dbconfigs.NewTestDBConfigs(cp, cp, "fakesqldb") + + db.AddQuery("SELECT 1", &sqltypes.Result{}) + db.AddQuery("SHOW VARIABLES LIKE 'rpl_semi_sync_%_enabled'", sqltypes.MakeTestResult(sqltypes.MakeTestFields("field1|field2", "varchar|varchar"), "rpl_semi_sync_master_enabled|OFF", "rpl_semi_sync_slave_enabled|ON")) + + testMysqld := NewMysqld(dbc) + defer testMysqld.Close() + + p, r := testMysqld.SemiSyncEnabled() + assert.False(t, p) + assert.True(t, r) +} + +func TestSemiSyncStatus(t *testing.T) { + db := fakesqldb.New(t) + defer db.Close() + + params := db.ConnParams() + cp := *params + dbc := dbconfigs.NewTestDBConfigs(cp, cp, "fakesqldb") + + db.AddQuery("SELECT 1", &sqltypes.Result{}) + db.AddQuery("SHOW STATUS LIKE 'Rpl_semi_sync_%_status'", sqltypes.MakeTestResult(sqltypes.MakeTestFields("field1|field2", "varchar|varchar"), "Rpl_semi_sync_master_status|ON", "Rpl_semi_sync_slave_status|OFF")) + + testMysqld := NewMysqld(dbc) + defer testMysqld.Close() + + p, r := testMysqld.SemiSyncStatus() + assert.True(t, p) + assert.False(t, r) +} + +func TestSemiSyncClients(t *testing.T) { + db := fakesqldb.New(t) + defer db.Close() + + params := db.ConnParams() + cp := *params + dbc := dbconfigs.NewTestDBConfigs(cp, cp, "fakesqldb") + + db.AddQuery("SELECT 1", &sqltypes.Result{}) + db.AddQuery("SHOW STATUS LIKE 'Rpl_semi_sync_master_clients'", sqltypes.MakeTestResult(sqltypes.MakeTestFields("field1|field2", "varchar|uint64"), "val1|12")) + + testMysqld := NewMysqld(dbc) + defer testMysqld.Close() + + res := testMysqld.SemiSyncClients() + assert.Equal(t, uint32(12), res) +} + +func TestSemiSyncSettings(t *testing.T) { + db := fakesqldb.New(t) + defer db.Close() + + params := db.ConnParams() + cp := *params + dbc := dbconfigs.NewTestDBConfigs(cp, cp, "fakesqldb") + + db.AddQuery("SELECT 1", &sqltypes.Result{}) + db.AddQuery("SHOW VARIABLES LIKE 'rpl_semi_sync_%'", sqltypes.MakeTestResult(sqltypes.MakeTestFields("field1|field2", "varchar|uint64"), "rpl_semi_sync_master_timeout|123", "rpl_semi_sync_master_wait_for_slave_count|80")) + + testMysqld := NewMysqld(dbc) + defer testMysqld.Close() + + timeout, replicas := testMysqld.SemiSyncSettings() + assert.Equal(t, uint64(123), timeout) + assert.Equal(t, uint32(80), replicas) +} + +func TestSemiSyncReplicationStatus(t *testing.T) { + db := fakesqldb.New(t) + defer db.Close() + + params := db.ConnParams() + cp := *params + dbc := dbconfigs.NewTestDBConfigs(cp, cp, "fakesqldb") + + db.AddQuery("SELECT 1", &sqltypes.Result{}) + db.AddQuery("SHOW STATUS LIKE 'rpl_semi_sync_slave_status'", sqltypes.MakeTestResult(sqltypes.MakeTestFields("field1|field2", "varchar|uint64"), "rpl_semi_sync_slave_status|ON")) + + testMysqld := NewMysqld(dbc) + defer testMysqld.Close() + + res, err := testMysqld.SemiSyncReplicationStatus() + assert.NoError(t, err) + assert.True(t, res) + + db.AddQuery("SHOW STATUS LIKE 'rpl_semi_sync_slave_status'", sqltypes.MakeTestResult(sqltypes.MakeTestFields("field1|field2", "varchar|uint64"), "rpl_semi_sync_slave_status|OFF")) + + res, err = testMysqld.SemiSyncReplicationStatus() + assert.NoError(t, err) + assert.False(t, res) +} + +func TestSemiSyncExtensionLoaded(t *testing.T) { + db := fakesqldb.New(t) + defer db.Close() + + params := db.ConnParams() + cp := *params + dbc := dbconfigs.NewTestDBConfigs(cp, cp, "fakesqldb") + + db.AddQuery("SELECT 1", &sqltypes.Result{}) + db.AddQuery("SELECT COUNT(*) > 0 AS plugin_loaded FROM information_schema.plugins WHERE plugin_name LIKE 'rpl_semi_sync%'", sqltypes.MakeTestResult(sqltypes.MakeTestFields("field1", "int64"), "1")) + + testMysqld := NewMysqld(dbc) + defer testMysqld.Close() + + res, err := testMysqld.SemiSyncExtensionLoaded() + assert.NoError(t, err) + assert.True(t, res) + + db.AddQuery("SELECT COUNT(*) > 0 AS plugin_loaded FROM information_schema.plugins WHERE plugin_name LIKE 'rpl_semi_sync%'", sqltypes.MakeTestResult(sqltypes.MakeTestFields("field1", "int64"), "0")) + + res, err = testMysqld.SemiSyncExtensionLoaded() + assert.NoError(t, err) + assert.False(t, res) } diff --git a/go/vt/mysqlctl/schema_test.go b/go/vt/mysqlctl/schema_test.go index 72036a54cdd..e1ea0d7d955 100644 --- a/go/vt/mysqlctl/schema_test.go +++ b/go/vt/mysqlctl/schema_test.go @@ -1,3 +1,19 @@ +/* +Copyright 2024 The Vitess Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + package mysqlctl import ( @@ -10,6 +26,8 @@ import ( "vitess.io/vitess/go/mysql/fakesqldb" "vitess.io/vitess/go/sqltypes" + "vitess.io/vitess/go/vt/dbconfigs" + "vitess.io/vitess/go/vt/mysqlctl/tmutils" querypb "vitess.io/vitess/go/vt/proto/query" "vitess.io/vitess/go/vt/proto/tabletmanagerdata" ) @@ -107,46 +125,88 @@ func TestColumnList(t *testing.T) { } -// func TestGetSchema(t *testing.T) { -// uid := uint32(11111) -// cnf := NewMycnf(uid, 6802) -// // Assigning ServerID to be different from tablet UID to make sure that there are no -// // assumptions in the code that those IDs are the same. -// cnf.ServerID = 22222 - -// // expect these in the output my.cnf -// os.Setenv("KEYSPACE", "test-messagedb") -// os.Setenv("SHARD", "0") -// os.Setenv("TABLET_TYPE", "PRIMARY") -// os.Setenv("TABLET_ID", "11111") -// os.Setenv("TABLET_DIR", TabletDir(uid)) -// os.Setenv("MYSQL_PORT", "15306") -// // this is not being passed, so it should be nil -// os.Setenv("MY_VAR", "myvalue") - -// dbconfigs.GlobalDBConfigs.InitWithSocket(cnf.SocketFile, collations.MySQL8()) -// mysqld := NewMysqld(&dbconfigs.GlobalDBConfigs) -// sc, err := mysqld.GetSchema(context.Background(), mysqld.dbcfgs.DBName, &tabletmanagerdata.GetSchemaRequest{}) - -// // TODO: This needs to be fixed -// fmt.Println(sc, err) -// } +func TestGetSchemaAndPreflightSchemaChange(t *testing.T) { + db := fakesqldb.New(t) + defer db.Close() + + params := db.ConnParams() + cp := *params + dbc := dbconfigs.NewTestDBConfigs(cp, cp, "fakesqldb") + + testMysqld := NewMysqld(dbc) + defer testMysqld.Close() + + db.AddQuery("SELECT 1", &sqltypes.Result{}) + db.AddQuery("SET sql_log_bin = 0", &sqltypes.Result{}) + db.AddQuery("DROP DATABASE IF EXISTS _vt_preflight", &sqltypes.Result{}) + + db.AddQuery("SHOW CREATE DATABASE IF NOT EXISTS `fakesqldb`", sqltypes.MakeTestResult(sqltypes.MakeTestFields("test_field|cmd", "varchar|varchar"), "create_db|create_db_cmd")) + db.AddQuery("SHOW CREATE TABLE `fakesqldb`.`test_table`", sqltypes.MakeTestResult(sqltypes.MakeTestFields("test_field|cmd", "varchar|varchar"), "create_table|create_table_cmd")) + + db.AddQuery("SELECT table_name, table_type, data_length, table_rows FROM information_schema.tables WHERE table_schema = 'fakesqldb' AND table_type = 'BASE TABLE'", sqltypes.MakeTestResult( + sqltypes.MakeTestFields("table_name|table_type|data_length|table_rows", "varchar|varchar|uint64|uint64"), "test_table|test_type|NULL|2")) + + db.AddQuery("SELECT table_name, table_type, data_length, table_rows FROM information_schema.tables WHERE table_schema = 'fakesqldb'", sqltypes.MakeTestResult( + sqltypes.MakeTestFields("table_name|table_type|data_length|table_rows", "varchar|varchar|uint64|uint64"), "test_table|test_type|NULL|2")) + + query := fmt.Sprintf(GetColumnNamesQuery, sqltypes.EncodeStringSQL(db.Name()), sqltypes.EncodeStringSQL("test_table")) + db.AddQuery(query, &sqltypes.Result{ + Fields: []*querypb.Field{{ + Name: "column_name", + Type: sqltypes.VarChar, + }}, + Rows: [][]sqltypes.Value{ + {sqltypes.NewVarChar("col1")}, + {sqltypes.NewVarChar("col2")}, + }, + }) + + db.AddQuery("SELECT `col1`, `col2` FROM `fakesqldb`.`test_table` WHERE 1 != 1", &sqltypes.Result{ + Fields: []*querypb.Field{ + { + Name: "col1", + Type: sqltypes.VarChar, + }, + { + Name: "col2", + Type: sqltypes.VarChar, + }, + }, + Rows: [][]sqltypes.Value{}, + }) + + tableList, err := tableListSQL([]string{"test_table"}) + require.NoError(t, err) + + query = ` + SELECT TABLE_NAME as table_name, COLUMN_NAME as column_name + FROM information_schema.STATISTICS + WHERE TABLE_SCHEMA = %s AND TABLE_NAME IN %s AND LOWER(INDEX_NAME) = 'primary' + ORDER BY table_name, SEQ_IN_INDEX` + query = fmt.Sprintf(query, sqltypes.EncodeStringSQL("fakesqldb"), tableList) + db.AddQuery(query, sqltypes.MakeTestResult(sqltypes.MakeTestFields("TABLE_NAME|COLUMN_NAME", "varchar|varchar"), "test_table|col1", "test_table|col2")) + + ctx := context.Background() + res, err := testMysqld.GetSchema(ctx, db.Name(), &tabletmanagerdata.GetSchemaRequest{}) + assert.NoError(t, err) + assert.Equal(t, res.String(), `database_schema:"create_db_cmd" table_definitions:{name:"test_table" schema:"create_table_cmd" columns:"col1" columns:"col2" type:"test_type" row_count:2 fields:{name:"col1" type:VARCHAR} fields:{name:"col2" type:VARCHAR}}`) +} func TestResolveTables(t *testing.T) { db := fakesqldb.New(t) - md := NewFakeMysqlDaemon(db) + testMysqld := NewFakeMysqlDaemon(db) defer func() { db.Close() - md.Close() + testMysqld.Close() }() ctx := context.Background() - res, err := ResolveTables(ctx, md, db.Name(), []string{}) + res, err := ResolveTables(ctx, testMysqld, db.Name(), []string{}) assert.ErrorContains(t, err, "no schema defined") assert.Nil(t, res) - md.Schema = &tabletmanagerdata.SchemaDefinition{TableDefinitions: tableDefinitions{{ + testMysqld.Schema = &tabletmanagerdata.SchemaDefinition{TableDefinitions: tableDefinitions{{ Name: "table1", Schema: "schema1", }, { @@ -154,11 +214,137 @@ func TestResolveTables(t *testing.T) { Schema: "schema2", }}} - res, err = ResolveTables(ctx, md, db.Name(), []string{"table1"}) + res, err = ResolveTables(ctx, testMysqld, db.Name(), []string{"table1"}) assert.NoError(t, err) assert.Len(t, res, 1) - res, err = ResolveTables(ctx, md, db.Name(), []string{"table1", "table2"}) + res, err = ResolveTables(ctx, testMysqld, db.Name(), []string{"table1", "table2"}) assert.NoError(t, err) assert.Len(t, res, 2) } + +func TestGetColumns(t *testing.T) { + db := fakesqldb.New(t) + defer db.Close() + + params := db.ConnParams() + cp := *params + dbc := dbconfigs.NewTestDBConfigs(cp, cp, db.Name()) + + db.AddQuery("SELECT 1", &sqltypes.Result{}) + + tableName := "test_table" + query := fmt.Sprintf(GetColumnNamesQuery, sqltypes.EncodeStringSQL(db.Name()), sqltypes.EncodeStringSQL(tableName)) + db.AddQuery(query, &sqltypes.Result{ + Fields: []*querypb.Field{{ + Name: "column_name", + Type: sqltypes.VarChar, + }}, + Rows: [][]sqltypes.Value{ + {sqltypes.NewVarChar("col1")}, + {sqltypes.NewVarChar("col2")}, + }, + }) + db.AddQuery("SELECT `col1`, `col2` FROM `fakesqldb`.`test_table` WHERE 1 != 1", &sqltypes.Result{ + Fields: []*querypb.Field{ + { + Name: "col1", + Type: sqltypes.VarChar, + }, + { + Name: "col2", + Type: sqltypes.VarChar, + }, + }, + Rows: [][]sqltypes.Value{}, + }) + + testMysqld := NewMysqld(dbc) + defer testMysqld.Close() + + ctx := context.Background() + + want := sqltypes.MakeTestFields("col1|col2", "varchar|varchar") + + field, cols, err := testMysqld.GetColumns(ctx, db.Name(), tableName) + assert.Equal(t, want, field) + assert.Equal(t, []string{"col1", "col2"}, cols) + assert.NoError(t, err) +} + +// TODO: Fix this test +// func TestGetPrimaryKeyColumns(t *testing.T) { +// db := fakesqldb.New(t) +// defer db.Close() + +// params := db.ConnParams() +// cp := *params +// dbc := dbconfigs.NewTestDBConfigs(cp, cp, db.Name()) + +// db.AddQuery("SELECT 1", &sqltypes.Result{}) + +// testMysqld := NewMysqld(dbc) +// defer testMysqld.Close() + +// tableList, err := tableListSQL([]string{"test_table"}) +// require.NoError(t, err) + +// query := `SELECT TABLE_NAME as table_name, COLUMN_NAME as column_name +// FROM information_schema.STATISTICS +// WHERE TABLE_SCHEMA = %s AND TABLE_NAME IN %s AND LOWER(INDEX_NAME) = 'primary' +// ORDER BY table_name, SEQ_IN_INDEX` +// query = fmt.Sprintf(query, sqltypes.EncodeStringSQL(db.Name()), tableList) +// db.AddQuery(query, sqltypes.MakeTestResult(sqltypes.MakeTestFields("TABLE_NAME|COLUMN_NAME", "varchar|varchar"), "test_table|col1", "test_table|col2")) + +// ctx := context.Background() +// res, err := testMysqld.GetPrimaryKeyColumns(ctx, db.Name(), "test_table") +// fmt.Println(res, err) +// } + +func TestApplySchemaChange(t *testing.T) { + db := fakesqldb.New(t) + defer db.Close() + + params := db.ConnParams() + cp := *params + dbc := dbconfigs.NewTestDBConfigs(cp, cp, db.Name()) + + tableList, err := tableListSQL([]string{"test_table"}) + require.NoError(t, err) + + query := ` + SELECT TABLE_NAME as table_name, COLUMN_NAME as column_name + FROM information_schema.STATISTICS + WHERE TABLE_SCHEMA = %s AND TABLE_NAME IN %s AND LOWER(INDEX_NAME) = 'primary' + ORDER BY table_name, SEQ_IN_INDEX` + query = fmt.Sprintf(query, sqltypes.EncodeStringSQL("fakesqldb"), tableList) + db.AddQuery(query, sqltypes.MakeTestResult(sqltypes.MakeTestFields("TABLE_NAME|COLUMN_NAME", "varchar|varchar"), "test_table|col1", "test_table|col2")) + + db.AddQuery("SELECT 1", &sqltypes.Result{}) + db.AddQuery("SHOW CREATE DATABASE IF NOT EXISTS `fakesqldb`", sqltypes.MakeTestResult(sqltypes.MakeTestFields("test_field|cmd", "varchar|varchar"), "create_db|create_db_cmd")) + db.AddQuery("SHOW CREATE TABLE `fakesqldb`.`test_table`", sqltypes.MakeTestResult(sqltypes.MakeTestFields("test_field|cmd", "varchar|varchar"), "create_table|create_table_cmd")) + + query = fmt.Sprintf(GetColumnNamesQuery, sqltypes.EncodeStringSQL(db.Name()), sqltypes.EncodeStringSQL("test_table")) + db.AddQuery(query, &sqltypes.Result{ + Fields: []*querypb.Field{{ + Name: "column_name", + Type: sqltypes.VarChar, + }}, + Rows: [][]sqltypes.Value{ + {sqltypes.NewVarChar("col1")}, + {sqltypes.NewVarChar("col2")}, + }, + }) + + db.AddQuery("SELECT table_name, table_type, data_length, table_rows FROM information_schema.tables WHERE table_schema = 'fakesqldb'", sqltypes.MakeTestResult( + sqltypes.MakeTestFields("table_name|table_type|data_length|table_rows", "varchar|varchar|uint64|uint64"), "test_table|test_type|NULL|2")) + + testMysqld := NewMysqld(dbc) + defer testMysqld.Close() + + ctx := context.Background() + res, err := testMysqld.ApplySchemaChange(ctx, db.Name(), &tmutils.SchemaChange{}) + fmt.Println(res, err) +} + +// TODO: Add tests for ApplySchema And PreflightSchemaChange diff --git a/go/vt/mysqlctl/xtrabackupengine_test.go b/go/vt/mysqlctl/xtrabackupengine_test.go index 31d4bf8b639..473e326f9eb 100644 --- a/go/vt/mysqlctl/xtrabackupengine_test.go +++ b/go/vt/mysqlctl/xtrabackupengine_test.go @@ -47,7 +47,6 @@ func TestFindReplicationPosition(t *testing.T) { pos, err := findReplicationPosition(input, "MySQL56", logutil.NewConsoleLogger()) assert.NoError(t, err) - assert.Equal(t, want, pos.String()) } @@ -113,5 +112,3 @@ func TestShouldDrainForBackupXtrabackup(t *testing.T) { assert.False(t, be.ShouldDrainForBackup(nil)) assert.False(t, be.ShouldDrainForBackup(&tabletmanagerdatapb.BackupRequest{})) } - -// TODO: Write the missing tests diff --git a/go/vt/vttablet/tabletmanager/vreplication/vreplicator_test.go b/go/vt/vttablet/tabletmanager/vreplication/vreplicator_test.go index 3be0525dc88..b4b46619fe4 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/vreplicator_test.go +++ b/go/vt/vttablet/tabletmanager/vreplication/vreplicator_test.go @@ -187,10 +187,7 @@ func TestPrimaryKeyEquivalentColumns(t *testing.T) { require.NoError(t, err, "could not connect to mysqld: %v", err) defer conn.Close() cols, indexName, err := mysqlctl.GetPrimaryKeyEquivalentColumns(ctx, conn.ExecuteFetch, env.Dbcfgs.DBName, tt.table) - if (err != nil) != tt.wantErr { - t.Errorf("Mysqld.GetPrimaryKeyEquivalentColumns() error = %v, wantErr %v", err, tt.wantErr) - return - } + assert.NoError(t, err) require.Equalf(t, cols, tt.wantCols, "Mysqld.GetPrimaryKeyEquivalentColumns() columns = %v, want %v", cols, tt.wantCols) require.Equalf(t, indexName, tt.wantIndex, "Mysqld.GetPrimaryKeyEquivalentColumns() index = %v, want %v", indexName, tt.wantIndex) })