github.com/ledgerwatch/erigon-lib@v1.0.0/kv/mdbx/kv_migrator_test.go (about)

     1  //go:build !windows
     2  
     3  /*
     4  Copyright 2021 Erigon contributors
     5  
     6  Licensed under the Apache License, Version 2.0 (the "License");
     7  you may not use this file except in compliance with the License.
     8  You may obtain a copy of the License at
     9  
    10  	http://www.apache.org/licenses/LICENSE-2.0
    11  
    12  Unless required by applicable law or agreed to in writing, software
    13  distributed under the License is distributed on an "AS IS" BASIS,
    14  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    15  See the License for the specific language governing permissions and
    16  limitations under the License.
    17  */
    18  package mdbx_test
    19  
    20  import (
    21  	"context"
    22  	"errors"
    23  	"testing"
    24  	"time"
    25  
    26  	"github.com/c2h5oh/datasize"
    27  	"github.com/ledgerwatch/erigon-lib/kv"
    28  	"github.com/ledgerwatch/erigon-lib/kv/mdbx"
    29  	"github.com/ledgerwatch/erigon-lib/kv/memdb"
    30  	"github.com/ledgerwatch/log/v3"
    31  	"github.com/stretchr/testify/require"
    32  )
    33  
    34  func TestBucketCRUD(t *testing.T) {
    35  	require := require.New(t)
    36  	db, tx := memdb.NewTestTx(t)
    37  
    38  	normalBucket := kv.ChaindataTables[15]
    39  	deprecatedBucket := kv.ChaindataDeprecatedTables[0]
    40  	migrator, ok := tx.(kv.BucketMigrator)
    41  	if !ok {
    42  		return
    43  	}
    44  
    45  	// check thad buckets have unique DBI's
    46  	uniquness := map[kv.DBI]bool{}
    47  	castedKv, ok := db.(*mdbx.MdbxKV)
    48  	if !ok {
    49  		t.Skip()
    50  	}
    51  	for _, dbi := range castedKv.AllDBI() {
    52  		if dbi == mdbx.NonExistingDBI {
    53  			continue
    54  		}
    55  		_, ok := uniquness[dbi]
    56  		require.False(ok)
    57  		uniquness[dbi] = true
    58  	}
    59  
    60  	require.True(migrator.ExistsBucket(normalBucket))
    61  	require.True(errors.Is(migrator.DropBucket(normalBucket), kv.ErrAttemptToDeleteNonDeprecatedBucket))
    62  
    63  	require.False(migrator.ExistsBucket(deprecatedBucket))
    64  	require.NoError(migrator.CreateBucket(deprecatedBucket))
    65  	require.True(migrator.ExistsBucket(deprecatedBucket))
    66  
    67  	require.NoError(migrator.DropBucket(deprecatedBucket))
    68  	require.False(migrator.ExistsBucket(deprecatedBucket))
    69  
    70  	require.NoError(migrator.CreateBucket(deprecatedBucket))
    71  	require.True(migrator.ExistsBucket(deprecatedBucket))
    72  
    73  	c, err := tx.RwCursor(deprecatedBucket)
    74  	require.NoError(err)
    75  	err = c.Put([]byte{1}, []byte{1})
    76  	require.NoError(err)
    77  	v, err := tx.GetOne(deprecatedBucket, []byte{1})
    78  	require.NoError(err)
    79  	require.Equal([]byte{1}, v)
    80  
    81  	buckets, err := migrator.ListBuckets()
    82  	require.NoError(err)
    83  	require.True(len(buckets) > 10)
    84  
    85  	// check thad buckets have unique DBI's
    86  	uniquness = map[kv.DBI]bool{}
    87  	for _, dbi := range castedKv.AllDBI() {
    88  		if dbi == mdbx.NonExistingDBI {
    89  			continue
    90  		}
    91  		_, ok := uniquness[dbi]
    92  		require.False(ok)
    93  		uniquness[dbi] = true
    94  	}
    95  }
    96  
    97  func TestReadOnlyMode(t *testing.T) {
    98  	path := t.TempDir()
    99  	logger := log.New()
   100  	db1 := mdbx.NewMDBX(logger).Path(path).MapSize(16 * datasize.MB).WithTableCfg(func(defaultBuckets kv.TableCfg) kv.TableCfg {
   101  		return kv.TableCfg{
   102  			kv.Headers: kv.TableCfgItem{},
   103  		}
   104  	}).MustOpen()
   105  	db1.Close()
   106  	time.Sleep(10 * time.Millisecond) // win sometime need time to close file
   107  
   108  	db2 := mdbx.NewMDBX(logger).Readonly().Path(path).MapSize(16 * datasize.MB).WithTableCfg(func(defaultBuckets kv.TableCfg) kv.TableCfg {
   109  		return kv.TableCfg{
   110  			kv.Headers: kv.TableCfgItem{},
   111  		}
   112  	}).MustOpen()
   113  	defer db2.Close()
   114  
   115  	tx, err := db2.BeginRo(context.Background())
   116  	require.NoError(t, err)
   117  	defer tx.Rollback()
   118  
   119  	c, err := tx.Cursor(kv.Headers)
   120  	require.NoError(t, err)
   121  	defer c.Close()
   122  	_, _, err = c.Seek([]byte("some prefix"))
   123  	require.NoError(t, err)
   124  }