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  }