diff --git a/ddl/attributes_sql_test.go b/ddl/attributes_sql_test.go index 9f6a7ac4425e6..c4b5f704bbb7c 100644 --- a/ddl/attributes_sql_test.go +++ b/ddl/attributes_sql_test.go @@ -19,8 +19,10 @@ import ( "fmt" "math" "testing" + "time" "github.com/pingcap/failpoint" + "github.com/pingcap/tidb/ddl" "github.com/pingcap/tidb/domain/infosync" "github.com/pingcap/tidb/store/gcworker" "github.com/pingcap/tidb/testkit" @@ -28,6 +30,31 @@ import ( "github.com/stretchr/testify/require" ) +// MockGC is used to make GC work in the test environment. +func mockGC(tk *testkit.TestKit) (string, string, string, func()) { + originGC := ddl.IsEmulatorGCEnable() + resetGC := func() { + if originGC { + ddl.EmulatorGCEnable() + } else { + ddl.EmulatorGCDisable() + } + } + + // disable emulator GC. + // Otherwise emulator GC will delete table record as soon as possible after execute drop table ddl. + ddl.EmulatorGCDisable() + gcTimeFormat := "20060102-15:04:05 -0700 MST" + timeBeforeDrop := time.Now().Add(0 - 48*60*60*time.Second).Format(gcTimeFormat) + timeAfterDrop := time.Now().Add(48 * 60 * 60 * time.Second).Format(gcTimeFormat) + safePointSQL := `INSERT HIGH_PRIORITY INTO mysql.tidb VALUES ('tikv_gc_safe_point', '%[1]s', '') + ON DUPLICATE KEY + UPDATE variable_value = '%[1]s'` + // clear GC variables first. + tk.MustExec("delete from mysql.tidb where variable_name in ( 'tikv_gc_safe_point','tikv_gc_enable' )") + return timeBeforeDrop, timeAfterDrop, safePointSQL, resetGC +} + func TestAlterTableAttributes(t *testing.T) { store, clean := testkit.CreateMockStore(t) defer clean() @@ -179,7 +206,7 @@ PARTITION BY RANGE (c) ( PARTITION p1 VALUES LESS THAN (11) );`) - timeBeforeDrop, _, safePointSQL, resetGC := testkit.MockGC(tk) + timeBeforeDrop, _, safePointSQL, resetGC := mockGC(tk) defer resetGC() // Set GC safe point @@ -222,7 +249,7 @@ PARTITION BY RANGE (c) ( PARTITION p1 VALUES LESS THAN (11) );`) - timeBeforeDrop, _, safePointSQL, resetGC := testkit.MockGC(tk) + timeBeforeDrop, _, safePointSQL, resetGC := mockGC(tk) defer resetGC() // Set GC safe point @@ -285,7 +312,7 @@ PARTITION BY RANGE (c) ( failpoint.Disable("github.com/pingcap/tidb/store/gcworker/ignoreDeleteRangeFailed") }() - timeBeforeDrop, _, safePointSQL, resetGC := testkit.MockGC(tk) + timeBeforeDrop, _, safePointSQL, resetGC := mockGC(tk) defer resetGC() // Set GC safe point @@ -329,7 +356,7 @@ PARTITION BY RANGE (c) ( failpoint.Disable("github.com/pingcap/tidb/store/gcworker/ignoreDeleteRangeFailed") }() - timeBeforeDrop, _, safePointSQL, resetGC := testkit.MockGC(tk) + timeBeforeDrop, _, safePointSQL, resetGC := mockGC(tk) defer resetGC() // Set GC safe point diff --git a/ddl/column_type_change_test.go b/ddl/column_type_change_test.go index 2e5f88cfa038a..9d9b5175ddf3c 100644 --- a/ddl/column_type_change_test.go +++ b/ddl/column_type_change_test.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package ddl_test +package ddl import ( "context" @@ -21,12 +21,11 @@ import ( "strconv" "strings" "sync" + "testing" "time" - . "github.com/pingcap/check" errors2 "github.com/pingcap/errors" "github.com/pingcap/failpoint" - "github.com/pingcap/tidb/ddl" "github.com/pingcap/tidb/domain" mysql "github.com/pingcap/tidb/errno" "github.com/pingcap/tidb/kv" @@ -34,41 +33,21 @@ import ( "github.com/pingcap/tidb/parser/model" parser_mysql "github.com/pingcap/tidb/parser/mysql" "github.com/pingcap/tidb/parser/terror" - "github.com/pingcap/tidb/session" "github.com/pingcap/tidb/sessionctx" "github.com/pingcap/tidb/store/helper" - "github.com/pingcap/tidb/store/mockstore" "github.com/pingcap/tidb/table" "github.com/pingcap/tidb/table/tables" "github.com/pingcap/tidb/tablecodec" + "github.com/pingcap/tidb/testkit" "github.com/pingcap/tidb/util/collate" "github.com/pingcap/tidb/util/dbterror" - "github.com/pingcap/tidb/util/testkit" + "github.com/stretchr/testify/require" ) -var _ = SerialSuites(&testColumnTypeChangeSuite{}) - -type testColumnTypeChangeSuite struct { - store kv.Storage - dom *domain.Domain -} - -func (s *testColumnTypeChangeSuite) SetUpSuite(c *C) { - var err error - ddl.SetWaitTimeWhenErrorOccurred(1 * time.Microsecond) - s.store, err = mockstore.NewMockStore() - c.Assert(err, IsNil) - s.dom, err = session.BootstrapSession(s.store) - c.Assert(err, IsNil) -} - -func (s *testColumnTypeChangeSuite) TearDownSuite(c *C) { - s.dom.Close() - c.Assert(s.store.Close(), IsNil) -} - -func (s *testColumnTypeChangeSuite) TestColumnTypeChangeBetweenInteger(c *C) { - tk := testkit.NewTestKit(c, s.store) +func TestColumnTypeChangeBetweenInteger(t *testing.T) { + store, clean := testkit.CreateMockStore(t) + defer clean() + tk := testkit.NewTestKit(t, store) tk.MustExec("use test") // Modify column from null to not null. @@ -79,7 +58,7 @@ func (s *testColumnTypeChangeSuite) TestColumnTypeChangeBetweenInteger(c *C) { tk.MustExec("insert into t(a, b) values (null, 1)") // Modify column from null to not null in same type will cause ErrWarnDataTruncated _, err := tk.Exec("alter table t modify column a int not null") - c.Assert(err.Error(), Equals, "[ddl:1265]Data truncated for column 'a' at row 1") + require.EqualError(t, err, "[ddl:1265]Data truncated for column 'a' at row 1") // Modify column from null to not null in different type will cause WarnDataTruncated. tk.MustGetErrCode("alter table t modify column a tinyint not null", mysql.WarnDataTruncated) @@ -128,30 +107,57 @@ func (s *testColumnTypeChangeSuite) TestColumnTypeChangeBetweenInteger(c *C) { tk.MustGetErrCode("alter table t modify column a mediumint", mysql.ErrDataOutOfRange) tk.MustGetErrCode("alter table t modify column a smallint", mysql.ErrDataOutOfRange) tk.MustGetErrCode("alter table t modify column a tinyint", mysql.ErrDataOutOfRange) - _, err = tk.Exec("admin check table t") - c.Assert(err, IsNil) + tk.MustExec("admin check table t") } -func (s *testColumnTypeChangeSuite) TestColumnTypeChangeStateBetweenInteger(c *C) { - tk := testkit.NewTestKit(c, s.store) +func getModifyColumnT(t *testing.T, ctx sessionctx.Context, db, tbl, colName string, allColumn bool) *table.Column { + dom := domain.GetDomain(ctx) + // Make sure the table schema is the new schema. + err := dom.Reload() + require.NoError(t, err) + tt, err := dom.InfoSchema().TableByName(model.NewCIStr(db), model.NewCIStr(tbl)) + require.NoError(t, err) + + colName = strings.ToLower(colName) + var cols []*table.Column + if allColumn { + cols = tt.(*tables.TableCommon).Columns + } else { + cols = tt.Cols() + } + for _, col := range cols { + if col.Name.L == colName { + return col + } + } + return nil +} +func TestColumnTypeChangeStateBetweenInteger(t *testing.T) { + store, dom, clean := testkit.CreateMockStoreAndDomain(t) + defer clean() + tk := testkit.NewTestKit(t, store) tk.MustExec("use test") tk.MustExec("drop table if exists t") tk.MustExec("create table t (c1 int, c2 int)") tk.MustExec("insert into t(c1, c2) values (1, 1)") // use new session to check meta in callback function. - internalTK := testkit.NewTestKit(c, s.store) + internalTK := testkit.NewTestKit(t, store) internalTK.MustExec("use test") - tbl := testGetTableByName(c, tk.Se, "test", "t") - c.Assert(tbl, NotNil) - c.Assert(len(tbl.Cols()), Equals, 2) - c.Assert(getModifyColumn(c, tk.Se.(sessionctx.Context), "test", "t", "c2", false), NotNil) + err := dom.Reload() + require.NoError(t, err) + tbl, err := dom.InfoSchema().TableByName(model.NewCIStr("test"), model.NewCIStr("t")) + require.NoError(t, err) - originalHook := s.dom.DDL().GetHook() - defer s.dom.DDL().(ddl.DDLForTest).SetHook(originalHook) + require.NotNil(t, tbl) + require.Len(t, tbl.Cols(), 2) + require.NotNil(t, getModifyColumnT(t, tk.Session().(sessionctx.Context), "test", "t", "c2", false)) - hook := &ddl.TestDDLCallback{} + originalHook := dom.DDL().GetHook() + defer dom.DDL().SetHook(originalHook) + + hook := &TestDDLCallback{} var checkErr error hook.OnJobRunBeforeExported = func(job *model.Job) { if checkErr != nil { @@ -162,98 +168,105 @@ func (s *testColumnTypeChangeSuite) TestColumnTypeChangeStateBetweenInteger(c *C } switch job.SchemaState { case model.StateNone: - tbl = testGetTableByName(c, internalTK.Se, "test", "t") + tbl, err := dom.InfoSchema().TableByName(model.NewCIStr("test"), model.NewCIStr("t")) + require.NoError(t, err) if tbl == nil { checkErr = errors.New("tbl is nil") } else if len(tbl.Cols()) != 2 { checkErr = errors.New("len(cols) is not right") } case model.StateDeleteOnly, model.StateWriteOnly, model.StateWriteReorganization: - tbl = testGetTableByName(c, internalTK.Se, "test", "t") + tbl, err := dom.InfoSchema().TableByName(model.NewCIStr("test"), model.NewCIStr("t")) + require.NoError(t, err) if tbl == nil { checkErr = errors.New("tbl is nil") } else if len(tbl.(*tables.TableCommon).Columns) != 3 { // changingCols has been added into meta. checkErr = errors.New("len(cols) is not right") - } else if getModifyColumn(c, internalTK.Se.(sessionctx.Context), "test", "t", "c2", true).Flag&parser_mysql.PreventNullInsertFlag == uint(0) { + } else if getModifyColumnT(t, tk.Session().(sessionctx.Context), "test", "t", "c2", true).Flag&parser_mysql.PreventNullInsertFlag == uint(0) { checkErr = errors.New("old col's flag is not right") - } else if getModifyColumn(c, internalTK.Se.(sessionctx.Context), "test", "t", "_Col$_c2_0", true) == nil { + } else if getModifyColumnT(t, tk.Session().(sessionctx.Context), "test", "t", "_Col$_c2_0", true) == nil { checkErr = errors.New("changingCol is nil") } } } - s.dom.DDL().(ddl.DDLForTest).SetHook(hook) + dom.DDL().SetHook(hook) // Alter sql will modify column c2 to tinyint not null. SQL := "alter table t modify column c2 tinyint not null" tk.MustExec(SQL) // Assert the checkErr in the job of every state. - c.Assert(checkErr, IsNil) + require.NoError(t, checkErr) // Check the col meta after the column type change. - tbl = testGetTableByName(c, tk.Se, "test", "t") - c.Assert(tbl, NotNil) - c.Assert(len(tbl.Cols()), Equals, 2) - col := getModifyColumn(c, tk.Se.(sessionctx.Context), "test", "t", "c2", false) - c.Assert(col, NotNil) - c.Assert(parser_mysql.HasNotNullFlag(col.Flag), Equals, true) - c.Assert(col.Flag&parser_mysql.NoDefaultValueFlag, Not(Equals), uint(0)) - c.Assert(col.Tp, Equals, parser_mysql.TypeTiny) - c.Assert(col.ChangeStateInfo, IsNil) + tbl, err = dom.InfoSchema().TableByName(model.NewCIStr("test"), model.NewCIStr("t")) + require.NoError(t, err) + require.NotNil(t, tbl) + require.Len(t, tbl.Cols(), 2) + col := getModifyColumnT(t, tk.Session().(sessionctx.Context), "test", "t", "c2", false) + require.NotNil(t, col) + require.True(t, parser_mysql.HasNotNullFlag(col.Flag)) + require.NotEqual(t, uint(0), col.Flag&parser_mysql.NoDefaultValueFlag) + require.Equal(t, parser_mysql.TypeTiny, col.Tp) + require.Nil(t, col.ChangeStateInfo) tk.MustQuery("select * from t").Check(testkit.Rows("1 1")) } -func (s *testColumnTypeChangeSuite) TestRollbackColumnTypeChangeBetweenInteger(c *C) { - tk := testkit.NewTestKit(c, s.store) +func TestRollbackColumnTypeChangeBetweenInteger(t *testing.T) { + store, dom, clean := testkit.CreateMockStoreAndDomain(t) + defer clean() + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") tk.MustExec("drop table if exists t") tk.MustExec("create table t (c1 bigint, c2 bigint)") tk.MustExec("insert into t(c1, c2) values (1, 1)") - tbl := testGetTableByName(c, tk.Se, "test", "t") - c.Assert(tbl, NotNil) - c.Assert(len(tbl.Cols()), Equals, 2) - c.Assert(getModifyColumn(c, tk.Se.(sessionctx.Context), "test", "t", "c2", false), NotNil) + tbl, err := dom.InfoSchema().TableByName(model.NewCIStr("test"), model.NewCIStr("t")) + require.NoError(t, err) + require.NotNil(t, tbl) + require.Len(t, tbl.Cols(), 2) + require.NotNil(t, getModifyColumnT(t, tk.Session().(sessionctx.Context), "test", "t", "c2", false)) - originalHook := s.dom.DDL().GetHook() - defer s.dom.DDL().(ddl.DDLForTest).SetHook(originalHook) + originalHook := dom.DDL().GetHook() + defer dom.DDL().SetHook(originalHook) - hook := &ddl.TestDDLCallback{} + hook := &TestDDLCallback{} // Mock roll back at model.StateNone. customizeHookRollbackAtState(hook, tbl, model.StateNone) - s.dom.DDL().(ddl.DDLForTest).SetHook(hook) + dom.DDL().SetHook(hook) // Alter sql will modify column c2 to bigint not null. SQL := "alter table t modify column c2 int not null" - _, err := tk.Exec(SQL) - c.Assert(err, NotNil) - c.Assert(err.Error(), Equals, "[ddl:1]MockRollingBackInCallBack-queueing") - assertRollBackedColUnchanged(c, tk) + _, err = tk.Exec(SQL) + require.Error(t, err) + require.EqualError(t, err, "[ddl:1]MockRollingBackInCallBack-queueing") + assertRollBackedColUnchanged(t, tk, dom) // Mock roll back at model.StateDeleteOnly. customizeHookRollbackAtState(hook, tbl, model.StateDeleteOnly) - s.dom.DDL().(ddl.DDLForTest).SetHook(hook) + dom.DDL().SetHook(hook) _, err = tk.Exec(SQL) - c.Assert(err, NotNil) - c.Assert(err.Error(), Equals, "[ddl:1]MockRollingBackInCallBack-delete only") - assertRollBackedColUnchanged(c, tk) + require.Error(t, err) + require.EqualError(t, err, "[ddl:1]MockRollingBackInCallBack-delete only") + assertRollBackedColUnchanged(t, tk, dom) // Mock roll back at model.StateWriteOnly. customizeHookRollbackAtState(hook, tbl, model.StateWriteOnly) - s.dom.DDL().(ddl.DDLForTest).SetHook(hook) + dom.DDL().SetHook(hook) _, err = tk.Exec(SQL) - c.Assert(err, NotNil) - c.Assert(err.Error(), Equals, "[ddl:1]MockRollingBackInCallBack-write only") - assertRollBackedColUnchanged(c, tk) + require.Error(t, err) + require.EqualError(t, err, "[ddl:1]MockRollingBackInCallBack-write only") + assertRollBackedColUnchanged(t, tk, dom) // Mock roll back at model.StateWriteReorg. customizeHookRollbackAtState(hook, tbl, model.StateWriteReorganization) - s.dom.DDL().(ddl.DDLForTest).SetHook(hook) + dom.DDL().SetHook(hook) _, err = tk.Exec(SQL) - c.Assert(err, NotNil) - c.Assert(err.Error(), Equals, "[ddl:1]MockRollingBackInCallBack-write reorganization") - assertRollBackedColUnchanged(c, tk) + require.Error(t, err) + require.EqualError(t, err, "[ddl:1]MockRollingBackInCallBack-write reorganization") + assertRollBackedColUnchanged(t, tk, dom) } -func customizeHookRollbackAtState(hook *ddl.TestDDLCallback, tbl table.Table, state model.SchemaState) { +func customizeHookRollbackAtState(hook *TestDDLCallback, tbl table.Table, state model.SchemaState) { hook.OnJobRunBeforeExported = func(job *model.Job) { if tbl.Meta().ID != job.TableID { return @@ -265,15 +278,17 @@ func customizeHookRollbackAtState(hook *ddl.TestDDLCallback, tbl table.Table, st } } -func assertRollBackedColUnchanged(c *C, tk *testkit.TestKit) { - tbl := testGetTableByName(c, tk.Se, "test", "t") - c.Assert(tbl, NotNil) - c.Assert(len(tbl.Cols()), Equals, 2) - col := getModifyColumn(c, tk.Se.(sessionctx.Context), "test", "t", "c2", false) - c.Assert(col, NotNil) - c.Assert(col.Flag, Equals, uint(0)) - c.Assert(col.Tp, Equals, parser_mysql.TypeLonglong) - c.Assert(col.ChangeStateInfo, IsNil) +func assertRollBackedColUnchanged(t *testing.T, tk *testkit.TestKit, dom *domain.Domain) { + tbl, err := dom.InfoSchema().TableByName(model.NewCIStr("test"), model.NewCIStr("t")) + require.NoError(t, err) + require.NotNil(t, tbl) + require.Len(t, tbl.Cols(), 2) + col := getModifyColumnT(t, tk.Session().(sessionctx.Context), "test", "t", "c2", false) + + require.NotNil(t, col) + require.Equal(t, uint(0), col.Flag) + require.Equal(t, parser_mysql.TypeLonglong, col.Tp) + require.Nil(t, col.ChangeStateInfo) tk.MustQuery("select * from t").Check(testkit.Rows("1 1")) } @@ -287,8 +302,10 @@ func init() { mockTerrorMap[model.StateWriteReorganization.String()] = dbterror.ClassDDL.New(1, "MockRollingBackInCallBack-"+model.StateWriteReorganization.String()) } -func (s *testColumnTypeChangeSuite) TestColumnTypeChangeFromIntegerToOthers(c *C) { - tk := testkit.NewTestKit(c, s.store) +func TestColumnTypeChangeFromIntegerToOthers(t *testing.T) { + store, clean := testkit.CreateMockStore(t) + defer clean() + tk := testkit.NewTestKit(t, store) tk.MustExec("use test") prepare := func(tk *testkit.TestKit) { @@ -305,129 +322,129 @@ func (s *testColumnTypeChangeSuite) TestColumnTypeChangeFromIntegerToOthers(c *C // integer to string prepare(tk) tk.MustExec("alter table t modify a varchar(10)") - modifiedColumn := getModifyColumn(c, tk.Se, "test", "t", "a", false) - c.Assert(modifiedColumn, NotNil) - c.Assert(modifiedColumn.Tp, Equals, parser_mysql.TypeVarchar) + modifiedColumn := getModifyColumnT(t, tk.Session(), "test", "t", "a", false) + require.NotNil(t, modifiedColumn) + require.Equal(t, parser_mysql.TypeVarchar, modifiedColumn.Tp) tk.MustQuery("select a from t").Check(testkit.Rows("1")) tk.MustExec("alter table t modify b char(10)") - modifiedColumn = getModifyColumn(c, tk.Se, "test", "t", "b", false) - c.Assert(modifiedColumn, NotNil) - c.Assert(modifiedColumn.Tp, Equals, parser_mysql.TypeString) + modifiedColumn = getModifyColumnT(t, tk.Session(), "test", "t", "b", false) + require.NotNil(t, modifiedColumn) + require.Equal(t, parser_mysql.TypeString, modifiedColumn.Tp) tk.MustQuery("select b from t").Check(testkit.Rows("11")) tk.MustExec("alter table t modify c binary(10)") - modifiedColumn = getModifyColumn(c, tk.Se, "test", "t", "c", false) - c.Assert(modifiedColumn, NotNil) - c.Assert(modifiedColumn.Tp, Equals, parser_mysql.TypeString) + modifiedColumn = getModifyColumnT(t, tk.Session(), "test", "t", "c", false) + require.NotNil(t, modifiedColumn) + require.Equal(t, parser_mysql.TypeString, modifiedColumn.Tp) tk.MustQuery("select c from t").Check(testkit.Rows("111\x00\x00\x00\x00\x00\x00\x00")) tk.MustExec("alter table t modify d varbinary(10)") - modifiedColumn = getModifyColumn(c, tk.Se, "test", "t", "d", false) - c.Assert(modifiedColumn, NotNil) - c.Assert(modifiedColumn.Tp, Equals, parser_mysql.TypeVarchar) + modifiedColumn = getModifyColumnT(t, tk.Session(), "test", "t", "d", false) + require.NotNil(t, modifiedColumn) + require.Equal(t, parser_mysql.TypeVarchar, modifiedColumn.Tp) tk.MustQuery("select d from t").Check(testkit.Rows("1111")) tk.MustExec("alter table t modify e blob(10)") - modifiedColumn = getModifyColumn(c, tk.Se, "test", "t", "e", false) - c.Assert(modifiedColumn, NotNil) - c.Assert(modifiedColumn.Tp, Equals, parser_mysql.TypeTinyBlob) + modifiedColumn = getModifyColumnT(t, tk.Session(), "test", "t", "e", false) + require.NotNil(t, modifiedColumn) + require.Equal(t, parser_mysql.TypeTinyBlob, modifiedColumn.Tp) tk.MustQuery("select e from t").Check(testkit.Rows("11111")) tk.MustExec("alter table t modify f text(10)") - modifiedColumn = getModifyColumn(c, tk.Se, "test", "t", "f", false) - c.Assert(modifiedColumn, NotNil) - c.Assert(modifiedColumn.Tp, Equals, parser_mysql.TypeTinyBlob) + modifiedColumn = getModifyColumnT(t, tk.Session(), "test", "t", "f", false) + require.NotNil(t, modifiedColumn) + require.Equal(t, parser_mysql.TypeTinyBlob, modifiedColumn.Tp) tk.MustQuery("select f from t").Check(testkit.Rows("111111")) // integer to decimal prepare(tk) tk.MustExec("alter table t modify a decimal(2,1)") - modifiedColumn = getModifyColumn(c, tk.Se, "test", "t", "a", false) - c.Assert(modifiedColumn, NotNil) - c.Assert(modifiedColumn.Tp, Equals, parser_mysql.TypeNewDecimal) + modifiedColumn = getModifyColumnT(t, tk.Session(), "test", "t", "a", false) + require.NotNil(t, modifiedColumn) + require.Equal(t, parser_mysql.TypeNewDecimal, modifiedColumn.Tp) tk.MustQuery("select a from t").Check(testkit.Rows("1.0")) // integer to year // For year(2), MySQL converts values in the ranges '0' to '69' and '70' to '99' to YEAR values in the ranges 2000 to 2069 and 1970 to 1999. tk.MustExec("alter table t modify b year") - modifiedColumn = getModifyColumn(c, tk.Se, "test", "t", "b", false) - c.Assert(modifiedColumn, NotNil) - c.Assert(modifiedColumn.Tp, Equals, parser_mysql.TypeYear) + modifiedColumn = getModifyColumnT(t, tk.Session(), "test", "t", "b", false) + require.NotNil(t, modifiedColumn) + require.Equal(t, parser_mysql.TypeYear, modifiedColumn.Tp) tk.MustQuery("select b from t").Check(testkit.Rows("2011")) // integer to time tk.MustExec("alter table t modify c time") - modifiedColumn = getModifyColumn(c, tk.Se, "test", "t", "c", false) - c.Assert(modifiedColumn, NotNil) - c.Assert(modifiedColumn.Tp, Equals, parser_mysql.TypeDuration) // mysql.TypeTime has rename to TypeDuration. + modifiedColumn = getModifyColumnT(t, tk.Session(), "test", "t", "c", false) + require.NotNil(t, modifiedColumn) + require.Equal(t, parser_mysql.TypeDuration, modifiedColumn.Tp) tk.MustQuery("select c from t").Check(testkit.Rows("00:01:11")) // integer to date (mysql will throw `Incorrect date value: '1111' for column 'd' at row 1` error) tk.MustExec("alter table t modify d date") - modifiedColumn = getModifyColumn(c, tk.Se, "test", "t", "d", false) - c.Assert(modifiedColumn, NotNil) - c.Assert(modifiedColumn.Tp, Equals, parser_mysql.TypeDate) + modifiedColumn = getModifyColumnT(t, tk.Session(), "test", "t", "d", false) + require.NotNil(t, modifiedColumn) + require.Equal(t, parser_mysql.TypeDate, modifiedColumn.Tp) tk.MustQuery("select d from t").Check(testkit.Rows("2000-11-11")) // the given number will be left-forward used. // integer to timestamp (according to what timezone you have set) tk.MustExec("alter table t modify e timestamp") tk.MustExec("set @@session.time_zone=UTC") - modifiedColumn = getModifyColumn(c, tk.Se, "test", "t", "e", false) - c.Assert(modifiedColumn, NotNil) - c.Assert(modifiedColumn.Tp, Equals, parser_mysql.TypeTimestamp) + modifiedColumn = getModifyColumnT(t, tk.Session(), "test", "t", "e", false) + require.NotNil(t, modifiedColumn) + require.Equal(t, parser_mysql.TypeTimestamp, modifiedColumn.Tp) tk.MustQuery("select e from t").Check(testkit.Rows("2001-11-11 00:00:00")) // the given number will be left-forward used. // integer to datetime tk.MustExec("alter table t modify f datetime") - modifiedColumn = getModifyColumn(c, tk.Se, "test", "t", "f", false) - c.Assert(modifiedColumn, NotNil) - c.Assert(modifiedColumn.Tp, Equals, parser_mysql.TypeDatetime) + modifiedColumn = getModifyColumnT(t, tk.Session(), "test", "t", "f", false) + require.NotNil(t, modifiedColumn) + require.Equal(t, parser_mysql.TypeDatetime, modifiedColumn.Tp) tk.MustQuery("select f from t").Check(testkit.Rows("2011-11-11 00:00:00")) // the given number will be left-forward used. // integer to floating-point values prepare(tk) tk.MustExec("alter table t modify a float") - modifiedColumn = getModifyColumn(c, tk.Se, "test", "t", "a", false) - c.Assert(modifiedColumn, NotNil) - c.Assert(modifiedColumn.Tp, Equals, parser_mysql.TypeFloat) + modifiedColumn = getModifyColumnT(t, tk.Session(), "test", "t", "a", false) + require.NotNil(t, modifiedColumn) + require.Equal(t, parser_mysql.TypeFloat, modifiedColumn.Tp) tk.MustQuery("select a from t").Check(testkit.Rows("1")) tk.MustExec("alter table t modify b double") - modifiedColumn = getModifyColumn(c, tk.Se, "test", "t", "b", false) - c.Assert(modifiedColumn, NotNil) - c.Assert(modifiedColumn.Tp, Equals, parser_mysql.TypeDouble) + modifiedColumn = getModifyColumnT(t, tk.Session(), "test", "t", "b", false) + require.NotNil(t, modifiedColumn) + require.Equal(t, parser_mysql.TypeDouble, modifiedColumn.Tp) tk.MustQuery("select b from t").Check(testkit.Rows("11")) // integer to bit tk.MustExec("alter table t modify c bit(10)") - modifiedColumn = getModifyColumn(c, tk.Se, "test", "t", "c", false) - c.Assert(modifiedColumn, NotNil) - c.Assert(modifiedColumn.Tp, Equals, parser_mysql.TypeBit) + modifiedColumn = getModifyColumnT(t, tk.Session(), "test", "t", "c", false) + require.NotNil(t, modifiedColumn) + require.Equal(t, parser_mysql.TypeBit, modifiedColumn.Tp) // 111 will be stored ad 0x00,0110,1111 = 0x6F, which will be shown as ASCII('o')=111 as well. tk.MustQuery("select c from t").Check(testkit.Rows("\x00o")) // integer to json tk.MustExec("alter table t modify d json") - modifiedColumn = getModifyColumn(c, tk.Se, "test", "t", "d", false) - c.Assert(modifiedColumn, NotNil) - c.Assert(modifiedColumn.Tp, Equals, parser_mysql.TypeJSON) + modifiedColumn = getModifyColumnT(t, tk.Session(), "test", "t", "d", false) + require.NotNil(t, modifiedColumn) + require.Equal(t, parser_mysql.TypeJSON, modifiedColumn.Tp) tk.MustQuery("select d from t").Check(testkit.Rows("1111")) // integer to enum prepareForEnumSet(tk) // TiDB take integer as the enum element offset to cast. tk.MustExec("alter table t modify a enum(\"a\", \"b\")") - modifiedColumn = getModifyColumn(c, tk.Se, "test", "t", "a", false) - c.Assert(modifiedColumn, NotNil) - c.Assert(modifiedColumn.Tp, Equals, parser_mysql.TypeEnum) + modifiedColumn = getModifyColumnT(t, tk.Session(), "test", "t", "a", false) + require.NotNil(t, modifiedColumn) + require.Equal(t, parser_mysql.TypeEnum, modifiedColumn.Tp) tk.MustQuery("select a from t").Check(testkit.Rows("a")) // TiDB take integer as the set element offset to cast. tk.MustExec("alter table t modify b set(\"a\", \"b\")") - modifiedColumn = getModifyColumn(c, tk.Se, "test", "t", "b", false) - c.Assert(modifiedColumn, NotNil) - c.Assert(modifiedColumn.Tp, Equals, parser_mysql.TypeSet) + modifiedColumn = getModifyColumnT(t, tk.Session(), "test", "t", "b", false) + require.NotNil(t, modifiedColumn) + require.Equal(t, parser_mysql.TypeSet, modifiedColumn.Tp) tk.MustQuery("select b from t").Check(testkit.Rows("a")) // TiDB can't take integer as the enum element string to cast, while the MySQL can. @@ -437,8 +454,10 @@ func (s *testColumnTypeChangeSuite) TestColumnTypeChangeFromIntegerToOthers(c *C tk.MustGetErrCode("alter table t modify e set(\"11111\", \"22222\")", mysql.WarnDataTruncated) } -func (s *testColumnTypeChangeSuite) TestColumnTypeChangeBetweenVarcharAndNonVarchar(c *C) { - tk := testkit.NewTestKit(c, s.store) +func TestColumnTypeChangeBetweenVarcharAndNonVarchar(t *testing.T) { + store, clean := testkit.CreateMockStore(t) + defer clean() + tk := testkit.NewTestKit(t, store) tk.MustExec("use test") collate.SetNewCollationEnabledForTest(true) defer collate.SetNewCollationEnabledForTest(false) @@ -466,15 +485,17 @@ func (s *testColumnTypeChangeSuite) TestColumnTypeChangeBetweenVarcharAndNonVarc tk.MustQuery("select a from t;").Check(testkit.Rows("aaa")) } -func (s *testColumnTypeChangeSuite) TestColumnTypeChangeFromStringToOthers(c *C) { - tk := testkit.NewTestKit(c, s.store) +func TestColumnTypeChangeFromStringToOthers(t *testing.T) { + store, clean := testkit.CreateMockStore(t) + defer clean() + tk := testkit.NewTestKit(t, store) tk.MustExec("use test") // Set time zone to UTC. - originalTz := tk.Se.GetSessionVars().TimeZone - tk.Se.GetSessionVars().TimeZone = time.UTC + originalTz := tk.Session().GetSessionVars().TimeZone + tk.Session().GetSessionVars().TimeZone = time.UTC defer func() { - tk.Se.GetSessionVars().TimeZone = originalTz + tk.Session().GetSessionVars().TimeZone = originalTz }() // Init string date type table. @@ -693,15 +714,17 @@ func (s *testColumnTypeChangeSuite) TestColumnTypeChangeFromStringToOthers(c *C) tk.MustGetErrCode("alter table t modify vc decimal(5,3)", mysql.ErrBadNumber) } -func (s *testColumnTypeChangeSuite) TestColumnTypeChangeFromNumericToOthers(c *C) { - tk := testkit.NewTestKit(c, s.store) +func TestColumnTypeChangeFromNumericToOthers(t *testing.T) { + store, clean := testkit.CreateMockStore(t) + defer clean() + tk := testkit.NewTestKit(t, store) tk.MustExec("use test") // Set time zone to UTC. - originalTz := tk.Se.GetSessionVars().TimeZone - tk.Se.GetSessionVars().TimeZone = time.UTC + originalTz := tk.Session().GetSessionVars().TimeZone + tk.Session().GetSessionVars().TimeZone = time.UTC defer func() { - tk.Se.GetSessionVars().TimeZone = originalTz + tk.Session().GetSessionVars().TimeZone = originalTz }() // Init string date type table. @@ -956,18 +979,20 @@ func (s *testColumnTypeChangeSuite) TestColumnTypeChangeFromNumericToOthers(c *C } // Test issue #20529. -func (s *testColumnTypeChangeSuite) TestColumnTypeChangeIgnoreDisplayLength(c *C) { - tk := testkit.NewTestKit(c, s.store) +func TestColumnTypeChangeIgnoreDisplayLength(t *testing.T) { + store, dom, clean := testkit.CreateMockStoreAndDomain(t) + defer clean() + tk := testkit.NewTestKit(t, store) tk.MustExec("use test") - originalHook := s.dom.DDL().GetHook() - defer s.dom.DDL().(ddl.DDLForTest).SetHook(originalHook) + originalHook := dom.DDL().GetHook() + defer dom.DDL().SetHook(originalHook) var assertResult bool assertHasAlterWriteReorg := func(tbl table.Table) { // Restore the assert result to false. assertResult = false - hook := &ddl.TestDDLCallback{} + hook := &TestDDLCallback{} hook.OnJobRunBeforeExported = func(job *model.Job) { if tbl.Meta().ID != job.TableID { return @@ -976,38 +1001,42 @@ func (s *testColumnTypeChangeSuite) TestColumnTypeChangeIgnoreDisplayLength(c *C assertResult = true } } - s.dom.DDL().(ddl.DDLForTest).SetHook(hook) + dom.DDL().SetHook(hook) } // Change int to tinyint. // Although display length is increased, the default flen is decreased, reorg is needed. tk.MustExec("drop table if exists t") tk.MustExec("create table t(a int(1))") - tbl := testGetTableByName(c, tk.Se, "test", "t") + tbl, err := dom.InfoSchema().TableByName(model.NewCIStr("test"), model.NewCIStr("t")) + require.NoError(t, err) assertHasAlterWriteReorg(tbl) tk.MustExec("alter table t modify column a tinyint(3)") - c.Assert(assertResult, Equals, true) + require.Equal(t, true, assertResult) // Change tinyint to tinyint // Although display length is decreased, default flen is the same, reorg is not needed. tk.MustExec("drop table if exists t") tk.MustExec("create table t(a tinyint(3))") - tbl = testGetTableByName(c, tk.Se, "test", "t") + tbl, err = dom.InfoSchema().TableByName(model.NewCIStr("test"), model.NewCIStr("t")) + require.NoError(t, err) assertHasAlterWriteReorg(tbl) tk.MustExec("alter table t modify column a tinyint(1)") - c.Assert(assertResult, Equals, false) + require.Equal(t, false, assertResult) tk.MustExec("drop table if exists t") } -func (s *testColumnTypeChangeSuite) TestColumnTypeChangeFromDateTimeTypeToOthers(c *C) { - tk := testkit.NewTestKit(c, s.store) +func TestColumnTypeChangeFromDateTimeTypeToOthers(t *testing.T) { + store, clean := testkit.CreateMockStore(t) + defer clean() + tk := testkit.NewTestKit(t, store) tk.MustExec("use test") // Set time zone to UTC. - originalTz := tk.Se.GetSessionVars().TimeZone - tk.Se.GetSessionVars().TimeZone = time.UTC + originalTz := tk.Session().GetSessionVars().TimeZone + tk.Session().GetSessionVars().TimeZone = time.UTC defer func() { - tk.Se.GetSessionVars().TimeZone = originalTz + tk.Session().GetSessionVars().TimeZone = originalTz }() // Init string date type table. @@ -1176,15 +1205,17 @@ func (s *testColumnTypeChangeSuite) TestColumnTypeChangeFromDateTimeTypeToOthers tk.MustQuery("select * from t").Check(testkit.Rows("\"2020-10-30\" \"19:38:25.001\" \"2020-10-30 08:21:33.455555\" \"2020-10-30 08:21:33.455555\" 2020")) } -func (s *testColumnTypeChangeSuite) TestColumnTypeChangeFromJsonToOthers(c *C) { - tk := testkit.NewTestKit(c, s.store) +func TestColumnTypeChangeFromJsonToOthers(t *testing.T) { + store, clean := testkit.CreateMockStore(t) + defer clean() + tk := testkit.NewTestKit(t, store) tk.MustExec("use test") // Set time zone to UTC. - originalTz := tk.Se.GetSessionVars().TimeZone - tk.Se.GetSessionVars().TimeZone = time.UTC + originalTz := tk.Session().GetSessionVars().TimeZone + tk.Session().GetSessionVars().TimeZone = time.UTC defer func() { - tk.Se.GetSessionVars().TimeZone = originalTz + tk.Session().GetSessionVars().TimeZone = originalTz }() // Init string date type table. @@ -1568,8 +1599,10 @@ func (s *testColumnTypeChangeSuite) TestColumnTypeChangeFromJsonToOthers(c *C) { tk.MustQuery("select * from t").Check(testkit.Rows("{\"obj\": 100} [-1, 0, 1] null 2001 0 2020 1991 2009 2020 ")) } -func (s *testColumnTypeChangeSuite) TestUpdateDataAfterChangeTimestampToDate(c *C) { - tk := testkit.NewTestKit(c, s.store) +func TestUpdateDataAfterChangeTimestampToDate(t *testing.T) { + store, clean := testkit.CreateMockStore(t) + defer clean() + tk := testkit.NewTestKit(t, store) tk.MustExec("use test") tk.MustExec("drop table if exists t, t1") tk.MustExec("create table t (col timestamp default '1971-06-09' not null, col1 int default 1, unique key(col1));") @@ -1589,22 +1622,25 @@ func (s *testColumnTypeChangeSuite) TestUpdateDataAfterChangeTimestampToDate(c * } // TestRowFormat is used to close issue #21391, the encoded row in column type change should be aware of the new row format. -func (s *testColumnTypeChangeSuite) TestRowFormat(c *C) { - tk := testkit.NewTestKit(c, s.store) +func TestRowFormat(t *testing.T) { + store, dom, clean := testkit.CreateMockStoreAndDomain(t) + defer clean() + tk := testkit.NewTestKit(t, store) tk.MustExec("use test") tk.MustExec("drop table if exists t") tk.MustExec("create table t (id int primary key, v varchar(10))") tk.MustExec("insert into t values (1, \"123\");") tk.MustExec("alter table t modify column v varchar(5);") - tbl := testGetTableByName(c, tk.Se, "test", "t") + tbl, err := dom.InfoSchema().TableByName(model.NewCIStr("test"), model.NewCIStr("t")) + require.NoError(t, err) encodedKey := tablecodec.EncodeRowKeyWithHandle(tbl.Meta().ID, kv.IntHandle(1)) - h := helper.NewHelper(s.store.(helper.Storage)) + h := helper.NewHelper(store.(helper.Storage)) data, err := h.GetMvccByEncodedKey(encodedKey) - c.Assert(err, IsNil) + require.NoError(t, err) // The new format will start with CodecVer = 128 (0x80). - c.Assert(data.Info.Writes[0].ShortValue, DeepEquals, []byte{0x80, 0x0, 0x3, 0x0, 0x0, 0x0, 0x1, 0x2, 0x3, 0x1, 0x0, 0x4, 0x0, 0x7, 0x0, 0x1, 0x31, 0x32, 0x33, 0x31, 0x32, 0x33}) + require.Equal(t, []byte{0x80, 0x0, 0x3, 0x0, 0x0, 0x0, 0x1, 0x2, 0x3, 0x1, 0x0, 0x4, 0x0, 0x7, 0x0, 0x1, 0x31, 0x32, 0x33, 0x31, 0x32, 0x33}, data.Info.Writes[0].ShortValue) tk.MustExec("drop table if exists t") } @@ -1614,11 +1650,13 @@ func (s *testColumnTypeChangeSuite) TestRowFormat(c *C) { // The added column with NOT-NULL option will be fetched with error when it's origin default value is not set. // It's good because the insert / update logic will cast the related column to changing column rather than use // origin default value directly. -func (s *testColumnTypeChangeSuite) TestChangingColOriginDefaultValue(c *C) { - tk := testkit.NewTestKit(c, s.store) +func TestChangingColOriginDefaultValue(t *testing.T) { + store, dom, clean := testkit.CreateMockStoreAndDomain(t) + defer clean() + tk := testkit.NewTestKit(t, store) tk.MustExec("use test") - tk1 := testkit.NewTestKit(c, s.store) + tk1 := testkit.NewTestKit(t, store) tk1.MustExec("use test") tk.MustExec("drop table if exists t") @@ -1626,9 +1664,10 @@ func (s *testColumnTypeChangeSuite) TestChangingColOriginDefaultValue(c *C) { tk.MustExec("insert into t values(1, 1)") tk.MustExec("insert into t values(2, 2)") - tbl := testGetTableByName(c, tk.Se, "test", "t") - originalHook := s.dom.DDL().GetHook() - hook := &ddl.TestDDLCallback{Do: s.dom} + tbl, err := dom.InfoSchema().TableByName(model.NewCIStr("test"), model.NewCIStr("t")) + require.NoError(t, err) + originalHook := dom.DDL().GetHook() + hook := &TestDDLCallback{Do: dom} var ( once bool checkErr error @@ -1644,7 +1683,8 @@ func (s *testColumnTypeChangeSuite) TestChangingColOriginDefaultValue(c *C) { if (job.SchemaState == model.StateWriteOnly || job.SchemaState == model.StateWriteReorganization) && i < 3 { if !once { once = true - tbl := testGetTableByName(c, tk1.Se, "test", "t") + tbl, err = dom.InfoSchema().TableByName(model.NewCIStr("test"), model.NewCIStr("t")) + require.NoError(t, err) if len(tbl.WritableCols()) != 3 { checkErr = errors.New("assert the writable column number error") return @@ -1680,20 +1720,22 @@ func (s *testColumnTypeChangeSuite) TestChangingColOriginDefaultValue(c *C) { i++ } } - s.dom.DDL().(ddl.DDLForTest).SetHook(hook) + dom.DDL().SetHook(hook) tk.MustExec("alter table t modify column b tinyint NOT NULL") - s.dom.DDL().(ddl.DDLForTest).SetHook(originalHook) - c.Assert(checkErr, IsNil) + dom.DDL().SetHook(originalHook) + require.Nil(t, checkErr) // Since getReorgInfo will stagnate StateWriteReorganization for a ddl round, so insert should exec 3 times. tk.MustQuery("select * from t order by a").Check(testkit.Rows("1 -1", "2 -2", "3 3", "4 4", "5 5")) tk.MustExec("drop table if exists t") } -func (s *testColumnTypeChangeSuite) TestChangingColOriginDefaultValueAfterAddColAndCastSucc(c *C) { - tk := testkit.NewTestKit(c, s.store) +func TestChangingColOriginDefaultValueAfterAddColAndCastSucc(t *testing.T) { + store, dom, clean := testkit.CreateMockStoreAndDomain(t) + defer clean() + tk := testkit.NewTestKit(t, store) tk.MustExec("use test") - tk1 := testkit.NewTestKit(c, s.store) + tk1 := testkit.NewTestKit(t, store) tk1.MustExec("use test") tk.MustExec("set time_zone = 'UTC'") @@ -1703,9 +1745,10 @@ func (s *testColumnTypeChangeSuite) TestChangingColOriginDefaultValueAfterAddCol tk.MustExec("insert into t values(2, 2)") tk.MustExec("alter table t add column c timestamp default '1971-06-09' not null") - tbl := testGetTableByName(c, tk.Se, "test", "t") - originalHook := s.dom.DDL().GetHook() - hook := &ddl.TestDDLCallback{Do: s.dom} + tbl, err := dom.InfoSchema().TableByName(model.NewCIStr("test"), model.NewCIStr("t")) + require.NoError(t, err) + originalHook := dom.DDL().GetHook() + hook := &TestDDLCallback{Do: dom} var ( once bool checkErr error @@ -1721,7 +1764,8 @@ func (s *testColumnTypeChangeSuite) TestChangingColOriginDefaultValueAfterAddCol if (job.SchemaState == model.StateWriteOnly || job.SchemaState == model.StateWriteReorganization) && stableTimes < 3 { if !once { once = true - tbl := testGetTableByName(c, tk1.Se, "test", "t") + tbl, err = dom.InfoSchema().TableByName(model.NewCIStr("test"), model.NewCIStr("t")) + require.NoError(t, err) if len(tbl.WritableCols()) != 4 { checkErr = errors.New("assert the writable column number error") return @@ -1764,10 +1808,10 @@ func (s *testColumnTypeChangeSuite) TestChangingColOriginDefaultValueAfterAddCol i++ } - s.dom.DDL().(ddl.DDLForTest).SetHook(hook) + dom.DDL().SetHook(hook) tk.MustExec("alter table t modify column c date NOT NULL") - s.dom.DDL().(ddl.DDLForTest).SetHook(originalHook) - c.Assert(checkErr, IsNil) + dom.DDL().SetHook(originalHook) + require.Nil(t, checkErr) // Since getReorgInfo will stagnate StateWriteReorganization for a ddl round, so insert should exec 3 times. tk.MustQuery("select * from t order by a").Check( testkit.Rows("1 -1 1971-06-09", "2 -2 1971-06-09", "5 5 2021-06-06", "6 6 2021-06-06", "7 7 2021-06-06")) @@ -1775,11 +1819,13 @@ func (s *testColumnTypeChangeSuite) TestChangingColOriginDefaultValueAfterAddCol } // TestChangingColOriginDefaultValueAfterAddColAndCastFail tests #25383. -func (s *testColumnTypeChangeSuite) TestChangingColOriginDefaultValueAfterAddColAndCastFail(c *C) { - tk := testkit.NewTestKit(c, s.store) +func TestChangingColOriginDefaultValueAfterAddColAndCastFail(t *testing.T) { + store, dom, clean := testkit.CreateMockStoreAndDomain(t) + defer clean() + tk := testkit.NewTestKit(t, store) tk.MustExec("use test") - tk1 := testkit.NewTestKit(c, s.store) + tk1 := testkit.NewTestKit(t, store) tk1.MustExec("use test") tk.MustExec("set time_zone = 'UTC'") @@ -1787,9 +1833,10 @@ func (s *testColumnTypeChangeSuite) TestChangingColOriginDefaultValueAfterAddCol tk.MustExec("create table t(a VARCHAR(31) NULL DEFAULT 'wwrzfwzb01j6ddj', b DECIMAL(12,0) NULL DEFAULT '-729850476163')") tk.MustExec("ALTER TABLE t ADD COLUMN x CHAR(218) NULL DEFAULT 'lkittuae'") - tbl := testGetTableByName(c, tk.Se, "test", "t") - originalHook := s.dom.DDL().GetHook() - hook := &ddl.TestDDLCallback{Do: s.dom} + tbl, err := dom.InfoSchema().TableByName(model.NewCIStr("test"), model.NewCIStr("t")) + require.NoError(t, err) + originalHook := dom.DDL().GetHook() + hook := &TestDDLCallback{Do: dom} var checkErr error hook.OnJobRunBeforeExported = func(job *model.Job) { if checkErr != nil { @@ -1800,7 +1847,8 @@ func (s *testColumnTypeChangeSuite) TestChangingColOriginDefaultValueAfterAddCol } if job.SchemaState == model.StateWriteOnly || job.SchemaState == model.StateWriteReorganization { - tbl := testGetTableByName(c, tk1.Se, "test", "t") + tbl, err = dom.InfoSchema().TableByName(model.NewCIStr("test"), model.NewCIStr("t")) + require.NoError(t, err) if len(tbl.WritableCols()) != 4 { errMsg := fmt.Sprintf("cols len:%v", len(tbl.WritableCols())) checkErr = errors.New("assert the writable column number error" + errMsg) @@ -1822,17 +1870,19 @@ func (s *testColumnTypeChangeSuite) TestChangingColOriginDefaultValueAfterAddCol } } - s.dom.DDL().(ddl.DDLForTest).SetHook(hook) + dom.DDL().SetHook(hook) tk.MustExec("alter table t modify column x DATETIME NULL DEFAULT '3771-02-28 13:00:11' AFTER b;") - s.dom.DDL().(ddl.DDLForTest).SetHook(originalHook) - c.Assert(checkErr, IsNil) + dom.DDL().SetHook(originalHook) + require.Nil(t, checkErr) tk.MustQuery("select * from t order by a").Check(testkit.Rows()) tk.MustExec("drop table if exists t") } // Close issue #22820 -func (s *testColumnTypeChangeSuite) TestChangingAttributeOfColumnWithFK(c *C) { - tk := testkit.NewTestKit(c, s.store) +func TestChangingAttributeOfColumnWithFK(t *testing.T) { + store, dom, clean := testkit.CreateMockStoreAndDomain(t) + defer clean() + tk := testkit.NewTestKit(t, store) tk.MustExec("use test") prepare := func() { @@ -1845,20 +1895,23 @@ func (s *testColumnTypeChangeSuite) TestChangingAttributeOfColumnWithFK(c *C) { prepare() // For column with FK, alter action can be performed for changing null/not null, default value, comment and so on, but column type. tk.MustExec("alter table orders modify user_id int null;") - tbl := testGetTableByName(c, tk.Se, "test", "orders") - c.Assert(parser_mysql.HasNotNullFlag(tbl.Meta().Columns[1].Flag), Equals, false) + tbl, err := dom.InfoSchema().TableByName(model.NewCIStr("test"), model.NewCIStr("orders")) + require.NoError(t, err) + require.Equal(t, false, parser_mysql.HasNotNullFlag(tbl.Meta().Columns[1].Flag)) prepare() tk.MustExec("alter table orders change user_id user_id2 int null") - tbl = testGetTableByName(c, tk.Se, "test", "orders") - c.Assert(tbl.Meta().Columns[1].Name.L, Equals, "user_id2") - c.Assert(parser_mysql.HasNotNullFlag(tbl.Meta().Columns[1].Flag), Equals, false) + tbl, err = dom.InfoSchema().TableByName(model.NewCIStr("test"), model.NewCIStr("orders")) + require.NoError(t, err) + require.Equal(t, "user_id2", tbl.Meta().Columns[1].Name.L) + require.Equal(t, false, parser_mysql.HasNotNullFlag(tbl.Meta().Columns[1].Flag)) prepare() tk.MustExec("alter table orders modify user_id int default -1 comment \"haha\"") - tbl = testGetTableByName(c, tk.Se, "test", "orders") - c.Assert(tbl.Meta().Columns[1].Comment, Equals, "haha") - c.Assert(tbl.Meta().Columns[1].DefaultValue.(string), Equals, "-1") + tbl, err = dom.InfoSchema().TableByName(model.NewCIStr("test"), model.NewCIStr("orders")) + require.NoError(t, err) + require.Equal(t, "haha", tbl.Meta().Columns[1].Comment) + require.Equal(t, "-1", tbl.Meta().Columns[1].DefaultValue.(string)) prepare() tk.MustGetErrCode("alter table orders modify user_id bigint", mysql.ErrFKIncompatibleColumns) @@ -1866,8 +1919,10 @@ func (s *testColumnTypeChangeSuite) TestChangingAttributeOfColumnWithFK(c *C) { tk.MustExec("drop table if exists orders, users") } -func (s *testColumnTypeChangeSuite) TestAlterPrimaryKeyToNull(c *C) { - tk := testkit.NewTestKit(c, s.store) +func TestAlterPrimaryKeyToNull(t *testing.T) { + store, clean := testkit.CreateMockStore(t) + defer clean() + tk := testkit.NewTestKit(t, store) tk.MustExec("use test") tk.MustExec("drop table if exists t, t1") @@ -1880,8 +1935,10 @@ func (s *testColumnTypeChangeSuite) TestAlterPrimaryKeyToNull(c *C) { } // Close https://github.com/pingcap/tidb/issues/24839. -func (s testColumnTypeChangeSuite) TestChangeUnsignedIntToDatetime(c *C) { - tk := testkit.NewTestKit(c, s.store) +func TestChangeUnsignedIntToDatetime(t *testing.T) { + store, clean := testkit.CreateMockStore(t) + defer clean() + tk := testkit.NewTestKit(t, store) tk.MustExec("use test;") tk.MustExec("drop table if exists t;") @@ -1900,8 +1957,10 @@ func (s testColumnTypeChangeSuite) TestChangeUnsignedIntToDatetime(c *C) { } // Close issue #23202 -func (s *testColumnTypeChangeSuite) TestDDLExitWhenCancelMeetPanic(c *C) { - tk := testkit.NewTestKit(c, s.store) +func TestDDLExitWhenCancelMeetPanic(t *testing.T) { + store, dom, clean := testkit.CreateMockStoreAndDomain(t) + defer clean() + tk := testkit.NewTestKit(t, store) tk.MustExec("use test") tk.MustExec("drop table if exists t") @@ -1915,10 +1974,10 @@ func (s *testColumnTypeChangeSuite) TestDDLExitWhenCancelMeetPanic(c *C) { failpoint.Disable("github.com/pingcap/tidb/ddl/mockExceedErrorLimit") }() - originalHook := s.dom.DDL().GetHook() - defer s.dom.DDL().(ddl.DDLForTest).SetHook(originalHook) + originalHook := dom.DDL().GetHook() + defer dom.DDL().SetHook(originalHook) - hook := &ddl.TestDDLCallback{Do: s.dom} + hook := &TestDDLCallback{Do: dom} var jobID int64 hook.OnJobRunBeforeExported = func(job *model.Job) { if jobID != 0 { @@ -1928,31 +1987,33 @@ func (s *testColumnTypeChangeSuite) TestDDLExitWhenCancelMeetPanic(c *C) { jobID = job.ID } } - s.dom.DDL().(ddl.DDLForTest).SetHook(hook) + dom.DDL().SetHook(hook) // when it panics in write-reorg state, the job will be pulled up as a cancelling job. Since drop-index with // write-reorg can't be cancelled, so it will be converted to running state and try again (dead loop). _, err := tk.Exec("alter table t drop index b") - c.Assert(err, NotNil) - c.Assert(err.Error(), Equals, "[ddl:-1]panic in handling DDL logic and error count beyond the limitation 3, cancelled") - c.Assert(jobID > 0, Equals, true) + require.Error(t, err) + require.EqualError(t, err, "[ddl:-1]panic in handling DDL logic and error count beyond the limitation 3, cancelled") + require.Equal(t, true, jobID > 0) // Verification of the history job state. var job *model.Job - err = kv.RunInNewTxn(context.Background(), s.store, false, func(ctx context.Context, txn kv.Transaction) error { + err = kv.RunInNewTxn(context.Background(), store, false, func(ctx context.Context, txn kv.Transaction) error { t := meta.NewMeta(txn) var err1 error job, err1 = t.GetHistoryDDLJob(jobID) return errors2.Trace(err1) }) - c.Assert(err, IsNil) - c.Assert(job.ErrorCount, Equals, int64(4)) - c.Assert(job.Error.Error(), Equals, "[ddl:-1]panic in handling DDL logic and error count beyond the limitation 3, cancelled") + require.NoError(t, err) + require.Equal(t, int64(4), job.ErrorCount) + require.Equal(t, "[ddl:-1]panic in handling DDL logic and error count beyond the limitation 3, cancelled", job.Error.Error()) } // Close issue #24253 -func (s *testColumnTypeChangeSuite) TestChangeIntToBitWillPanicInBackfillIndexes(c *C) { - tk := testkit.NewTestKit(c, s.store) +func TestChangeIntToBitWillPanicInBackfillIndexes(t *testing.T) { + store, clean := testkit.CreateMockStore(t) + defer clean() + tk := testkit.NewTestKit(t, store) tk.MustExec("use test") tk.MustExec("drop table if exists t") @@ -1980,8 +2041,10 @@ func (s *testColumnTypeChangeSuite) TestChangeIntToBitWillPanicInBackfillIndexes } // Close issue #24584 -func (s *testColumnTypeChangeSuite) TestCancelCTCInReorgStateWillCauseGoroutineLeak(c *C) { - tk := testkit.NewTestKit(c, s.store) +func TestCancelCTCInReorgStateWillCauseGoroutineLeak(t *testing.T) { + store, dom, clean := testkit.CreateMockStoreAndDomain(t) + defer clean() + tk := testkit.NewTestKit(t, store) tk.MustExec("use test") failpoint.Enable("github.com/pingcap/tidb/ddl/mockInfiniteReorgLogic", `return(true)`) @@ -1990,15 +2053,16 @@ func (s *testColumnTypeChangeSuite) TestCancelCTCInReorgStateWillCauseGoroutineL }() // set ddl hook - originalHook := s.dom.DDL().GetHook() - defer s.dom.DDL().(ddl.DDLForTest).SetHook(originalHook) + originalHook := dom.DDL().GetHook() + defer dom.DDL().SetHook(originalHook) tk.MustExec("drop table if exists ctc_goroutine_leak") tk.MustExec("create table ctc_goroutine_leak (a int)") tk.MustExec("insert into ctc_goroutine_leak values(1),(2),(3)") - tbl := testGetTableByName(c, tk.Se, "test", "ctc_goroutine_leak") + tbl, err := dom.InfoSchema().TableByName(model.NewCIStr("test"), model.NewCIStr("ctc_goroutine_leak")) + require.NoError(t, err) - hook := &ddl.TestDDLCallback{} + hook := &TestDDLCallback{} var jobID int64 hook.OnJobRunBeforeExported = func(job *model.Job) { if jobID != 0 { @@ -2011,9 +2075,9 @@ func (s *testColumnTypeChangeSuite) TestCancelCTCInReorgStateWillCauseGoroutineL jobID = job.ID } } - s.dom.DDL().(ddl.DDLForTest).SetHook(hook) + dom.DDL().SetHook(hook) - tk1 := testkit.NewTestKit(c, s.store) + tk1 := testkit.NewTestKit(t, store) tk1.MustExec("use test") var ( wg = sync.WaitGroup{} @@ -2025,15 +2089,17 @@ func (s *testColumnTypeChangeSuite) TestCancelCTCInReorgStateWillCauseGoroutineL // This ddl will be hang over in the failpoint loop, waiting for outside cancel. _, alterErr = tk1.Exec("alter table ctc_goroutine_leak modify column a tinyint") }() - <-ddl.TestReorgGoroutineRunning + <-TestReorgGoroutineRunning tk.MustExec("admin cancel ddl jobs " + strconv.Itoa(int(jobID))) wg.Wait() - c.Assert(alterErr.Error(), Equals, "[ddl:8214]Cancelled DDL job") + require.Equal(t, "[ddl:8214]Cancelled DDL job", alterErr.Error()) } // Close issue #24971, #24973, #24974 -func (s *testColumnTypeChangeSuite) TestCTCShouldCastTheDefaultValue(c *C) { - tk := testkit.NewTestKit(c, s.store) +func TestCTCShouldCastTheDefaultValue(t *testing.T) { + store, clean := testkit.CreateMockStore(t) + defer clean() + tk := testkit.NewTestKit(t, store) tk.MustExec("use test") tk.MustExec("drop table if exists t") @@ -2062,8 +2128,10 @@ func (s *testColumnTypeChangeSuite) TestCTCShouldCastTheDefaultValue(c *C) { // Close issue #25037 // 1: for default value of binary of create-table, it should append the \0 as the suffix to meet flen. // 2: when cast the bit to binary, we should consider to convert it to uint then cast uint to string, rather than taking the bit to string directly. -func (s *testColumnTypeChangeSuite) TestCTCCastBitToBinary(c *C) { - tk := testkit.NewTestKit(c, s.store) +func TestCTCCastBitToBinary(t *testing.T) { + store, clean := testkit.CreateMockStore(t) + defer clean() + tk := testkit.NewTestKit(t, store) tk.MustExec("use test") // For point 1: @@ -2088,37 +2156,35 @@ func (s *testColumnTypeChangeSuite) TestCTCCastBitToBinary(c *C) { tk.MustQuery("select * from t").Check(testkit.Rows("4047")) } -func (s *testColumnTypeChangeSuite) TestChangePrefixedIndexColumnToNonPrefixOne(c *C) { - tk := testkit.NewTestKit(c, s.store) +func TestChangePrefixedIndexColumnToNonPrefixOne(t *testing.T) { + store, clean := testkit.CreateMockStore(t) + defer clean() + tk := testkit.NewTestKit(t, store) tk.MustExec("use test;") tk.MustExec("drop table if exists t;") tk.MustExec("create table t (a text, unique index idx(a(2)));") tk.MustExec("alter table t modify column a int;") showCreateTable := tk.MustQuery("show create table t").Rows()[0][1].(string) - c.Assert(strings.Contains(showCreateTable, "UNIQUE KEY `idx` (`a`)"), IsTrue, - Commentf("%s", showCreateTable)) + require.Contains(t, showCreateTable, "UNIQUE KEY `idx` (`a`)", "%s", showCreateTable) tk.MustExec("drop table if exists t;") tk.MustExec("create table t (a char(255), unique index idx(a(2)));") tk.MustExec("alter table t modify column a float;") showCreateTable = tk.MustQuery("show create table t").Rows()[0][1].(string) - c.Assert(strings.Contains(showCreateTable, "UNIQUE KEY `idx` (`a`)"), IsTrue, - Commentf("%s", showCreateTable)) + require.Contains(t, showCreateTable, "UNIQUE KEY `idx` (`a`)", "%s", showCreateTable) tk.MustExec("drop table if exists t;") tk.MustExec("create table t (a char(255), b text, unique index idx(a(2), b(10)));") tk.MustExec("alter table t modify column b int;") showCreateTable = tk.MustQuery("show create table t").Rows()[0][1].(string) - c.Assert(strings.Contains(showCreateTable, "UNIQUE KEY `idx` (`a`(2),`b`)"), IsTrue, - Commentf("%s", showCreateTable)) + require.Contains(t, showCreateTable, "UNIQUE KEY `idx` (`a`(2),`b`)", "%s", showCreateTable) tk.MustExec("drop table if exists t;") tk.MustExec("create table t(a char(250), unique key idx(a(10)));") tk.MustExec("alter table t modify a char(9);") showCreateTable = tk.MustQuery("show create table t").Rows()[0][1].(string) - c.Assert(strings.Contains(showCreateTable, "UNIQUE KEY `idx` (`a`)"), IsTrue, - Commentf("%s", showCreateTable)) + require.Contains(t, showCreateTable, "UNIQUE KEY `idx` (`a`)", "%s", showCreateTable) tk.MustExec("drop table if exists t;") tk.MustExec("create table t(a varchar(700), key(a(700)));") @@ -2126,8 +2192,10 @@ func (s *testColumnTypeChangeSuite) TestChangePrefixedIndexColumnToNonPrefixOne( } // Fix issue https://github.com/pingcap/tidb/issues/25469 -func (s *testColumnTypeChangeSuite) TestCastToTimeStampDecodeError(c *C) { - tk := testkit.NewTestKit(c, s.store) +func TestCastToTimeStampDecodeError(t *testing.T) { + store, clean := testkit.CreateMockStore(t) + defer clean() + tk := testkit.NewTestKit(t, store) tk.MustExec("use test;") tk.MustExec("drop table if exists t") @@ -2150,8 +2218,10 @@ func (s *testColumnTypeChangeSuite) TestCastToTimeStampDecodeError(c *C) { } // https://github.com/pingcap/tidb/issues/25285. -func (s *testColumnTypeChangeSuite) TestCastFromZeroIntToTimeError(c *C) { - tk := testkit.NewTestKit(c, s.store) +func TestCastFromZeroIntToTimeError(t *testing.T) { + store, clean := testkit.CreateMockStore(t) + defer clean() + tk := testkit.NewTestKit(t, store) tk.MustExec("use test;") prepare := func() { @@ -2195,8 +2265,10 @@ func (s *testColumnTypeChangeSuite) TestCastFromZeroIntToTimeError(c *C) { tk.MustExec("drop table if exists t;") } -func (s *testColumnTypeChangeSuite) TestChangeFromTimeToYear(c *C) { - tk := testkit.NewTestKit(c, s.store) +func TestChangeFromTimeToYear(t *testing.T) { + store, clean := testkit.CreateMockStore(t) + defer clean() + tk := testkit.NewTestKit(t, store) tk.MustExec("use test;") tk.MustExec("drop table if exists t;") @@ -2225,26 +2297,29 @@ func (s *testColumnTypeChangeSuite) TestChangeFromTimeToYear(c *C) { // Cast date to timestamp has two kind behavior: cast("3977-02-22" as date) // For select statement, it truncate the string and return no errors. (which is 3977-02-22 00:00:00 here) // For ddl reorging or changing column in ctc, it need report some errors. -func (s *testColumnTypeChangeSuite) TestCastDateToTimestampInReorgAttribute(c *C) { - tk := testkit.NewTestKit(c, s.store) +func TestCastDateToTimestampInReorgAttribute(t *testing.T) { + store, dom, clean := testkit.CreateMockStoreAndDomain(t) + defer clean() + tk := testkit.NewTestKit(t, store) tk.MustExec("use test;") tk.MustExec("drop table if exists t") tk.MustExec("CREATE TABLE `t` (`a` DATE NULL DEFAULT '8497-01-06')") tk.MustExec("insert into t values(now())") - originalHook := s.dom.DDL().GetHook() - defer s.dom.DDL().(ddl.DDLForTest).SetHook(originalHook) + originalHook := dom.DDL().GetHook() + defer dom.DDL().SetHook(originalHook) // use new session to check meta in callback function. - internalTK := testkit.NewTestKit(c, s.store) + internalTK := testkit.NewTestKit(t, store) internalTK.MustExec("use test") - tbl := testGetTableByName(c, tk.Se, "test", "t") - c.Assert(tbl, NotNil) - c.Assert(len(tbl.Cols()), Equals, 1) + tbl, err := dom.InfoSchema().TableByName(model.NewCIStr("test"), model.NewCIStr("t")) + require.NoError(t, err) + require.NotNil(t, tbl) + require.Equal(t, 1, len(tbl.Cols())) - hook := &ddl.TestDDLCallback{} + hook := &TestDDLCallback{} var ( checkErr1 error checkErr2 error @@ -2258,21 +2333,23 @@ func (s *testColumnTypeChangeSuite) TestCastDateToTimestampInReorgAttribute(c *C } switch job.SchemaState { case model.StateWriteOnly: - _, checkErr1 = internalTK.Exec("insert into `t` set `a` = '3977-02-22'") // this(string) will be cast to a as date, then cast a(date) as timestamp to changing column. - _, checkErr2 = internalTK.Exec("update t set `a` = '3977-02-22'") + _, checkErr1 = tk.Exec("insert into `t` set `a` = '3977-02-22'") // this(string) will be cast to a as date, then cast a(date) as timestamp to changing column. + _, checkErr2 = tk.Exec("update t set `a` = '3977-02-22'") } } - s.dom.DDL().(ddl.DDLForTest).SetHook(hook) + dom.DDL().SetHook(hook) tk.MustExec("alter table t modify column a TIMESTAMP NULL DEFAULT '2021-04-28 03:35:11' FIRST") - c.Assert(checkErr1.Error(), Equals, "[types:1292]Incorrect timestamp value: '3977-02-22'") - c.Assert(checkErr2.Error(), Equals, "[types:1292]Incorrect timestamp value: '3977-02-22'") + require.Equal(t, "[types:1292]Incorrect timestamp value: '3977-02-22'", checkErr1.Error()) + require.Equal(t, "[types:1292]Incorrect timestamp value: '3977-02-22'", checkErr2.Error()) tk.MustExec("drop table if exists t") } // https://github.com/pingcap/tidb/issues/25282. -func (s *testColumnTypeChangeSuite) TestChangeFromUnsignedIntToTime(c *C) { - tk := testkit.NewTestKit(c, s.store) +func TestChangeFromUnsignedIntToTime(t *testing.T) { + store, clean := testkit.CreateMockStore(t) + defer clean() + tk := testkit.NewTestKit(t, store) tk.MustExec("use test;") tk.MustExec("drop table if exists t;") @@ -2285,8 +2362,10 @@ func (s *testColumnTypeChangeSuite) TestChangeFromUnsignedIntToTime(c *C) { // See https://github.com/pingcap/tidb/issues/25287. // Revised according to https://github.com/pingcap/tidb/pull/31031#issuecomment-1001404832. -func (s *testColumnTypeChangeSuite) TestChangeFromBitToStringInvalidUtf8ErrMsg(c *C) { - tk := testkit.NewTestKit(c, s.store) +func TestChangeFromBitToStringInvalidUtf8ErrMsg(t *testing.T) { + store, clean := testkit.CreateMockStore(t) + defer clean() + tk := testkit.NewTestKit(t, store) tk.MustExec("use test;") tk.MustExec("drop table if exists t;") @@ -2296,8 +2375,10 @@ func (s *testColumnTypeChangeSuite) TestChangeFromBitToStringInvalidUtf8ErrMsg(c tk.MustQuery("select a from t;").Check(testkit.Rows("1174717")) } -func (s *testColumnTypeChangeSuite) TestForIssue24621(c *C) { - tk := testkit.NewTestKit(c, s.store) +func TestForIssue24621(t *testing.T) { + store, clean := testkit.CreateMockStore(t) + defer clean() + tk := testkit.NewTestKit(t, store) tk.MustExec("use test") tk.MustExec("drop table if exists t") @@ -2307,8 +2388,10 @@ func (s *testColumnTypeChangeSuite) TestForIssue24621(c *C) { tk.MustGetErrMsg("alter table t modify a char(12) null;", errMsg) } -func (s *testColumnTypeChangeSuite) TestChangeNullValueFromOtherTypeToTimestamp(c *C) { - tk := testkit.NewTestKit(c, s.store) +func TestChangeNullValueFromOtherTypeToTimestamp(t *testing.T) { + store, clean := testkit.CreateMockStore(t) + defer clean() + tk := testkit.NewTestKit(t, store) tk.MustExec("use test") // Some ddl cases. @@ -2326,8 +2409,8 @@ func (s *testColumnTypeChangeSuite) TestChangeNullValueFromOtherTypeToTimestamp( prepare() // only from other type NULL to timestamp type NOT NULL, it should be successful. _, err := tk.Exec("alter table t change column a a1 time NOT NULL") - c.Assert(err, NotNil) - c.Assert(err.Error(), Equals, "[ddl:1265]Data truncated for column 'a1' at row 1") + require.Error(t, err) + require.EqualError(t, err, "[ddl:1265]Data truncated for column 'a1' at row 1") prepare2 := func() { tk.MustExec("drop table if exists t") @@ -2339,23 +2422,25 @@ func (s *testColumnTypeChangeSuite) TestChangeNullValueFromOtherTypeToTimestamp( prepare2() // only from other type NULL to timestamp type NOT NULL, it should be successful. (timestamp to timestamp excluded) _, err = tk.Exec("alter table t modify column a timestamp NOT NULL") - c.Assert(err, NotNil) - c.Assert(err.Error(), Equals, "[ddl:1265]Data truncated for column 'a' at row 1") + require.Error(t, err) + require.EqualError(t, err, "[ddl:1265]Data truncated for column 'a' at row 1") // Some dml cases. tk.MustExec("drop table if exists t") tk.MustExec("create table t(a timestamp NOT NULL)") _, err = tk.Exec("insert into t values()") - c.Assert(err, NotNil) - c.Assert(err.Error(), Equals, "[table:1364]Field 'a' doesn't have a default value") + require.Error(t, err) + require.EqualError(t, err, "[table:1364]Field 'a' doesn't have a default value") _, err = tk.Exec("insert into t values(null)") - c.Assert(err.Error(), Equals, "[table:1048]Column 'a' cannot be null") + require.EqualError(t, err, "[table:1048]Column 'a' cannot be null") } -func (s *testColumnTypeChangeSuite) TestColumnTypeChangeBetweenFloatAndDouble(c *C) { +func TestColumnTypeChangeBetweenFloatAndDouble(t *testing.T) { // issue #31372 - tk := testkit.NewTestKit(c, s.store) + store, clean := testkit.CreateMockStore(t) + defer clean() + tk := testkit.NewTestKit(t, store) tk.MustExec("use test") prepare := func(createTableStmt string) { diff --git a/ddl/db_cache_test.go b/ddl/db_cache_test.go index c1f591869e3b9..c18ea40f2f1dc 100644 --- a/ddl/db_cache_test.go +++ b/ddl/db_cache_test.go @@ -24,29 +24,18 @@ import ( "github.com/pingcap/tidb/parser/model" "github.com/pingcap/tidb/parser/terror" "github.com/pingcap/tidb/session" - "github.com/pingcap/tidb/sessionctx" "github.com/pingcap/tidb/store/mockstore" - "github.com/pingcap/tidb/table" "github.com/pingcap/tidb/testkit" "github.com/stretchr/testify/require" ) func checkTableCacheStatus(t *testing.T, se session.Session, dbName, tableName string, status model.TableCacheStatusType) { - tb := testGetTableByNameT(t, se, dbName, tableName) dom := domain.GetDomain(se) err := dom.Reload() require.NoError(t, err) - require.Equal(t, status, tb.Meta().TableCacheStatusType) -} - -func testGetTableByNameT(t *testing.T, ctx sessionctx.Context, db, table string) table.Table { - dom := domain.GetDomain(ctx) - // Make sure the table schema is the new schema. - err := dom.Reload() - require.NoError(t, err) - tbl, err := dom.InfoSchema().TableByName(model.NewCIStr(db), model.NewCIStr(table)) + tb, err := dom.InfoSchema().TableByName(model.NewCIStr(dbName), model.NewCIStr(tableName)) require.NoError(t, err) - return tbl + require.Equal(t, status, tb.Meta().TableCacheStatusType) } func TestAlterPartitionCache(t *testing.T) { diff --git a/ddl/db_test.go b/ddl/db_test.go index 97b9954d9a4e0..d077f90a38232 100644 --- a/ddl/db_test.go +++ b/ddl/db_test.go @@ -25,6 +25,7 @@ import ( "strings" "sync" "sync/atomic" + "testing" "time" . "github.com/pingcap/check" @@ -65,6 +66,7 @@ import ( "github.com/pingcap/tidb/util/sqlexec" "github.com/pingcap/tidb/util/testkit" "github.com/pingcap/tidb/util/testutil" + "github.com/stretchr/testify/require" "github.com/tikv/client-go/v2/testutils" ) @@ -244,6 +246,16 @@ func (s *testDBSuite1) TestRenameIndex(c *C) { tk.MustGetErrCode("alter table t rename key k3 to K2", errno.ErrDupKeyName) } +func testGetTableByNameT(t *testing.T, ctx sessionctx.Context, db, table string) table.Table { + dom := domain.GetDomain(ctx) + // Make sure the table schema is the new schema. + err := dom.Reload() + require.NoError(t, err) + tbl, err := dom.InfoSchema().TableByName(model.NewCIStr(db), model.NewCIStr(table)) + require.NoError(t, err) + return tbl +} + func testGetTableByName(c *C, ctx sessionctx.Context, db, table string) table.Table { dom := domain.GetDomain(ctx) // Make sure the table schema is the new schema. diff --git a/ddl/integration_test.go b/ddl/integration_test.go index 1a2213df0d661..de4a4df0a9b22 100644 --- a/ddl/integration_test.go +++ b/ddl/integration_test.go @@ -124,10 +124,3 @@ func TestSchema(t *testing.T) { ddl.ExportTestSchema(t) } - -func TestTestSerialStatSuite(t *testing.T) { - _, clean := testkit.CreateMockStore(t) - defer clean() - - ddl.ExportTestSerialStatSuite(t) -} diff --git a/ddl/restart_test.go b/ddl/restart_test.go index 1aa962bbbfa7f..9169be5a1027f 100644 --- a/ddl/restart_test.go +++ b/ddl/restart_test.go @@ -26,6 +26,7 @@ import ( "github.com/pingcap/tidb/kv" "github.com/pingcap/tidb/parser/model" "github.com/pingcap/tidb/parser/terror" + "github.com/pingcap/tidb/testkit" "github.com/pingcap/tidb/util/mock" "github.com/stretchr/testify/require" "github.com/stretchr/testify/suite" @@ -108,11 +109,8 @@ LOOP: } func TestSchemaResume(t *testing.T) { - store := testCreateStore(t, "test_schema_resume") - defer func() { - err := store.Close() - require.NoError(t, err) - }() + store, clean := testkit.CreateMockStore(t) + defer clean() d1, err := testNewDDLAndStart( context.Background(), @@ -147,27 +145,24 @@ func TestSchemaResume(t *testing.T) { testCheckSchemaState(t, d1, dbInfo, model.StateNone) } -func (s *testStatSuiteToVerify) TestStat() { - store := testCreateStore(s.T(), "test_stat") - defer func() { - err := store.Close() - require.NoError(s.T(), err) - }() +func TestStat(t *testing.T) { + store, clean := testkit.CreateMockStore(t) + defer clean() d, err := testNewDDLAndStart( context.Background(), WithStore(store), WithLease(testLease), ) - require.NoError(s.T(), err) + require.NoError(t, err) defer func() { err := d.Stop() - require.NoError(s.T(), err) + require.NoError(t, err) }() dbInfo, err := testSchemaInfo(d, "test_restart") - require.NoError(s.T(), err) - testCreateSchema(s.T(), testNewContext(d), d, dbInfo) + require.NoError(t, err) + testCreateSchema(t, testNewContext(d), d, dbInfo) // TODO: Get this information from etcd. // m, err := d.Stats(nil) @@ -186,20 +181,19 @@ func (s *testStatSuiteToVerify) TestStat() { ticker := time.NewTicker(d.lease * 1) defer ticker.Stop() - ver := s.getDDLSchemaVer(d) + ver := getDDLSchemaVer(t, d) LOOP: for { select { case <-ticker.C: - err := d.Stop() - require.Nil(s.T(), err) - require.GreaterOrEqual(s.T(), s.getDDLSchemaVer(d), ver) + require.NoError(t, d.Stop()) + require.GreaterOrEqual(t, getDDLSchemaVer(t, d), ver) d.restartWorkers(context.Background()) time.Sleep(time.Millisecond * 20) - case err := <-done: + case result := <-done: // TODO: Get this information from etcd. // m, err := d.Stats(nil) - require.Nil(s.T(), err) + require.Nil(t, result) break LOOP } } diff --git a/ddl/serial_test.go b/ddl/serial_test.go index b06bf67f824ca..131e0b519ba67 100644 --- a/ddl/serial_test.go +++ b/ddl/serial_test.go @@ -40,7 +40,6 @@ import ( "github.com/pingcap/tidb/parser/mysql" "github.com/pingcap/tidb/planner/core" "github.com/pingcap/tidb/session" - "github.com/pingcap/tidb/sessionctx" "github.com/pingcap/tidb/sessionctx/variable" "github.com/pingcap/tidb/store/mockstore" "github.com/pingcap/tidb/tablecodec" @@ -426,7 +425,7 @@ func (s *testSerialSuite) TestCreateTableWithLike(c *C) { tk.MustQuery("select * from t").Check(testkit.Rows("10 1")) tk.MustQuery("select * from t1").Check(testkit.Rows("1 11")) tk.MustQuery("select * from t2").Check(testkit.Rows("1 12")) - ctx := tk.Se.(sessionctx.Context) + ctx := tk.Se is := domain.GetDomain(ctx).InfoSchema() tbl1, err := is.TableByName(model.NewCIStr("ctwl_db"), model.NewCIStr("t1")) c.Assert(err, IsNil) @@ -579,7 +578,7 @@ func (s *testSerialSuite) TestCreateTableWithLikeAtTemporaryMode(c *C) { tk.MustExec(`create table test_gv_ddl(a int, b int as (a+8) virtual, c int as (b + 2) stored)`) tk.MustExec(`create global temporary table test_gv_ddl_temp like test_gv_ddl on commit delete rows;`) defer tk.MustExec("drop table if exists test_gv_ddl_temp, test_gv_ddl") - is := tk.Se.(sessionctx.Context).GetInfoSchema().(infoschema.InfoSchema) + is := tk.Se.GetInfoSchema().(infoschema.InfoSchema) table, err := is.TableByName(model.NewCIStr("test"), model.NewCIStr("test_gv_ddl")) c.Assert(err, IsNil) testCases := []struct { @@ -608,7 +607,7 @@ func (s *testSerialSuite) TestCreateTableWithLikeAtTemporaryMode(c *C) { tk.MustExec("create table test_foreign_key (c int,d int,foreign key (d) references t1 (b));") defer tk.MustExec("drop table if exists test_foreign_key, t1;") tk.MustExec("create global temporary table test_foreign_key_temp like test_foreign_key on commit delete rows;") - is = tk.Se.(sessionctx.Context).GetInfoSchema().(infoschema.InfoSchema) + is = tk.Se.GetInfoSchema().(infoschema.InfoSchema) table, err = is.TableByName(model.NewCIStr("test"), model.NewCIStr("test_foreign_key_temp")) c.Assert(err, IsNil) tableInfo := table.Meta() @@ -655,7 +654,7 @@ func (s *testSerialSuite) TestCreateTableWithLikeAtTemporaryMode(c *C) { " `i` int(11) NOT NULL,\n `j` int(11) DEFAULT NULL,\n PRIMARY KEY (`i`) /*T![clustered_index] CLUSTERED */\n" + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin")) tk.MustExec("create temporary table if not exists tb12 like tb11;") - c.Assert(tk.Se.(sessionctx.Context).GetSessionVars().StmtCtx.GetWarnings()[0].Err.Error(), Equals, + c.Assert(tk.Se.GetSessionVars().StmtCtx.GetWarnings()[0].Err.Error(), Equals, infoschema.ErrTableExists.GenWithStackByArgs("test.tb12").Error()) defer tk.MustExec("drop table if exists tb11, tb12") // Test from->local temporary, to->local temporary @@ -692,7 +691,7 @@ func (s *testSerialSuite) TestCreateTableWithLikeAtTemporaryMode(c *C) { tk.MustExec("create table foreign_key_table1 (a int, b int);") tk.MustExec("create table foreign_key_table2 (c int,d int,foreign key (d) references foreign_key_table1 (b));") tk.MustExec("create temporary table foreign_key_tmp like foreign_key_table2") - is = tk.Se.(sessionctx.Context).GetInfoSchema().(infoschema.InfoSchema) + is = tk.Se.GetInfoSchema().(infoschema.InfoSchema) table, err = is.TableByName(model.NewCIStr("test"), model.NewCIStr("foreign_key_tmp")) c.Assert(err, IsNil) tableInfo = table.Meta() @@ -1676,7 +1675,7 @@ func (s *testIntegrationSuite7) TestCreateClusteredIndex(c *C) { tk.MustExec("CREATE TABLE t2 (a varchar(255) primary key, b int)") tk.MustExec("CREATE TABLE t3 (a int, b int, c int, primary key (a, b))") tk.MustExec("CREATE TABLE t4 (a int, b int, c int)") - ctx := tk.Se.(sessionctx.Context) + ctx := tk.Se is := domain.GetDomain(ctx).InfoSchema() tbl, err := is.TableByName(model.NewCIStr("test"), model.NewCIStr("t1")) c.Assert(err, IsNil) diff --git a/ddl/stat_test.go b/ddl/stat_test.go index d2f52cb672c36..540ff7150b7a3 100644 --- a/ddl/stat_test.go +++ b/ddl/stat_test.go @@ -19,84 +19,59 @@ import ( "testing" "github.com/pingcap/failpoint" + "github.com/pingcap/tidb/testkit" "github.com/pingcap/tidb/types" "github.com/stretchr/testify/require" - "github.com/stretchr/testify/suite" ) -type testStatSuiteToVerify struct { - suite.Suite -} - -func TestStatSuite(t *testing.T) { - suite.Run(t, new(testStatSuiteToVerify)) -} - -func (s *testStatSuiteToVerify) SetupSuite() { -} - -func (s *testStatSuiteToVerify) TearDownSuite() { -} - -type testSerialStatSuiteToVerify struct { - suite.Suite -} - -func ExportTestSerialStatSuite(t *testing.T) { - suite.Run(t, new(testSerialStatSuiteToVerify)) -} - -func (s *testStatSuiteToVerify) getDDLSchemaVer(d *ddl) int64 { +func getDDLSchemaVer(t *testing.T, d *ddl) int64 { m, err := d.Stats(nil) - require.NoError(s.T(), err) + require.NoError(t, err) v := m[ddlSchemaVersion] return v.(int64) } -func (s *testSerialStatSuiteToVerify) TestDDLStatsInfo() { - store := testCreateStore(s.T(), "test_stat") - defer func() { - err := store.Close() - require.NoError(s.T(), err) - }() +func TestDDLStatsInfo(t *testing.T) { + store, clean := testkit.CreateMockStore(t) + defer clean() d, err := testNewDDLAndStart( context.Background(), WithStore(store), WithLease(testLease), ) - require.NoError(s.T(), err) + require.NoError(t, err) defer func() { err := d.Stop() - require.NoError(s.T(), err) + require.NoError(t, err) }() dbInfo, err := testSchemaInfo(d, "test_stat") - require.NoError(s.T(), err) - testCreateSchema(s.T(), testNewContext(d), d, dbInfo) + require.NoError(t, err) + testCreateSchema(t, testNewContext(d), d, dbInfo) tblInfo, err := testTableInfo(d, "t", 2) - require.NoError(s.T(), err) + require.NoError(t, err) ctx := testNewContext(d) - testCreateTable(s.T(), ctx, d, dbInfo, tblInfo) + testCreateTable(t, ctx, d, dbInfo, tblInfo) - t := testGetTable(s.T(), d, dbInfo.ID, tblInfo.ID) + tt := testGetTable(t, d, dbInfo.ID, tblInfo.ID) // insert t values (1, 1), (2, 2), (3, 3) - _, err = t.AddRecord(ctx, types.MakeDatums(1, 1)) - require.NoError(s.T(), err) - _, err = t.AddRecord(ctx, types.MakeDatums(2, 2)) - require.NoError(s.T(), err) - _, err = t.AddRecord(ctx, types.MakeDatums(3, 3)) - require.NoError(s.T(), err) + _, err = tt.AddRecord(ctx, types.MakeDatums(1, 1)) + require.NoError(t, err) + _, err = tt.AddRecord(ctx, types.MakeDatums(2, 2)) + require.NoError(t, err) + _, err = tt.AddRecord(ctx, types.MakeDatums(3, 3)) + require.NoError(t, err) txn, err := ctx.Txn(true) - require.NoError(s.T(), err) + require.NoError(t, err) err = txn.Commit(context.Background()) - require.NoError(s.T(), err) + require.NoError(t, err) job := buildCreateIdxJob(dbInfo, tblInfo, true, "idx", "c1") - require.Nil(s.T(), failpoint.Enable("github.com/pingcap/tidb/ddl/checkBackfillWorkerNum", `return(true)`)) + require.NoError(t, failpoint.Enable("github.com/pingcap/tidb/ddl/checkBackfillWorkerNum", `return(true)`)) defer func() { - require.Nil(s.T(), failpoint.Disable("github.com/pingcap/tidb/ddl/checkBackfillWorkerNum")) + require.NoError(t, failpoint.Disable("github.com/pingcap/tidb/ddl/checkBackfillWorkerNum")) }() done := make(chan error, 1) @@ -108,12 +83,12 @@ func (s *testSerialStatSuiteToVerify) TestDDLStatsInfo() { for !exit { select { case err := <-done: - require.NoError(s.T(), err) + require.NoError(t, err) exit = true case <-TestCheckWorkerNumCh: varMap, err := d.Stats(nil) - require.NoError(s.T(), err) - require.Equal(s.T(), varMap[ddlJobReorgHandle], "1") + require.NoError(t, err) + require.Equal(t, varMap[ddlJobReorgHandle], "1") } } } diff --git a/executor/executor_test.go b/executor/executor_test.go index 0ac87e1b35aa6..98270b65307e9 100644 --- a/executor/executor_test.go +++ b/executor/executor_test.go @@ -189,6 +189,30 @@ func newStoreWithBootstrap() (kv.Storage, *domain.Domain, error) { var mockTikv = flag.Bool("mockTikv", true, "use mock tikv store in executor test") +func mockGC(tk *testkit.TestKit) (string, string, string, func()) { + originGC := ddl.IsEmulatorGCEnable() + resetGC := func() { + if originGC { + ddl.EmulatorGCEnable() + } else { + ddl.EmulatorGCDisable() + } + } + + // disable emulator GC. + // Otherwise emulator GC will delete table record as soon as possible after execute drop table ddl. + ddl.EmulatorGCDisable() + gcTimeFormat := "20060102-15:04:05 -0700 MST" + timeBeforeDrop := time.Now().Add(0 - 48*60*60*time.Second).Format(gcTimeFormat) + timeAfterDrop := time.Now().Add(48 * 60 * 60 * time.Second).Format(gcTimeFormat) + safePointSQL := `INSERT HIGH_PRIORITY INTO mysql.tidb VALUES ('tikv_gc_safe_point', '%[1]s', '') + ON DUPLICATE KEY + UPDATE variable_value = '%[1]s'` + // clear GC variables first. + tk.MustExec("delete from mysql.tidb where variable_name in ( 'tikv_gc_safe_point','tikv_gc_enable' )") + return timeBeforeDrop, timeAfterDrop, safePointSQL, resetGC +} + func (s *baseTestSuite) SetUpSuite(c *C) { s.Parser = parser.New() flag.Lookup("mockTikv") @@ -6013,7 +6037,7 @@ func (s *testRecoverTable) TestRecoverTable(c *C) { tk.MustExec("drop table if exists t_recover") tk.MustExec("create table t_recover (a int);") - timeBeforeDrop, timeAfterDrop, safePointSQL, resetGC := testkit.MockGC(tk) + timeBeforeDrop, timeAfterDrop, safePointSQL, resetGC := mockGC(tk) defer resetGC() tk.MustExec("insert into t_recover values (1),(2),(3)") @@ -6108,7 +6132,7 @@ func (s *testRecoverTable) TestFlashbackTable(c *C) { tk.MustExec("drop table if exists t_flashback") tk.MustExec("create table t_flashback (a int);") - timeBeforeDrop, _, safePointSQL, resetGC := testkit.MockGC(tk) + timeBeforeDrop, _, safePointSQL, resetGC := mockGC(tk) defer resetGC() // Set GC safe point @@ -6224,7 +6248,7 @@ func (s *testRecoverTable) TestRecoverTempTable(c *C) { tk.MustExec("drop table if exists tmp2_recover") tk.MustExec("create temporary table tmp2_recover (a int);") - timeBeforeDrop, _, safePointSQL, resetGC := testkit.MockGC(tk) + timeBeforeDrop, _, safePointSQL, resetGC := mockGC(tk) defer resetGC() // Set GC safe point tk.MustExec(fmt.Sprintf(safePointSQL, timeBeforeDrop)) diff --git a/testkit/testkit.go b/testkit/testkit.go index da5005adb2e73..c99791efe369a 100644 --- a/testkit/testkit.go +++ b/testkit/testkit.go @@ -22,10 +22,8 @@ import ( "fmt" "strings" "testing" - "time" "github.com/pingcap/errors" - "github.com/pingcap/tidb/ddl" "github.com/pingcap/tidb/kv" "github.com/pingcap/tidb/parser/terror" "github.com/pingcap/tidb/session" @@ -266,28 +264,3 @@ func WithPruneMode(tk *TestKit, mode variable.PartitionPruneMode, f func()) { tk.MustExec("set global tidb_partition_prune_mode=`" + string(mode) + "`") f() } - -// MockGC is used to make GC work in the test environment. -func MockGC(tk *TestKit) (string, string, string, func()) { - originGC := ddl.IsEmulatorGCEnable() - resetGC := func() { - if originGC { - ddl.EmulatorGCEnable() - } else { - ddl.EmulatorGCDisable() - } - } - - // disable emulator GC. - // Otherwise emulator GC will delete table record as soon as possible after execute drop table ddl. - ddl.EmulatorGCDisable() - gcTimeFormat := "20060102-15:04:05 -0700 MST" - timeBeforeDrop := time.Now().Add(0 - 48*60*60*time.Second).Format(gcTimeFormat) - timeAfterDrop := time.Now().Add(48 * 60 * 60 * time.Second).Format(gcTimeFormat) - safePointSQL := `INSERT HIGH_PRIORITY INTO mysql.tidb VALUES ('tikv_gc_safe_point', '%[1]s', '') - ON DUPLICATE KEY - UPDATE variable_value = '%[1]s'` - // clear GC variables first. - tk.MustExec("delete from mysql.tidb where variable_name in ( 'tikv_gc_safe_point','tikv_gc_enable' )") - return timeBeforeDrop, timeAfterDrop, safePointSQL, resetGC -} diff --git a/util/testkit/testkit.go b/util/testkit/testkit.go index e1f0542797c14..857300f7a7efc 100644 --- a/util/testkit/testkit.go +++ b/util/testkit/testkit.go @@ -24,11 +24,9 @@ import ( "sort" "strings" "sync/atomic" - "time" "github.com/pingcap/check" "github.com/pingcap/errors" - "github.com/pingcap/tidb/ddl" "github.com/pingcap/tidb/domain" "github.com/pingcap/tidb/kv" "github.com/pingcap/tidb/parser/model" @@ -141,31 +139,6 @@ func NewTestKitWithInit(c *check.C, store kv.Storage) *TestKit { return tk } -// MockGC is used to make GC work in the test environment. -func MockGC(tk *TestKit) (string, string, string, func()) { - originGC := ddl.IsEmulatorGCEnable() - resetGC := func() { - if originGC { - ddl.EmulatorGCEnable() - } else { - ddl.EmulatorGCDisable() - } - } - - // disable emulator GC. - // Otherwise emulator GC will delete table record as soon as possible after execute drop table ddl. - ddl.EmulatorGCDisable() - gcTimeFormat := "20060102-15:04:05 -0700 MST" - timeBeforeDrop := time.Now().Add(0 - 48*60*60*time.Second).Format(gcTimeFormat) - timeAfterDrop := time.Now().Add(48 * 60 * 60 * time.Second).Format(gcTimeFormat) - safePointSQL := `INSERT HIGH_PRIORITY INTO mysql.tidb VALUES ('tikv_gc_safe_point', '%[1]s', '') - ON DUPLICATE KEY - UPDATE variable_value = '%[1]s'` - // clear GC variables first. - tk.MustExec("delete from mysql.tidb where variable_name in ( 'tikv_gc_safe_point','tikv_gc_enable' )") - return timeBeforeDrop, timeAfterDrop, safePointSQL, resetGC -} - var connectionID uint64 // GetConnectionID get the connection ID for tk.Se