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 | |
Robert Findley | ae242ec | 2023-01-19 16:41:08 -0500 | [diff] [blame] | 17 | func TestFileInfo(t *testing.T) { |
Alan Donovan | 6ad27d0 | 2022-12-16 16:31:15 -0500 | [diff] [blame] | 18 | // A nonexistent file has no ID. |
| 19 | nonexistent := filepath.Join(t.TempDir(), "nonexistent") |
Robert Findley | ae242ec | 2023-01-19 16:41:08 -0500 | [diff] [blame] | 20 | if _, _, err := robustio.GetFileID(nonexistent); err == nil { |
Alan Donovan | 6ad27d0 | 2022-12-16 16:31:15 -0500 | [diff] [blame] | 21 | t.Fatalf("GetFileID(nonexistent) succeeded unexpectedly") |
| 22 | } |
| 23 | |
| 24 | // A regular file has an ID. |
| 25 | real := filepath.Join(t.TempDir(), "real") |
| 26 | if err := os.WriteFile(real, nil, 0644); err != nil { |
| 27 | t.Fatalf("can't create regular file: %v", err) |
| 28 | } |
Robert Findley | ae242ec | 2023-01-19 16:41:08 -0500 | [diff] [blame] | 29 | realID, realMtime, err := robustio.GetFileID(real) |
Alan Donovan | 6ad27d0 | 2022-12-16 16:31:15 -0500 | [diff] [blame] | 30 | if err != nil { |
| 31 | t.Fatalf("can't get ID of regular file: %v", err) |
| 32 | } |
| 33 | |
Robert Findley | ae242ec | 2023-01-19 16:41:08 -0500 | [diff] [blame] | 34 | // Sleep so that we get a new mtime for subsequent writes. |
| 35 | time.Sleep(2 * time.Second) |
| 36 | |
Alan Donovan | 6ad27d0 | 2022-12-16 16:31:15 -0500 | [diff] [blame] | 37 | // A second regular file has a different ID. |
| 38 | real2 := filepath.Join(t.TempDir(), "real2") |
| 39 | if err := os.WriteFile(real2, nil, 0644); err != nil { |
| 40 | t.Fatalf("can't create second regular file: %v", err) |
| 41 | } |
Robert Findley | ae242ec | 2023-01-19 16:41:08 -0500 | [diff] [blame] | 42 | real2ID, real2Mtime, err := robustio.GetFileID(real2) |
Alan Donovan | 6ad27d0 | 2022-12-16 16:31:15 -0500 | [diff] [blame] | 43 | if err != nil { |
| 44 | t.Fatalf("can't get ID of second regular file: %v", err) |
| 45 | } |
| 46 | if realID == real2ID { |
Robert Findley | ae242ec | 2023-01-19 16:41:08 -0500 | [diff] [blame] | 47 | t.Errorf("realID %+v == real2ID %+v", realID, real2ID) |
| 48 | } |
| 49 | if realMtime.Equal(real2Mtime) { |
| 50 | t.Errorf("realMtime %v == real2Mtime %v", realMtime, real2Mtime) |
Alan Donovan | 6ad27d0 | 2022-12-16 16:31:15 -0500 | [diff] [blame] | 51 | } |
| 52 | |
| 53 | // A symbolic link has the same ID as its target. |
Alan Donovan | 3856a5d | 2023-01-05 16:17:44 -0500 | [diff] [blame] | 54 | if runtime.GOOS != "plan9" { |
| 55 | symlink := filepath.Join(t.TempDir(), "symlink") |
| 56 | if err := os.Symlink(real, symlink); err != nil { |
| 57 | t.Fatalf("can't create symbolic link: %v", err) |
| 58 | } |
Robert Findley | ae242ec | 2023-01-19 16:41:08 -0500 | [diff] [blame] | 59 | symlinkID, symlinkMtime, err := robustio.GetFileID(symlink) |
Alan Donovan | 3856a5d | 2023-01-05 16:17:44 -0500 | [diff] [blame] | 60 | if err != nil { |
| 61 | t.Fatalf("can't get ID of symbolic link: %v", err) |
| 62 | } |
| 63 | if realID != symlinkID { |
| 64 | t.Errorf("realID %+v != symlinkID %+v", realID, symlinkID) |
| 65 | } |
Robert Findley | ae242ec | 2023-01-19 16:41:08 -0500 | [diff] [blame] | 66 | if !realMtime.Equal(symlinkMtime) { |
| 67 | t.Errorf("realMtime %v != symlinkMtime %v", realMtime, symlinkMtime) |
| 68 | } |
Alan Donovan | 5c176b1 | 2023-01-17 12:24:46 -0500 | [diff] [blame] | 69 | } |
Alan Donovan | 6ad27d0 | 2022-12-16 16:31:15 -0500 | [diff] [blame] | 70 | |
Alan Donovan | 5c176b1 | 2023-01-17 12:24:46 -0500 | [diff] [blame] | 71 | // Two hard-linked files have the same ID. |
| 72 | if runtime.GOOS != "plan9" && runtime.GOOS != "android" { |
Alan Donovan | 3856a5d | 2023-01-05 16:17:44 -0500 | [diff] [blame] | 73 | hardlink := filepath.Join(t.TempDir(), "hardlink") |
| 74 | if err := os.Link(real, hardlink); err != nil { |
| 75 | t.Fatal(err) |
| 76 | } |
Robert Findley | ae242ec | 2023-01-19 16:41:08 -0500 | [diff] [blame] | 77 | hardlinkID, hardlinkMtime, err := robustio.GetFileID(hardlink) |
Alan Donovan | 3856a5d | 2023-01-05 16:17:44 -0500 | [diff] [blame] | 78 | if err != nil { |
| 79 | t.Fatalf("can't get ID of hard link: %v", err) |
| 80 | } |
Robert Findley | ae242ec | 2023-01-19 16:41:08 -0500 | [diff] [blame] | 81 | if realID != hardlinkID { |
Alan Donovan | 3856a5d | 2023-01-05 16:17:44 -0500 | [diff] [blame] | 82 | t.Errorf("realID %+v != hardlinkID %+v", realID, hardlinkID) |
| 83 | } |
Robert Findley | ae242ec | 2023-01-19 16:41:08 -0500 | [diff] [blame] | 84 | if !realMtime.Equal(hardlinkMtime) { |
| 85 | t.Errorf("realMtime %v != hardlinkMtime %v", realMtime, hardlinkMtime) |
| 86 | } |
Alan Donovan | 6ad27d0 | 2022-12-16 16:31:15 -0500 | [diff] [blame] | 87 | } |
| 88 | } |