|
@@ -8,9 +8,16 @@ package fs
|
|
|
|
|
|
import (
|
|
import (
|
|
"bytes"
|
|
"bytes"
|
|
|
|
+ "fmt"
|
|
"io"
|
|
"io"
|
|
"io/ioutil"
|
|
"io/ioutil"
|
|
|
|
+ "os"
|
|
|
|
+ "path"
|
|
|
|
+ "path/filepath"
|
|
|
|
+ "runtime"
|
|
|
|
+ "sort"
|
|
"testing"
|
|
"testing"
|
|
|
|
+ "time"
|
|
)
|
|
)
|
|
|
|
|
|
func TestFakeFS(t *testing.T) {
|
|
func TestFakeFS(t *testing.T) {
|
|
@@ -123,13 +130,11 @@ func TestFakeFS(t *testing.T) {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
-func TestFakeFSRead(t *testing.T) {
|
|
|
|
|
|
+func testFakeFSRead(t *testing.T, fs Filesystem) {
|
|
// Test some basic aspects of the fakefs
|
|
// Test some basic aspects of the fakefs
|
|
-
|
|
|
|
- fs := newFakeFilesystem("/foo/bar/baz")
|
|
|
|
-
|
|
|
|
// Create
|
|
// Create
|
|
fd, _ := fs.Create("test")
|
|
fd, _ := fs.Create("test")
|
|
|
|
+ defer fd.Close()
|
|
fd.Truncate(3 * 1 << randomBlockShift)
|
|
fd.Truncate(3 * 1 << randomBlockShift)
|
|
|
|
|
|
// Read
|
|
// Read
|
|
@@ -172,3 +177,734 @@ func TestFakeFSRead(t *testing.T) {
|
|
t.Error("data mismatch")
|
|
t.Error("data mismatch")
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+type testFS struct {
|
|
|
|
+ name string
|
|
|
|
+ fs Filesystem
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+type test struct {
|
|
|
|
+ name string
|
|
|
|
+ impl func(t *testing.T, fs Filesystem)
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+func TestFakeFSCaseSensitive(t *testing.T) {
|
|
|
|
+ var tests = []test{
|
|
|
|
+ {"Read", testFakeFSRead},
|
|
|
|
+ {"OpenFile", testFakeFSOpenFile},
|
|
|
|
+ {"RemoveAll", testFakeFSRemoveAll},
|
|
|
|
+ {"Remove", testFakeFSRemove},
|
|
|
|
+ {"Rename", testFakeFSRename},
|
|
|
|
+ {"Mkdir", testFakeFSMkdir},
|
|
|
|
+ {"SameFile", testFakeFSSameFile},
|
|
|
|
+ {"DirNames", testDirNames},
|
|
|
|
+ {"FileName", testFakeFSFileName},
|
|
|
|
+ }
|
|
|
|
+ var filesystems = []testFS{
|
|
|
|
+ {"fakefs", newFakeFilesystem("/foo")},
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ testDir, sensitive := createTestDir(t)
|
|
|
|
+ defer removeTestDir(t, testDir)
|
|
|
|
+ if sensitive {
|
|
|
|
+ filesystems = append(filesystems, testFS{runtime.GOOS, newBasicFilesystem(testDir)})
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ runTests(t, tests, filesystems)
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+func TestFakeFSCaseInsensitive(t *testing.T) {
|
|
|
|
+ var tests = []test{
|
|
|
|
+ {"Read", testFakeFSRead},
|
|
|
|
+ {"OpenFile", testFakeFSOpenFile},
|
|
|
|
+ {"RemoveAll", testFakeFSRemoveAll},
|
|
|
|
+ {"Remove", testFakeFSRemove},
|
|
|
|
+ {"Mkdir", testFakeFSMkdir},
|
|
|
|
+ {"SameFile", testFakeFSSameFile},
|
|
|
|
+ {"DirNames", testDirNames},
|
|
|
|
+ {"FileName", testFakeFSFileName},
|
|
|
|
+ {"GeneralInsens", testFakeFSCaseInsensitive},
|
|
|
|
+ {"MkdirAllInsens", testFakeFSCaseInsensitiveMkdirAll},
|
|
|
|
+ {"StatInsens", testFakeFSStatInsens},
|
|
|
|
+ {"RenameInsens", testFakeFSRenameInsensitive},
|
|
|
|
+ {"MkdirInsens", testFakeFSMkdirInsens},
|
|
|
|
+ {"OpenFileInsens", testFakeFSOpenFileInsens},
|
|
|
|
+ {"RemoveAllInsens", testFakeFSRemoveAllInsens},
|
|
|
|
+ {"RemoveInsens", testFakeFSRemoveInsens},
|
|
|
|
+ {"SameFileInsens", testFakeFSSameFileInsens},
|
|
|
|
+ {"CreateInsens", testFakeFSCreateInsens},
|
|
|
|
+ {"FileNameInsens", testFakeFSFileNameInsens},
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ var filesystems = []testFS{
|
|
|
|
+ {"fakefs", newFakeFilesystem("/foobar?insens=true")},
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ testDir, sensitive := createTestDir(t)
|
|
|
|
+ defer removeTestDir(t, testDir)
|
|
|
|
+ if !sensitive {
|
|
|
|
+ filesystems = append(filesystems, testFS{runtime.GOOS, newBasicFilesystem(testDir)})
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ runTests(t, tests, filesystems)
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+func createTestDir(t *testing.T) (string, bool) {
|
|
|
|
+ t.Helper()
|
|
|
|
+
|
|
|
|
+ testDir, err := ioutil.TempDir("", "")
|
|
|
|
+ if err != nil {
|
|
|
|
+ t.Fatalf("could not create temporary dir for testing: %s", err)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if fd, err := os.Create(filepath.Join(testDir, ".stfolder")); err != nil {
|
|
|
|
+ t.Fatalf("could not create .stfolder: %s", err)
|
|
|
|
+ } else {
|
|
|
|
+ fd.Close()
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ var sensitive bool
|
|
|
|
+
|
|
|
|
+ if f, err := os.Open(filepath.Join(testDir, ".STfolder")); err != nil {
|
|
|
|
+ sensitive = true
|
|
|
|
+ } else {
|
|
|
|
+ defer f.Close()
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return testDir, sensitive
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+func removeTestDir(t *testing.T, testDir string) {
|
|
|
|
+ t.Helper()
|
|
|
|
+
|
|
|
|
+ if err := os.RemoveAll(testDir); err != nil {
|
|
|
|
+ t.Fatalf("could not remove test directory: %s", err)
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+func runTests(t *testing.T, tests []test, filesystems []testFS) {
|
|
|
|
+ for _, filesystem := range filesystems {
|
|
|
|
+ for _, test := range tests {
|
|
|
|
+ name := fmt.Sprintf("%s_%s", test.name, filesystem.name)
|
|
|
|
+ t.Run(name, func(t *testing.T) {
|
|
|
|
+ test.impl(t, filesystem.fs)
|
|
|
|
+ if err := cleanup(filesystem.fs); err != nil {
|
|
|
|
+ t.Errorf("cleanup failed: %s", err)
|
|
|
|
+ }
|
|
|
|
+ })
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+func testFakeFSCaseInsensitive(t *testing.T, fs Filesystem) {
|
|
|
|
+ bs1 := []byte("test")
|
|
|
|
+
|
|
|
|
+ err := fs.Mkdir("/fUbar", 0755)
|
|
|
|
+ if err != nil {
|
|
|
|
+ t.Fatal(err)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ fd1, err := fs.Create("fuBAR/SISYPHOS")
|
|
|
|
+ if err != nil {
|
|
|
|
+ t.Fatalf("could not create file: %s", err)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ defer fd1.Close()
|
|
|
|
+
|
|
|
|
+ _, err = fd1.Write(bs1)
|
|
|
|
+ if err != nil {
|
|
|
|
+ t.Fatal(err)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // Try reading from the same file with different filenames
|
|
|
|
+ fd2, err := fs.Open("Fubar/Sisyphos")
|
|
|
|
+ if err != nil {
|
|
|
|
+ t.Fatalf("could not open file by its case-differing filename: %s", err)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ defer fd2.Close()
|
|
|
|
+
|
|
|
|
+ if _, err := fd2.Seek(0, io.SeekStart); err != nil {
|
|
|
|
+ t.Fatal(err)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ bs2, err := ioutil.ReadAll(fd2)
|
|
|
|
+ if err != nil {
|
|
|
|
+ t.Fatal(err)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if len(bs1) != len(bs2) {
|
|
|
|
+ t.Errorf("wrong number of bytes, expected %d, got %d", len(bs1), len(bs2))
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+func testFakeFSCaseInsensitiveMkdirAll(t *testing.T, fs Filesystem) {
|
|
|
|
+ err := fs.MkdirAll("/fOO/Bar/bAz", 0755)
|
|
|
|
+ if err != nil {
|
|
|
|
+ t.Fatal(err)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ fd, err := fs.OpenFile("/foo/BaR/BaZ/tESt", os.O_CREATE, 0644)
|
|
|
|
+ if err != nil {
|
|
|
|
+ t.Fatal(err)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if err = fd.Close(); err != nil {
|
|
|
|
+ t.Fatal(err)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if err = fs.Rename("/FOO/BAR/baz/tesT", "/foo/baR/BAZ/Qux"); err != nil {
|
|
|
|
+ t.Fatal(err)
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+func testDirNames(t *testing.T, fs Filesystem) {
|
|
|
|
+ filenames := []string{"fOO", "Bar", "baz"}
|
|
|
|
+ for _, filename := range filenames {
|
|
|
|
+ if fd, err := fs.Create("/" + filename); err != nil {
|
|
|
|
+ t.Errorf("Could not create %s: %s", filename, err)
|
|
|
|
+ } else {
|
|
|
|
+ fd.Close()
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ assertDir(t, fs, "/", filenames)
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+func assertDir(t *testing.T, fs Filesystem, directory string, filenames []string) {
|
|
|
|
+ t.Helper()
|
|
|
|
+ got, err := fs.DirNames(directory)
|
|
|
|
+ if err != nil {
|
|
|
|
+ t.Fatal(err)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if path.Clean(directory) == "/" {
|
|
|
|
+ filenames = append(filenames, ".stfolder")
|
|
|
|
+ }
|
|
|
|
+ sort.Strings(filenames)
|
|
|
|
+ sort.Strings(got)
|
|
|
|
+
|
|
|
|
+ if len(filenames) != len(got) {
|
|
|
|
+ t.Errorf("want %s, got %s", filenames, got)
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ for i := range filenames {
|
|
|
|
+ if filenames[i] != got[i] {
|
|
|
|
+ t.Errorf("want %s, got %s", filenames, got)
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+func testFakeFSStatInsens(t *testing.T, fs Filesystem) {
|
|
|
|
+ // this is to test that neither fs.Stat nor fd.Stat change the filename
|
|
|
|
+ // both in directory and in previous Stat results
|
|
|
|
+ fd1, err := fs.Create("aAa")
|
|
|
|
+ if err != nil {
|
|
|
|
+ t.Fatal(err)
|
|
|
|
+ }
|
|
|
|
+ defer fd1.Close()
|
|
|
|
+
|
|
|
|
+ info1, err := fs.Stat("AAA")
|
|
|
|
+ if err != nil {
|
|
|
|
+ t.Fatal(err)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if _, err = fs.Stat("AaA"); err != nil {
|
|
|
|
+ t.Fatal(err)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ info2, err := fd1.Stat()
|
|
|
|
+ if err != nil {
|
|
|
|
+ t.Fatal(err)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ fd2, err := fs.Open("aaa")
|
|
|
|
+ if err != nil {
|
|
|
|
+ t.Fatal(err)
|
|
|
|
+ }
|
|
|
|
+ defer fd2.Close()
|
|
|
|
+
|
|
|
|
+ if _, err = fd2.Stat(); err != nil {
|
|
|
|
+ t.Fatal(err)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if info1.Name() != "AAA" {
|
|
|
|
+ t.Errorf("want AAA, got %s", info1.Name())
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if info2.Name() != "aAa" {
|
|
|
|
+ t.Errorf("want aAa, got %s", info2.Name())
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ assertDir(t, fs, "/", []string{"aAa"})
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+func testFakeFSFileName(t *testing.T, fs Filesystem) {
|
|
|
|
+ var testCases = []struct {
|
|
|
|
+ create string
|
|
|
|
+ open string
|
|
|
|
+ }{
|
|
|
|
+ {"bar", "bar"},
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ for _, testCase := range testCases {
|
|
|
|
+ if fd, err := fs.Create(testCase.create); err != nil {
|
|
|
|
+ t.Fatal(err)
|
|
|
|
+ } else {
|
|
|
|
+ fd.Close()
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ fd, err := fs.Open(testCase.open)
|
|
|
|
+ if err != nil {
|
|
|
|
+ t.Fatal(err)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ defer fd.Close()
|
|
|
|
+
|
|
|
|
+ if got := fd.Name(); got != testCase.open {
|
|
|
|
+ t.Errorf("want %s, got %s", testCase.open, got)
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+func testFakeFSFileNameInsens(t *testing.T, fs Filesystem) {
|
|
|
|
+ var testCases = []struct {
|
|
|
|
+ create string
|
|
|
|
+ open string
|
|
|
|
+ }{
|
|
|
|
+ {"BaZ", "bAz"},
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ for _, testCase := range testCases {
|
|
|
|
+ fd, err := fs.Create(testCase.create)
|
|
|
|
+ if err != nil {
|
|
|
|
+ t.Fatal(err)
|
|
|
|
+ }
|
|
|
|
+ fd.Close()
|
|
|
|
+
|
|
|
|
+ fd, err = fs.Open(testCase.open)
|
|
|
|
+ if err != nil {
|
|
|
|
+ t.Fatal(err)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ defer fd.Close()
|
|
|
|
+
|
|
|
|
+ if got := fd.Name(); got != testCase.open {
|
|
|
|
+ t.Errorf("want %s, got %s", testCase.open, got)
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+func testFakeFSRename(t *testing.T, fs Filesystem) {
|
|
|
|
+ if err := fs.MkdirAll("/foo/bar/baz", 0755); err != nil {
|
|
|
|
+ t.Fatal(err)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ fd, err := fs.Create("/foo/bar/baz/qux")
|
|
|
|
+ if err != nil {
|
|
|
|
+ t.Fatal(err)
|
|
|
|
+ }
|
|
|
|
+ fd.Close()
|
|
|
|
+
|
|
|
|
+ if err := fs.Rename("/foo/bar/baz/qux", "/foo/notthere/qux"); err == nil {
|
|
|
|
+ t.Errorf("rename to non-existent dir gave no error")
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if err := fs.MkdirAll("/baz/bar/foo", 0755); err != nil {
|
|
|
|
+ t.Fatal(err)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if err := fs.Rename("/foo/bar/baz/qux", "/baz/bar/foo/qux"); err != nil {
|
|
|
|
+ t.Fatal(err)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ var dirs = []struct {
|
|
|
|
+ dir string
|
|
|
|
+ files []string
|
|
|
|
+ }{
|
|
|
|
+ {dir: "/", files: []string{"foo", "baz"}},
|
|
|
|
+ {dir: "/foo", files: []string{"bar"}},
|
|
|
|
+ {dir: "/foo/bar/baz", files: []string{}},
|
|
|
|
+ {dir: "/baz/bar/foo", files: []string{"qux"}},
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ for _, dir := range dirs {
|
|
|
|
+ assertDir(t, fs, dir.dir, dir.files)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if err := fs.Rename("/baz/bar/foo", "/baz/bar/FOO"); err != nil {
|
|
|
|
+ t.Fatal(err)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ assertDir(t, fs, "/baz/bar", []string{"FOO"})
|
|
|
|
+ assertDir(t, fs, "/baz/bar/FOO", []string{"qux"})
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+func testFakeFSRenameInsensitive(t *testing.T, fs Filesystem) {
|
|
|
|
+ if err := fs.MkdirAll("/baz/bar/foo", 0755); err != nil {
|
|
|
|
+ t.Fatal(err)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if err := fs.MkdirAll("/foO/baR/baZ", 0755); err != nil {
|
|
|
|
+ t.Fatal(err)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ fd, err := fs.Create("/BAZ/BAR/FOO/QUX")
|
|
|
|
+ if err != nil {
|
|
|
|
+ t.Fatal(err)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ fd.Close()
|
|
|
|
+
|
|
|
|
+ if err := fs.Rename("/Baz/bAr/foO/QuX", "/Foo/Bar/Baz/qUUx"); err != nil {
|
|
|
|
+ t.Fatal(err)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ var dirs = []struct {
|
|
|
|
+ dir string
|
|
|
|
+ files []string
|
|
|
|
+ }{
|
|
|
|
+ {dir: "/", files: []string{"foO", "baz"}},
|
|
|
|
+ {dir: "/foo", files: []string{"baR"}},
|
|
|
|
+ {dir: "/foo/bar/baz", files: []string{"qUUx"}},
|
|
|
|
+ {dir: "/baz/bar/foo", files: []string{}},
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ for _, dir := range dirs {
|
|
|
|
+ assertDir(t, fs, dir.dir, dir.files)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // not checking on darwin due to https://github.com/golang/go/issues/35222
|
|
|
|
+ if runtime.GOOS != "darwin" {
|
|
|
|
+ if err := fs.Rename("/foo/bar/BAZ", "/FOO/BAR/bAz"); err != nil {
|
|
|
|
+ t.Errorf("Could not perform in-place case-only directory rename: %s", err)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ assertDir(t, fs, "/foo/bar", []string{"bAz"})
|
|
|
|
+ assertDir(t, fs, "/fOO/bAr/baz", []string{"qUUx"})
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if err := fs.Rename("foo/bar/baz/quux", "foo/bar/BaZ/Quux"); err != nil {
|
|
|
|
+ t.Errorf("File rename failed: %s", err)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ assertDir(t, fs, "/FOO/BAR/BAZ", []string{"Quux"})
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+func testFakeFSMkdir(t *testing.T, fs Filesystem) {
|
|
|
|
+ if err := fs.Mkdir("/foo", 0755); err != nil {
|
|
|
|
+ t.Fatal(err)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if _, err := fs.Stat("/foo"); err != nil {
|
|
|
|
+ t.Fatal(err)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if err := fs.Mkdir("/foo", 0755); err == nil {
|
|
|
|
+ t.Errorf("got no error while creating existing directory")
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+func testFakeFSMkdirInsens(t *testing.T, fs Filesystem) {
|
|
|
|
+ if err := fs.Mkdir("/foo", 0755); err != nil {
|
|
|
|
+ t.Fatal(err)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if _, err := fs.Stat("/Foo"); err != nil {
|
|
|
|
+ t.Fatal(err)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if err := fs.Mkdir("/FOO", 0755); err == nil {
|
|
|
|
+ t.Errorf("got no error while creating existing directory")
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+func testFakeFSOpenFile(t *testing.T, fs Filesystem) {
|
|
|
|
+ fd, err := fs.OpenFile("foobar", os.O_RDONLY, 0664)
|
|
|
|
+ if err == nil {
|
|
|
|
+ fd.Close()
|
|
|
|
+ t.Fatalf("got no error opening a non-existing file")
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ fd, err = fs.OpenFile("foobar", os.O_RDWR|os.O_CREATE, 0664)
|
|
|
|
+ if err != nil {
|
|
|
|
+ t.Fatal(err)
|
|
|
|
+ }
|
|
|
|
+ fd.Close()
|
|
|
|
+
|
|
|
|
+ fd, err = fs.OpenFile("foobar", os.O_RDWR|os.O_CREATE|os.O_EXCL, 0664)
|
|
|
|
+ if err == nil {
|
|
|
|
+ fd.Close()
|
|
|
|
+ t.Fatalf("created an existing file while told not to")
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ fd, err = fs.OpenFile("foobar", os.O_RDWR|os.O_CREATE, 0664)
|
|
|
|
+ if err != nil {
|
|
|
|
+ t.Fatal(err)
|
|
|
|
+ }
|
|
|
|
+ fd.Close()
|
|
|
|
+
|
|
|
|
+ fd, err = fs.OpenFile("foobar", os.O_RDWR, 0664)
|
|
|
|
+ if err != nil {
|
|
|
|
+ t.Fatal(err)
|
|
|
|
+ }
|
|
|
|
+ fd.Close()
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+func testFakeFSOpenFileInsens(t *testing.T, fs Filesystem) {
|
|
|
|
+ fd, err := fs.OpenFile("FooBar", os.O_RDONLY, 0664)
|
|
|
|
+ if err == nil {
|
|
|
|
+ fd.Close()
|
|
|
|
+ t.Fatalf("got no error opening a non-existing file")
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ fd, err = fs.OpenFile("fOObar", os.O_RDWR|os.O_CREATE, 0664)
|
|
|
|
+ if err != nil {
|
|
|
|
+ t.Fatal(err)
|
|
|
|
+ }
|
|
|
|
+ fd.Close()
|
|
|
|
+
|
|
|
|
+ fd, err = fs.OpenFile("fOoBaR", os.O_RDWR|os.O_CREATE|os.O_EXCL, 0664)
|
|
|
|
+ if err == nil {
|
|
|
|
+ fd.Close()
|
|
|
|
+ t.Fatalf("created an existing file while told not to")
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ fd, err = fs.OpenFile("FoObAr", os.O_RDWR|os.O_CREATE, 0664)
|
|
|
|
+ if err != nil {
|
|
|
|
+ t.Fatal(err)
|
|
|
|
+ }
|
|
|
|
+ fd.Close()
|
|
|
|
+
|
|
|
|
+ fd, err = fs.OpenFile("FOOBAR", os.O_RDWR, 0664)
|
|
|
|
+ if err != nil {
|
|
|
|
+ t.Fatal(err)
|
|
|
|
+ }
|
|
|
|
+ fd.Close()
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+func testFakeFSRemoveAll(t *testing.T, fs Filesystem) {
|
|
|
|
+ if err := fs.Mkdir("/foo", 0755); err != nil {
|
|
|
|
+ t.Fatal(err)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ filenames := []string{"bar", "baz", "qux"}
|
|
|
|
+ for _, filename := range filenames {
|
|
|
|
+ fd, err := fs.Create("/foo/" + filename)
|
|
|
|
+ if err != nil {
|
|
|
|
+ t.Fatalf("Could not create %s: %s", filename, err)
|
|
|
|
+ } else {
|
|
|
|
+ fd.Close()
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if err := fs.RemoveAll("/foo"); err != nil {
|
|
|
|
+ t.Fatal(err)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if _, err := fs.Stat("/foo"); err == nil {
|
|
|
|
+ t.Errorf("this should be an error, as file doesn not exist anymore")
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if err := fs.RemoveAll("/foo/bar"); err != nil {
|
|
|
|
+ t.Errorf("real systems don't return error here")
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+func testFakeFSRemoveAllInsens(t *testing.T, fs Filesystem) {
|
|
|
|
+ if err := fs.Mkdir("/Foo", 0755); err != nil {
|
|
|
|
+ t.Fatal(err)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ filenames := []string{"bar", "baz", "qux"}
|
|
|
|
+ for _, filename := range filenames {
|
|
|
|
+ fd, err := fs.Create("/FOO/" + filename)
|
|
|
|
+ if err != nil {
|
|
|
|
+ t.Fatalf("Could not create %s: %s", filename, err)
|
|
|
|
+ }
|
|
|
|
+ fd.Close()
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if err := fs.RemoveAll("/fOo"); err != nil {
|
|
|
|
+ t.Errorf("Could not remove dir: %s", err)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if _, err := fs.Stat("/foo"); err == nil {
|
|
|
|
+ t.Errorf("this should be an error, as file doesn not exist anymore")
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if err := fs.RemoveAll("/foO/bAr"); err != nil {
|
|
|
|
+ t.Errorf("real systems don't return error here")
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+func testFakeFSRemove(t *testing.T, fs Filesystem) {
|
|
|
|
+ if err := fs.Mkdir("/Foo", 0755); err != nil {
|
|
|
|
+ t.Fatal(err)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ fd, err := fs.Create("/Foo/Bar")
|
|
|
|
+ if err != nil {
|
|
|
|
+ t.Fatal(err)
|
|
|
|
+ } else {
|
|
|
|
+ fd.Close()
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if err := fs.Remove("/Foo"); err == nil {
|
|
|
|
+ t.Errorf("not empty, should give error")
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if err := fs.Remove("/Foo/Bar"); err != nil {
|
|
|
|
+ t.Fatal(err)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if err := fs.Remove("/Foo"); err != nil {
|
|
|
|
+ t.Fatal(err)
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+func testFakeFSRemoveInsens(t *testing.T, fs Filesystem) {
|
|
|
|
+ if err := fs.Mkdir("/Foo", 0755); err != nil {
|
|
|
|
+ t.Fatal(err)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ fd, err := fs.Create("/Foo/Bar")
|
|
|
|
+ if err != nil {
|
|
|
|
+ t.Fatal(err)
|
|
|
|
+ }
|
|
|
|
+ fd.Close()
|
|
|
|
+
|
|
|
|
+ if err := fs.Remove("/FOO"); err == nil {
|
|
|
|
+ t.Errorf("not empty, should give error")
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if err := fs.Remove("/Foo/BaR"); err != nil {
|
|
|
|
+ t.Fatal(err)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if err := fs.Remove("/FoO"); err != nil {
|
|
|
|
+ t.Fatal(err)
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+func testFakeFSSameFile(t *testing.T, fs Filesystem) {
|
|
|
|
+ if err := fs.Mkdir("/Foo", 0755); err != nil {
|
|
|
|
+ t.Fatal(err)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ filenames := []string{"Bar", "Baz", "/Foo/Bar"}
|
|
|
|
+ for _, filename := range filenames {
|
|
|
|
+ if fd, err := fs.Create(filename); err != nil {
|
|
|
|
+ t.Fatalf("Could not create %s: %s", filename, err)
|
|
|
|
+ } else {
|
|
|
|
+ fd.Close()
|
|
|
|
+ if runtime.GOOS == "windows" {
|
|
|
|
+ time.Sleep(1 * time.Millisecond)
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ testCases := []struct {
|
|
|
|
+ f1 string
|
|
|
|
+ f2 string
|
|
|
|
+ want bool
|
|
|
|
+ }{
|
|
|
|
+ {"Bar", "Baz", false},
|
|
|
|
+ {"Bar", "/Foo/Bar", false},
|
|
|
|
+ {"Bar", "Bar", true},
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ for _, test := range testCases {
|
|
|
|
+ assertSameFile(t, fs, test.f1, test.f2, test.want)
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+func testFakeFSSameFileInsens(t *testing.T, fs Filesystem) {
|
|
|
|
+ if err := fs.Mkdir("/Foo", 0755); err != nil {
|
|
|
|
+ t.Fatal(err)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ filenames := []string{"Bar", "Baz"}
|
|
|
|
+ for _, filename := range filenames {
|
|
|
|
+ fd, err := fs.Create(filename)
|
|
|
|
+ if err != nil {
|
|
|
|
+ t.Errorf("Could not create %s: %s", filename, err)
|
|
|
|
+ }
|
|
|
|
+ fd.Close()
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ testCases := []struct {
|
|
|
|
+ f1 string
|
|
|
|
+ f2 string
|
|
|
|
+ want bool
|
|
|
|
+ }{
|
|
|
|
+ {"bAr", "baZ", false},
|
|
|
|
+ {"baz", "BAZ", true},
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ for _, test := range testCases {
|
|
|
|
+ assertSameFile(t, fs, test.f1, test.f2, test.want)
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+func assertSameFile(t *testing.T, fs Filesystem, f1, f2 string, want bool) {
|
|
|
|
+ t.Helper()
|
|
|
|
+
|
|
|
|
+ fi1, err := fs.Stat(f1)
|
|
|
|
+ if err != nil {
|
|
|
|
+ t.Fatal(err)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ fi2, err := fs.Stat(f2)
|
|
|
|
+ if err != nil {
|
|
|
|
+ t.Fatal(err)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ got := fs.SameFile(fi1, fi2)
|
|
|
|
+ if got != want {
|
|
|
|
+ t.Errorf("for \"%s\" and \"%s\" want SameFile %v, got %v", f1, f2, want, got)
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+func testFakeFSCreateInsens(t *testing.T, fs Filesystem) {
|
|
|
|
+ fd1, err := fs.Create("FOO")
|
|
|
|
+ if err != nil {
|
|
|
|
+ t.Fatal(err)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ defer fd1.Close()
|
|
|
|
+
|
|
|
|
+ fd2, err := fs.Create("fOo")
|
|
|
|
+ if err != nil {
|
|
|
|
+ t.Fatal(err)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ defer fd2.Close()
|
|
|
|
+
|
|
|
|
+ if fd1.Name() != "FOO" {
|
|
|
|
+ t.Errorf("name of the file created as \"FOO\" is %s", fd1.Name())
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if fd2.Name() != "fOo" {
|
|
|
|
+ t.Errorf("name of created file \"fOo\" is %s", fd2.Name())
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // one would expect DirNames to show the last variant, but in fact it shows
|
|
|
|
+ // the original one
|
|
|
|
+ assertDir(t, fs, "/", []string{"FOO"})
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+func cleanup(fs Filesystem) error {
|
|
|
|
+ filenames, _ := fs.DirNames("/")
|
|
|
|
+ for _, filename := range filenames {
|
|
|
|
+ if filename != ".stfolder" {
|
|
|
|
+ if err := fs.RemoveAll(filename); err != nil {
|
|
|
|
+ return err
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return nil
|
|
|
|
+}
|