blob: 030090db93ab1fd5aeb5460b9d982ffad76e443b [file] [log] [blame]
Alan Donovan6ad27d02022-12-16 16:31:15 -05001// 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
5package robustio_test
6
7import (
8 "os"
9 "path/filepath"
Alan Donovan3856a5d2023-01-05 16:17:44 -050010 "runtime"
Alan Donovan6ad27d02022-12-16 16:31:15 -050011 "testing"
Robert Findleyae242ec2023-01-19 16:41:08 -050012 "time"
Alan Donovan6ad27d02022-12-16 16:31:15 -050013
Tim King33071fb2022-12-30 17:02:30 -080014 "golang.org/x/tools/internal/robustio"
Alan Donovan6ad27d02022-12-16 16:31:15 -050015)
16
Bryan C. Mills5b123a22023-12-13 15:47:46 -050017func 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 Findleyae242ec2023-01-19 16:41:08 -050032func TestFileInfo(t *testing.T) {
Alan Donovan6ad27d02022-12-16 16:31:15 -050033 // A nonexistent file has no ID.
34 nonexistent := filepath.Join(t.TempDir(), "nonexistent")
Robert Findleyae242ec2023-01-19 16:41:08 -050035 if _, _, err := robustio.GetFileID(nonexistent); err == nil {
Alan Donovan6ad27d02022-12-16 16:31:15 -050036 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 Findleyae242ec2023-01-19 16:41:08 -050044 realID, realMtime, err := robustio.GetFileID(real)
Alan Donovan6ad27d02022-12-16 16:31:15 -050045 if err != nil {
46 t.Fatalf("can't get ID of regular file: %v", err)
47 }
48
Robert Findleyae242ec2023-01-19 16:41:08 -050049 // Sleep so that we get a new mtime for subsequent writes.
50 time.Sleep(2 * time.Second)
51
Alan Donovan6ad27d02022-12-16 16:31:15 -050052 // 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 Findleyae242ec2023-01-19 16:41:08 -050057 real2ID, real2Mtime, err := robustio.GetFileID(real2)
Alan Donovan6ad27d02022-12-16 16:31:15 -050058 if err != nil {
59 t.Fatalf("can't get ID of second regular file: %v", err)
60 }
61 if realID == real2ID {
Robert Findleyae242ec2023-01-19 16:41:08 -050062 t.Errorf("realID %+v == real2ID %+v", realID, real2ID)
63 }
64 if realMtime.Equal(real2Mtime) {
65 t.Errorf("realMtime %v == real2Mtime %v", realMtime, real2Mtime)
Alan Donovan6ad27d02022-12-16 16:31:15 -050066 }
67
68 // A symbolic link has the same ID as its target.
Bryan C. Mills5b123a22023-12-13 15:47:46 -050069 t.Run("symlink", func(t *testing.T) {
Alan Donovan3856a5d2023-01-05 16:17:44 -050070 symlink := filepath.Join(t.TempDir(), "symlink")
Bryan C. Mills5b123a22023-12-13 15:47:46 -050071 checkOSLink(t, os.Symlink(real, symlink))
72
Robert Findleyae242ec2023-01-19 16:41:08 -050073 symlinkID, symlinkMtime, err := robustio.GetFileID(symlink)
Alan Donovan3856a5d2023-01-05 16:17:44 -050074 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 Findleyae242ec2023-01-19 16:41:08 -050080 if !realMtime.Equal(symlinkMtime) {
81 t.Errorf("realMtime %v != symlinkMtime %v", realMtime, symlinkMtime)
82 }
Bryan C. Mills5b123a22023-12-13 15:47:46 -050083 })
Alan Donovan6ad27d02022-12-16 16:31:15 -050084
Alan Donovan5c176b12023-01-17 12:24:46 -050085 // Two hard-linked files have the same ID.
Bryan C. Mills5b123a22023-12-13 15:47:46 -050086 t.Run("hardlink", func(t *testing.T) {
Alan Donovan3856a5d2023-01-05 16:17:44 -050087 hardlink := filepath.Join(t.TempDir(), "hardlink")
Bryan C. Mills5b123a22023-12-13 15:47:46 -050088 checkOSLink(t, os.Link(real, hardlink))
89
Robert Findleyae242ec2023-01-19 16:41:08 -050090 hardlinkID, hardlinkMtime, err := robustio.GetFileID(hardlink)
Alan Donovan3856a5d2023-01-05 16:17:44 -050091 if err != nil {
92 t.Fatalf("can't get ID of hard link: %v", err)
93 }
Robert Findleyae242ec2023-01-19 16:41:08 -050094 if realID != hardlinkID {
Alan Donovan3856a5d2023-01-05 16:17:44 -050095 t.Errorf("realID %+v != hardlinkID %+v", realID, hardlinkID)
96 }
Robert Findleyae242ec2023-01-19 16:41:08 -050097 if !realMtime.Equal(hardlinkMtime) {
98 t.Errorf("realMtime %v != hardlinkMtime %v", realMtime, hardlinkMtime)
99 }
Bryan C. Mills5b123a22023-12-13 15:47:46 -0500100 })
Alan Donovan6ad27d02022-12-16 16:31:15 -0500101}