func TestMultiDuplicateContent(t *testing.T) { _, multi, _, done := prepareMultiTest(t, 1, 1, 1) defer done() data := []byte("this is some test data") for i := 0; i < 10; i++ { storetests.ShouldCAS(t, multi, strconv.FormatInt(int64(i), 10), store.MissingV, store.DataV(data)) } for i := 0; i < 10; i++ { storetests.ShouldGet(t, multi, strconv.FormatInt(int64(i), 10), data) } for i := 0; i < 5; i++ { storetests.ShouldCAS(t, multi, strconv.FormatInt(int64(i), 10), store.AnyV, store.MissingV) } for i := 5; i < 10; i++ { storetests.ShouldGet(t, multi, strconv.FormatInt(int64(i), 10), data) } }
func TestCacheGCWorks(t *testing.T) { inner := &CountingStore{MockStore: storetests.NewMockStore(0)} cache := New(1024, inner) for i := 0; i < 1024; i++ { key := strconv.FormatInt(int64(i), 10) storetests.ShouldCAS(t, cache, key, store.AnyV, store.DataV([]byte(key))) } cache.assertUsedIsCorrect() t.Logf("cache.used after writes is %v", cache.used) for i := 0; i < 1024; i++ { key := strconv.FormatInt(int64(i), 10) storetests.ShouldGet(t, cache, key, []byte(key)) } cache.assertUsedIsCorrect() t.Logf("cache.used after first reads is %v", cache.used) getsBefore := inner.gets for i := 0; i < 1024; i++ { key := strconv.FormatInt(int64(i), 10) storetests.ShouldGet(t, cache, key, []byte(key)) } cache.assertUsedIsCorrect() t.Logf("cache.used after second reads is %v", cache.used) getsAfter := inner.gets if getsAfter != getsBefore+1024 { t.Errorf("wanted %v gets after, got %v", getsBefore+1024, getsAfter) } }
func TestResplit(t *testing.T) { ds, tmpDir := makeTestingDirectory(t) defer os.RemoveAll(tmpDir) defer ds.Close() ds.mu.Lock() ds.minSplitSize = 2 ds.maxSplitSize = 8 ds.mu.Unlock() const itemCount = 50 for i := 0; i < itemCount; i++ { key := strconv.FormatInt(int64(i), 3) storetests.ShouldCAS(t, ds, key, store.AnyV, store.DataV([]byte(key))) ds.resplit() for j := 0; j < itemCount; j++ { key := strconv.FormatInt(int64(j), 3) if j <= i { storetests.ShouldGet(t, ds, key, []byte(key)) } else { storetests.ShouldGetMiss(t, ds, key) } } checkSplitCountSizes(t, "insertion", tmpDir, 2, 8) } for i := 0; i < itemCount; i++ { key := strconv.FormatInt(int64(i), 3) storetests.ShouldCAS(t, ds, key, store.AnyV, store.MissingV) ds.resplit() for j := 0; j < itemCount; j++ { key := strconv.FormatInt(int64(j), 3) if j <= i { storetests.ShouldGetMiss(t, ds, key) } else { storetests.ShouldGet(t, ds, key, []byte(key)) } } checkSplitCountSizes(t, "deletion", tmpDir, 2, 8) } }
func TestMultiScrubChangeRedundancy(t *testing.T) { killers, multi, _, done := prepareMultiTest(t, 2, 3, 5) defer done() data := []byte("who knows where the wind goes") for i := 0; i < 10; i++ { storetests.ShouldCAS(t, multi, strconv.FormatInt(int64(i), 10), store.MissingV, store.DataV(data)) } err := multi.SetRedundancy(2, 5) if err != nil { t.Fatalf("Couldn't adjust redundancy: %v", err) } multi.scrubAll() killers[0].setKilled(true) killers[1].setKilled(true) killers[2].setKilled(true) for i := 0; i < 10; i++ { storetests.ShouldGet(t, multi, strconv.FormatInt(int64(i), 10), data) } }
func TestCacheUpdatesOnUnknownChanges(t *testing.T) { inner := &CountingStore{MockStore: storetests.NewMockStore(0)} cache := New(1024, inner) storetests.ShouldCAS(t, cache, "asdf", store.AnyV, store.DataV([]byte("hello"))) cache.Clear() storetests.ShouldGet(t, cache, "asdf", []byte("hello")) storetests.ShouldCAS(t, inner, "asdf", store.AnyV, store.DataV([]byte("world"))) storetests.ShouldGet(t, cache, "asdf", []byte("world")) if inner.gets != 2 { t.Errorf("wanted 2 inner gets, got %v", inner.gets) } if inner.stats != 1 { t.Errorf("wanted 1 inner Stats, got %v", inner.stats) } cache.assertUsedIsCorrect() }
func TestCacheUpdatesOnStats(t *testing.T) { inner := &CountingStore{MockStore: storetests.NewMockStore(0)} cache := New(1024, inner) storetests.ShouldCAS(t, cache, "asdf", store.AnyV, store.DataV([]byte("hello"))) storetests.ShouldGet(t, cache, "asdf", []byte("hello")) newData := store.DataV([]byte("world")) storetests.ShouldCAS(t, inner, "asdf", store.AnyV, newData) storetests.ShouldStatNoTime(t, cache, "asdf", store.Stat{Size: 5, SHA256: newData.SHA256}) storetests.ShouldGet(t, cache, "asdf", []byte("world")) if inner.gets != 1 { t.Errorf("wanted 1 inner gets, got %v", inner.gets) } if inner.stats != 2 { t.Errorf("wanted 2 inner Stats, got %v", inner.stats) } cache.assertUsedIsCorrect() }
func TestCacheDoesntCacheErrors(t *testing.T) { inner := &ErrorStore{MockStore: storetests.NewMockStore(0)} cache := New(1024, inner) storetests.ShouldCAS(t, cache, "asdf", store.AnyV, store.DataV([]byte("hello"))) cache.Clear() inner.isErroring = true for i := 0; i < 10; i++ { storetests.ShouldGetError(t, cache, "asdf", ErrErrorStore) } cache.assertUsedIsCorrect() inner.isErroring = false storetests.ShouldGet(t, cache, "asdf", []byte("hello")) cache.assertUsedIsCorrect() }
func TestCacheCachesGets(t *testing.T) { inner := &CountingStore{MockStore: storetests.NewMockStore(0)} cache := New(1024, inner) storetests.ShouldCAS(t, inner, "asdf", store.AnyV, store.DataV([]byte("hello"))) cache.assertUsedIsCorrect() for i := 0; i < 10; i++ { storetests.ShouldGet(t, cache, "asdf", []byte("hello")) cache.assertUsedIsCorrect() } if inner.gets != 1 { t.Errorf("wanted 1 inner Get, got %v", inner.gets) } if inner.stats != 9 { t.Errorf("wanted 9 inner Stats, got %v", inner.stats) } cache.assertUsedIsCorrect() }
func TestMultiRecovery(t *testing.T) { for total := 4; total < 6; total++ { killers, multi, _, done := prepareMultiTest(t, 3, total, 6) defer done() for i := 0; i < 20; i++ { key := strconv.FormatInt(int64(i), 10) var value []byte for j := 0; j < i; j++ { value = append(value, []byte(key)...) } storetests.ShouldCAS(t, multi, key, store.MissingV, store.DataV(value)) } for i := 0; i < total-3; i++ { for { k := killers[rand.Intn(len(killers))] if k.isKilled() { continue } k.setKilled(true) break } } for i := 0; i < 20; i++ { key := strconv.FormatInt(int64(i), 10) var value []byte for j := 0; j < i; j++ { value = append(value, []byte(key)...) } storetests.ShouldGet(t, multi, key, value) } } }