| 1 | //go:build windows |
| 2 | |
| 3 | package main |
| 4 | |
| 5 | import ( |
| 6 | "os" |
| 7 | "os/exec" |
| 8 | "path/filepath" |
| 9 | "testing" |
| 10 | ) |
| 11 | |
| 12 | func TestNativeJunctionUsesTargetIdentity(t *testing.T) { |
| 13 | dir := t.TempDir() |
| 14 | target := filepath.Join(dir, "target") |
| 15 | alias := filepath.Join(dir, "alias") |
| 16 | if err := os.Mkdir(target, 0o700); err != nil { |
| 17 | t.Fatal(err) |
| 18 | } |
| 19 | if out, err := exec.Command("cmd", "/c", "mklink", "/J", alias, target).CombinedOutput(); err != nil { |
| 20 | t.Fatalf("create junction fixture: %v: %s", err, out) |
| 21 | } |
| 22 | left, right := nativePath(alias), nativePath(target) |
| 23 | if !left.OK || !right.OK || left.FileID == "" || left.Volume == "" || |
| 24 | left.FileID != right.FileID || left.Volume != right.Volume || left.Path != right.Path { |
| 25 | t.Fatalf("junction identity mismatch: %+v / %+v", left, right) |
| 26 | } |
| 27 | if err := os.Remove(target); err != nil { |
| 28 | t.Fatal(err) |
| 29 | } |
| 30 | if got := nativePath(alias); got.OK || len(got.Errors) == 0 { |
| 31 | t.Fatalf("broken junction must retain failure: %+v", got) |
| 32 | } |
| 33 | if _, err := os.Lstat(target); !os.IsNotExist(err) { |
| 34 | t.Fatalf("native probe recreated target: %v", err) |
| 35 | } |
| 36 | } |
| 37 | |
| 38 | func TestNormalizeNativePath(t *testing.T) { |
| 39 | for input, want := range map[string]string{ |
| 40 | `\\?\C:\Users\example`: `C:\Users\example`, |
| 41 | `\\?\UNC\server\share`: `\\server\share`, |
| 42 | `\\?\Volume{test}\dir`: `\\?\Volume{test}\dir`, |
| 43 | `C:\normal`: `C:\normal`, |
| 44 | } { |
| 45 | if got := normalizeNativePath(input); got != want { |
| 46 | t.Errorf("normalize %q = %q, want %q", input, got, want) |
| 47 | } |
| 48 | } |
| 49 | } |
| 50 |