From ed60580730402b75053e6d23e313f6653302fd50 Mon Sep 17 00:00:00 2001 From: Nick Craig-Wood Date: Fri, 17 Jul 2026 08:50:17 +0100 Subject: [PATCH] sync: fix tests failing on backends that drop hashes on server side copy ownCloud does not carry the checksum over to the destination of a server side copy and refuses attempts to set it afterwards, so the destination legitimately has no hash. The logger vs lsf check compared the predicted hash against the empty hash and failed. Treat an empty hash in the listing as unknown rather than wrong, matching how sync itself compares hashes. --- fs/sync/sync_test.go | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/fs/sync/sync_test.go b/fs/sync/sync_test.go index de00e1544..dbdfd6ec7 100644 --- a/fs/sync/sync_test.go +++ b/fs/sync/sync_test.go @@ -3101,7 +3101,36 @@ func testLoggerVsLsf(ctx context.Context, fdst, fsrc fs.Fs, logger *bytes.Buffer if fsrc.Precision() == fdst.Precision() && fsrc.Hashes().Contains(hash.MD5) && canTestHash { lsf := DstLsf(ctx, fdst) + blankMissingHashes(&newlogger, lsf) err := LoggerMatchesLsf(&newlogger, lsf) require.NoError(t, err) } } + +// blankMissingHashes clears the hash in logger lines for paths where +// the lsf listing has an empty hash. An empty hash from a backend +// means the hash is unknown, not wrong - for example ownCloud does +// not carry the checksum over on a server-side copy - so it should +// not be compared against the hash the logger predicted. +func blankMissingHashes(logger, lsf *bytes.Buffer) { + noHash := map[string]bool{} + for _, line := range bytes.Split(lsf.Bytes(), []byte("\n")) { + elements := bytes.SplitN(line, []byte(";"), 4) + if len(elements) == 4 && len(elements[1]) == 0 { + noHash[string(elements[3])] = true + } + } + if len(noHash) == 0 { + return + } + loggerSplit := bytes.Split(logger.Bytes(), []byte("\n")) + for i, line := range loggerSplit { + elements := bytes.SplitN(line, []byte(";"), 4) + if len(elements) == 4 && noHash[string(elements[3])] { + elements[1] = nil + loggerSplit[i] = bytes.Join(elements, []byte(";")) + } + } + logger.Reset() + logger.Write(bytes.Join(loggerSplit, []byte("\n"))) +}