github.com/matrixorigin/matrixone@v1.2.0/pkg/vm/engine/entire_engine_test.go (about) 1 // Copyright 2022 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 engine 16 17 import ( 18 "context" 19 "testing" 20 "time" 21 22 "github.com/matrixorigin/matrixone/pkg/defines" 23 "github.com/matrixorigin/matrixone/pkg/pb/lock" 24 "github.com/matrixorigin/matrixone/pkg/pb/plan" 25 pb "github.com/matrixorigin/matrixone/pkg/pb/statsinfo" 26 "github.com/matrixorigin/matrixone/pkg/pb/timestamp" 27 "github.com/matrixorigin/matrixone/pkg/pb/txn" 28 "github.com/matrixorigin/matrixone/pkg/txn/client" 29 "github.com/matrixorigin/matrixone/pkg/txn/rpc" 30 31 "github.com/stretchr/testify/assert" 32 ) 33 34 const ( 35 origin = "origin" 36 temporary = "temporary" 37 ) 38 39 // There is no way to know the control flow of EntireEngine directly through the Engine method 40 // BUT this is exactly what we want to test. 41 // So we need sth to mark the transition of states 42 // The following enumeration shows all the possible states of the EntireEngine 43 const ( 44 first_engine_then_tempengine = -2 45 only_tempengine = 0 46 only_engine = 2 47 ) 48 49 type testEntireEngine struct { 50 EntireEngine 51 step int 52 state int 53 } 54 55 type testEngine struct { 56 name string // origin or temporary 57 parent *testEntireEngine 58 } 59 60 var _ Engine = new(testEngine) 61 62 type testOperator struct { 63 } 64 65 func TestEntireEngineNew(t *testing.T) { 66 ctx := context.TODO() 67 op := newtestOperator() 68 ee := buildEntireEngineWithoutTempEngine() 69 ee.New(ctx, op) 70 assert.Equal(t, only_engine, ee.state) 71 ee = buildEntireEngineWithTempEngine() 72 ee.New(ctx, op) 73 assert.Equal(t, first_engine_then_tempengine, ee.state) 74 } 75 76 func TestEntireEngineDelete(t *testing.T) { 77 ctx := context.TODO() 78 op := newtestOperator() 79 ee := buildEntireEngineWithoutTempEngine() 80 ee.Delete(ctx, "bar", op) 81 assert.Equal(t, only_engine, ee.state) 82 ee = buildEntireEngineWithTempEngine() 83 ee.Delete(ctx, "foo", op) 84 assert.Equal(t, only_engine, ee.state) 85 } 86 87 func TestEntireEngineCreate(t *testing.T) { 88 ctx := context.TODO() 89 op := newtestOperator() 90 ee := buildEntireEngineWithoutTempEngine() 91 ee.Create(ctx, "bar", op) 92 assert.Equal(t, only_engine, ee.state) 93 ee = buildEntireEngineWithTempEngine() 94 ee.Create(ctx, "foo", op) 95 assert.Equal(t, only_engine, ee.state) 96 } 97 98 func TestEntireEngineDatabases(t *testing.T) { 99 ctx := context.TODO() 100 op := newtestOperator() 101 ee := buildEntireEngineWithoutTempEngine() 102 ee.Databases(ctx, op) 103 assert.Equal(t, only_engine, ee.state) 104 ee = buildEntireEngineWithTempEngine() 105 ee.Databases(ctx, op) 106 assert.Equal(t, only_engine, ee.state) 107 } 108 109 func TestEntireEngineDatabase(t *testing.T) { 110 ctx := context.TODO() 111 op := newtestOperator() 112 ee := buildEntireEngineWithoutTempEngine() 113 ee.Database(ctx, "foo", op) 114 assert.Equal(t, only_engine, ee.state) 115 ee = buildEntireEngineWithTempEngine() 116 ee.Database(ctx, defines.TEMPORARY_DBNAME, op) 117 assert.Equal(t, only_tempengine, ee.state) 118 119 } 120 121 func TestEntireEngineNodes(t *testing.T) { 122 ee := buildEntireEngineWithoutTempEngine() 123 ee.Nodes(false, "", "", nil) 124 assert.Equal(t, only_engine, ee.state) 125 ee = buildEntireEngineWithTempEngine() 126 ee.Nodes(false, "", "", nil) 127 assert.Equal(t, only_engine, ee.state) 128 } 129 130 func TestEntireEngineHints(t *testing.T) { 131 ee := buildEntireEngineWithoutTempEngine() 132 ee.Hints() 133 assert.Equal(t, only_engine, ee.state) 134 ee = buildEntireEngineWithTempEngine() 135 ee.Hints() 136 assert.Equal(t, only_engine, ee.state) 137 138 } 139 140 func TestEntireEngineNewBlockReader(t *testing.T) { 141 ctx := context.TODO() 142 ee := buildEntireEngineWithoutTempEngine() 143 ee.NewBlockReader(ctx, 1, timestamp.Timestamp{}, nil, nil, nil, nil) 144 assert.Equal(t, only_engine, ee.state) 145 ee = buildEntireEngineWithTempEngine() 146 ee.NewBlockReader(ctx, 1, timestamp.Timestamp{}, nil, nil, nil, nil) 147 assert.Equal(t, only_engine, ee.state) 148 } 149 150 func buildEntireEngineWithTempEngine() *testEntireEngine { 151 ee := new(testEntireEngine) 152 ee.state = 1 153 154 e := newtestEngine(origin, ee) 155 te := newtestEngine(temporary, ee) 156 157 ee.Engine = e 158 ee.TempEngine = te 159 return ee 160 } 161 162 func buildEntireEngineWithoutTempEngine() *testEntireEngine { 163 ee := new(testEntireEngine) 164 ee.state = 1 165 166 e := newtestEngine(origin, ee) 167 ee.Engine = e 168 return ee 169 } 170 171 func newtestEngine(name string, tee *testEntireEngine) *testEngine { 172 return &testEngine{name: name, parent: tee} 173 } 174 175 func (e *testEngine) New(_ context.Context, _ client.TxnOperator) error { 176 e.parent.step = e.parent.step + 1 177 if e.name == origin { 178 e.parent.state = e.parent.state + e.parent.step*e.parent.state 179 } else { 180 e.parent.state = e.parent.state - e.parent.step*e.parent.state 181 } 182 183 return nil 184 } 185 186 func (e *testEngine) Commit(_ context.Context, _ client.TxnOperator) error { 187 e.parent.step = e.parent.step + 1 188 if e.name == origin { 189 e.parent.state = e.parent.state + e.parent.step*e.parent.state 190 } else { 191 e.parent.state = e.parent.state - e.parent.step*e.parent.state 192 } 193 194 return nil 195 } 196 197 func (e *testEngine) Rollback(_ context.Context, _ client.TxnOperator) error { 198 e.parent.step = e.parent.step + 1 199 if e.name == origin { 200 e.parent.state = e.parent.state + e.parent.step*e.parent.state 201 } else { 202 e.parent.state = e.parent.state - e.parent.step*e.parent.state 203 } 204 205 return nil 206 } 207 208 func (e *testEngine) Delete(ctx context.Context, name string, _ client.TxnOperator) error { 209 e.parent.step = e.parent.step + 1 210 if e.name == origin { 211 e.parent.state = e.parent.state + e.parent.step*e.parent.state 212 } else { 213 e.parent.state = e.parent.state - e.parent.step*e.parent.state 214 } 215 216 return nil 217 } 218 219 func (e *testEngine) Create(ctx context.Context, name string, _ client.TxnOperator) error { 220 e.parent.step = e.parent.step + 1 221 if e.name == origin { 222 e.parent.state = e.parent.state + e.parent.step*e.parent.state 223 } else { 224 e.parent.state = e.parent.state - e.parent.step*e.parent.state 225 } 226 227 return nil 228 } 229 230 func (e *testEngine) Databases(ctx context.Context, txnOp client.TxnOperator) ([]string, error) { 231 e.parent.step = e.parent.step + 1 232 if e.name == origin { 233 e.parent.state = e.parent.state + e.parent.step*e.parent.state 234 } else { 235 e.parent.state = e.parent.state - e.parent.step*e.parent.state 236 } 237 238 var a []string 239 a = append(a, "foo") 240 a = append(a, "bar") 241 return a, nil 242 } 243 244 func (e *testEngine) Database(ctx context.Context, name string, txnOp client.TxnOperator) (Database, error) { 245 e.parent.step = e.parent.step + 1 246 if e.name == origin { 247 e.parent.state = e.parent.state + e.parent.step*e.parent.state 248 } else { 249 e.parent.state = e.parent.state - e.parent.step*e.parent.state 250 } 251 return nil, nil 252 } 253 254 func (e *testEngine) Nodes(_ bool, _ string, _ string, _ map[string]string) (Nodes, error) { 255 e.parent.step = e.parent.step + 1 256 if e.name == origin { 257 e.parent.state = e.parent.state + e.parent.step*e.parent.state 258 } else { 259 e.parent.state = e.parent.state - e.parent.step*e.parent.state 260 } 261 return nil, nil 262 } 263 264 func (e *testEngine) Hints() (h Hints) { 265 e.parent.step = e.parent.step + 1 266 if e.name == origin { 267 e.parent.state = e.parent.state + e.parent.step*e.parent.state 268 } else { 269 e.parent.state = e.parent.state - e.parent.step*e.parent.state 270 } 271 return 272 } 273 274 func (e *testEngine) NewBlockReader(_ context.Context, _ int, _ timestamp.Timestamp, 275 _ *plan.Expr, _ []byte, _ *plan.TableDef, proc any) ([]Reader, error) { 276 e.parent.step = e.parent.step + 1 277 if e.name == origin { 278 e.parent.state = e.parent.state + e.parent.step*e.parent.state 279 } else { 280 e.parent.state = e.parent.state - e.parent.step*e.parent.state 281 } 282 return nil, nil 283 } 284 285 func (e *testEngine) GetNameById(ctx context.Context, op client.TxnOperator, tableId uint64) (dbName string, tblName string, err error) { 286 return "", "", nil 287 } 288 289 func (e *testEngine) GetRelationById(ctx context.Context, op client.TxnOperator, tableId uint64) (dbName string, tblName string, rel Relation, err error) { 290 return "", "", nil, nil 291 } 292 293 func (e *testEngine) AllocateIDByKey(ctx context.Context, key string) (uint64, error) { 294 return 0, nil 295 } 296 297 func (e *testEngine) TryToSubscribeTable(ctx context.Context, dbID, tbID uint64) error { 298 return nil 299 } 300 301 func (e *testEngine) UnsubscribeTable(ctx context.Context, dbID, tbID uint64) error { 302 return nil 303 } 304 305 func (e *testEngine) Stats(ctx context.Context, key pb.StatsInfoKey, sync bool) *pb.StatsInfo { 306 return nil 307 } 308 309 func (e *testEngine) Rows(ctx context.Context, key pb.StatsInfoKey) uint64 { 310 return 0 311 } 312 313 func (e *testEngine) Size(ctx context.Context, key pb.StatsInfoKey, colName string) (uint64, error) { 314 return 0, nil 315 } 316 317 func newtestOperator() *testOperator { 318 return &testOperator{} 319 } 320 321 func (o *testOperator) AddWorkspace(_ client.Workspace) { 322 } 323 324 func (o *testOperator) GetWorkspace() client.Workspace { 325 return nil 326 } 327 328 func (o *testOperator) ApplySnapshot(data []byte) error { 329 return nil 330 } 331 332 func (o *testOperator) WriteAndCommit(ctx context.Context, ops []txn.TxnRequest) (*rpc.SendResult, error) { 333 return nil, nil 334 } 335 336 func (o *testOperator) Commit(ctx context.Context) error { 337 return nil 338 } 339 340 func (o *testOperator) Read(ctx context.Context, ops []txn.TxnRequest) (*rpc.SendResult, error) { 341 return nil, nil 342 } 343 344 func (o *testOperator) Rollback(ctx context.Context) error { 345 return nil 346 } 347 348 func (o *testOperator) Snapshot() ([]byte, error) { 349 return nil, nil 350 } 351 352 func (o *testOperator) Txn() txn.TxnMeta { 353 return txn.TxnMeta{} 354 } 355 356 func (o *testOperator) IsSnapOp() bool { 357 panic("should not call") 358 } 359 360 func (o *testOperator) CloneSnapshotOp(snapshot timestamp.Timestamp) client.TxnOperator { 361 panic("should not call") 362 } 363 364 func (o *testOperator) PKDedupCount() int { 365 panic("should not call") 366 } 367 368 func (o *testOperator) SnapshotTS() timestamp.Timestamp { 369 panic("should not call") 370 } 371 372 func (o *testOperator) CreateTS() timestamp.Timestamp { 373 panic("should not call") 374 } 375 376 func (o *testOperator) Status() txn.TxnStatus { 377 panic("should not call") 378 } 379 380 func (o *testOperator) TxnRef() *txn.TxnMeta { 381 return &txn.TxnMeta{} 382 } 383 384 func (o *testOperator) Write(ctx context.Context, ops []txn.TxnRequest) (*rpc.SendResult, error) { 385 return nil, nil 386 } 387 388 func (o *testOperator) AddLockTable(lock.LockTable) error { 389 return nil 390 } 391 392 func (o *testOperator) UpdateSnapshot(ctx context.Context, ts timestamp.Timestamp) error { 393 panic("should not call") 394 } 395 396 func (o *testOperator) ResetRetry(retry bool) { 397 panic("unimplemented") 398 } 399 400 func (o *testOperator) IsRetry() bool { 401 panic("unimplemented") 402 } 403 404 func (o *testOperator) SetOpenLog(retry bool) { 405 panic("unimplemented") 406 } 407 408 func (o *testOperator) IsOpenLog() bool { 409 panic("unimplemented") 410 } 411 412 func (o *testOperator) AppendEventCallback(event client.EventType, callbacks ...func(event client.TxnEvent)) { 413 panic("unimplemented") 414 } 415 416 func (o *testOperator) Debug(ctx context.Context, ops []txn.TxnRequest) (*rpc.SendResult, error) { 417 panic("unimplemented") 418 } 419 420 func (o *testOperator) AddWaitLock(tableID uint64, rows [][]byte, opt lock.LockOptions) uint64 { 421 panic("should not call") 422 } 423 424 func (o *testOperator) RemoveWaitLock(key uint64) { 425 panic("should not call") 426 } 427 428 func (o *testOperator) LockTableCount() int32 { 429 panic("should not call") 430 } 431 432 func (o *testOperator) GetOverview() client.TxnOverview { 433 panic("should not call") 434 } 435 436 func (o *testOperator) LockSkipped(tableID uint64, mode lock.LockMode) bool { 437 panic("should not call") 438 } 439 440 func (o *testOperator) TxnOptions() txn.TxnOptions { 441 panic("should not call") 442 } 443 444 func (o *testOperator) NextSequence() uint64 { 445 panic("should not call") 446 } 447 448 func (o *testOperator) EnterRunSql() {} 449 450 func (o *testOperator) ExitRunSql() {} 451 452 func (o *testOperator) GetWaitActiveCost() time.Duration { 453 return time.Duration(0) 454 }