github.com/insionng/yougam@v0.0.0-20170714101924-2bc18d833463/libraries/pingcap/tidb/ddl/table_test.go (about) 1 // Copyright 2015 PingCAP, Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // See the License for the specific language governing permissions and 12 // limitations under the License. 13 14 package ddl 15 16 import ( 17 "fmt" 18 "time" 19 20 . "github.com/insionng/yougam/libraries/pingcap/check" 21 "github.com/insionng/yougam/libraries/pingcap/tidb/context" 22 "github.com/insionng/yougam/libraries/pingcap/tidb/kv" 23 "github.com/insionng/yougam/libraries/pingcap/tidb/meta" 24 "github.com/insionng/yougam/libraries/pingcap/tidb/meta/autoid" 25 "github.com/insionng/yougam/libraries/pingcap/tidb/model" 26 "github.com/insionng/yougam/libraries/pingcap/tidb/mysql" 27 "github.com/insionng/yougam/libraries/pingcap/tidb/sessionctx/variable" 28 "github.com/insionng/yougam/libraries/pingcap/tidb/table" 29 "github.com/insionng/yougam/libraries/pingcap/tidb/util/mock" 30 "github.com/insionng/yougam/libraries/pingcap/tidb/util/testleak" 31 "github.com/insionng/yougam/libraries/pingcap/tidb/util/types" 32 ) 33 34 var _ = Suite(&testTableSuite{}) 35 36 type testTableSuite struct { 37 store kv.Storage 38 dbInfo *model.DBInfo 39 40 d *ddl 41 } 42 43 // create a test table with num int columns and with no index. 44 func testTableInfo(c *C, d *ddl, name string, num int) *model.TableInfo { 45 var err error 46 tblInfo := &model.TableInfo{ 47 Name: model.NewCIStr(name), 48 } 49 tblInfo.ID, err = d.genGlobalID() 50 c.Assert(err, IsNil) 51 52 cols := make([]*model.ColumnInfo, num) 53 for i := range cols { 54 col := &model.ColumnInfo{ 55 Name: model.NewCIStr(fmt.Sprintf("c%d", i+1)), 56 Offset: i, 57 DefaultValue: i + 1, 58 State: model.StatePublic, 59 } 60 61 col.FieldType = *types.NewFieldType(mysql.TypeLong) 62 63 col.ID, err = d.genGlobalID() 64 c.Assert(err, IsNil) 65 cols[i] = col 66 } 67 68 tblInfo.Columns = cols 69 70 return tblInfo 71 } 72 73 func testCreateTable(c *C, ctx context.Context, d *ddl, dbInfo *model.DBInfo, tblInfo *model.TableInfo) *model.Job { 74 job := &model.Job{ 75 SchemaID: dbInfo.ID, 76 TableID: tblInfo.ID, 77 Type: model.ActionCreateTable, 78 Args: []interface{}{tblInfo}, 79 } 80 81 err := d.doDDLJob(ctx, job) 82 c.Assert(err, IsNil) 83 return job 84 } 85 86 func testDropTable(c *C, ctx context.Context, d *ddl, dbInfo *model.DBInfo, tblInfo *model.TableInfo) *model.Job { 87 job := &model.Job{ 88 SchemaID: dbInfo.ID, 89 TableID: tblInfo.ID, 90 Type: model.ActionDropTable, 91 } 92 93 err := d.doDDLJob(ctx, job) 94 c.Assert(err, IsNil) 95 return job 96 } 97 98 func testCheckTableState(c *C, d *ddl, dbInfo *model.DBInfo, tblInfo *model.TableInfo, state model.SchemaState) { 99 kv.RunInNewTxn(d.store, false, func(txn kv.Transaction) error { 100 t := meta.NewMeta(txn) 101 info, err := t.GetTable(dbInfo.ID, tblInfo.ID) 102 c.Assert(err, IsNil) 103 104 if state == model.StateNone { 105 c.Assert(info, IsNil) 106 return nil 107 } 108 109 c.Assert(info.Name, DeepEquals, tblInfo.Name) 110 c.Assert(info.State, Equals, state) 111 return nil 112 }) 113 } 114 115 func testGetTable(c *C, d *ddl, schemaID int64, tableID int64) table.Table { 116 var tblInfo *model.TableInfo 117 kv.RunInNewTxn(d.store, false, func(txn kv.Transaction) error { 118 t := meta.NewMeta(txn) 119 var err error 120 tblInfo, err = t.GetTable(schemaID, tableID) 121 c.Assert(err, IsNil) 122 c.Assert(tblInfo, NotNil) 123 return nil 124 }) 125 alloc := autoid.NewAllocator(d.store, schemaID) 126 tbl, err := table.TableFromMeta(alloc, tblInfo) 127 c.Assert(err, IsNil) 128 return tbl 129 } 130 131 func (s *testTableSuite) SetUpSuite(c *C) { 132 s.store = testCreateStore(c, "test_table") 133 lease := 50 * time.Millisecond 134 s.d = newDDL(s.store, nil, nil, lease) 135 136 s.dbInfo = testSchemaInfo(c, s.d, "test") 137 testCreateSchema(c, mock.NewContext(), s.d, s.dbInfo) 138 } 139 140 func (s *testTableSuite) TearDownSuite(c *C) { 141 testDropSchema(c, mock.NewContext(), s.d, s.dbInfo) 142 s.d.close() 143 s.store.Close() 144 } 145 146 func testNewContext(c *C, d *ddl) context.Context { 147 ctx := d.newReorgContext() 148 variable.BindSessionVars(ctx) 149 return ctx 150 } 151 152 func (s *testTableSuite) TestTable(c *C) { 153 defer testleak.AfterTest(c)() 154 d := s.d 155 156 ctx := testNewContext(c, d) 157 defer ctx.FinishTxn(true) 158 159 tblInfo := testTableInfo(c, d, "t", 3) 160 161 job := testCreateTable(c, ctx, d, s.dbInfo, tblInfo) 162 testCheckTableState(c, d, s.dbInfo, tblInfo, model.StatePublic) 163 testCheckJobDone(c, d, job, true) 164 165 newTblInfo := testTableInfo(c, d, "t", 3) 166 job = &model.Job{ 167 SchemaID: s.dbInfo.ID, 168 TableID: newTblInfo.ID, 169 Type: model.ActionCreateTable, 170 Args: []interface{}{newTblInfo}, 171 } 172 173 err := d.doDDLJob(ctx, job) 174 c.Assert(err, NotNil) 175 testCheckJobCancelled(c, d, job) 176 177 tbl := testGetTable(c, d, s.dbInfo.ID, tblInfo.ID) 178 179 _, err = tbl.AddRecord(ctx, types.MakeDatums(1, 1, 1)) 180 c.Assert(err, IsNil) 181 182 _, err = tbl.AddRecord(ctx, types.MakeDatums(2, 2, 2)) 183 c.Assert(err, IsNil) 184 185 job = testDropTable(c, ctx, d, s.dbInfo, tblInfo) 186 testCheckJobDone(c, d, job, false) 187 } 188 189 func (s *testTableSuite) TestTableResume(c *C) { 190 defer testleak.AfterTest(c)() 191 d := s.d 192 193 testCheckOwner(c, d, true, ddlJobFlag) 194 195 tblInfo := testTableInfo(c, d, "t1", 3) 196 197 job := &model.Job{ 198 SchemaID: s.dbInfo.ID, 199 TableID: tblInfo.ID, 200 Type: model.ActionCreateTable, 201 Args: []interface{}{tblInfo}, 202 } 203 204 testRunInterruptedJob(c, d, job) 205 testCheckTableState(c, d, s.dbInfo, tblInfo, model.StatePublic) 206 207 job = &model.Job{ 208 SchemaID: s.dbInfo.ID, 209 TableID: tblInfo.ID, 210 Type: model.ActionDropTable, 211 } 212 213 testRunInterruptedJob(c, d, job) 214 testCheckTableState(c, d, s.dbInfo, tblInfo, model.StateNone) 215 }