| // Copyright 2014 The Go Authors. All rights reserved. | |
| // Use of this source code is governed by a BSD-style | |
| // license that can be found in the LICENSE file. | |
| package os_test | |
| import ( | |
| "io/ioutil" | |
| "os" | |
| osexec "os/exec" | |
| "path/filepath" | |
| "sort" | |
| "strings" | |
| "syscall" | |
| "testing" | |
| ) | |
| var supportJunctionLinks = true | |
| func init() { | |
| tmpdir, err := ioutil.TempDir("", "symtest") | |
| if err != nil { | |
| panic("failed to create temp directory: " + err.Error()) | |
| } | |
| defer os.RemoveAll(tmpdir) | |
| err = os.Symlink("target", filepath.Join(tmpdir, "symlink")) | |
| if err != nil { | |
| err = err.(*os.LinkError).Err | |
| switch err { | |
| case syscall.EWINDOWS, syscall.ERROR_PRIVILEGE_NOT_HELD: | |
| supportsSymlinks = false | |
| } | |
| } | |
| defer os.Remove("target") | |
| b, _ := osexec.Command("cmd", "/c", "mklink", "/?").Output() | |
| if !strings.Contains(string(b), " /J ") { | |
| supportJunctionLinks = false | |
| } | |
| } | |
| func TestSameWindowsFile(t *testing.T) { | |
| temp, err := ioutil.TempDir("", "TestSameWindowsFile") | |
| if err != nil { | |
| t.Fatal(err) | |
| } | |
| defer os.RemoveAll(temp) | |
| wd, err := os.Getwd() | |
| if err != nil { | |
| t.Fatal(err) | |
| } | |
| err = os.Chdir(temp) | |
| if err != nil { | |
| t.Fatal(err) | |
| } | |
| defer os.Chdir(wd) | |
| f, err := os.Create("a") | |
| if err != nil { | |
| t.Fatal(err) | |
| } | |
| f.Close() | |
| ia1, err := os.Stat("a") | |
| if err != nil { | |
| t.Fatal(err) | |
| } | |
| path, err := filepath.Abs("a") | |
| if err != nil { | |
| t.Fatal(err) | |
| } | |
| ia2, err := os.Stat(path) | |
| if err != nil { | |
| t.Fatal(err) | |
| } | |
| if !os.SameFile(ia1, ia2) { | |
| t.Errorf("files should be same") | |
| } | |
| p := filepath.VolumeName(path) + filepath.Base(path) | |
| if err != nil { | |
| t.Fatal(err) | |
| } | |
| ia3, err := os.Stat(p) | |
| if err != nil { | |
| t.Fatal(err) | |
| } | |
| if !os.SameFile(ia1, ia3) { | |
| t.Errorf("files should be same") | |
| } | |
| } | |
| func TestStatJunctionLink(t *testing.T) { | |
| if !supportJunctionLinks { | |
| t.Skip("skipping because junction links are not supported") | |
| } | |
| dir, err := ioutil.TempDir("", "go-build") | |
| if err != nil { | |
| t.Fatalf("failed to create temp directory: %v", err) | |
| } | |
| defer os.RemoveAll(dir) | |
| link := filepath.Join(filepath.Dir(dir), filepath.Base(dir)+"-link") | |
| output, err := osexec.Command("cmd", "/c", "mklink", "/J", link, dir).CombinedOutput() | |
| if err != nil { | |
| t.Fatalf("failed to run mklink %v %v: %v %q", link, dir, err, output) | |
| } | |
| defer os.Remove(link) | |
| fi, err := os.Stat(link) | |
| if err != nil { | |
| t.Fatalf("failed to stat link %v: %v", link, err) | |
| } | |
| expected := filepath.Base(dir) | |
| got := fi.Name() | |
| if !fi.IsDir() || expected != got { | |
| t.Fatalf("link should point to %v but points to %v instead", expected, got) | |
| } | |
| } | |
| func TestStartProcessAttr(t *testing.T) { | |
| p, err := os.StartProcess(os.Getenv("COMSPEC"), []string{"/c", "cd"}, new(os.ProcAttr)) | |
| if err != nil { | |
| return | |
| } | |
| defer p.Wait() | |
| t.Fatalf("StartProcess expected to fail, but succeeded.") | |
| } | |
| func TestShareNotExistError(t *testing.T) { | |
| if testing.Short() { | |
| t.Skip("slow test that uses network; skipping") | |
| } | |
| _, err := os.Stat(`\\no_such_server\no_such_share\no_such_file`) | |
| if err == nil { | |
| t.Fatal("stat succeeded, but expected to fail") | |
| } | |
| if !os.IsNotExist(err) { | |
| t.Fatalf("os.Stat failed with %q, but os.IsNotExist(err) is false", err) | |
| } | |
| } | |
| func TestBadNetPathError(t *testing.T) { | |
| const ERROR_BAD_NETPATH = syscall.Errno(53) | |
| if !os.IsNotExist(ERROR_BAD_NETPATH) { | |
| t.Fatal("os.IsNotExist(syscall.Errno(53)) is false, but want true") | |
| } | |
| } | |
| func TestStatDir(t *testing.T) { | |
| defer chtmpdir(t)() | |
| f, err := os.Open(".") | |
| if err != nil { | |
| t.Fatal(err) | |
| } | |
| defer f.Close() | |
| fi, err := f.Stat() | |
| if err != nil { | |
| t.Fatal(err) | |
| } | |
| err = os.Chdir("..") | |
| if err != nil { | |
| t.Fatal(err) | |
| } | |
| fi2, err := f.Stat() | |
| if err != nil { | |
| t.Fatal(err) | |
| } | |
| if !os.SameFile(fi, fi2) { | |
| t.Fatal("race condition occured") | |
| } | |
| } | |
| func TestOpenVolumeName(t *testing.T) { | |
| tmpdir, err := ioutil.TempDir("", "TestOpenVolumeName") | |
| if err != nil { | |
| t.Fatal(err) | |
| } | |
| defer os.RemoveAll(tmpdir) | |
| wd, err := os.Getwd() | |
| if err != nil { | |
| t.Fatal(err) | |
| } | |
| err = os.Chdir(tmpdir) | |
| if err != nil { | |
| t.Fatal(err) | |
| } | |
| defer os.Chdir(wd) | |
| want := []string{"file1", "file2", "file3", "gopher.txt"} | |
| sort.Strings(want) | |
| for _, name := range want { | |
| err := ioutil.WriteFile(filepath.Join(tmpdir, name), nil, 0777) | |
| if err != nil { | |
| t.Fatal(err) | |
| } | |
| } | |
| f, err := os.Open(filepath.VolumeName(tmpdir)) | |
| if err != nil { | |
| t.Fatal(err) | |
| } | |
| defer f.Close() | |
| have, err := f.Readdirnames(-1) | |
| if err != nil { | |
| t.Fatal(err) | |
| } | |
| sort.Strings(have) | |
| if strings.Join(want, "/") != strings.Join(have, "/") { | |
| t.Fatalf("unexpected file list %q, want %q", have, want) | |
| } | |
| } |