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.
This commit is contained in:
Nick Craig-Wood
2026-07-17 18:29:39 +01:00
parent 8ac8d1821c
commit ed60580730
+29
View File
@@ -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")))
}