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  }