func TestPartWriter(t *testing.T) { t.Parallel() test := func(start, length, partSize uint64) { cz := &types.CacheZone{ ID: "TestCZ", Storage: mock.NewStorage(partSize), Algorithm: mock.NewCacheAlgorithm(&mock.CacheAlgorithmRepliers{ ShouldKeep: func(*types.ObjectIndex) bool { return true }, }), } if err := cz.Storage.SaveMetadata(oMeta); err != nil { t.Fatalf("Unexpected error: %s", err) } write(t, start, length, cz, oid) checkParts(t, start, length, cz, oid) } // Test all variants for partSize := uint64(1); partSize <= inputSize+3; partSize++ { for start := uint64(0); start < inputSize; start++ { for length := uint64(1); length+start <= inputSize; length++ { test(start, length, partSize) } } } }
func TestAlgorithmCompliance(t *testing.T) { t.Parallel() partSize := uint64(5) totalParts := inputSize/partSize + 1 state := make([]struct{ added, promoted bool }, totalParts) expectedParts := make([]bool, totalParts) algo := mock.NewCacheAlgorithm(&mock.CacheAlgorithmRepliers{ AddObject: func(idx *types.ObjectIndex) error { state[idx.Part].added = true return nil }, PromoteObject: func(idx *types.ObjectIndex) { state[idx.Part].promoted = true }, }) for i := uint64(0); i < totalParts; i++ { if rand.Intn(2) == 1 { expectedParts[i] = true algo.SetFakeReplies(&types.ObjectIndex{ObjID: oid, Part: uint32(i)}, &mock.CacheAlgorithmRepliers{ ShouldKeep: func(*types.ObjectIndex) bool { return true }, }) } } cz := &types.CacheZone{ID: "TestCZ", Storage: mock.NewStorage(partSize), Algorithm: algo} if err := cz.Storage.SaveMetadata(oMeta); err != nil { t.Fatalf("Unexpected error: %s", err) } write(t, 0, inputSize, cz, oid) for i := uint64(0); i < totalParts; i++ { idx := &types.ObjectIndex{ObjID: oid, Part: uint32(i)} if expectedParts[i] { expected := input[partSize*i : umin(inputSize, (i+1)*partSize)] checkPart(t, fmt.Sprintf("part %d", i), expected, cz.Storage, idx) if !state[i].added || state[i].promoted { t.Errorf("Wrong cache state for part %d: %v", i, state[i]) } } else { checkPartIsMissing(t, fmt.Sprintf("part %d", i), cz.Storage, idx) if state[i].added || state[i].promoted { t.Errorf("Wrong cache state for expected missing part %d: %v", i, state[i]) } } } }
func testSetupWithStorage(t *testing.T, st types.Storage) (context.Context, *Handler, *types.Location) { var cz = &types.CacheZone{ ID: "testZoen", Algorithm: mock.NewCacheAlgorithm(&mock.CacheAlgorithmRepliers{ Remove: removeFunctionMock(t), }), Storage: st, } loc1 := &types.Location{ Logger: mock.NewLogger(), Cache: cz, CacheKey: cacheKey1, Name: "location1", } loc2 := &types.Location{ Logger: mock.NewLogger(), Cache: cz, CacheKey: cacheKey2, Name: "location2", } app := &mockApp{ getLocationFor: func(host, path string) *types.Location { if host == host1 { return loc1 } if host == host2 { return loc2 } return nil }, } loc3 := &types.Location{ Logger: mock.NewLogger(), } ctx := contexts.NewAppContext(context.Background(), app) purger, err := New(&config.Handler{}, loc3, nil) if err != nil { t.Fatal(err) } return ctx, purger, loc3 }