From 74404a41cad60352ef087aa4ec21ead74fce6c65 Mon Sep 17 00:00:00 2001 From: fzzf678 <108643977+fzzf678@users.noreply.github.com> Date: Wed, 28 Aug 2024 15:21:17 +0800 Subject: [PATCH] infoschema_v2: add ut test `Data` struct fields' correctness (#55709) ref pingcap/tidb#50959 --- pkg/infoschema/BUILD.bazel | 2 +- pkg/infoschema/infoschema_v2_test.go | 106 +++++++++++++++++++++++++++ pkg/meta/BUILD.bazel | 2 +- pkg/meta/meta_test.go | 85 ++++++++++++++++++++- 4 files changed, 192 insertions(+), 3 deletions(-) diff --git a/pkg/infoschema/BUILD.bazel b/pkg/infoschema/BUILD.bazel index 46f3615541cb5..7119d302119f2 100644 --- a/pkg/infoschema/BUILD.bazel +++ b/pkg/infoschema/BUILD.bazel @@ -91,7 +91,7 @@ go_test( ], embed = [":infoschema"], flaky = True, - shard_count = 23, + shard_count = 24, deps = [ "//pkg/ddl/placement", "//pkg/domain", diff --git a/pkg/infoschema/infoschema_v2_test.go b/pkg/infoschema/infoschema_v2_test.go index 7366ca0a61846..1307a072f8caf 100644 --- a/pkg/infoschema/infoschema_v2_test.go +++ b/pkg/infoschema/infoschema_v2_test.go @@ -453,3 +453,109 @@ func TestSpecialAttributeCorrectnessInSchemaChange(t *testing.T) { tblInfo.ForeignKeys = nil updateTableSpecialAttribute(t, dbInfo, tblInfo, builder, r, model.ActionDropForeignKey, 12, ForeignKeysAttribute, false) } + +func TestDataStructFieldsCorrectnessInSchemaChange(t *testing.T) { + r := internal.CreateAutoIDRequirement(t) + defer func() { + r.Store().Close() + }() + + schemaName := model.NewCIStr("testDB") + tableName := model.NewCIStr("testTable") + builder := NewBuilder(r, nil, NewData(), variable.SchemaCacheSize.Load() > 0) + err := builder.InitWithDBInfos(nil, nil, nil, 1) + require.NoError(t, err) + is := builder.Build(math.MaxUint64) + v2, ok := is.(*infoschemaV2) + require.True(t, ok) + + // verify schema related fields after create database + dbInfo := internal.MockDBInfo(t, r.Store(), schemaName.O) + internal.AddDB(t, r.Store(), dbInfo) + txn, err := r.Store().Begin() + require.NoError(t, err) + _, err = builder.ApplyDiff(meta.NewMeta(txn), &model.SchemaDiff{Type: model.ActionCreateSchema, Version: 1, SchemaID: dbInfo.ID}) + require.NoError(t, err) + dbIDName, ok := v2.Data.schemaID2Name.Get(schemaIDName{id: dbInfo.ID, schemaVersion: 1}) + require.True(t, ok) + require.Equal(t, dbIDName.name, dbInfo.Name) + dbItem, ok := v2.Data.schemaMap.Get(schemaItem{schemaVersion: 1, dbInfo: &model.DBInfo{Name: dbInfo.Name}}) + require.True(t, ok) + require.Equal(t, dbItem.dbInfo.ID, dbInfo.ID) + + // verify table related fields after create table + tblInfo := internal.MockTableInfo(t, r.Store(), tableName.O) + internal.AddTable(t, r.Store(), dbInfo, tblInfo) + txn, err = r.Store().Begin() + require.NoError(t, err) + _, err = builder.ApplyDiff(meta.NewMeta(txn), &model.SchemaDiff{Type: model.ActionCreateTable, Version: 2, SchemaID: dbInfo.ID, TableID: tblInfo.ID}) + require.NoError(t, err) + tblItem, ok := v2.Data.byName.Get(tableItem{dbName: dbInfo.Name, tableName: tblInfo.Name, schemaVersion: 2}) + require.True(t, ok) + require.Equal(t, tblItem.tableID, tblInfo.ID) + tblItem, ok = v2.Data.byID.Get(tableItem{tableID: tblInfo.ID, schemaVersion: 2}) + require.True(t, ok) + require.Equal(t, tblItem.dbID, dbInfo.ID) + tbl, ok := v2.Data.tableCache.Get(tableCacheKey{tableID: tblInfo.ID, schemaVersion: 2}) + require.True(t, ok) + require.Equal(t, tbl.Meta().Name, tblInfo.Name) + + // verify partition related fields after add partition + require.Equal(t, v2.Data.pid2tid.Len(), 0) + tblInfo.Partition = &model.PartitionInfo{ + Definitions: []model.PartitionDefinition{ + {ID: 1, Name: model.NewCIStr("p1")}, + {ID: 2, Name: model.NewCIStr("p2")}, + }, + Enable: true, + DDLState: model.StatePublic, + } + tblInfo1 := updateTableSpecialAttribute(t, dbInfo, tblInfo, builder, r, model.ActionAddTablePartition, 3, PartitionAttribute, true) + require.Equal(t, tblInfo.Partition, tblInfo1.Partition) + require.Equal(t, v2.Data.pid2tid.Len(), 2) + tblInfoItem, ok := v2.Data.pid2tid.Get(partitionItem{partitionID: 2, schemaVersion: 3}) + require.True(t, ok) + require.Equal(t, tblInfoItem.tableID, tblInfo.ID) + + // verify partition related fields drop partition + tblInfo.Partition.Definitions = tblInfo.Partition.Definitions[:1] + tblInfo1 = updateTableSpecialAttribute(t, dbInfo, tblInfo, builder, r, model.ActionDropTablePartition, 4, PartitionAttribute, true) + require.Equal(t, tblInfo.Partition, tblInfo1.Partition) + require.Equal(t, v2.Data.pid2tid.Len(), 4) + tblInfoItem, ok = v2.Data.pid2tid.Get(partitionItem{partitionID: 1, schemaVersion: 4}) + require.True(t, ok) + require.False(t, tblInfoItem.tomb) + tblInfoItem, ok = v2.Data.pid2tid.Get(partitionItem{partitionID: 2, schemaVersion: 4}) + require.True(t, ok) + require.True(t, tblInfoItem.tomb) + + // verify table and partition related fields after drop table + txn, err = r.Store().Begin() + require.NoError(t, err) + _, err = builder.ApplyDiff(meta.NewMeta(txn), &model.SchemaDiff{Type: model.ActionDropTable, Version: 5, SchemaID: dbInfo.ID, TableID: tblInfo.ID}) + require.NoError(t, err) + tblItem, ok = v2.Data.byName.Get(tableItem{dbName: dbInfo.Name, tableName: tblInfo.Name, schemaVersion: 5}) + require.True(t, ok) + require.True(t, tblItem.tomb) + tblItem, ok = v2.Data.byID.Get(tableItem{tableID: tblInfo.ID, schemaVersion: 5}) + require.True(t, ok) + require.True(t, tblItem.tomb) + tbl, ok = v2.Data.tableCache.Get(tableCacheKey{tableID: tblInfo.ID, schemaVersion: 5}) + require.False(t, ok) + require.Equal(t, v2.Data.pid2tid.Len(), 5) // tomb partition info + tblInfoItem, ok = v2.Data.pid2tid.Get(partitionItem{partitionID: 1, schemaVersion: 5}) + require.True(t, ok) + require.True(t, tblInfoItem.tomb) + + // verify schema related fields after drop database + txn, err = r.Store().Begin() + require.NoError(t, err) + _, err = builder.ApplyDiff(meta.NewMeta(txn), &model.SchemaDiff{Type: model.ActionDropSchema, Version: 6, SchemaID: dbInfo.ID}) + require.NoError(t, err) + dbIDName, ok = v2.Data.schemaID2Name.Get(schemaIDName{id: dbInfo.ID, schemaVersion: 6}) + require.True(t, ok) + require.True(t, dbIDName.tomb) + dbItem, ok = v2.Data.schemaMap.Get(schemaItem{schemaVersion: 6, dbInfo: &model.DBInfo{Name: dbInfo.Name}}) + require.True(t, ok) + require.True(t, dbItem.tomb) +} diff --git a/pkg/meta/BUILD.bazel b/pkg/meta/BUILD.bazel index b25f4655f2c79..229f82c1dea7f 100644 --- a/pkg/meta/BUILD.bazel +++ b/pkg/meta/BUILD.bazel @@ -34,7 +34,7 @@ go_test( ], embed = [":meta"], flaky = True, - shard_count = 15, + shard_count = 16, deps = [ "//pkg/ddl", "//pkg/infoschema", diff --git a/pkg/meta/meta_test.go b/pkg/meta/meta_test.go index c07e958d073a5..9fe41e71b9a44 100644 --- a/pkg/meta/meta_test.go +++ b/pkg/meta/meta_test.go @@ -859,7 +859,7 @@ func benchFastJSONTableNameInfo(b *testing.B, sql string) { } } -func TestSpecialAttributeCorrectnessAfterBootstrap(t *testing.T) { +func TestInfoSchemaV2SpecialAttributeCorrectnessAfterBootstrap(t *testing.T) { store, err := mockstore.NewMockStore() require.NoError(t, err) defer func() { @@ -954,3 +954,86 @@ func TestSpecialAttributeCorrectnessAfterBootstrap(t *testing.T) { require.Equal(t, len(tblInfoRes[0].TableInfos), 1) require.Equal(t, tblInfo.TTLInfo, tblInfoRes[0].TableInfos[0].TTLInfo) } + +func TestInfoSchemaV2DataFieldsCorrectnessAfterBootstrap(t *testing.T) { + store, err := mockstore.NewMockStore() + require.NoError(t, err) + defer func() { + require.NoError(t, store.Close()) + }() + + // create database + dbInfo := &model.DBInfo{ + ID: 10001, + Name: model.NewCIStr("sc"), + Charset: "utf8", + Collate: "utf8_general_ci", + State: model.StatePublic, + } + + // create table with partition info + tblInfo := &model.TableInfo{ + ID: 10002, + Name: model.NewCIStr("cs"), + Charset: "latin1", + Collate: "latin1_bin", + State: model.StatePublic, + Partition: &model.PartitionInfo{ + Definitions: []model.PartitionDefinition{ + {ID: 1, Name: model.NewCIStr("p1")}, + }, + Enable: true, + }, + } + + ctx := kv.WithInternalSourceType(context.Background(), kv.InternalTxnDDL) + err = kv.RunInNewTxn(ctx, store, true, func(ctx context.Context, txn kv.Transaction) error { + err := meta.NewMeta(txn).CreateDatabase(dbInfo) + require.NoError(t, err) + err = meta.NewMeta(txn).CreateTableOrView(dbInfo.ID, tblInfo) + require.NoError(t, err) + return errors.Trace(err) + }) + require.NoError(t, err) + + // bootstrap + dom, err := session.BootstrapSession(store) + require.NoError(t, err) + defer dom.Close() + + is := dom.InfoSchema() + //byID, traverse byID and load from store + tbl, ok := is.TableByID(context.Background(), 10002) + require.True(t, ok) + require.Equal(t, tbl.Meta().ID, tblInfo.ID) + + //byName, traverse byName and load from store, + tbl, err = is.TableByName(context.Background(), model.NewCIStr("sc"), model.NewCIStr("cs")) + require.NoError(t, err) + require.Equal(t, tbl.Meta().ID, tblInfo.ID) + + //tableCache, table info exists in cache now, just use id to seek + tbl, ok = is.TableByID(context.Background(), 10002) + require.True(t, ok) + require.Equal(t, tbl.Meta().ID, tblInfo.ID) + + //schemaMap, traverse schemaMap find dbInfo + db, ok := is.SchemaByName(model.NewCIStr("sc")) + require.True(t, ok) + require.Equal(t, db.ID, dbInfo.ID) + + //schemaID2Name, traverse schemaID2Name find dbInfo + db, ok = is.SchemaByID(dbInfo.ID) + require.True(t, ok) + require.Equal(t, db.ID, dbInfo.ID) + + //pid2tid, traverse pid2tid find tblInfo, dbInfo and partition info + tbl, ok = is.TableByID(context.Background(), 10002) + require.True(t, ok) + require.Equal(t, len(tbl.Meta().GetPartitionInfo().Definitions), 1) + pid := tbl.Meta().GetPartitionInfo().Definitions[0].ID + tbl, db, pDef := is.FindTableByPartitionID(pid) + require.NotNil(t, tbl) + require.NotNil(t, db) + require.NotNil(t, pDef) +}