Skip to content
This repository has been archived by the owner on Apr 5, 2023. It is now read-only.

Commit

Permalink
Merge pull request #126 from DRK3/FixGetBulkWithNilArgumentErrorHandling
Browse files Browse the repository at this point in the history
fix: Incorrect error handling when GetBulk argument is nil
  • Loading branch information
Derek Trider authored Dec 4, 2020
2 parents 901584a + be0275a commit 05009dc
Show file tree
Hide file tree
Showing 6 changed files with 54 additions and 0 deletions.
4 changes: 4 additions & 0 deletions pkg/storage/couchdb/couchdbstore.go
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,10 @@ func (c *CouchDBStore) Get(k string) ([]byte, error) {
// attachments.
// If values are stored as attachments, then there are still optimizations that could be done - see TODO #124.
func (c *CouchDBStore) GetBulk(keys ...string) ([][]byte, error) {
if keys == nil {
return nil, storage.ErrGetBulkKeysStringSliceNil
}

rawDocs, err := c.getRawDocs(keys)
if err != nil {
return nil, fmt.Errorf(getRawDocsFailureErrMsg, err)
Expand Down
24 changes: 24 additions & 0 deletions pkg/storage/couchdb/couchdbstore_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -914,6 +914,7 @@ func TestCouchDBStore_GetBulk(t *testing.T) {
fmt.Errorf(getBulkKeyNotFound, testDocKey2, storage.ErrValueNotFound)).Error())
require.Nil(t, values)
})

t.Run("Value (stored as JSON) not found after being deleted", func(t *testing.T) {
provider := initializeTest(t)

Expand Down Expand Up @@ -1028,6 +1029,29 @@ func TestCouchDBStore_GetBulk(t *testing.T) {
fmt.Errorf(failureWhileReadingAttachmentContent, errFailingReadAll))).Error())
require.Nil(t, values)
})
t.Run("Failure: nil argument", func(t *testing.T) {
provider := initializeTest(t)

store := createAndOpenTestStore(t, provider)

err := store.Put(testDocKey1, []byte(testJSONValue1))
require.NoError(t, err)

values, err := store.GetBulk(nil...)
require.EqualError(t, err, storage.ErrGetBulkKeysStringSliceNil.Error())
require.Nil(t, values)
})
t.Run("Value not found, bulk get called with only one key", func(t *testing.T) {
provider := initializeTest(t)

store := createAndOpenTestStore(t, provider)

values, err := store.GetBulk(testDocKey1)
require.EqualError(t, err,
fmt.Errorf(failureWhileGettingStoredValuesFromRawDocs,
fmt.Errorf(getBulkKeyNotFound, testDocKey1, storage.ErrValueNotFound)).Error())
require.Nil(t, values)
})
}

func TestCouchDBStore_GetAll(t *testing.T) {
Expand Down
4 changes: 4 additions & 0 deletions pkg/storage/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,7 @@ var ErrNilValues = errors.New("values slice cannot be nil")
// ErrKeysAndValuesDifferentLengths is returned when an attempt is made to call the PutBulk method with
// differently sized keys and values arrays.
var ErrKeysAndValuesDifferentLengths = errors.New("keys and values must be the same length")

// ErrGetBulkKeysStringSliceNil is returned when an attempt is made to call the GetBulk method with a nil slice of
// strings.
var ErrGetBulkKeysStringSliceNil = errors.New("keys string slice cannot be nil")
4 changes: 4 additions & 0 deletions pkg/storage/memstore/memstore.go
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,10 @@ func (m *MemStore) Get(k string) ([]byte, error) {
// GetBulk fetches the values associated with the given keys. This method works in an all-or-nothing manner.
// It returns an error if any of the keys don't exist. If even one key is missing, then no values are returned.
func (m *MemStore) GetBulk(keys ...string) ([][]byte, error) {
if keys == nil {
return nil, storage.ErrGetBulkKeysStringSliceNil
}

storedValues := make([][]byte, len(keys))

m.mux.RLock()
Expand Down
14 changes: 14 additions & 0 deletions pkg/storage/memstore/memstore_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,20 @@ func TestMemStore_GetBulk(t *testing.T) {
require.EqualError(t, err, fmt.Errorf(getBulkKeyNotFound, "testKey", storage.ErrValueNotFound).Error())
require.Nil(t, values)
})
t.Run("Failure: key not found, called with a single key", func(t *testing.T) {
store := MemStore{db: make(map[string][]byte)}

values, err := store.GetBulk("testKey")
require.EqualError(t, err, fmt.Errorf(getBulkKeyNotFound, "testKey", storage.ErrValueNotFound).Error())
require.Nil(t, values)
})
t.Run("Failure: nil argument", func(t *testing.T) {
store := MemStore{db: make(map[string][]byte)}

values, err := store.GetBulk(nil...)
require.EqualError(t, err, storage.ErrGetBulkKeysStringSliceNil.Error())
require.Nil(t, values)
})
}

func TestMemStore_GetAll(t *testing.T) {
Expand Down
4 changes: 4 additions & 0 deletions pkg/storage/mockstore/mockstore.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,10 @@ func (s *MockStore) Get(k string) ([]byte, error) {
// GetBulk fetches the values associated with the given keys. This method works in an all-or-nothing manner.
// It returns an error if any of the keys don't exist. If even one key is missing, then no values are returned.
func (s *MockStore) GetBulk(keys ...string) ([][]byte, error) {
if keys == nil {
return nil, storage.ErrGetBulkKeysStringSliceNil
}

storedValues := make([][]byte, len(keys))

s.lock.RLock()
Expand Down

0 comments on commit 05009dc

Please sign in to comment.