Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion pkg/cache/cache_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,11 @@ func TestFileCache_concurrentStoreNeverYieldsTornFile(t *testing.T) {
// half-written content and json.Unmarshal would error.
for range 100 {
data, err := os.ReadFile(path)
if errors.Is(err, os.ErrNotExist) {
// Tolerate transient open failures caused by the writer itself:
// the file may not exist yet, and on Windows the open can race a
// rename replacing it. Only successfully read bytes are asserted
// on — the torn-write check is about content, not availability.
if errors.Is(err, os.ErrNotExist) || isTransientSharingViolation(err) {
continue
}
require.NoError(t, err)
Expand Down
10 changes: 10 additions & 0 deletions pkg/cache/sharing_violation_other_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
//go:build !windows

package cache

// isTransientSharingViolation only exists on Windows, where opening a file
// can transiently fail while a concurrent rename replaces it. POSIX renames
// never make the destination unopenable.
func isTransientSharingViolation(error) bool {
return false
}
18 changes: 18 additions & 0 deletions pkg/cache/sharing_violation_windows_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//go:build windows

package cache

import (
"errors"

"golang.org/x/sys/windows"
)

// isTransientSharingViolation reports whether a file open failed because a
// concurrent rename-over-existing briefly held the destination. During
// MoveFileEx(MOVEFILE_REPLACE_EXISTING) the target can be transiently
// unopenable, so a reader racing Store's temp-file+rename publish sees
// ERROR_SHARING_VIOLATION; that is not a torn write.
func isTransientSharingViolation(err error) bool {
return errors.Is(err, windows.ERROR_SHARING_VIOLATION)
}
Loading