github.com/matrixorigin/matrixone@v0.7.0/pkg/vm/engine/tae/catalog/catalog_test.go (about) 1 // Copyright 2021 Matrix Origin 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 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package catalog 16 17 import ( 18 "fmt" 19 "sync" 20 "testing" 21 "time" 22 23 "github.com/matrixorigin/matrixone/pkg/common/moerr" 24 "github.com/matrixorigin/matrixone/pkg/container/types" 25 "github.com/matrixorigin/matrixone/pkg/vm/engine/tae/common" 26 "github.com/matrixorigin/matrixone/pkg/vm/engine/tae/iface/txnif" 27 "github.com/matrixorigin/matrixone/pkg/vm/engine/tae/testutils" 28 "github.com/matrixorigin/matrixone/pkg/vm/engine/tae/txn/txnbase" 29 "github.com/stretchr/testify/assert" 30 ) 31 32 const ( 33 ModuleName = "TAECATALOG" 34 ) 35 36 func TestCreateDB1(t *testing.T) { 37 defer testutils.AfterTest(t)() 38 catalog := MockCatalog(nil) 39 defer catalog.Close() 40 41 txnMgr := txnbase.NewTxnManager(MockTxnStoreFactory(catalog), MockTxnFactory(catalog), types.NewMockHLCClock(1)) 42 txnMgr.Start() 43 defer txnMgr.Stop() 44 45 txn1, _ := txnMgr.StartTxn(nil) 46 47 name := fmt.Sprintf("%s-%d", t.Name(), 1) 48 db1, err := txn1.CreateDatabase(name, "") 49 assert.Nil(t, err) 50 t.Log(db1.String()) 51 52 assert.Equal(t, 2, len(catalog.entries)) 53 cnt := 0 54 catalog.link.Loop(func(n *common.GenericDLNode[*DBEntry]) bool { 55 t.Log(n.GetPayload().GetID()) 56 cnt++ 57 return true 58 }, true) 59 assert.Equal(t, 2, cnt) 60 61 _, err = txn1.CreateDatabase(name, "") 62 assert.True(t, moerr.IsMoErrCode(err, moerr.OkExpectedDup)) 63 64 txn2, _ := txnMgr.StartTxn(nil) 65 66 _, err = txn2.CreateDatabase(name, "") 67 assert.True(t, moerr.IsMoErrCode(err, moerr.ErrTxnWWConflict)) 68 69 _, err = txn1.GetDatabase(name) 70 assert.Nil(t, err) 71 72 err = txn1.Commit() 73 assert.Nil(t, err) 74 75 assert.Nil(t, err) 76 // assert.False(t, db1.(*mcokDBHandle).entry.IsCommitting()) 77 78 _, err = txn2.CreateDatabase(name, "") 79 assert.NotNil(t, err) 80 81 _, err = txn2.DropDatabase(name) 82 assert.True(t, moerr.IsMoErrCode(err, moerr.OkExpectedEOB)) 83 84 txn3, _ := txnMgr.StartTxn(nil) 85 _, err = txn3.DropDatabase(name) 86 assert.Nil(t, err) 87 // assert.True(t, db1.(*mcokDBHandle).entry.IsDroppedUncommitted()) 88 89 _, err = txn3.CreateDatabase(name, "") 90 assert.Nil(t, err) 91 92 cnt = 0 93 catalog.link.Loop(func(n *common.GenericDLNode[*DBEntry]) bool { 94 // t.Log(n.payload.(*DBEntry).String()) 95 cnt++ 96 return true 97 }, true) 98 assert.Equal(t, 3, cnt) 99 100 txn4, _ := txnMgr.StartTxn(nil) 101 102 h, err := txn4.GetDatabase(name) 103 assert.Nil(t, err) 104 assert.NotNil(t, h) 105 // assert.Equal(t, db1.(*mcokDBHandle).entry, h.(*mcokDBHandle).entry) 106 } 107 108 // TXN1-S TXN2-S TXN1-C TXN3-S TXN4-S TXN3-C TXN5-S 109 // 110 // | | | | | | | Time 111 // 112 // -+-+---+---+--+--+----+---+--+---+-+----+-+-----+------+-+------------------------------------> 113 // 114 // | | | | | | | | | 115 // | | | | | | | | [TXN5]: GET TBL [NOTFOUND] 116 // | | | | | | | [TXN4]: GET TBL [OK] | DROP DB1-TB1 [W-W] 117 // | | | | | | [TXN3]: GET TBL [OK] | DROP DB1-TB1 [OK] | GET TBL [NOT FOUND] 118 // | | | | | [TXN2]: DROP DB [NOTFOUND] 119 // | | | | [TXN2]: DROP DB [NOTFOUND] 120 // | | | [TXN2]: GET DB [NOTFOUND] | CREATE DB [W-W] 121 // | | [TXN1]: CREATE DB1-TB1 [DUP] 122 // | [TXN1]: CREATE DB1-TB1 [OK] | GET TBL [OK] 123 // [TXN1]: CREATE DB1 [OK] | GET DB [OK] 124 func TestTableEntry1(t *testing.T) { 125 defer testutils.AfterTest(t)() 126 catalog := MockCatalog(nil) 127 defer catalog.Close() 128 129 txnMgr := txnbase.NewTxnManager(MockTxnStoreFactory(catalog), MockTxnFactory(catalog), types.NewMockHLCClock(1)) 130 txnMgr.Start() 131 defer txnMgr.Stop() 132 133 txn1, _ := txnMgr.StartTxn(nil) 134 name := "db1" 135 db1, err := txn1.CreateDatabase(name, "") 136 assert.Nil(t, err) 137 t.Log(db1.String()) 138 139 schema := MockSchema(2, 0) 140 schema.Name = "tb1" 141 tb1, err := db1.CreateRelation(schema) 142 assert.Nil(t, err) 143 t.Log(tb1.String()) 144 145 _, err = db1.GetRelationByName(schema.Name) 146 assert.Nil(t, err) 147 148 _, err = db1.CreateRelation(schema) 149 assert.True(t, moerr.IsMoErrCode(err, moerr.OkExpectedDup)) 150 151 txn2, _ := txnMgr.StartTxn(nil) 152 _, err = txn2.GetDatabase(schema.Name) 153 assert.True(t, moerr.IsMoErrCode(err, moerr.ErrBadDB)) 154 155 _, err = txn2.CreateDatabase(name, "") 156 assert.True(t, moerr.IsMoErrCode(err, moerr.ErrTxnWWConflict)) 157 158 _, err = txn2.DropDatabase(name) 159 assert.True(t, moerr.IsMoErrCode(err, moerr.OkExpectedEOB)) 160 161 err = txn1.Commit() 162 assert.Nil(t, err) 163 164 _, err = txn2.DropDatabase(name) 165 assert.True(t, moerr.IsMoErrCode(err, moerr.OkExpectedEOB)) 166 167 txn3, _ := txnMgr.StartTxn(nil) 168 db, err := txn3.GetDatabase(name) 169 assert.Nil(t, err) 170 171 _, err = db.DropRelationByName(schema.Name) 172 assert.Nil(t, err) 173 t.Log(tb1.String()) 174 175 _, err = db.GetRelationByName(schema.Name) 176 assert.True(t, moerr.IsMoErrCode(err, moerr.OkExpectedEOB)) 177 178 txn4, _ := txnMgr.StartTxn(nil) 179 db, err = txn4.GetDatabase(name) 180 assert.Nil(t, err) 181 _, err = db.GetRelationByName(schema.Name) 182 assert.Nil(t, err) 183 184 _, err = db.DropRelationByName(schema.Name) 185 assert.True(t, moerr.IsMoErrCode(err, moerr.ErrTxnWWConflict)) 186 187 err = txn3.Commit() 188 assert.Nil(t, err) 189 190 t.Log(tb1.String()) 191 192 txn5, _ := txnMgr.StartTxn(nil) 193 db, err = txn5.GetDatabase(name) 194 assert.Nil(t, err) 195 _, err = db.GetRelationByName(schema.Name) 196 assert.True(t, moerr.IsMoErrCode(err, moerr.OkExpectedEOB)) 197 } 198 199 func TestTableEntry2(t *testing.T) { 200 defer testutils.AfterTest(t)() 201 catalog := MockCatalog(nil) 202 defer catalog.Close() 203 204 txnMgr := txnbase.NewTxnManager(MockTxnStoreFactory(catalog), MockTxnFactory(catalog), types.NewMockHLCClock(1)) 205 txnMgr.Start() 206 defer txnMgr.Stop() 207 208 txn1, _ := txnMgr.StartTxn(nil) 209 name := "db1" 210 db, err := txn1.CreateDatabase(name, "") 211 assert.Nil(t, err) 212 schema := MockSchema(2, 0) 213 schema.Name = "tb1" 214 _, err = db.CreateRelation(schema) 215 assert.Nil(t, err) 216 217 for i := 0; i < 1000; i++ { 218 s := MockSchema(1, 0) 219 s.Name = fmt.Sprintf("xx%d", i) 220 _, err = db.CreateRelation(s) 221 assert.Nil(t, err) 222 } 223 err = txn1.Commit() 224 assert.Nil(t, err) 225 226 txn2, _ := txnMgr.StartTxn(nil) 227 db, err = txn2.GetDatabase(name) 228 assert.Nil(t, err) 229 rel, err := db.DropRelationByName(schema.Name) 230 assert.Nil(t, err) 231 t.Log(rel.String()) 232 db, err = txn2.DropDatabase(name) 233 assert.Nil(t, err) 234 t.Log(db.String()) 235 236 var wg sync.WaitGroup 237 txns := []txnif.AsyncTxn{txn2} 238 for i := 0; i < 10; i++ { 239 txn, _ := txnMgr.StartTxn(nil) 240 txns = append(txns, txn) 241 } 242 now := time.Now() 243 for _, txn := range txns { 244 wg.Add(1) 245 go func(ttxn txnif.AsyncTxn) { 246 defer wg.Done() 247 for i := 0; i < 1000; i++ { 248 database, err := ttxn.GetDatabase(name) 249 if err != nil { 250 // t.Logf("db-ttxn=%d, %s", ttxn.GetID(), err) 251 } else { 252 // t.Logf("db-ttxn=%d, %v", ttxn.GetID(), err) 253 _, err := database.GetRelationByName(schema.Name) 254 assert.NoError(t, err) 255 } 256 } 257 }(txn) 258 } 259 wg.Wait() 260 t.Log(time.Since(now)) 261 } 262 263 func TestDB1(t *testing.T) { 264 defer testutils.AfterTest(t)() 265 catalog := MockCatalog(nil) 266 defer catalog.Close() 267 268 txnMgr := txnbase.NewTxnManager(MockTxnStoreFactory(catalog), MockTxnFactory(catalog), types.NewMockHLCClock(1)) 269 txnMgr.Start() 270 defer txnMgr.Stop() 271 name := "db1" 272 var wg sync.WaitGroup 273 flow := func() { 274 defer wg.Done() 275 txn, _ := txnMgr.StartTxn(nil) 276 _, err := txn.GetDatabase(name) 277 if moerr.IsMoErrCode(err, moerr.OkExpectedEOB) { 278 _, err = txn.CreateDatabase(name, "") 279 if err != nil { 280 return 281 } 282 } else { 283 _, err = txn.DropDatabase(name) 284 if err != nil { 285 return 286 } 287 } 288 err = txn.Commit() 289 assert.Nil(t, err) 290 } 291 292 for i := 0; i < 1000; i++ { 293 wg.Add(1) 294 go flow() 295 } 296 wg.Wait() 297 } 298 299 func TestTable1(t *testing.T) { 300 defer testutils.AfterTest(t)() 301 catalog := MockCatalog(nil) 302 defer catalog.Close() 303 304 txnMgr := txnbase.NewTxnManager(MockTxnStoreFactory(catalog), MockTxnFactory(catalog), types.NewMockHLCClock(1)) 305 txnMgr.Start() 306 defer txnMgr.Stop() 307 name := "db1" 308 tbName := "tb1" 309 var wg sync.WaitGroup 310 flow := func() { 311 defer wg.Done() 312 txn, _ := txnMgr.StartTxn(nil) 313 db, err := txn.GetDatabase(name) 314 assert.Nil(t, err) 315 _, err = db.GetRelationByName(tbName) 316 if moerr.IsMoErrCode(err, moerr.OkExpectedEOB) { 317 schema := MockSchema(1, 0) 318 schema.Name = tbName 319 if _, err = db.CreateRelation(schema); err != nil { 320 return 321 } 322 } else { 323 if _, err = db.DropRelationByName(tbName); err != nil { 324 return 325 } 326 } 327 err = txn.Commit() 328 assert.Nil(t, err) 329 // t.Log(rel.String()) 330 } 331 { 332 txn, _ := txnMgr.StartTxn(nil) 333 _, err := txn.CreateDatabase(name, "") 334 assert.Nil(t, err) 335 err = txn.Commit() 336 assert.Nil(t, err) 337 } 338 for i := 0; i < 1000; i++ { 339 wg.Add(1) 340 go flow() 341 } 342 wg.Wait() 343 } 344 345 // UT Steps 346 // 1. Start Txn1, create a database "db", table "tb" and segment "seg1", then commit Txn1 347 // 1. Start Txn2, create a segment "seg2". Txn2 scan "tb" and "seg1, seg2" found 348 // 2. Start Txn3, scan "tb" and only "seg1" found 349 // 3. Commit Txn2 350 // 4. Txn3 scan "tb" and also only "seg1" found 351 // 5. Start Txn4, scan "tb" and both "seg1" and "seg2" found 352 func TestSegment1(t *testing.T) { 353 defer testutils.AfterTest(t)() 354 catalog := MockCatalog(nil) 355 defer catalog.Close() 356 txnMgr := txnbase.NewTxnManager(MockTxnStoreFactory(catalog), MockTxnFactory(catalog), types.NewMockHLCClock(1)) 357 txnMgr.Start() 358 defer txnMgr.Stop() 359 name := "db" 360 tbName := "tb" 361 txn1, _ := txnMgr.StartTxn(nil) 362 db, err := catalog.CreateDBEntry(name, "", txn1) 363 assert.Nil(t, err) 364 schema := MockSchema(1, 0) 365 schema.Name = tbName 366 tb, err := db.CreateTableEntry(schema, txn1, nil) 367 assert.Nil(t, err) 368 seg1, err := tb.CreateSegment(txn1, ES_Appendable, nil) 369 assert.Nil(t, err) 370 err = txn1.Commit() 371 assert.Nil(t, err) 372 t.Log(seg1.String()) 373 t.Log(tb.String()) 374 }