github.com/treeverse/lakefs@v1.24.1-0.20240520134607-95648127bfb0/pkg/graveler/staging/manager_test.go (about)

     1  package staging_test
     2  
     3  import (
     4  	"bytes"
     5  	"context"
     6  	"errors"
     7  	"fmt"
     8  	"testing"
     9  
    10  	"github.com/stretchr/testify/require"
    11  	"github.com/treeverse/lakefs/pkg/graveler"
    12  	"github.com/treeverse/lakefs/pkg/graveler/staging"
    13  	"github.com/treeverse/lakefs/pkg/kv"
    14  	"github.com/treeverse/lakefs/pkg/kv/kvtest"
    15  	"github.com/treeverse/lakefs/pkg/testutil"
    16  	"go.uber.org/ratelimit"
    17  )
    18  
    19  func newTestStagingManager(t *testing.T) (context.Context, graveler.StagingManager) {
    20  	t.Helper()
    21  	ctx := context.Background()
    22  	store := kvtest.GetStore(ctx, t)
    23  	return ctx, staging.NewManager(ctx, store, kv.NewStoreLimiter(store, ratelimit.NewUnlimited()), false, nil)
    24  }
    25  
    26  func TestUpdate(t *testing.T) {
    27  	ctx, s := newTestStagingManager(t)
    28  
    29  	key := "a/b/c/my-key-1234"
    30  	testVal := newTestValue("identity1", "value1")
    31  	testVal2 := newTestValue("identity2", "value2")
    32  	// update missing key
    33  	err := s.Update(ctx, "t1", []byte(key), func(value *graveler.Value) (*graveler.Value, error) {
    34  		require.Nil(t, value)
    35  		return testVal, nil
    36  	})
    37  	require.NoError(t, err)
    38  
    39  	// update existing key
    40  	err = s.Update(ctx, "t1", []byte(key), func(value *graveler.Value) (*graveler.Value, error) {
    41  		require.Equal(t, testVal, value)
    42  		return testVal2, nil
    43  	})
    44  	require.NoError(t, err)
    45  
    46  	// get value
    47  	val, err := s.Get(ctx, "t1", []byte(key))
    48  	require.NoError(t, err)
    49  	require.Equal(t, testVal2, val)
    50  
    51  	// update with error
    52  	err = s.Update(ctx, "t1", []byte(key), func(value *graveler.Value) (*graveler.Value, error) {
    53  		require.Equal(t, testVal2, value)
    54  		return testVal, graveler.ErrNotUnique
    55  	})
    56  	require.ErrorIs(t, err, graveler.ErrNotUnique)
    57  
    58  	// get value - see it didn't update after an error
    59  	val, err = s.Get(ctx, "t1", []byte(key))
    60  	require.NoError(t, err)
    61  	require.Equal(t, testVal2, val)
    62  
    63  	// update without set new value
    64  	err = s.Update(ctx, "t1", []byte(key), func(value *graveler.Value) (*graveler.Value, error) {
    65  		require.Equal(t, testVal2, value)
    66  		return nil, graveler.ErrSkipValueUpdate
    67  	})
    68  	require.NoError(t, err)
    69  	// verify that we didn't update the value
    70  	val, err = s.Get(ctx, "t1", []byte(key))
    71  	require.NoError(t, err)
    72  	require.Equal(t, testVal2, val)
    73  }
    74  
    75  func TestSetGet(t *testing.T) {
    76  	ctx, s := newTestStagingManager(t)
    77  	_, err := s.Get(ctx, "t1", []byte("a/b/c/"))
    78  	if !errors.Is(err, graveler.ErrNotFound) {
    79  		t.Fatalf("error different than expected. expected=%v, got=%v", graveler.ErrNotFound, err)
    80  	}
    81  	value := newTestValue("identity1", "value1")
    82  	err = s.Set(ctx, "t1", []byte("a/b/c/"), value, false)
    83  	testutil.Must(t, err)
    84  	e, err := s.Get(ctx, "t1", []byte("a/b/c/"))
    85  	testutil.Must(t, err)
    86  	if string(e.Identity) != "identity1" {
    87  		t.Errorf("got wrong value. expected=%s, got=%s", "identity1", string(e.Identity))
    88  	}
    89  }
    90  
    91  func TestMultiToken(t *testing.T) {
    92  	ctx, s := newTestStagingManager(t)
    93  	_, err := s.Get(ctx, "t1", []byte("a/b/c/"))
    94  	if !errors.Is(err, graveler.ErrNotFound) {
    95  		t.Fatalf("error different than expected. expected=%v, got=%v", graveler.ErrNotFound, err)
    96  	}
    97  	err = s.Set(ctx, "t1", []byte("a/b/c/"), newTestValue("identity1", "value1"), false)
    98  	testutil.Must(t, err)
    99  	e, err := s.Get(ctx, "t1", []byte("a/b/c/"))
   100  	testutil.Must(t, err)
   101  	if string(e.Identity) != "identity1" {
   102  		t.Errorf("got wrong identity. expected=%s, got=%s", "identity1", string(e.Identity))
   103  	}
   104  	err = s.Set(ctx, "t2", []byte("a/b/c/"), newTestValue("identity2", "value2"), false)
   105  	testutil.Must(t, err)
   106  	e, err = s.Get(ctx, "t1", []byte("a/b/c/"))
   107  	testutil.Must(t, err)
   108  	if string(e.Identity) != "identity1" {
   109  		t.Errorf("got wrong value identity. expected=%s, got=%s", "identity1", string(e.Identity))
   110  	}
   111  	e, err = s.Get(ctx, "t2", []byte("a/b/c/"))
   112  	testutil.Must(t, err)
   113  	if string(e.Identity) != "identity2" {
   114  		t.Errorf("got wrong value identity. expected=%s, got=%s", "identity2", string(e.Identity))
   115  		t.Errorf("got wrong value identity. expected=%s, got=%s", "identity2", string(e.Identity))
   116  	}
   117  }
   118  
   119  func TestDrop(t *testing.T) {
   120  	ctx, s := newTestStagingManager(t)
   121  	numOfValues := 1400
   122  	setupDrop(ctx, t, numOfValues, s)
   123  	err := s.Drop(ctx, "t1")
   124  	testutil.Must(t, err)
   125  	v, err := s.Get(ctx, "t1", []byte("key0000"))
   126  	if !errors.Is(err, graveler.ErrNotFound) {
   127  		t.Fatalf("after dropping staging area, expected ErrNotFound in Get. got err=%v, got value=%v", err, v)
   128  	}
   129  	it := s.List(ctx, "t1", 0)
   130  	if it.Next() {
   131  		t.Fatal("expected staging area with token t1 to be empty, got non-empty iterator")
   132  	}
   133  	it.Close()
   134  	it = s.List(ctx, "t2", 0)
   135  	count := 0
   136  	for it.Next() {
   137  		if string(it.Value().Data) != fmt.Sprintf("value%d", count) {
   138  			t.Fatalf("unexpected value returned from List at index %d. expected=%s, got=%s", count, fmt.Sprintf("value%d", count), string(it.Value().Data))
   139  		}
   140  		count++
   141  	}
   142  	it.Close()
   143  	if count != numOfValues {
   144  		t.Errorf("got unexpected number of results. expected=%d, got=%d", numOfValues, count)
   145  	}
   146  }
   147  
   148  func setupDrop(ctx context.Context, t *testing.T, numOfValues int, s graveler.StagingManager) {
   149  	for i := 0; i < numOfValues; i++ {
   150  		err := s.Set(ctx, "t1", []byte(fmt.Sprintf("key%04d", i)), newTestValue(fmt.Sprintf("identity%d", i), fmt.Sprintf("value%d", i)), false)
   151  		testutil.Must(t, err)
   152  		err = s.Set(ctx, "t2", []byte(fmt.Sprintf("key%04d", i)), newTestValue(fmt.Sprintf("identity%d", i), fmt.Sprintf("value%d", i)), false)
   153  		testutil.Must(t, err)
   154  	}
   155  }
   156  
   157  func TestDropAsync(t *testing.T) {
   158  	ctx := context.Background()
   159  	store := kvtest.GetStore(ctx, t)
   160  	ch := make(chan bool)
   161  	s := staging.NewManager(ctx, store, kv.NewStoreLimiter(store, ratelimit.NewUnlimited()), false, nil)
   162  	s.OnCleanup(func() {
   163  		close(ch)
   164  	})
   165  
   166  	numOfValues := 1400
   167  	setupDrop(ctx, t, numOfValues, s)
   168  
   169  	err := s.DropAsync(ctx, "t1")
   170  	require.NoError(t, err)
   171  
   172  	// wait for async cleanup to end
   173  	<-ch
   174  	it := s.List(ctx, "t1", 0)
   175  	if it.Next() {
   176  		t.Fatal("expected staging area with token t1 to be empty, got non-empty iterator")
   177  	}
   178  	it.Close()
   179  }
   180  
   181  func TestDropByPrefix(t *testing.T) {
   182  	ctx, s := newTestStagingManager(t)
   183  	numOfValues := 2400
   184  	setupDrop(ctx, t, numOfValues, s)
   185  
   186  	err := s.DropByPrefix(ctx, "t1", []byte("key1"))
   187  	testutil.Must(t, err)
   188  	v, err := s.Get(ctx, "t1", []byte("key1000"))
   189  	if !errors.Is(err, graveler.ErrNotFound) {
   190  		// key1000 starts with the deleted prefix - should have been deleted
   191  		t.Fatalf("after dropping staging area, expected ErrNotFound in Get. got err=%v, got value=%s", err, v)
   192  	}
   193  	_, err = s.Get(ctx, "t1", []byte("key0000"))
   194  	// key0000 does not start with the deleted prefix - should be returned
   195  	testutil.Must(t, err)
   196  	it := s.List(ctx, "t1", 0)
   197  	count := 0
   198  	for it.Next() {
   199  		count++
   200  	}
   201  	it.Close()
   202  	if count != numOfValues-1000 {
   203  		t.Errorf("got unexpected number of results after drop. expected=%d, got=%d", numOfValues-1000, count)
   204  	}
   205  	it = s.List(ctx, "t2", 0)
   206  	count = 0
   207  	for it.Next() {
   208  		count++
   209  	}
   210  	it.Close()
   211  	if count != numOfValues {
   212  		t.Errorf("got unexpected number of results. expected=%d, got=%d", numOfValues, count)
   213  	}
   214  }
   215  
   216  func TestDropPrefixBytes(t *testing.T) {
   217  	ctx, s := newTestStagingManager(t)
   218  	tests := map[string]struct {
   219  		keys                    []graveler.Key
   220  		prefix                  graveler.Key
   221  		expectedLengthAfterDrop int
   222  	}{
   223  		"prefix with all bytes=MaxUint8": {
   224  			keys:                    []graveler.Key{{255, 255, 254, 254}, {255, 255, 254, 255}, {255, 255, 255, 253}, {255, 255, 255, 254}, {255, 255, 255, 255}},
   225  			prefix:                  graveler.Key{255, 255, 255},
   226  			expectedLengthAfterDrop: 2,
   227  		},
   228  		"all zero prefix": {
   229  			keys:                    []graveler.Key{{0, 0, 0, 0}, {0, 0, 0, 255}, {0, 0, 1, 0}, {0, 0, 1, 1}},
   230  			prefix:                  graveler.Key{0, 0, 0},
   231  			expectedLengthAfterDrop: 2,
   232  		},
   233  		"prefix common to all keys": {
   234  			keys:                    []graveler.Key{{0, 0, 0, 0}, {0, 0, 0, 255}, {0, 0, 1, 0}, {0, 0, 1, 1}},
   235  			prefix:                  graveler.Key{0, 0},
   236  			expectedLengthAfterDrop: 0,
   237  		},
   238  		"axUint8 in keys - prefix length 1": {
   239  			keys:                    []graveler.Key{{1, 0, 0, 0}, {1, 0, 0, 255}, {1, 0, 255, 255}, {1, 255, 255, 255}},
   240  			prefix:                  graveler.Key{1},
   241  			expectedLengthAfterDrop: 0,
   242  		},
   243  		"MaxUint8 in keys - prefix length 2": {
   244  			keys:                    []graveler.Key{{1, 0, 0, 0}, {1, 0, 0, 255}, {1, 0, 255, 255}, {1, 255, 255, 255}},
   245  			prefix:                  graveler.Key{1, 0},
   246  			expectedLengthAfterDrop: 1,
   247  		},
   248  		"MaxUint8 in keys - prefix length 3": {
   249  			keys:                    []graveler.Key{{1, 0, 0, 0}, {1, 0, 0, 255}, {1, 0, 255, 255}, {1, 255, 255, 255}},
   250  			prefix:                  graveler.Key{1, 0, 0},
   251  			expectedLengthAfterDrop: 2,
   252  		},
   253  		"MaxUint8 in keys - prefix length 4": {
   254  			keys:                    []graveler.Key{{1, 0, 0, 0}, {1, 0, 0, 255}, {1, 0, 255, 255}, {1, 255, 255, 255}},
   255  			prefix:                  graveler.Key{1, 0, 0, 0},
   256  			expectedLengthAfterDrop: 3,
   257  		},
   258  		"multi-length keys - prefix length 3": {
   259  			keys:                    []graveler.Key{{1, 0}, {1, 1}, {1, 0, 1}, {1, 1, 1}, {1, 1, 1, 255}, {1, 1, 255, 1}, {1, 1, 1, 1, 1}, {1, 1, 1, 255, 1, 1, 1, 1, 1, 1, 1, 1}},
   260  			prefix:                  graveler.Key{1, 1, 1},
   261  			expectedLengthAfterDrop: 4,
   262  		},
   263  		"multi-length keys - prefix length 4": {
   264  			keys:                    []graveler.Key{{1, 0}, {1, 1}, {1, 0, 1}, {1, 1, 1}, {1, 1, 1, 255}, {1, 1, 255, 1}, {1, 1, 1, 1, 1}, {1, 1, 1, 255, 1, 1, 1, 1, 1, 1, 1, 1}, {1, 1, 1, 1, 1, 255, 255, 255, 255}},
   265  			prefix:                  graveler.Key{1, 1, 1, 1},
   266  			expectedLengthAfterDrop: 7,
   267  		},
   268  		"empty prefix": {
   269  			keys:                    []graveler.Key{{1, 0}, {1, 1}, {1, 0, 1}, {1, 1, 1}, {1, 1, 1, 255}, {1, 1, 255, 1}, {1, 1, 1, 1, 1}, {1, 1, 1, 255, 1, 1, 1, 1, 1, 1, 1, 1}, {1, 1, 1, 1, 1, 255, 255, 255, 255}, {2, 0}},
   270  			prefix:                  graveler.Key{},
   271  			expectedLengthAfterDrop: 0,
   272  		},
   273  		"multi-length keys - prefix with MaxUint 8": {
   274  			keys:                    []graveler.Key{{1, 0}, {1, 1}, {1, 0, 1}, {1, 1, 1}, {1, 1, 1, 255}, {1, 1, 255, 1}, {1, 1, 1, 1, 1}, {1, 1, 1, 255, 1, 1, 1, 1, 1, 1, 1, 1}, {1, 1, 1, 1, 1, 255, 255, 255, 255}, {2, 0}},
   275  			prefix:                  graveler.Key{0, 255, 255, 255},
   276  			expectedLengthAfterDrop: 10,
   277  		},
   278  		"multi-length keys - prefix with MaxUint 8 - prefix length 2": {
   279  			keys:                    []graveler.Key{{1, 0}, {1, 1}, {1, 0, 1}, {1, 1, 1}, {1, 1, 1, 255}, {1, 1, 255, 1}, {1, 1, 1, 1, 1}, {1, 1, 1, 255, 1, 1, 1, 1, 1, 1, 1, 1}, {1, 1, 1, 1, 1, 255, 255, 255, 255}, {2, 0}},
   280  			prefix:                  graveler.Key{1, 255},
   281  			expectedLengthAfterDrop: 10,
   282  		},
   283  		"multi-length keys - prefix with MaxUint 8 - prefix length 3": {
   284  			keys:                    []graveler.Key{{1, 254, 255, 255}, {1, 255}, {1, 255, 255}, {1, 255, 255, 255}, {2, 255}},
   285  			prefix:                  graveler.Key{1, 255, 255},
   286  			expectedLengthAfterDrop: 3,
   287  		},
   288  	}
   289  	for name, tst := range tests {
   290  		st := graveler.StagingToken(fmt.Sprintf("t_%s", name))
   291  		t.Run(name, func(t *testing.T) {
   292  			for _, k := range tst.keys {
   293  				err := s.Set(ctx, st, k, &graveler.Value{
   294  					Identity: []byte{0, 0, 0, 0, 0, 0},
   295  					Data:     []byte{0, 0, 0, 0, 0, 0},
   296  				}, false)
   297  				testutil.Must(t, err)
   298  			}
   299  			err := s.DropByPrefix(ctx, st, tst.prefix)
   300  			testutil.Must(t, err)
   301  			it := s.List(ctx, st, 0)
   302  			testutil.Must(t, err)
   303  			count := 0
   304  			for it.Next() {
   305  				count++
   306  			}
   307  			if count != tst.expectedLengthAfterDrop {
   308  				t.Fatalf("unexpected number of values after drop. expected=%d, got=%d", tst.expectedLengthAfterDrop, count)
   309  			}
   310  			if it.Err() != nil {
   311  				t.Fatalf("got unexpected error: %v", it.Err())
   312  			}
   313  			it.Close()
   314  		})
   315  	}
   316  }
   317  
   318  func TestList(t *testing.T) {
   319  	ctx, s := newTestStagingManager(t)
   320  	for _, numOfValues := range []int{1, 100, 1000, 1500, 2500} {
   321  		token := graveler.StagingToken(fmt.Sprintf("t_%d", numOfValues))
   322  		for i := 0; i < numOfValues; i++ {
   323  			err := s.Set(ctx, token, []byte(fmt.Sprintf("key%04d", i)), newTestValue(fmt.Sprintf("identity%d", i), fmt.Sprintf("value%d", i)), false)
   324  			testutil.Must(t, err)
   325  		}
   326  		res := make([]*graveler.ValueRecord, 0, numOfValues)
   327  		it := s.List(ctx, token, 0)
   328  		for it.Next() {
   329  			res = append(res, it.Value())
   330  		}
   331  		if it.Err() != nil {
   332  			t.Fatalf("got unexpected error from list: %v", it.Err())
   333  		}
   334  		it.Close()
   335  		if len(res) != numOfValues {
   336  			t.Errorf("got unexpected number of results. expected=%d, got=%d", numOfValues, len(res))
   337  		}
   338  		for i, e := range res {
   339  			if !bytes.Equal(e.Key, []byte(fmt.Sprintf("key%04d", i))) {
   340  				t.Fatalf("got unexpected key from List at index %d: expected: key%04d, got: %s", i, i, string(e.Key))
   341  			}
   342  			if string(e.Data) != fmt.Sprintf("value%d", i) {
   343  				t.Fatalf("unexpected value returned from List at index %d. expected=%s, got=%s", i, fmt.Sprintf("value%d", i), string(e.Data))
   344  			}
   345  		}
   346  	}
   347  }
   348  
   349  func TestSeek(t *testing.T) {
   350  	ctx, s := newTestStagingManager(t)
   351  	numOfValues := 100
   352  	for i := 0; i < numOfValues; i++ {
   353  		err := s.Set(ctx, "t1", []byte(fmt.Sprintf("key%04d", i)), newTestValue("identity1", "value1"), false)
   354  		testutil.Must(t, err)
   355  	}
   356  	it := s.List(ctx, "t1", 0)
   357  	defer it.Close()
   358  	if it.SeekGE([]byte("key0050")); !it.Next() {
   359  		t.Fatal("iterator seek expected to return true, got false")
   360  	}
   361  	expected := "key0050"
   362  	if !bytes.Equal(it.Value().Key, []byte("key0050")) {
   363  		t.Fatalf("got unexpected key after iterator seek. expected=%s, got=%s", expected, string(it.Value().Key))
   364  	}
   365  	if !it.Next() {
   366  		t.Fatal("iterator next expected to return true, got false")
   367  	}
   368  	expected = "key0051"
   369  	if !bytes.Equal(it.Value().Key, []byte(expected)) {
   370  		t.Fatalf("got unexpected key after iterator seek. expected=%s, got=%s", expected, string(it.Value().Key))
   371  	}
   372  	if it.SeekGE([]byte("key1000")); it.Next() {
   373  		t.Fatal("iterator seek expected to return false, got true")
   374  	}
   375  	if it.SeekGE([]byte("key0060a")); !it.Next() {
   376  		t.Fatal("iterator seek expected to return true, got false")
   377  	}
   378  	expected = "key0061"
   379  	if !bytes.Equal(it.Value().Key, []byte(expected)) {
   380  		t.Fatalf("got unexpected key after iterator seek. expected=%s, got=%s", expected, string(it.Value().Key))
   381  	}
   382  	if !it.Next() {
   383  		t.Fatal("iterator next expected to return true, got false")
   384  	}
   385  }
   386  
   387  func TestNilValue(t *testing.T) {
   388  	ctx, s := newTestStagingManager(t)
   389  	err := s.Set(ctx, "t1", []byte("key1"), nil, false)
   390  	testutil.Must(t, err)
   391  	err = s.Set(ctx, "t1", []byte("key2"), newTestValue("identity2", "value2"), false)
   392  	testutil.Must(t, err)
   393  	e, err := s.Get(ctx, "t1", []byte("key1"))
   394  	testutil.Must(t, err)
   395  	if e != nil {
   396  		t.Errorf("got unexpected value. expected=nil, got=%s", e)
   397  	}
   398  	it := s.List(ctx, "t1", 0)
   399  	testutil.Must(t, err)
   400  	defer it.Close()
   401  	if !it.Next() {
   402  		t.Fatalf("expected to get key from list")
   403  	}
   404  
   405  	expected := "key1"
   406  	if !bytes.Equal(it.Value().Key, []byte(expected)) {
   407  		t.Errorf("got unexpected key. expected=key1, got=%s", it.Value().Key)
   408  	}
   409  	if it.Value().Value != nil {
   410  		t.Errorf("got unexpected value. expected=nil, got=%s", it.Value().Value)
   411  	}
   412  
   413  	if !it.Next() {
   414  		t.Fatalf("expected to get key from list")
   415  	}
   416  	e = it.Value().Value
   417  	if string(e.Identity) != "identity2" {
   418  		t.Errorf("got wrong identity. expected=%s, got=%s", "identity2", string(e.Identity))
   419  	}
   420  }
   421  
   422  func TestNilIdentity(t *testing.T) {
   423  	ctx, s := newTestStagingManager(t)
   424  	err := s.Set(ctx, "t1", []byte("key1"), newTestValue("identity1", "value1"), false)
   425  	testutil.Must(t, err)
   426  	err = s.Set(ctx, "t1", []byte("key1"), &graveler.Value{
   427  		Identity: nil,
   428  		Data:     []byte("value1"),
   429  	}, false)
   430  	if !errors.Is(err, graveler.ErrInvalidValue) {
   431  		t.Fatalf("got unexpected error. expected=%v, got=%v", graveler.ErrInvalidValue, err)
   432  	}
   433  	e, err := s.Get(ctx, "t1", []byte("key1"))
   434  	testutil.Must(t, err)
   435  	if string(e.Identity) != "identity1" {
   436  		t.Errorf("got wrong identity. expected=%s, got=%s", "identity1", string(e.Identity))
   437  	}
   438  }
   439  
   440  func TestDeleteAndTombstone(t *testing.T) {
   441  	ctx, s := newTestStagingManager(t)
   442  	_, err := s.Get(ctx, "t1", []byte("key1"))
   443  	if !errors.Is(err, graveler.ErrNotFound) {
   444  		t.Fatalf("error different than expected. expected=%v, got=%v", graveler.ErrNotFound, err)
   445  	}
   446  	tombstoneValues := []*graveler.Value{
   447  		{
   448  			Identity: []byte("identity1"),
   449  			Data:     make([]byte, 0),
   450  		},
   451  		{
   452  			Identity: []byte("identity1"),
   453  			Data:     nil,
   454  		},
   455  	}
   456  	for _, val := range tombstoneValues {
   457  		err = s.Set(ctx, "t1", []byte("key1"), val, false)
   458  		testutil.Must(t, err)
   459  		e, err := s.Get(ctx, "t1", []byte("key1"))
   460  		testutil.Must(t, err)
   461  		if len(e.Data) != 0 {
   462  			t.Fatalf("expected empty data, got: %v", e.Data)
   463  		}
   464  		if string(e.Identity) != "identity1" {
   465  			t.Fatalf("got unexpected value identity. expected=%s, got=%s", "identity1", string(e.Identity))
   466  		}
   467  		it := s.List(ctx, "t1", 0)
   468  		testutil.Must(t, err)
   469  		if !it.Next() {
   470  			t.Fatalf("expected to get key from list")
   471  		}
   472  		if it.Err() != nil {
   473  			t.Fatalf("unexpected error from iterator: %v", it.Err())
   474  		}
   475  		if len(it.Value().Value.Data) != 0 {
   476  			t.Fatalf("expected empty value data from iterator, got: %v", it.Value().Value.Data)
   477  		}
   478  		it.Close()
   479  	}
   480  	err = s.Set(ctx, "t1", []byte("key1"), newTestValue("identity3", "value3"), false)
   481  	testutil.Must(t, err)
   482  	e, err := s.Get(ctx, "t1", []byte("key1"))
   483  	testutil.Must(t, err)
   484  	if string(e.Identity) != "identity3" {
   485  		t.Fatalf("got unexpected value identity. expected=%s, got=%s", "identity3", string(e.Identity))
   486  	}
   487  	err = s.DropKey(ctx, "t1", []byte("key1"))
   488  	testutil.Must(t, err)
   489  	_, err = s.Get(ctx, "t1", []byte("key1"))
   490  	if !errors.Is(err, graveler.ErrNotFound) {
   491  		t.Fatalf("error different than expected. expected=%v, got=%v", graveler.ErrNotFound, err)
   492  	}
   493  }
   494  
   495  func newTestValue(identity, data string) *graveler.Value {
   496  	return &graveler.Value{
   497  		Identity: []byte(identity),
   498  		Data:     []byte(data),
   499  	}
   500  }