1 package os_test 2 3 import ( 4 "io/ioutil" 5 "os" 6 osexec "os/exec" 7 "path/filepath" 8 "strings" 9 "syscall" 10 "testing" 11 ) 12 13 var supportJunctionLinks = true 14 15 func init() { 16 tmpdir, err := ioutil.TempDir("", "symtest") 17 if err != nil { 18 panic("failed to create temp directory: " + err.Error()) 19 } 20 defer os.RemoveAll(tmpdir) 21 22 err = os.Symlink("target", filepath.Join(tmpdir, "symlink")) 23 if err != nil { 24 err = err.(*os.LinkError).Err 25 switch err { 26 case syscall.EWINDOWS, syscall.ERROR_PRIVILEGE_NOT_HELD: 27 supportsSymlinks = false 28 } 29 } 30 defer os.Remove("target") 31 32 b, _ := osexec.Command("cmd", "/c", "mklink", "/?").Output() 33 if !strings.Contains(string(b), " /J ") { 34 supportJunctionLinks = false 35 } 36 } 37 38 func TestSameWindowsFile(t *testing.T) { 39 temp, err := ioutil.TempDir("", "TestSameWindowsFile") 40 if err != nil { 41 t.Fatal(err) 42 } 43 defer os.RemoveAll(temp) 44 45 wd, err := os.Getwd() 46 if err != nil { 47 t.Fatal(err) 48 } 49 err = os.Chdir(temp) 50 if err != nil { 51 t.Fatal(err) 52 } 53 defer os.Chdir(wd) 54 55 f, err := os.Create("a") 56 if err != nil { 57 t.Fatal(err) 58 } 59 f.Close() 60 61 ia1, err := os.Stat("a") 62 if err != nil { 63 t.Fatal(err) 64 } 65 66 path, err := filepath.Abs("a") 67 if err != nil { 68 t.Fatal(err) 69 } 70 ia2, err := os.Stat(path) 71 if err != nil { 72 t.Fatal(err) 73 } 74 if !os.SameFile(ia1, ia2) { 75 t.Errorf("files should be same") 76 } 77 78 p := filepath.VolumeName(path) + filepath.Base(path) 79 if err != nil { 80 t.Fatal(err) 81 } 82 ia3, err := os.Stat(p) 83 if err != nil { 84 t.Fatal(err) 85 } 86 if !os.SameFile(ia1, ia3) { 87 t.Errorf("files should be same") 88 } 89 } 90 91 func TestStatJunctionLink(t *testing.T) { 92 if !supportJunctionLinks { 93 t.Skip("skipping because junction links are not supported") 94 } 95 96 dir, err := ioutil.TempDir("", "go-build") 97 if err != nil { 98 t.Fatalf("failed to create temp directory: %v", err) 99 } 100 defer os.RemoveAll(dir) 101 102 link := filepath.Join(filepath.Dir(dir), filepath.Base(dir)+"-link") 103 104 output, err := osexec.Command("cmd", "/c", "mklink", "/J", link, dir).CombinedOutput() 105 if err != nil { 106 t.Fatalf("failed to run mklink %v %v: %v %q", link, dir, err, output) 107 } 108 defer os.Remove(link) 109 110 fi, err := os.Stat(link) 111 if err != nil { 112 t.Fatalf("failed to stat link %v: %v", link, err) 113 } 114 expected := filepath.Base(dir) 115 got := fi.Name() 116 if !fi.IsDir() || expected != got { 117 t.Fatalf("link should point to %v but points to %v instead", expected, got) 118 } 119 } 120 121 func TestStartProcessAttr(t *testing.T) { 122 p, err := os.StartProcess(os.Getenv("COMSPEC"), []string{"/c", "cd"}, new(os.ProcAttr)) 123 if err != nil { 124 return 125 } 126 defer p.Wait() 127 t.Fatalf("StartProcess expected to fail, but succeeded.") 128 } 129