github.com/MetalBlockchain/metalgo@v1.11.9/database/linkeddb/linkeddb_test.go (about)

     1  // Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved.
     2  // See the file LICENSE for licensing terms.
     3  
     4  package linkeddb
     5  
     6  import (
     7  	"testing"
     8  
     9  	"github.com/stretchr/testify/require"
    10  
    11  	"github.com/MetalBlockchain/metalgo/database"
    12  	"github.com/MetalBlockchain/metalgo/database/memdb"
    13  )
    14  
    15  func TestLinkedDB(t *testing.T) {
    16  	require := require.New(t)
    17  
    18  	db := memdb.New()
    19  	ldb := NewDefault(db)
    20  
    21  	key := []byte("hello")
    22  	value := []byte("world")
    23  
    24  	has, err := ldb.Has(key)
    25  	require.NoError(err)
    26  	require.False(has)
    27  
    28  	_, err = ldb.Get(key)
    29  	require.Equal(database.ErrNotFound, err)
    30  
    31  	require.NoError(ldb.Delete(key))
    32  
    33  	require.NoError(ldb.Put(key, value))
    34  
    35  	has, err = ldb.Has(key)
    36  	require.NoError(err)
    37  	require.True(has)
    38  
    39  	v, err := ldb.Get(key)
    40  	require.NoError(err)
    41  	require.Equal(value, v)
    42  
    43  	require.NoError(ldb.Delete(key))
    44  
    45  	has, err = ldb.Has(key)
    46  	require.NoError(err)
    47  	require.False(has)
    48  
    49  	_, err = ldb.Get(key)
    50  	require.Equal(database.ErrNotFound, err)
    51  
    52  	iterator := db.NewIterator()
    53  	require.False(iterator.Next())
    54  	iterator.Release()
    55  }
    56  
    57  func TestLinkedDBDuplicatedPut(t *testing.T) {
    58  	require := require.New(t)
    59  
    60  	db := memdb.New()
    61  	ldb := NewDefault(db)
    62  
    63  	key := []byte("hello")
    64  	value1 := []byte("world1")
    65  	value2 := []byte("world2")
    66  
    67  	require.NoError(ldb.Put(key, value1))
    68  
    69  	require.NoError(ldb.Put(key, value2))
    70  
    71  	v, err := ldb.Get(key)
    72  	require.NoError(err)
    73  	require.Equal(value2, v)
    74  
    75  	require.NoError(ldb.Delete(key))
    76  
    77  	iterator := db.NewIterator()
    78  	require.False(iterator.Next())
    79  	iterator.Release()
    80  }
    81  
    82  func TestLinkedDBMultiplePuts(t *testing.T) {
    83  	require := require.New(t)
    84  
    85  	db := memdb.New()
    86  	ldb := NewDefault(db)
    87  
    88  	key1 := []byte("hello1")
    89  	key2 := []byte("hello2")
    90  	key3 := []byte("hello3")
    91  	value1 := []byte("world1")
    92  	value2 := []byte("world2")
    93  	value3 := []byte("world3")
    94  
    95  	require.NoError(ldb.Put(key1, value1))
    96  
    97  	require.NoError(ldb.Put(key2, value2))
    98  
    99  	v, err := ldb.Get(key1)
   100  	require.NoError(err)
   101  	require.Equal(value1, v)
   102  
   103  	v, err = ldb.Get(key2)
   104  	require.NoError(err)
   105  	require.Equal(value2, v)
   106  
   107  	require.NoError(ldb.Delete(key2))
   108  
   109  	require.NoError(ldb.Put(key2, value2))
   110  
   111  	require.NoError(ldb.Put(key3, value3))
   112  
   113  	require.NoError(ldb.Delete(key2))
   114  
   115  	require.NoError(ldb.Delete(key1))
   116  
   117  	require.NoError(ldb.Delete(key3))
   118  
   119  	iterator := db.NewIterator()
   120  	next := iterator.Next()
   121  	require.False(next, "database should be empty")
   122  	iterator.Release()
   123  }
   124  
   125  func TestEmptyLinkedDBIterator(t *testing.T) {
   126  	require := require.New(t)
   127  
   128  	db := memdb.New()
   129  	ldb := NewDefault(db)
   130  
   131  	iterator := ldb.NewIterator()
   132  	next := iterator.Next()
   133  	require.False(next, "The iterator should now be exhausted")
   134  
   135  	k := iterator.Key()
   136  	require.Nil(k, "The iterator returned the wrong key")
   137  
   138  	v := iterator.Value()
   139  	require.Nil(v, "The iterator returned the wrong value")
   140  
   141  	require.NoError(iterator.Error())
   142  
   143  	iterator.Release()
   144  }
   145  
   146  func TestLinkedDBLoadHeadKey(t *testing.T) {
   147  	require := require.New(t)
   148  
   149  	db := memdb.New()
   150  	ldb := NewDefault(db)
   151  
   152  	key := []byte("hello")
   153  	value := []byte("world")
   154  
   155  	require.NoError(ldb.Put(key, value))
   156  
   157  	ldb = NewDefault(db)
   158  
   159  	iterator := ldb.NewIterator()
   160  	next := iterator.Next()
   161  	require.True(next, "The iterator shouldn't be exhausted yet")
   162  
   163  	k := iterator.Key()
   164  	require.Equal(key, k, "The iterator returned the wrong key")
   165  
   166  	v := iterator.Value()
   167  	require.Equal(value, v, "The iterator returned the wrong value")
   168  
   169  	next = iterator.Next()
   170  	require.False(next, "The iterator should now be exhausted")
   171  
   172  	k = iterator.Key()
   173  	require.Nil(k, "The iterator returned the wrong key")
   174  
   175  	v = iterator.Value()
   176  	require.Nil(v, "The iterator returned the wrong value")
   177  
   178  	require.NoError(iterator.Error())
   179  
   180  	iterator.Release()
   181  }
   182  
   183  func TestSingleLinkedDBIterator(t *testing.T) {
   184  	require := require.New(t)
   185  
   186  	db := memdb.New()
   187  	ldb := NewDefault(db)
   188  
   189  	key := []byte("hello")
   190  	value := []byte("world")
   191  
   192  	require.NoError(ldb.Put(key, value))
   193  
   194  	iterator := ldb.NewIterator()
   195  	next := iterator.Next()
   196  	require.True(next, "The iterator shouldn't be exhausted yet")
   197  
   198  	k := iterator.Key()
   199  	require.Equal(key, k, "The iterator returned the wrong key")
   200  
   201  	v := iterator.Value()
   202  	require.Equal(value, v, "The iterator returned the wrong value")
   203  
   204  	next = iterator.Next()
   205  	require.False(next, "The iterator should now be exhausted")
   206  
   207  	k = iterator.Key()
   208  	require.Nil(k, "The iterator returned the wrong key")
   209  
   210  	v = iterator.Value()
   211  	require.Nil(v, "The iterator returned the wrong value")
   212  
   213  	require.NoError(iterator.Error())
   214  
   215  	iterator.Release()
   216  }
   217  
   218  func TestMultipleLinkedDBIterator(t *testing.T) {
   219  	require := require.New(t)
   220  
   221  	db := memdb.New()
   222  	ldb := NewDefault(db)
   223  
   224  	key0 := []byte("hello0")
   225  	key1 := []byte("hello1")
   226  	value0 := []byte("world0")
   227  	value1 := []byte("world1")
   228  
   229  	require.NoError(ldb.Put(key0, value0))
   230  
   231  	require.NoError(ldb.Put(key1, value1))
   232  
   233  	iterator := ldb.NewIterator()
   234  	next := iterator.Next()
   235  	require.True(next, "The iterator shouldn't be exhausted yet")
   236  
   237  	k := iterator.Key()
   238  	require.Equal(key1, k, "The iterator returned the wrong key")
   239  
   240  	v := iterator.Value()
   241  	require.Equal(value1, v, "The iterator returned the wrong value")
   242  
   243  	next = iterator.Next()
   244  	require.True(next, "The iterator shouldn't be exhausted yet")
   245  
   246  	k = iterator.Key()
   247  	require.Equal(key0, k, "The iterator returned the wrong key")
   248  
   249  	v = iterator.Value()
   250  	require.Equal(value0, v, "The iterator returned the wrong value")
   251  
   252  	next = iterator.Next()
   253  	require.False(next, "The iterator should now be exhausted")
   254  
   255  	require.NoError(iterator.Error())
   256  
   257  	iterator.Release()
   258  }
   259  
   260  func TestMultipleLinkedDBIteratorStart(t *testing.T) {
   261  	require := require.New(t)
   262  
   263  	db := memdb.New()
   264  	ldb := NewDefault(db)
   265  
   266  	key0 := []byte("hello0")
   267  	key1 := []byte("hello1")
   268  	value0 := []byte("world0")
   269  	value1 := []byte("world1")
   270  
   271  	require.NoError(ldb.Put(key0, value0))
   272  
   273  	require.NoError(ldb.Put(key1, value1))
   274  
   275  	iterator := ldb.NewIteratorWithStart(key1)
   276  	next := iterator.Next()
   277  	require.True(next, "The iterator shouldn't be exhausted yet")
   278  
   279  	k := iterator.Key()
   280  	require.Equal(key1, k, "The iterator returned the wrong key")
   281  
   282  	v := iterator.Value()
   283  	require.Equal(value1, v, "The iterator returned the wrong value")
   284  
   285  	next = iterator.Next()
   286  	require.True(next, "The iterator shouldn't be exhausted yet")
   287  
   288  	k = iterator.Key()
   289  	require.Equal(key0, k, "The iterator returned the wrong key")
   290  
   291  	v = iterator.Value()
   292  	require.Equal(value0, v, "The iterator returned the wrong value")
   293  
   294  	next = iterator.Next()
   295  	require.False(next, "The iterator should now be exhausted")
   296  
   297  	require.NoError(iterator.Error())
   298  
   299  	iterator.Release()
   300  }
   301  
   302  func TestSingleLinkedDBIteratorStart(t *testing.T) {
   303  	require := require.New(t)
   304  
   305  	db := memdb.New()
   306  	ldb := NewDefault(db)
   307  
   308  	key0 := []byte("hello0")
   309  	key1 := []byte("hello1")
   310  	value0 := []byte("world0")
   311  	value1 := []byte("world1")
   312  
   313  	require.NoError(ldb.Put(key0, value0))
   314  
   315  	require.NoError(ldb.Put(key1, value1))
   316  
   317  	iterator := ldb.NewIteratorWithStart(key0)
   318  
   319  	next := iterator.Next()
   320  	require.True(next, "The iterator shouldn't be exhausted yet")
   321  
   322  	k := iterator.Key()
   323  	require.Equal(key0, k, "The iterator returned the wrong key")
   324  
   325  	v := iterator.Value()
   326  	require.Equal(value0, v, "The iterator returned the wrong value")
   327  
   328  	next = iterator.Next()
   329  	require.False(next, "The iterator should now be exhausted")
   330  
   331  	require.NoError(iterator.Error())
   332  
   333  	iterator.Release()
   334  }
   335  
   336  // Test that if we call NewIteratorWithStart with a key that is not
   337  // in the database, the iterator will start at the head
   338  func TestEmptyLinkedDBIteratorStart(t *testing.T) {
   339  	require := require.New(t)
   340  
   341  	db := memdb.New()
   342  	ldb := NewDefault(db)
   343  
   344  	key0 := []byte("hello0")
   345  	key1 := []byte("hello1")
   346  	key2 := []byte("hello2")
   347  	value0 := []byte("world0")
   348  	value1 := []byte("world1")
   349  
   350  	require.NoError(ldb.Put(key0, value0))
   351  
   352  	require.NoError(ldb.Put(key1, value1))
   353  
   354  	iter := ldb.NewIteratorWithStart(key2)
   355  
   356  	i := 0
   357  	for iter.Next() {
   358  		require.Contains([][]byte{key0, key1}, iter.Key())
   359  		require.Contains([][]byte{value0, value1}, iter.Value())
   360  		i++
   361  	}
   362  	require.Equal(2, i)
   363  
   364  	require.NoError(iter.Error())
   365  
   366  	iter.Release()
   367  }
   368  
   369  func TestLinkedDBIsEmpty(t *testing.T) {
   370  	require := require.New(t)
   371  
   372  	db := memdb.New()
   373  	ldb := NewDefault(db)
   374  
   375  	isEmpty, err := ldb.IsEmpty()
   376  	require.NoError(err)
   377  	require.True(isEmpty)
   378  
   379  	key := []byte("hello")
   380  	value := []byte("world")
   381  
   382  	require.NoError(ldb.Put(key, value))
   383  
   384  	isEmpty, err = ldb.IsEmpty()
   385  	require.NoError(err)
   386  	require.False(isEmpty)
   387  
   388  	require.NoError(ldb.Delete(key))
   389  
   390  	isEmpty, err = ldb.IsEmpty()
   391  	require.NoError(err)
   392  	require.True(isEmpty)
   393  }
   394  
   395  func TestLinkedDBHeadKey(t *testing.T) {
   396  	require := require.New(t)
   397  
   398  	db := memdb.New()
   399  	ldb := NewDefault(db)
   400  
   401  	_, err := ldb.HeadKey()
   402  	require.Equal(database.ErrNotFound, err)
   403  
   404  	key0 := []byte("hello0")
   405  	value0 := []byte("world0")
   406  	key1 := []byte("hello1")
   407  	value1 := []byte("world1")
   408  
   409  	require.NoError(ldb.Put(key0, value0))
   410  
   411  	headKey, err := ldb.HeadKey()
   412  	require.NoError(err)
   413  	require.Equal(key0, headKey)
   414  
   415  	require.NoError(ldb.Put(key1, value1))
   416  
   417  	headKey, err = ldb.HeadKey()
   418  	require.NoError(err)
   419  	require.Equal(key1, headKey)
   420  
   421  	require.NoError(ldb.Delete(key1))
   422  
   423  	headKey, err = ldb.HeadKey()
   424  	require.NoError(err)
   425  	require.Equal(key0, headKey)
   426  }
   427  
   428  func TestLinkedDBHead(t *testing.T) {
   429  	require := require.New(t)
   430  
   431  	db := memdb.New()
   432  	ldb := NewDefault(db)
   433  
   434  	_, _, err := ldb.Head()
   435  	require.Equal(database.ErrNotFound, err)
   436  
   437  	key0 := []byte("hello0")
   438  	value0 := []byte("world0")
   439  	key1 := []byte("hello1")
   440  	value1 := []byte("world1")
   441  
   442  	require.NoError(ldb.Put(key0, value0))
   443  
   444  	headKey, headVal, err := ldb.Head()
   445  	require.NoError(err)
   446  	require.Equal(key0, headKey)
   447  	require.Equal(value0, headVal)
   448  
   449  	require.NoError(ldb.Put(key1, value1))
   450  
   451  	headKey, headVal, err = ldb.Head()
   452  	require.NoError(err)
   453  	require.Equal(key1, headKey)
   454  	require.Equal(value1, headVal)
   455  
   456  	require.NoError(ldb.Delete(key1))
   457  
   458  	headKey, headVal, err = ldb.Head()
   459  	require.NoError(err)
   460  	require.Equal(key0, headKey)
   461  	require.Equal(value0, headVal)
   462  }