github.com/XiaoMi/Gaea@v1.2.5/parser/model/model_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 model 15 16 import ( 17 "encoding/json" 18 "fmt" 19 "testing" 20 "time" 21 22 . "github.com/pingcap/check" 23 24 "github.com/XiaoMi/Gaea/mysql" 25 "github.com/XiaoMi/Gaea/parser/types" 26 ) 27 28 func TestT(t *testing.T) { 29 CustomVerboseFlag = true 30 TestingT(t) 31 } 32 33 var _ = Suite(&testModelSuite{}) 34 35 type testModelSuite struct { 36 } 37 38 func (*testModelSuite) TestT(c *C) { 39 abc := NewCIStr("aBC") 40 c.Assert(abc.O, Equals, "aBC") 41 c.Assert(abc.L, Equals, "abc") 42 c.Assert(abc.String(), Equals, "aBC") 43 } 44 45 func (*testModelSuite) TestModelBasic(c *C) { 46 column := &ColumnInfo{ 47 ID: 1, 48 Name: NewCIStr("c"), 49 Offset: 0, 50 DefaultValue: 0, 51 FieldType: *types.NewFieldType(0), 52 } 53 column.Flag |= mysql.PriKeyFlag 54 55 index := &IndexInfo{ 56 Name: NewCIStr("key"), 57 Table: NewCIStr("t"), 58 Columns: []*IndexColumn{ 59 { 60 Name: NewCIStr("c"), 61 Offset: 0, 62 Length: 10, 63 }}, 64 Unique: true, 65 Primary: true, 66 } 67 68 fk := &FKInfo{ 69 RefCols: []CIStr{NewCIStr("a")}, 70 Cols: []CIStr{NewCIStr("a")}, 71 } 72 73 table := &TableInfo{ 74 ID: 1, 75 Name: NewCIStr("t"), 76 Charset: "utf8", 77 Collate: "utf8_bin", 78 Columns: []*ColumnInfo{column}, 79 Indices: []*IndexInfo{index}, 80 ForeignKeys: []*FKInfo{fk}, 81 PKIsHandle: true, 82 } 83 84 dbInfo := &DBInfo{ 85 ID: 1, 86 Name: NewCIStr("test"), 87 Charset: "utf8", 88 Collate: "utf8_bin", 89 Tables: []*TableInfo{table}, 90 } 91 92 n := dbInfo.Clone() 93 c.Assert(n, DeepEquals, dbInfo) 94 95 pkName := table.GetPkName() 96 c.Assert(pkName, Equals, NewCIStr("c")) 97 newColumn := table.GetPkColInfo() 98 c.Assert(newColumn, DeepEquals, column) 99 inIdx := table.ColumnIsInIndex(column) 100 c.Assert(inIdx, Equals, true) 101 tp := IndexTypeBtree 102 c.Assert(tp.String(), Equals, "BTREE") 103 tp = IndexTypeHash 104 c.Assert(tp.String(), Equals, "HASH") 105 tp = 1E5 106 c.Assert(tp.String(), Equals, "") 107 has := index.HasPrefixIndex() 108 c.Assert(has, Equals, true) 109 t := table.GetUpdateTime() 110 c.Assert(t, Equals, TSConvert2Time(table.UpdateTS)) 111 112 // Corner cases 113 column.Flag ^= mysql.PriKeyFlag 114 pkName = table.GetPkName() 115 c.Assert(pkName, Equals, NewCIStr("")) 116 newColumn = table.GetPkColInfo() 117 c.Assert(newColumn, IsNil) 118 anCol := &ColumnInfo{ 119 Name: NewCIStr("d"), 120 } 121 exIdx := table.ColumnIsInIndex(anCol) 122 c.Assert(exIdx, Equals, false) 123 anIndex := &IndexInfo{ 124 Columns: []*IndexColumn{}, 125 } 126 no := anIndex.HasPrefixIndex() 127 c.Assert(no, Equals, false) 128 } 129 130 func (*testModelSuite) TestJobStartTime(c *C) { 131 job := &Job{ 132 ID: 123, 133 BinlogInfo: &HistoryInfo{}, 134 } 135 t := time.Unix(0, 0) 136 c.Assert(t, Equals, TSConvert2Time(job.StartTS)) 137 ret := fmt.Sprintf("%s", job) 138 c.Assert(job.String(), Equals, ret) 139 } 140 141 func (*testModelSuite) TestJobCodec(c *C) { 142 type A struct { 143 Name string 144 } 145 job := &Job{ 146 ID: 1, 147 TableID: 2, 148 SchemaID: 1, 149 BinlogInfo: &HistoryInfo{}, 150 Args: []interface{}{NewCIStr("a"), A{Name: "abc"}}, 151 } 152 job.BinlogInfo.AddDBInfo(123, &DBInfo{ID: 1, Name: NewCIStr("test_history_db")}) 153 job.BinlogInfo.AddTableInfo(123, &TableInfo{ID: 1, Name: NewCIStr("test_history_tbl")}) 154 155 // Test IsDependentOn. 156 // job: table ID is 2 157 // job1: table ID is 2 158 var err error 159 job1 := &Job{ 160 ID: 2, 161 TableID: 2, 162 SchemaID: 1, 163 Type: ActionRenameTable, 164 BinlogInfo: &HistoryInfo{}, 165 Args: []interface{}{int64(3), NewCIStr("new_table_name")}, 166 } 167 job1.RawArgs, err = json.Marshal(job1.Args) 168 c.Assert(err, IsNil) 169 isDependent, err := job.IsDependentOn(job1) 170 c.Assert(err, IsNil) 171 c.Assert(isDependent, IsTrue) 172 // job1: rename table, old schema ID is 3 173 // job2: create schema, schema ID is 3 174 job2 := &Job{ 175 ID: 3, 176 TableID: 3, 177 SchemaID: 3, 178 Type: ActionCreateSchema, 179 BinlogInfo: &HistoryInfo{}, 180 } 181 isDependent, err = job2.IsDependentOn(job1) 182 c.Assert(err, IsNil) 183 c.Assert(isDependent, IsTrue) 184 185 c.Assert(job.IsCancelled(), Equals, false) 186 b, err := job.Encode(false) 187 c.Assert(err, IsNil) 188 newJob := &Job{} 189 err = newJob.Decode(b) 190 c.Assert(err, IsNil) 191 c.Assert(newJob.BinlogInfo, DeepEquals, job.BinlogInfo) 192 name := CIStr{} 193 a := A{} 194 err = newJob.DecodeArgs(&name, &a) 195 c.Assert(err, IsNil) 196 c.Assert(name, DeepEquals, NewCIStr("")) 197 c.Assert(a, DeepEquals, A{Name: ""}) 198 c.Assert(len(newJob.String()), Greater, 0) 199 200 job.BinlogInfo.Clean() 201 b1, err := job.Encode(true) 202 c.Assert(err, IsNil) 203 newJob = &Job{} 204 err = newJob.Decode(b1) 205 c.Assert(err, IsNil) 206 c.Assert(newJob.BinlogInfo, DeepEquals, &HistoryInfo{}) 207 name = CIStr{} 208 a = A{} 209 err = newJob.DecodeArgs(&name, &a) 210 c.Assert(err, IsNil) 211 c.Assert(name, DeepEquals, NewCIStr("a")) 212 c.Assert(a, DeepEquals, A{Name: "abc"}) 213 c.Assert(len(newJob.String()), Greater, 0) 214 215 b2, err := job.Encode(true) 216 c.Assert(err, IsNil) 217 newJob = &Job{} 218 err = newJob.Decode(b2) 219 c.Assert(err, IsNil) 220 name = CIStr{} 221 // Don't decode to a here. 222 err = newJob.DecodeArgs(&name) 223 c.Assert(err, IsNil) 224 c.Assert(name, DeepEquals, NewCIStr("a")) 225 c.Assert(len(newJob.String()), Greater, 0) 226 227 job.State = JobStateDone 228 c.Assert(job.IsDone(), IsTrue) 229 c.Assert(job.IsFinished(), IsTrue) 230 c.Assert(job.IsRunning(), IsFalse) 231 c.Assert(job.IsSynced(), IsFalse) 232 c.Assert(job.IsRollbackDone(), IsFalse) 233 job.SetRowCount(3) 234 c.Assert(job.GetRowCount(), Equals, int64(3)) 235 } 236 237 func (testModelSuite) TestState(c *C) { 238 schemaTbl := []SchemaState{ 239 StateDeleteOnly, 240 StateWriteOnly, 241 StateWriteReorganization, 242 StateDeleteReorganization, 243 StatePublic, 244 } 245 246 for _, state := range schemaTbl { 247 c.Assert(len(state.String()), Greater, 0) 248 } 249 250 jobTbl := []JobState{ 251 JobStateRunning, 252 JobStateDone, 253 JobStateCancelled, 254 JobStateRollingback, 255 JobStateRollbackDone, 256 JobStateSynced, 257 } 258 259 for _, state := range jobTbl { 260 c.Assert(len(state.String()), Greater, 0) 261 } 262 } 263 264 func (testModelSuite) TestString(c *C) { 265 acts := []struct { 266 act ActionType 267 result string 268 }{ 269 {ActionNone, "none"}, 270 {ActionAddForeignKey, "add foreign key"}, 271 {ActionDropForeignKey, "drop foreign key"}, 272 {ActionTruncateTable, "truncate table"}, 273 {ActionModifyColumn, "modify column"}, 274 {ActionRenameTable, "rename table"}, 275 {ActionSetDefaultValue, "set default value"}, 276 {ActionCreateSchema, "create schema"}, 277 {ActionDropSchema, "drop schema"}, 278 {ActionCreateTable, "create table"}, 279 {ActionDropTable, "drop table"}, 280 {ActionAddIndex, "add index"}, 281 {ActionDropIndex, "drop index"}, 282 {ActionAddColumn, "add column"}, 283 {ActionDropColumn, "drop column"}, 284 } 285 286 for _, v := range acts { 287 str := v.act.String() 288 c.Assert(str, Equals, v.result) 289 } 290 } 291 292 func (testModelSuite) TestUnmarshalCIStr(c *C) { 293 var ci CIStr 294 295 // Test unmarshal CIStr from a single string. 296 str := "aaBB" 297 buf, err := json.Marshal(str) 298 c.Assert(err, IsNil) 299 ci.UnmarshalJSON(buf) 300 c.Assert(ci.O, Equals, str) 301 c.Assert(ci.L, Equals, "aabb") 302 303 buf, err = json.Marshal(ci) 304 c.Assert(string(buf), Equals, `{"O":"aaBB","L":"aabb"}`) 305 ci.UnmarshalJSON(buf) 306 c.Assert(ci.O, Equals, str) 307 c.Assert(ci.L, Equals, "aabb") 308 }