github.com/treeverse/lakefs@v1.24.1-0.20240520134607-95648127bfb0/pkg/kv/store_test.go (about)

     1  package kv_test
     2  
     3  import (
     4  	"context"
     5  	"errors"
     6  	"sort"
     7  	"testing"
     8  
     9  	"github.com/go-test/deep"
    10  	"github.com/treeverse/lakefs/pkg/kv"
    11  	"github.com/treeverse/lakefs/pkg/kv/kvparams"
    12  )
    13  
    14  type MockDriver struct {
    15  	Name string
    16  	Err  error
    17  }
    18  
    19  type MockStore struct {
    20  	Driver string
    21  	Params kvparams.Config
    22  }
    23  
    24  var errNotImplemented = errors.New("not implemented")
    25  
    26  func (m *MockStore) Get(_ context.Context, _, _ []byte) (*kv.ValueWithPredicate, error) {
    27  	return nil, errNotImplemented
    28  }
    29  
    30  func (m *MockStore) Set(_ context.Context, _, _, _ []byte) error {
    31  	return errNotImplemented
    32  }
    33  
    34  func (m *MockStore) SetIf(_ context.Context, _, _, _ []byte, _ kv.Predicate) error {
    35  	return errNotImplemented
    36  }
    37  
    38  func (m *MockStore) Delete(_ context.Context, _, _ []byte) error {
    39  	return errNotImplemented
    40  }
    41  
    42  func (m *MockStore) Scan(_ context.Context, _ []byte, _ kv.ScanOptions) (kv.EntriesIterator, error) {
    43  	return nil, errNotImplemented
    44  }
    45  
    46  func (m *MockStore) Close() {}
    47  
    48  func (m *MockDriver) Open(_ context.Context, params kvparams.Config) (kv.Store, error) {
    49  	if m.Err != nil {
    50  		return nil, m.Err
    51  	}
    52  	return &MockStore{
    53  		Driver: m.Name,
    54  		Params: params,
    55  	}, nil
    56  }
    57  
    58  func TestRegister(t *testing.T) {
    59  	t.Parallel()
    60  	ctx := context.Background()
    61  
    62  	t.Run("open", func(t *testing.T) {
    63  		md := &MockDriver{Name: "md"}
    64  		kv.Register("md", md)
    65  		// open registered 'md'
    66  		params := kvparams.Config{Type: "md", Postgres: &kvparams.Postgres{ConnectionString: "dsn1"}}
    67  		s1, err := kv.Open(ctx, params)
    68  		if err != nil {
    69  			t.Fatal("expected Store 'md'", err)
    70  		}
    71  		store1, ok := s1.(*kv.StoreMetricsWrapper)
    72  		if !ok {
    73  			t.Fatal("expected StoreMetricsWrapper")
    74  		}
    75  		if store, ok := store1.Store.(*MockStore); !ok {
    76  			t.Fatal("expected mock Store")
    77  		} else if store.Driver != "md" {
    78  			t.Fatal("expected Store from 'md' driver")
    79  		} else if store.Params.Postgres.ConnectionString != params.Postgres.ConnectionString {
    80  			t.Fatalf("Store open with dsn '%s', expected 'dsn1'", store.Params.Postgres.ConnectionString)
    81  		}
    82  		// open missing driver
    83  		params2 := kvparams.Config{Type: "missing", Postgres: &kvparams.Postgres{ConnectionString: "dsn2"}}
    84  		_, err = kv.Open(ctx, params2)
    85  		if !errors.Is(err, kv.ErrUnknownDriver) {
    86  			t.Fatalf("Open unknown driver err=%v, expected=%s", err, kv.ErrUnknownDriver)
    87  		}
    88  	})
    89  
    90  	t.Run("no_driver", func(t *testing.T) {
    91  		defer func() {
    92  			if r := recover(); r == nil {
    93  				t.Errorf("expected to panic on nil dirver")
    94  			}
    95  		}()
    96  		kv.Register("nil", nil)
    97  	})
    98  
    99  	t.Run("no_name", func(t *testing.T) {
   100  		defer func() {
   101  			if r := recover(); r == nil {
   102  				t.Errorf("expected to panic on no name")
   103  			}
   104  		}()
   105  		kv.Register("", &MockDriver{Name: "empty"})
   106  	})
   107  }
   108  
   109  func TestDrivers(t *testing.T) {
   110  	kv.UnregisterAllDrivers()
   111  	kv.Register("driver1", &MockDriver{Name: "driver1"})
   112  	kv.Register("driver2", &MockDriver{Name: "driver2"})
   113  	all := kv.Drivers()
   114  	sort.Strings(all)
   115  	expectedDrivers := []string{"driver1", "driver2"}
   116  	if diff := deep.Equal(all, expectedDrivers); diff != nil {
   117  		t.Fatalf("Drivers diff = %s", diff)
   118  	}
   119  }