github.com/matrixorigin/matrixone@v0.7.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  
    21  	"github.com/matrixorigin/matrixone/pkg/defines"
    22  	"github.com/matrixorigin/matrixone/pkg/pb/plan"
    23  	"github.com/matrixorigin/matrixone/pkg/pb/timestamp"
    24  	"github.com/matrixorigin/matrixone/pkg/pb/txn"
    25  	"github.com/matrixorigin/matrixone/pkg/txn/client"
    26  	"github.com/matrixorigin/matrixone/pkg/txn/rpc"
    27  	"github.com/stretchr/testify/assert"
    28  )
    29  
    30  const (
    31  	origin    = "origin"
    32  	temporary = "temporary"
    33  )
    34  
    35  // There is no way to know the control flow of EntireEngine directly through the Engine method
    36  // BUT this is exactly what we want to test.
    37  // So we need sth to mark the transition of states
    38  // The following enumeration shows all the possible states of the EntireEngine
    39  const (
    40  	first_engine_then_tempengine = -2
    41  	only_tempengine              = 0
    42  	only_engine                  = 2
    43  )
    44  
    45  type testEntireEngine struct {
    46  	EntireEngine
    47  	step  int
    48  	state int
    49  }
    50  
    51  type testEngine struct {
    52  	name   string // origin or temporary
    53  	parent *testEntireEngine
    54  }
    55  
    56  type testOperator struct {
    57  }
    58  
    59  func TestEntireEngineNew(t *testing.T) {
    60  	ctx := context.TODO()
    61  	op := newtestOperator()
    62  	ee := buildEntireEngineWithoutTempEngine()
    63  	ee.New(ctx, op)
    64  	assert.Equal(t, only_engine, ee.state)
    65  	ee = buildEntireEngineWithTempEngine()
    66  	ee.New(ctx, op)
    67  	assert.Equal(t, first_engine_then_tempengine, ee.state)
    68  }
    69  
    70  func TestEntireEngineCommit(t *testing.T) {
    71  	ctx := context.TODO()
    72  	op := newtestOperator()
    73  	ee := buildEntireEngineWithoutTempEngine()
    74  	ee.Commit(ctx, op)
    75  	assert.Equal(t, only_engine, ee.state)
    76  	ee = buildEntireEngineWithTempEngine()
    77  	ee.Commit(ctx, op)
    78  	assert.Equal(t, first_engine_then_tempengine, ee.state)
    79  }
    80  
    81  func TestEntireEngineRollback(t *testing.T) {
    82  	ctx := context.TODO()
    83  	op := newtestOperator()
    84  	ee := buildEntireEngineWithoutTempEngine()
    85  	ee.Rollback(ctx, op)
    86  	assert.Equal(t, only_engine, ee.state)
    87  	ee = buildEntireEngineWithTempEngine()
    88  	ee.Rollback(ctx, op)
    89  	assert.Equal(t, first_engine_then_tempengine, ee.state)
    90  }
    91  
    92  func TestEntireEngineDelete(t *testing.T) {
    93  	ctx := context.TODO()
    94  	op := newtestOperator()
    95  	ee := buildEntireEngineWithoutTempEngine()
    96  	ee.Delete(ctx, "bar", op)
    97  	assert.Equal(t, only_engine, ee.state)
    98  	ee = buildEntireEngineWithTempEngine()
    99  	ee.Delete(ctx, "foo", op)
   100  	assert.Equal(t, only_engine, ee.state)
   101  }
   102  
   103  func TestEntireEngineCreate(t *testing.T) {
   104  	ctx := context.TODO()
   105  	op := newtestOperator()
   106  	ee := buildEntireEngineWithoutTempEngine()
   107  	ee.Create(ctx, "bar", op)
   108  	assert.Equal(t, only_engine, ee.state)
   109  	ee = buildEntireEngineWithTempEngine()
   110  	ee.Create(ctx, "foo", op)
   111  	assert.Equal(t, only_engine, ee.state)
   112  }
   113  
   114  func TestEntireEngineDatabases(t *testing.T) {
   115  	ctx := context.TODO()
   116  	op := newtestOperator()
   117  	ee := buildEntireEngineWithoutTempEngine()
   118  	ee.Databases(ctx, op)
   119  	assert.Equal(t, only_engine, ee.state)
   120  	ee = buildEntireEngineWithTempEngine()
   121  	ee.Databases(ctx, op)
   122  	assert.Equal(t, only_engine, ee.state)
   123  }
   124  
   125  func TestEntireEngineDatabase(t *testing.T) {
   126  	ctx := context.TODO()
   127  	op := newtestOperator()
   128  	ee := buildEntireEngineWithoutTempEngine()
   129  	ee.Database(ctx, "foo", op)
   130  	assert.Equal(t, only_engine, ee.state)
   131  	ee = buildEntireEngineWithTempEngine()
   132  	ee.Database(ctx, defines.TEMPORARY_DBNAME, op)
   133  	assert.Equal(t, only_tempengine, ee.state)
   134  
   135  }
   136  
   137  func TestEntireEngineNodes(t *testing.T) {
   138  	ee := buildEntireEngineWithoutTempEngine()
   139  	ee.Nodes()
   140  	assert.Equal(t, only_engine, ee.state)
   141  	ee = buildEntireEngineWithTempEngine()
   142  	ee.Nodes()
   143  	assert.Equal(t, only_engine, ee.state)
   144  }
   145  
   146  func TestEntireEngineHints(t *testing.T) {
   147  	ee := buildEntireEngineWithoutTempEngine()
   148  	ee.Hints()
   149  	assert.Equal(t, only_engine, ee.state)
   150  	ee = buildEntireEngineWithTempEngine()
   151  	ee.Hints()
   152  	assert.Equal(t, only_engine, ee.state)
   153  
   154  }
   155  
   156  func TestEntireEngineNewBlockReader(t *testing.T) {
   157  	ctx := context.TODO()
   158  	ee := buildEntireEngineWithoutTempEngine()
   159  	ee.NewBlockReader(ctx, 1, timestamp.Timestamp{}, nil, nil, nil)
   160  	assert.Equal(t, only_engine, ee.state)
   161  	ee = buildEntireEngineWithTempEngine()
   162  	ee.NewBlockReader(ctx, 1, timestamp.Timestamp{}, nil, nil, nil)
   163  	assert.Equal(t, only_engine, ee.state)
   164  }
   165  
   166  func buildEntireEngineWithTempEngine() *testEntireEngine {
   167  	ee := new(testEntireEngine)
   168  	ee.state = 1
   169  
   170  	e := newtestEngine(origin, ee)
   171  	te := newtestEngine(temporary, ee)
   172  
   173  	ee.Engine = e
   174  	ee.TempEngine = te
   175  	return ee
   176  }
   177  
   178  func buildEntireEngineWithoutTempEngine() *testEntireEngine {
   179  	ee := new(testEntireEngine)
   180  	ee.state = 1
   181  
   182  	e := newtestEngine(origin, ee)
   183  	ee.Engine = e
   184  	return ee
   185  }
   186  
   187  func newtestEngine(name string, tee *testEntireEngine) *testEngine {
   188  	return &testEngine{name: name, parent: tee}
   189  }
   190  
   191  func (e *testEngine) New(_ context.Context, _ client.TxnOperator) error {
   192  	e.parent.step = e.parent.step + 1
   193  	if e.name == origin {
   194  		e.parent.state = e.parent.state + e.parent.step*e.parent.state
   195  	} else {
   196  		e.parent.state = e.parent.state - e.parent.step*e.parent.state
   197  	}
   198  
   199  	return nil
   200  }
   201  
   202  func (e *testEngine) Commit(_ context.Context, _ client.TxnOperator) error {
   203  	e.parent.step = e.parent.step + 1
   204  	if e.name == origin {
   205  		e.parent.state = e.parent.state + e.parent.step*e.parent.state
   206  	} else {
   207  		e.parent.state = e.parent.state - e.parent.step*e.parent.state
   208  	}
   209  
   210  	return nil
   211  }
   212  
   213  func (e *testEngine) Rollback(_ context.Context, _ client.TxnOperator) error {
   214  	e.parent.step = e.parent.step + 1
   215  	if e.name == origin {
   216  		e.parent.state = e.parent.state + e.parent.step*e.parent.state
   217  	} else {
   218  		e.parent.state = e.parent.state - e.parent.step*e.parent.state
   219  	}
   220  
   221  	return nil
   222  }
   223  
   224  func (e *testEngine) Delete(ctx context.Context, name string, _ client.TxnOperator) error {
   225  	e.parent.step = e.parent.step + 1
   226  	if e.name == origin {
   227  		e.parent.state = e.parent.state + e.parent.step*e.parent.state
   228  	} else {
   229  		e.parent.state = e.parent.state - e.parent.step*e.parent.state
   230  	}
   231  
   232  	return nil
   233  }
   234  
   235  func (e *testEngine) Create(ctx context.Context, name string, _ client.TxnOperator) error {
   236  	e.parent.step = e.parent.step + 1
   237  	if e.name == origin {
   238  		e.parent.state = e.parent.state + e.parent.step*e.parent.state
   239  	} else {
   240  		e.parent.state = e.parent.state - e.parent.step*e.parent.state
   241  	}
   242  
   243  	return nil
   244  }
   245  
   246  func (e *testEngine) Databases(ctx context.Context, txnOp client.TxnOperator) ([]string, error) {
   247  	e.parent.step = e.parent.step + 1
   248  	if e.name == origin {
   249  		e.parent.state = e.parent.state + e.parent.step*e.parent.state
   250  	} else {
   251  		e.parent.state = e.parent.state - e.parent.step*e.parent.state
   252  	}
   253  
   254  	var a []string
   255  	a = append(a, "foo")
   256  	a = append(a, "bar")
   257  	return a, nil
   258  }
   259  
   260  func (e *testEngine) Database(ctx context.Context, name string, txnOp client.TxnOperator) (Database, error) {
   261  	e.parent.step = e.parent.step + 1
   262  	if e.name == origin {
   263  		e.parent.state = e.parent.state + e.parent.step*e.parent.state
   264  	} else {
   265  		e.parent.state = e.parent.state - e.parent.step*e.parent.state
   266  	}
   267  	return nil, nil
   268  }
   269  
   270  func (e *testEngine) Nodes() (Nodes, error) {
   271  	e.parent.step = e.parent.step + 1
   272  	if e.name == origin {
   273  		e.parent.state = e.parent.state + e.parent.step*e.parent.state
   274  	} else {
   275  		e.parent.state = e.parent.state - e.parent.step*e.parent.state
   276  	}
   277  	return nil, nil
   278  }
   279  
   280  func (e *testEngine) Hints() (h Hints) {
   281  	e.parent.step = e.parent.step + 1
   282  	if e.name == origin {
   283  		e.parent.state = e.parent.state + e.parent.step*e.parent.state
   284  	} else {
   285  		e.parent.state = e.parent.state - e.parent.step*e.parent.state
   286  	}
   287  	return
   288  }
   289  
   290  func (e *testEngine) NewBlockReader(_ context.Context, _ int, _ timestamp.Timestamp,
   291  	_ *plan.Expr, _ [][]byte, _ *plan.TableDef) ([]Reader, error) {
   292  	e.parent.step = e.parent.step + 1
   293  	if e.name == origin {
   294  		e.parent.state = e.parent.state + e.parent.step*e.parent.state
   295  	} else {
   296  		e.parent.state = e.parent.state - e.parent.step*e.parent.state
   297  	}
   298  	return nil, nil
   299  }
   300  
   301  func (e *testEngine) GetNameById(ctx context.Context, op client.TxnOperator, tableId uint64) (dbName string, tblName string, err error) {
   302  	return "", "", nil
   303  }
   304  
   305  func (e *testEngine) GetRelationById(ctx context.Context, op client.TxnOperator, tableId uint64) (dbName string, tblName string, rel Relation, err error) {
   306  	return "", "", nil, nil
   307  }
   308  
   309  func newtestOperator() *testOperator {
   310  	return &testOperator{}
   311  }
   312  
   313  func (o *testOperator) ApplySnapshot(data []byte) error {
   314  	return nil
   315  }
   316  
   317  func (o *testOperator) WriteAndCommit(ctx context.Context, ops []txn.TxnRequest) (*rpc.SendResult, error) {
   318  	return nil, nil
   319  }
   320  
   321  func (o *testOperator) Commit(ctx context.Context) error {
   322  	return nil
   323  }
   324  
   325  func (o *testOperator) Read(ctx context.Context, ops []txn.TxnRequest) (*rpc.SendResult, error) {
   326  	return nil, nil
   327  }
   328  
   329  func (o *testOperator) Rollback(ctx context.Context) error {
   330  	return nil
   331  }
   332  
   333  func (o *testOperator) Snapshot() ([]byte, error) {
   334  	return nil, nil
   335  }
   336  
   337  func (o *testOperator) Txn() txn.TxnMeta {
   338  	return txn.TxnMeta{}
   339  }
   340  
   341  func (o *testOperator) Write(ctx context.Context, ops []txn.TxnRequest) (*rpc.SendResult, error) {
   342  	return nil, nil
   343  }