Alan Donovan | 6ad27d0 | 2022-12-16 16:31:15 -0500 | [diff] [blame] | 1 | // Copyright 2022 The Go Authors. All rights reserved. |
| 2 | // Use of this source code is governed by a BSD-style |
| 3 | // license that can be found in the LICENSE file. |
| 4 | |
| 5 | package robustio_test |
| 6 | |
| 7 | import ( |
| 8 | "os" |
| 9 | "path/filepath" |
Alan Donovan | 3856a5d | 2023-01-05 16:17:44 -0500 | [diff] [blame] | 10 | "runtime" |
Alan Donovan | 6ad27d0 | 2022-12-16 16:31:15 -0500 | [diff] [blame] | 11 | "testing" |
Robert Findley | ae242ec | 2023-01-19 16:41:08 -0500 | [diff] [blame] | 12 | "time" |
Alan Donovan | 6ad27d0 | 2022-12-16 16:31:15 -0500 | [diff] [blame] | 13 | |
Tim King | 33071fb | 2022-12-30 17:02:30 -0800 | [diff] [blame] | 14 | "golang.org/x/tools/internal/robustio" |
Alan Donovan | 6ad27d0 | 2022-12-16 16:31:15 -0500 | [diff] [blame] | 15 | ) |
| 16 | |
Bryan C. Mills | 5b123a2 | 2023-12-13 15:47:46 -0500 | [diff] [blame] | 17 | func checkOSLink(t *testing.T, err error) { |
| 18 | if err == nil { |
| 19 | return |
| 20 | } |
| 21 | |
| 22 | t.Helper() |
| 23 | switch runtime.GOOS { |
| 24 | case "aix", "darwin", "dragonfly", "freebsd", "illumos", "linux", "netbsd", "openbsd", "solaris": |
| 25 | // Non-mobile OS known to always support os.Symlink and os.Link. |
| 26 | t.Fatal(err) |
| 27 | default: |
| 28 | t.Skipf("skipping due to error on %v: %v", runtime.GOOS, err) |
| 29 | } |
| 30 | } |
| 31 | |
Robert Findley | ae242ec | 2023-01-19 16:41:08 -0500 | [diff] [blame] | 32 | func TestFileInfo(t *testing.T) { |
Alan Donovan | 6ad27d0 | 2022-12-16 16:31:15 -0500 | [diff] [blame] | 33 | // A nonexistent file has no ID. |
| 34 | nonexistent := filepath.Join(t.TempDir(), "nonexistent") |
Robert Findley | ae242ec | 2023-01-19 16:41:08 -0500 | [diff] [blame] | 35 | if _, _, err := robustio.GetFileID(nonexistent); err == nil { |
Alan Donovan | 6ad27d0 | 2022-12-16 16:31:15 -0500 | [diff] [blame] | 36 | t.Fatalf("GetFileID(nonexistent) succeeded unexpectedly") |
| 37 | } |
| 38 | |
| 39 | // A regular file has an ID. |
| 40 | real := filepath.Join(t.TempDir(), "real") |
| 41 | if err := os.WriteFile(real, nil, 0644); err != nil { |
| 42 | t.Fatalf("can't create regular file: %v", err) |
| 43 | } |
Robert Findley | ae242ec | 2023-01-19 16:41:08 -0500 | [diff] [blame] | 44 | realID, realMtime, err := robustio.GetFileID(real) |
Alan Donovan | 6ad27d0 | 2022-12-16 16:31:15 -0500 | [diff] [blame] | 45 | if err != nil { |
| 46 | t.Fatalf("can't get ID of regular file: %v", err) |
| 47 | } |
| 48 | |
Robert Findley | ae242ec | 2023-01-19 16:41:08 -0500 | [diff] [blame] | 49 | // Sleep so that we get a new mtime for subsequent writes. |
| 50 | time.Sleep(2 * time.Second) |
| 51 | |
Alan Donovan | 6ad27d0 | 2022-12-16 16:31:15 -0500 | [diff] [blame] | 52 | // A second regular file has a different ID. |
| 53 | real2 := filepath.Join(t.TempDir(), "real2") |
| 54 | if err := os.WriteFile(real2, nil, 0644); err != nil { |
| 55 | t.Fatalf("can't create second regular file: %v", err) |
| 56 | } |
Robert Findley | ae242ec | 2023-01-19 16:41:08 -0500 | [diff] [blame] | 57 | real2ID, real2Mtime, err := robustio.GetFileID(real2) |
Alan Donovan | 6ad27d0 | 2022-12-16 16:31:15 -0500 | [diff] [blame] | 58 | if err != nil { |
| 59 | t.Fatalf("can't get ID of second regular file: %v", err) |
| 60 | } |
| 61 | if realID == real2ID { |
Robert Findley | ae242ec | 2023-01-19 16:41:08 -0500 | [diff] [blame] | 62 | t.Errorf("realID %+v == real2ID %+v", realID, real2ID) |
| 63 | } |
| 64 | if realMtime.Equal(real2Mtime) { |
| 65 | t.Errorf("realMtime %v == real2Mtime %v", realMtime, real2Mtime) |
Alan Donovan | 6ad27d0 | 2022-12-16 16:31:15 -0500 | [diff] [blame] | 66 | } |
| 67 | |
| 68 | // A symbolic link has the same ID as its target. |
Bryan C. Mills | 5b123a2 | 2023-12-13 15:47:46 -0500 | [diff] [blame] | 69 | t.Run("symlink", func(t *testing.T) { |
Alan Donovan | 3856a5d | 2023-01-05 16:17:44 -0500 | [diff] [blame] | 70 | symlink := filepath.Join(t.TempDir(), "symlink") |
Bryan C. Mills | 5b123a2 | 2023-12-13 15:47:46 -0500 | [diff] [blame] | 71 | checkOSLink(t, os.Symlink(real, symlink)) |
| 72 | |
Robert Findley | ae242ec | 2023-01-19 16:41:08 -0500 | [diff] [blame] | 73 | symlinkID, symlinkMtime, err := robustio.GetFileID(symlink) |
Alan Donovan | 3856a5d | 2023-01-05 16:17:44 -0500 | [diff] [blame] | 74 | if err != nil { |
| 75 | t.Fatalf("can't get ID of symbolic link: %v", err) |
| 76 | } |
| 77 | if realID != symlinkID { |
| 78 | t.Errorf("realID %+v != symlinkID %+v", realID, symlinkID) |
| 79 | } |
Robert Findley | ae242ec | 2023-01-19 16:41:08 -0500 | [diff] [blame] | 80 | if !realMtime.Equal(symlinkMtime) { |
| 81 | t.Errorf("realMtime %v != symlinkMtime %v", realMtime, symlinkMtime) |
| 82 | } |
Bryan C. Mills | 5b123a2 | 2023-12-13 15:47:46 -0500 | [diff] [blame] | 83 | }) |
Alan Donovan | 6ad27d0 | 2022-12-16 16:31:15 -0500 | [diff] [blame] | 84 | |
Alan Donovan | 5c176b1 | 2023-01-17 12:24:46 -0500 | [diff] [blame] | 85 | // Two hard-linked files have the same ID. |
Bryan C. Mills | 5b123a2 | 2023-12-13 15:47:46 -0500 | [diff] [blame] | 86 | t.Run("hardlink", func(t *testing.T) { |
Alan Donovan | 3856a5d | 2023-01-05 16:17:44 -0500 | [diff] [blame] | 87 | hardlink := filepath.Join(t.TempDir(), "hardlink") |
Bryan C. Mills | 5b123a2 | 2023-12-13 15:47:46 -0500 | [diff] [blame] | 88 | checkOSLink(t, os.Link(real, hardlink)) |
| 89 | |
Robert Findley | ae242ec | 2023-01-19 16:41:08 -0500 | [diff] [blame] | 90 | hardlinkID, hardlinkMtime, err := robustio.GetFileID(hardlink) |
Alan Donovan | 3856a5d | 2023-01-05 16:17:44 -0500 | [diff] [blame] | 91 | if err != nil { |
| 92 | t.Fatalf("can't get ID of hard link: %v", err) |
| 93 | } |
Robert Findley | ae242ec | 2023-01-19 16:41:08 -0500 | [diff] [blame] | 94 | if realID != hardlinkID { |
Alan Donovan | 3856a5d | 2023-01-05 16:17:44 -0500 | [diff] [blame] | 95 | t.Errorf("realID %+v != hardlinkID %+v", realID, hardlinkID) |
| 96 | } |
Robert Findley | ae242ec | 2023-01-19 16:41:08 -0500 | [diff] [blame] | 97 | if !realMtime.Equal(hardlinkMtime) { |
| 98 | t.Errorf("realMtime %v != hardlinkMtime %v", realMtime, hardlinkMtime) |
| 99 | } |
Bryan C. Mills | 5b123a2 | 2023-12-13 15:47:46 -0500 | [diff] [blame] | 100 | }) |
Alan Donovan | 6ad27d0 | 2022-12-16 16:31:15 -0500 | [diff] [blame] | 101 | } |