cache: fix a mistake in returning cached error in the index list cache (#9853)

**What this PR does / why we need it**:
I did a mistake in returning a cached error in the code pushed in PR
#9798. Fixing it in the PR with some tests.

**Checklist**
- [x] Tests updated
pull/9850/head
Sandeep Sukhani 2 years ago committed by GitHub
parent 26f36d07f4
commit 7cbfdb5d6d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      pkg/storage/stores/indexshipper/storage/cached_client.go
  2. 122
      pkg/storage/stores/indexshipper/storage/cached_client_test.go

@ -210,7 +210,7 @@ func (c *cachedObjectClient) listUserIndexInTable(ctx context.Context, tableName
tbl.buildCacheWg.Wait() tbl.buildCacheWg.Wait()
if tbl.err != nil { if tbl.err != nil {
return nil, c.err return nil, tbl.err
} }
tbl.mtx.RLock() tbl.mtx.RLock()

@ -143,52 +143,90 @@ func TestCachedObjectClient(t *testing.T) {
func TestCachedObjectClient_errors(t *testing.T) { func TestCachedObjectClient_errors(t *testing.T) {
objectsInStorage := []string{ objectsInStorage := []string{
// table with just common dbs
"table1/db1.gz", "table1/db1.gz",
"table1/db2.gz", "table1/u1/db2.gz",
} }
objectClient := newMockObjectClient(t, objectsInStorage) for _, tc := range []struct {
cachedObjectClient := newCachedObjectClient(objectClient) name string
prefix string
// do the initial listing expectedObjects []client.StorageObject
objects, commonPrefixes, err := cachedObjectClient.List(context.Background(), "", "", false) expectedCommonPrefixes []client.StorageCommonPrefix
require.NoError(t, err) }{
require.Equal(t, 1, objectClient.listCallsCount) {
require.Equal(t, []client.StorageObject{}, objects) name: "list tables",
require.Equal(t, []client.StorageCommonPrefix{"table1"}, commonPrefixes) prefix: "",
expectedObjects: []client.StorageObject{},
// timeout the cache and call List concurrently with objectClient throwing an error expectedCommonPrefixes: []client.StorageCommonPrefix{
// objectClient must receive just one request and all the cachedObjectClient.List calls should get an error "table1",
wg := sync.WaitGroup{} },
cachedObjectClient.tableNamesCacheBuiltAt = time.Now().Add(-(cacheTimeout + time.Second)) },
objectClient.listDelay = time.Millisecond * 100 {
objectClient.errResp = errors.New("fake error") name: "list table1",
for i := 0; i < 5; i++ { prefix: "table1/",
wg.Add(1) expectedObjects: []client.StorageObject{
go func() { {Key: "table1/db1.gz", ModifiedAt: objectsMtime},
defer wg.Done() },
_, _, err := cachedObjectClient.List(context.Background(), "", "", false) expectedCommonPrefixes: []client.StorageCommonPrefix{
require.Error(t, err) "table1/u1",
require.Equal(t, 2, objectClient.listCallsCount) },
}() },
} {
name: "list table1/u1/",
wg.Wait() prefix: "table1/u1/",
expectedObjects: []client.StorageObject{
{Key: "table1/u1/db2.gz", ModifiedAt: objectsMtime},
},
expectedCommonPrefixes: []client.StorageCommonPrefix{},
},
} {
t.Run(tc.name, func(t *testing.T) {
objectClient := newMockObjectClient(t, objectsInStorage)
cachedObjectClient := newCachedObjectClient(objectClient)
// clear the error and call the List concurrently again // do the initial listing
// objectClient must receive just one request and all the calls should not get any error objects, commonPrefixes, err := cachedObjectClient.List(context.Background(), tc.prefix, "", false)
objectClient.errResp = nil
for i := 0; i < 5; i++ {
wg.Add(1)
go func() {
defer wg.Done()
objects, commonPrefixes, err = cachedObjectClient.List(context.Background(), "", "", false)
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, 3, objectClient.listCallsCount) require.Equal(t, tc.expectedObjects, objects)
require.Equal(t, []client.StorageObject{}, objects) require.Equal(t, tc.expectedCommonPrefixes, commonPrefixes)
require.Equal(t, []client.StorageCommonPrefix{"table1"}, commonPrefixes) expectedListCallsCount := objectClient.listCallsCount
}()
// timeout the cache and call List concurrently with objectClient throwing an error
// objectClient must receive just one request and all the cachedObjectClient.List calls should get an error
wg := sync.WaitGroup{}
cachedObjectClient.tableNamesCacheBuiltAt = time.Now().Add(-(cacheTimeout + time.Second))
cachedObjectClient.tables["table1"].cacheBuiltAt = time.Now().Add(-(cacheTimeout + time.Second))
objectClient.listDelay = time.Millisecond * 100
objectClient.errResp = errors.New("fake error")
expectedListCallsCount++
for i := 0; i < 5; i++ {
wg.Add(1)
go func() {
defer wg.Done()
_, _, err := cachedObjectClient.List(context.Background(), tc.prefix, "", false)
require.Error(t, err)
require.Equal(t, expectedListCallsCount, objectClient.listCallsCount)
}()
}
wg.Wait()
// clear the error and call the List concurrently again
// objectClient must receive just one request and all the calls should not get any error
objectClient.errResp = nil
expectedListCallsCount++
for i := 0; i < 5; i++ {
wg.Add(1)
go func() {
defer wg.Done()
objects, commonPrefixes, err = cachedObjectClient.List(context.Background(), tc.prefix, "", false)
require.NoError(t, err)
require.Equal(t, expectedListCallsCount, objectClient.listCallsCount)
require.Equal(t, tc.expectedObjects, objects)
require.Equal(t, tc.expectedCommonPrefixes, commonPrefixes)
}()
}
wg.Wait()
})
} }
wg.Wait()
} }

Loading…
Cancel
Save