github.com/tinygo-org/tinygo@v0.31.3-0.20240404173401-90b0bf646c27/src/os/file_anyos_test.go (about) 1 //go:build !baremetal && !js 2 3 package os_test 4 5 import ( 6 "errors" 7 "io" 8 . "os" 9 "runtime" 10 "testing" 11 ) 12 13 // TestTempDir assumes that the test environment has a filesystem with a working temp dir. 14 func TestTempDir(t *testing.T) { 15 name := TempDir() + "/_os_test_TestTempDir" 16 Remove(name) 17 f, err := OpenFile(name, O_RDWR|O_CREATE, 0644) 18 if err != nil { 19 t.Errorf("OpenFile %s: %s", name, err) 20 return 21 } 22 err = f.Close() 23 if err != nil { 24 t.Errorf("Close %s: %s", name, err) 25 } 26 err = Remove(name) 27 if err != nil { 28 t.Errorf("Remove %s: %s", name, err) 29 } 30 } 31 32 func TestChdir(t *testing.T) { 33 // Save and restore the current working directory after the test, otherwise 34 // we might break other tests that depend on it. 35 // 36 // Note that it doesn't work if Chdir is broken, but then this test should 37 // fail and highlight the issue if that is the case. 38 oldDir, err := Getwd() 39 if err != nil { 40 t.Errorf("Getwd() returned %v", err) 41 return 42 } 43 defer Chdir(oldDir) 44 45 // create and cd into a new directory 46 dir := "_os_test_TestChDir" 47 Remove(dir) 48 err = Mkdir(dir, 0755) 49 defer Remove(dir) // even though not quite sure which directory it will execute in 50 if err != nil { 51 t.Errorf("Mkdir(%s, 0755) returned %v", dir, err) 52 } 53 err = Chdir(dir) 54 if err != nil { 55 t.Fatalf("Chdir %s: %s", dir, err) 56 return 57 } 58 // create a file there 59 file := "_os_test_TestTempDir.dat" 60 f, err := OpenFile(file, O_RDWR|O_CREATE, 0644) 61 if err != nil { 62 t.Errorf("OpenFile %s: %s", file, err) 63 } 64 defer Remove(file) // even though not quite sure which directory it will execute in 65 err = f.Close() 66 if err != nil { 67 t.Errorf("Close %s: %s", file, err) 68 } 69 // cd back to original directory 70 err = Chdir("..") 71 if err != nil { 72 t.Errorf("Chdir ..: %s", err) 73 } 74 // clean up file and directory explicitly so we can check for errors 75 fullname := dir + "/" + file 76 err = Remove(fullname) 77 if err != nil { 78 t.Errorf("Remove %s: %s", fullname, err) 79 } 80 err = Remove(dir) 81 if err != nil { 82 t.Errorf("Remove %s: %s", dir, err) 83 } 84 } 85 86 func TestStandardFd(t *testing.T) { 87 if runtime.GOOS == "windows" { 88 t.Log("TODO: TestFd fails on Windows, skipping") 89 return 90 } 91 if fd := Stdin.Fd(); fd != 0 { 92 t.Errorf("Stdin.Fd() = %d, want 0", fd) 93 } 94 95 if fd := Stdout.Fd(); fd != 1 { 96 t.Errorf("Stdout.Fd() = %d, want 1", fd) 97 } 98 99 if fd := Stderr.Fd(); fd != 2 { 100 t.Errorf("Stderr.Fd() = %d, want 2", fd) 101 } 102 } 103 104 func TestFd(t *testing.T) { 105 if runtime.GOOS == "windows" { 106 t.Log("TODO: TestFd fails on Windows, skipping") 107 return 108 } 109 f := newFile("TestFd.txt", t) 110 defer Remove(f.Name()) 111 defer f.Close() 112 113 const data = "hello, world\n" 114 io.WriteString(f, data) 115 116 fd := NewFile(f.Fd(), "as-fd") 117 defer fd.Close() 118 119 b := make([]byte, 5) 120 n, err := fd.ReadAt(b, 0) 121 if n != 5 && err != nil { 122 t.Errorf("Failed to read 5 bytes from file descriptor: %v", err) 123 } 124 125 if string(b) != data[:5] { 126 t.Errorf("File descriptor contents not equal to file contents.") 127 } 128 } 129 130 // closeTests is the list of tests used to validate that after calling Close, 131 // calling any method of File returns ErrClosed. 132 var closeTests = map[string]func(*File) error{ 133 "Close": func(f *File) error { 134 return f.Close() 135 }, 136 "Read": func(f *File) error { 137 _, err := f.Read(nil) 138 return err 139 }, 140 "ReadAt": func(f *File) error { 141 _, err := f.ReadAt(nil, 0) 142 return err 143 }, 144 "Seek": func(f *File) error { 145 _, err := f.Seek(0, 0) 146 return err 147 }, 148 "Sync": func(f *File) error { 149 return f.Sync() 150 }, 151 "SyscallConn": func(f *File) error { 152 _, err := f.SyscallConn() 153 return err 154 }, 155 "Truncate": func(f *File) error { 156 return f.Truncate(0) 157 }, 158 "Write": func(f *File) error { 159 _, err := f.Write(nil) 160 return err 161 }, 162 "WriteAt": func(f *File) error { 163 _, err := f.WriteAt(nil, 0) 164 return err 165 }, 166 "WriteString": func(f *File) error { 167 _, err := f.WriteString("") 168 return err 169 }, 170 } 171 172 func TestClose(t *testing.T) { 173 f := newFile("TestClose.txt", t) 174 175 if err := f.Close(); err != nil { 176 t.Error("unexpected error closing the file:", err) 177 } 178 if fd := f.Fd(); fd != ^uintptr(0) { 179 t.Error("unexpected file handle after closing the file:", fd) 180 } 181 182 for name, test := range closeTests { 183 if err := test(f); !errors.Is(err, ErrClosed) { 184 t.Errorf("unexpected error returned by calling %s on a closed file: %v", name, err) 185 } 186 } 187 }