| 1 | //go:build windows |
| 2 | |
| 3 | package fileutil |
| 4 | |
| 5 | import ( |
| 6 | "os" |
| 7 | "testing" |
| 8 | |
| 9 | "golang.org/x/sys/windows" |
| 10 | ) |
| 11 | |
| 12 | func TestRenameCrossesDeviceClassifiesFilterDriverError(t *testing.T) { |
| 13 | // The filter-driver failure (#2696) surfaces as ERROR_NOT_SAME_DEVICE |
| 14 | // wrapped in a LinkError; it must route to the copy fallback. A sharing |
| 15 | // violation is transient and must not — copying there truncates dest under |
| 16 | // a concurrent reader. |
| 17 | notSameDevice := &os.LinkError{Op: "rename", Old: "a", New: "b", Err: windows.ERROR_NOT_SAME_DEVICE} |
| 18 | if !renameCrossesDevice(notSameDevice) { |
| 19 | t.Fatal("ERROR_NOT_SAME_DEVICE must be classified as cross-device") |
| 20 | } |
| 21 | sharing := &os.LinkError{Op: "rename", Old: "a", New: "b", Err: windows.ERROR_SHARING_VIOLATION} |
| 22 | if renameCrossesDevice(sharing) { |
| 23 | t.Fatal("a sharing violation is transient and must not take the non-atomic copy fallback") |
| 24 | } |
| 25 | accessDenied := &os.LinkError{Op: "rename", Old: "a", New: "b", Err: windows.ERROR_ACCESS_DENIED} |
| 26 | if renameCrossesDevice(accessDenied) { |
| 27 | t.Fatal("access denied is transient (AV/indexer) and must not take the non-atomic copy fallback") |
| 28 | } |
| 29 | } |
| 30 |