github.com/Serizao/go-winio@v0.0.0-20230906082528-f02f7f4ad6e8/fileinfo_test.go (about) 1 //go:build windows 2 // +build windows 3 4 package winio 5 6 import ( 7 "os" 8 "testing" 9 10 "golang.org/x/sys/windows" 11 ) 12 13 // Checks if current matches expected. Note that AllocationSize is filesystem-specific, 14 // so we check that the current.AllocationSize is >= expected.AllocationSize. 15 // https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-fscc/5afa7f66-619c-48f3-955f-68c4ece704ae 16 func checkFileStandardInfo(t *testing.T, current, expected *FileStandardInfo) { 17 t.Helper() 18 19 if current.AllocationSize < expected.AllocationSize { 20 t.Fatalf("FileStandardInfo unexpectedly had AllocationSize %d, expecting >=%d", current.AllocationSize, expected.AllocationSize) 21 } 22 23 if current.EndOfFile != expected.EndOfFile { 24 t.Fatalf("FileStandardInfo unexpectedly had EndOfFile %d, expecting %d", current.EndOfFile, expected.EndOfFile) 25 } 26 27 if current.NumberOfLinks != expected.NumberOfLinks { 28 t.Fatalf("FileStandardInfo unexpectedly had NumberOfLinks %d, expecting %d", current.NumberOfLinks, expected.NumberOfLinks) 29 } 30 31 if current.DeletePending != expected.DeletePending { 32 if current.DeletePending { 33 t.Fatalf("FileStandardInfo unexpectedly DeletePending") 34 } else { 35 t.Fatalf("FileStandardInfo unexpectedly not DeletePending") 36 } 37 } 38 39 if current.Directory != expected.Directory { 40 if current.Directory { 41 t.Fatalf("FileStandardInfo unexpectedly Directory") 42 } else { 43 t.Fatalf("FileStandardInfo unexpectedly not Directory") 44 } 45 } 46 } 47 48 func TestGetFileStandardInfo_File(t *testing.T) { 49 f, err := os.CreateTemp("", "tst") 50 if err != nil { 51 t.Fatal(err) 52 } 53 defer f.Close() 54 defer os.Remove(f.Name()) 55 56 expectedFileInfo := &FileStandardInfo{ 57 AllocationSize: 0, 58 EndOfFile: 0, 59 NumberOfLinks: 1, 60 DeletePending: false, 61 Directory: false, 62 } 63 64 info, err := GetFileStandardInfo(f) 65 if err != nil { 66 t.Fatal(err) 67 } 68 checkFileStandardInfo(t, info, expectedFileInfo) 69 70 bytesWritten, err := f.Write([]byte("0123456789")) 71 if err != nil { 72 t.Fatal(err) 73 } 74 75 expectedFileInfo.EndOfFile = int64(bytesWritten) 76 expectedFileInfo.AllocationSize = int64(bytesWritten) 77 78 info, err = GetFileStandardInfo(f) 79 if err != nil { 80 t.Fatal(err) 81 } 82 checkFileStandardInfo(t, info, expectedFileInfo) 83 84 linkName := f.Name() + ".link" 85 86 if err = os.Link(f.Name(), linkName); err != nil { 87 t.Fatal(err) 88 } 89 defer os.Remove(linkName) 90 91 expectedFileInfo.NumberOfLinks = 2 92 93 info, err = GetFileStandardInfo(f) 94 if err != nil { 95 t.Fatal(err) 96 } 97 checkFileStandardInfo(t, info, expectedFileInfo) 98 99 os.Remove(linkName) 100 101 expectedFileInfo.NumberOfLinks = 1 102 103 info, err = GetFileStandardInfo(f) 104 if err != nil { 105 t.Fatal(err) 106 } 107 checkFileStandardInfo(t, info, expectedFileInfo) 108 } 109 110 func TestGetFileStandardInfo_Directory(t *testing.T) { 111 tempDir := t.TempDir() 112 // os.Open returns the Search Handle, not the Directory Handle 113 // See https://github.com/golang/go/issues/13738 114 f, err := OpenForBackup(tempDir, windows.GENERIC_READ, 0, windows.OPEN_EXISTING) 115 if err != nil { 116 t.Fatal(err) 117 } 118 defer f.Close() 119 120 expectedFileInfo := &FileStandardInfo{ 121 AllocationSize: 0, 122 EndOfFile: 0, 123 NumberOfLinks: 1, 124 DeletePending: false, 125 Directory: true, 126 } 127 128 info, err := GetFileStandardInfo(f) 129 if err != nil { 130 t.Fatal(err) 131 } 132 checkFileStandardInfo(t, info, expectedFileInfo) 133 }