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  }