mirror of
https://github.com/seaweedfs/seaweedfs.git
synced 2026-08-22 07:06:51 +00:00
test(filer.sync): cover the in-place update delete-then-create fallback order
The recording sinks always reported foundExisting, so the fallback that an in-place update takes when the entry is missing on the sink was never run. Make it configurable and assert the fallback deletes before it recreates the same key, in both the replicator and the filer.sync drivers.
This commit is contained in:
@@ -15,6 +15,9 @@ type recordingSyncSink struct {
|
||||
deleteKeys []string
|
||||
createKeys []string
|
||||
updateKeys []string
|
||||
// updateFoundExisting is what UpdateEntry reports; false exercises the
|
||||
// delete-then-create fallback for an in-place update missing on the sink.
|
||||
updateFoundExisting bool
|
||||
// ordered records the sink method names in call order so tests can assert
|
||||
// create-before-delete sequencing.
|
||||
ordered []string
|
||||
@@ -37,7 +40,7 @@ func (s *recordingSyncSink) CreateEntry(key string, entry *filer_pb.Entry, signa
|
||||
func (s *recordingSyncSink) UpdateEntry(key string, oldEntry *filer_pb.Entry, newParentPath string, newEntry *filer_pb.Entry, deleteIncludeChunks bool, signatures []int32) (bool, error) {
|
||||
s.updateKeys = append(s.updateKeys, key)
|
||||
s.ordered = append(s.ordered, "update")
|
||||
return true, nil
|
||||
return s.updateFoundExisting, nil
|
||||
}
|
||||
|
||||
func equalSyncStrings(a, b []string) bool {
|
||||
@@ -125,7 +128,7 @@ func TestGenProcessFunctionRenameCreatesThenDeletes(t *testing.T) {
|
||||
// An in-place update (same dir + same name) must route to UpdateEntry, never the
|
||||
// rename create-then-delete path — otherwise it would delete the key it just wrote.
|
||||
func TestGenProcessFunctionInPlaceUpdateUsesUpdateEntry(t *testing.T) {
|
||||
dataSink := &recordingSyncSink{}
|
||||
dataSink := &recordingSyncSink{updateFoundExisting: true}
|
||||
processFn := genProcessFunction("/foo", "/dest", nil, nil, nil, nil, dataSink, true, false)
|
||||
|
||||
err := processFn(&filer_pb.SubscribeMetadataResponse{
|
||||
@@ -148,6 +151,34 @@ func TestGenProcessFunctionInPlaceUpdateUsesUpdateEntry(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// When an in-place update finds no existing entry on the sink, it falls back to
|
||||
// delete-then-create on the same key — and must delete before create, or the
|
||||
// recreated entry would be removed.
|
||||
func TestGenProcessFunctionInPlaceUpdateFallbackDeletesBeforeCreate(t *testing.T) {
|
||||
dataSink := &recordingSyncSink{updateFoundExisting: false}
|
||||
processFn := genProcessFunction("/foo", "/dest", nil, nil, nil, nil, dataSink, true, false)
|
||||
|
||||
err := processFn(&filer_pb.SubscribeMetadataResponse{
|
||||
Directory: "/foo/dir",
|
||||
EventNotification: &filer_pb.EventNotification{
|
||||
OldEntry: &filer_pb.Entry{Name: "file.txt"},
|
||||
NewEntry: &filer_pb.Entry{Name: "file.txt"},
|
||||
NewParentPath: "/foo/dir",
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("processFn in-place update fallback: %v", err)
|
||||
}
|
||||
|
||||
if got, want := dataSink.ordered, []string{"update", "delete", "create"}; !equalSyncStrings(got, want) {
|
||||
t.Fatalf("call order = %v, want %v", got, want)
|
||||
}
|
||||
if len(dataSink.deleteKeys) != 1 || dataSink.deleteKeys[0] != "/dest/dir/file.txt" ||
|
||||
len(dataSink.createKeys) != 1 || dataSink.createKeys[0] != "/dest/dir/file.txt" {
|
||||
t.Fatalf("fallback keys: deletes=%v creates=%v, want both [/dest/dir/file.txt]", dataSink.deleteKeys, dataSink.createKeys)
|
||||
}
|
||||
}
|
||||
|
||||
// With deletes disabled (e.g. incremental backup), a rename creates the new
|
||||
// entry only — the old key is left in place.
|
||||
func TestGenProcessFunctionRenameCreateOnlyWhenDeletesDisabled(t *testing.T) {
|
||||
|
||||
@@ -251,6 +251,9 @@ func TestReplicateInPlaceUpdateFallbackCreates(t *testing.T) {
|
||||
if len(s.createCalls) != 1 || s.createCalls[0].key != "/dest/dir/file.txt" {
|
||||
t.Fatalf("create calls = %+v, want same sink key", s.createCalls)
|
||||
}
|
||||
if got, want := s.ordered, []string{"update", "delete", "create"}; !equalStrings(got, want) {
|
||||
t.Fatalf("call order = %v, want %v", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
func equalStrings(a, b []string) bool {
|
||||
|
||||
Reference in New Issue
Block a user