func TestSymlink(t *testing.T) { testenv.MustHaveSymlink(t) defer chtmpdir(t)() from, to := "symlinktestfrom", "symlinktestto" Remove(from) // Just in case. file, err := Create(to) if err != nil { t.Fatalf("open %q failed: %v", to, err) } defer Remove(to) if err = file.Close(); err != nil { t.Errorf("close %q failed: %v", to, err) } err = Symlink(to, from) if err != nil { t.Fatalf("symlink %q, %q failed: %v", to, from, err) } defer Remove(from) tostat, err := Lstat(to) if err != nil { t.Fatalf("stat %q failed: %v", to, err) } if tostat.Mode()&ModeSymlink != 0 { t.Fatalf("stat %q claims to have found a symlink", to) } fromstat, err := Stat(from) if err != nil { t.Fatalf("stat %q failed: %v", from, err) } if !SameFile(tostat, fromstat) { t.Errorf("symlink %q, %q did not create symlink", to, from) } fromstat, err = Lstat(from) if err != nil { t.Fatalf("lstat %q failed: %v", from, err) } if fromstat.Mode()&ModeSymlink == 0 { t.Fatalf("symlink %q, %q did not create symlink", to, from) } fromstat, err = Stat(from) if err != nil { t.Fatalf("stat %q failed: %v", from, err) } if fromstat.Mode()&ModeSymlink != 0 { t.Fatalf("stat %q did not follow symlink", from) } s, err := Readlink(from) if err != nil { t.Fatalf("readlink %q failed: %v", from, err) } if s != to { t.Fatalf("after symlink %q != %q", s, to) } file, err = Open(from) if err != nil { t.Fatalf("open %q failed: %v", from, err) } file.Close() }
func TestMkdirAllWithSymlink(t *testing.T) { testenv.MustHaveSymlink(t) tmpDir, err := ioutil.TempDir("", "TestMkdirAllWithSymlink-") if err != nil { t.Fatal(err) } defer RemoveAll(tmpDir) dir := tmpDir + "/dir" err = Mkdir(dir, 0755) if err != nil { t.Fatalf("Mkdir %s: %s", dir, err) } link := tmpDir + "/link" err = Symlink("dir", link) if err != nil { t.Fatalf("Symlink %s: %s", link, err) } path := link + "/foo" err = MkdirAll(path, 0755) if err != nil { t.Errorf("MkdirAll %q: %s", path, err) } }
func TestEvalSymlinksIsNotExist(t *testing.T) { testenv.MustHaveSymlink(t) defer chtmpdir(t)() _, err := filepath.EvalSymlinks("notexist") if !os.IsNotExist(err) { t.Errorf("expected the file is not found, got %v\n", err) } err = os.Symlink("notexist", "link") if err != nil { t.Fatal(err) } defer os.Remove("link") _, err = filepath.EvalSymlinks("link") if !os.IsNotExist(err) { t.Errorf("expected the file is not found, got %v\n", err) } }
func TestStatSymlinkLoop(t *testing.T) { testenv.MustHaveSymlink(t) defer chtmpdir(t)() err := os.Symlink("x", "y") if err != nil { t.Fatal(err) } defer os.Remove("y") err = os.Symlink("y", "x") if err != nil { t.Fatal(err) } defer os.Remove("x") _, err = os.Stat("x") if perr, ok := err.(*os.PathError); !ok || perr.Err != syscall.ELOOP { t.Errorf("expected *PathError with ELOOP, got %T: %v\n", err, err) } }
func TestLongSymlink(t *testing.T) { testenv.MustHaveSymlink(t) defer chtmpdir(t)() s := "0123456789abcdef" // Long, but not too long: a common limit is 255. s = s + s + s + s + s + s + s + s + s + s + s + s + s + s + s from := "longsymlinktestfrom" Remove(from) // Just in case. err := Symlink(s, from) if err != nil { t.Fatalf("symlink %q, %q failed: %v", s, from, err) } defer Remove(from) r, err := Readlink(from) if err != nil { t.Fatalf("readlink %q failed: %v", from, err) } if r != s { t.Fatalf("after symlink %q != %q", r, s) } }
func TestGlobSymlink(t *testing.T) { testenv.MustHaveSymlink(t) tmpDir, err := ioutil.TempDir("", "globsymlink") if err != nil { t.Fatal("creating temp dir:", err) } defer os.RemoveAll(tmpDir) for _, tt := range globSymlinkTests { path := Join(tmpDir, tt.path) dest := Join(tmpDir, tt.dest) f, err := os.Create(path) if err != nil { t.Fatal(err) } if err := f.Close(); err != nil { t.Fatal(err) } err = os.Symlink(path, dest) if err != nil { t.Fatal(err) } if tt.brokenLink { // Break the symlink. os.Remove(path) } matches, err := Glob(dest) if err != nil { t.Errorf("GlobSymlink error for %q: %s", dest, err) } if !contains(matches, dest) { t.Errorf("Glob(%#q) = %#v want %v", dest, matches, dest) } } }
func TestNetworkSymbolicLink(t *testing.T) { testenv.MustHaveSymlink(t) dir, err := ioutil.TempDir("", "TestNetworkSymbolicLink") if err != nil { t.Fatal(err) } defer os.RemoveAll(dir) oldwd, err := os.Getwd() if err != nil { t.Fatal(err) } err = os.Chdir(dir) if err != nil { t.Fatal(err) } defer os.Chdir(oldwd) shareName := "GoSymbolicLinkTestShare" // hope no conflictions sharePath := filepath.Join(dir, shareName) testDir := "TestDir" err = os.MkdirAll(filepath.Join(sharePath, testDir), 0777) if err != nil { t.Fatal(err) } wShareName, err := syscall.UTF16PtrFromString(shareName) if err != nil { t.Fatal(err) } wSharePath, err := syscall.UTF16PtrFromString(sharePath) if err != nil { t.Fatal(err) } p := windows.SHARE_INFO_2{ Netname: wShareName, Type: windows.STYPE_DISKTREE, Remark: nil, Permissions: 0, MaxUses: 1, CurrentUses: 0, Path: wSharePath, Passwd: nil, } err = windows.NetShareAdd(nil, 2, (*byte)(unsafe.Pointer(&p)), nil) if err != nil { if err == syscall.ERROR_ACCESS_DENIED { t.Skip("you don't have enough privileges to add network share") } t.Fatal(err) } defer func() { err := windows.NetShareDel(nil, wShareName, 0) if err != nil { t.Fatal(err) } }() UNCPath := `\\localhost\` + shareName + `\` fi1, err := os.Stat(sharePath) if err != nil { t.Fatal(err) } fi2, err := os.Stat(UNCPath) if err != nil { t.Fatal(err) } if !os.SameFile(fi1, fi2) { t.Fatalf("%q and %q should be the same directory, but not", sharePath, UNCPath) } target := filepath.Join(UNCPath, testDir) link := "link" err = os.Symlink(target, link) if err != nil { t.Fatal(err) } defer os.Remove(link) got, err := os.Readlink(link) if err != nil { t.Fatal(err) } if got != target { t.Errorf(`os.Readlink("%s"): got %v, want %v`, link, got, target) } }
func TestIssue13582(t *testing.T) { testenv.MustHaveSymlink(t) tmpDir, err := ioutil.TempDir("", "issue13582") if err != nil { t.Fatal(err) } defer os.RemoveAll(tmpDir) dir := filepath.Join(tmpDir, "dir") err = os.Mkdir(dir, 0755) if err != nil { t.Fatal(err) } linkToDir := filepath.Join(tmpDir, "link_to_dir") err = os.Symlink(dir, linkToDir) if err != nil { t.Fatal(err) } file := filepath.Join(linkToDir, "file") err = ioutil.WriteFile(file, nil, 0644) if err != nil { t.Fatal(err) } link1 := filepath.Join(linkToDir, "link1") err = os.Symlink(file, link1) if err != nil { t.Fatal(err) } link2 := filepath.Join(linkToDir, "link2") err = os.Symlink(link1, link2) if err != nil { t.Fatal(err) } // /tmp may itself be a symlink! realTmpDir, err := filepath.EvalSymlinks(tmpDir) if err != nil { t.Fatal(err) } realDir := filepath.Join(realTmpDir, "dir") realFile := filepath.Join(realDir, "file") tests := []struct { path, want string }{ {dir, realDir}, {linkToDir, realDir}, {file, realFile}, {link1, realFile}, {link2, realFile}, } for i, test := range tests { have, err := filepath.EvalSymlinks(test.path) if err != nil { t.Fatal(err) } if have != test.want { t.Errorf("test#%d: EvalSymlinks(%q) returns %q, want %q", i, test.path, have, test.want) } } }
func TestEvalSymlinks(t *testing.T) { testenv.MustHaveSymlink(t) tmpDir, err := ioutil.TempDir("", "evalsymlink") if err != nil { t.Fatal("creating temp dir:", err) } defer os.RemoveAll(tmpDir) // /tmp may itself be a symlink! Avoid the confusion, although // it means trusting the thing we're testing. tmpDir, err = filepath.EvalSymlinks(tmpDir) if err != nil { t.Fatal("eval symlink for tmp dir:", err) } tests := EvalSymlinksTests testdirs := EvalSymlinksTestDirs if runtime.GOOS == "windows" { if len(tmpDir) < 3 { t.Fatalf("tmpDir path %q is too short", tmpDir) } if tmpDir[1] != ':' { t.Fatalf("tmpDir path %q must have drive letter in it", tmpDir) } newtest := EvalSymlinksTest{"test/linkabswin", tmpDir[:3]} tests = append(tests, newtest) testdirs = append(testdirs, newtest) } // Create the symlink farm using relative paths. for _, d := range testdirs { var err error path := simpleJoin(tmpDir, d.path) if d.dest == "" { err = os.Mkdir(path, 0755) } else { err = os.Symlink(d.dest, path) } if err != nil { t.Fatal(err) } } wd, err := os.Getwd() if err != nil { t.Fatal(err) } // Evaluate the symlink farm. for _, d := range tests { path := simpleJoin(tmpDir, d.path) dest := simpleJoin(tmpDir, d.dest) if filepath.IsAbs(d.dest) || os.IsPathSeparator(d.dest[0]) { dest = d.dest } if p, err := filepath.EvalSymlinks(path); err != nil { t.Errorf("EvalSymlinks(%q) error: %v", d.path, err) } else if filepath.Clean(p) != filepath.Clean(dest) { t.Errorf("EvalSymlinks(%q)=%q, want %q", path, p, dest) } // test EvalSymlinks(".") func() { defer func() { err := os.Chdir(wd) if err != nil { t.Fatal(err) } }() err := os.Chdir(path) if err != nil { t.Error(err) return } p, err := filepath.EvalSymlinks(".") if err != nil { t.Errorf(`EvalSymlinks(".") in %q directory error: %v`, d.path, err) return } if p == "." { return } want := filepath.Clean(findEvalSymlinksTestDirsDest(t, testdirs, d.path)) if p == want { return } t.Errorf(`EvalSymlinks(".") in %q directory returns %q, want "." or %q`, d.path, p, want) }() // test EvalSymlinks("C:.") on Windows if runtime.GOOS == "windows" { func() { defer func() { err := os.Chdir(wd) if err != nil { t.Fatal(err) } }() err := os.Chdir(path) if err != nil { t.Error(err) return } volDot := filepath.VolumeName(tmpDir) + "." p, err := filepath.EvalSymlinks(volDot) if err != nil { t.Errorf(`EvalSymlinks("%s") in %q directory error: %v`, volDot, d.path, err) return } if p == volDot { return } want := filepath.Clean(findEvalSymlinksTestDirsDest(t, testdirs, d.path)) if p == want { return } t.Errorf(`EvalSymlinks("%s") in %q directory returns %q, want %q or %q`, volDot, d.path, p, volDot, want) }() } // test EvalSymlinks(".."+path) func() { defer func() { err := os.Chdir(wd) if err != nil { t.Fatal(err) } }() err := os.Chdir(simpleJoin(tmpDir, "test")) if err != nil { t.Error(err) return } path := simpleJoin("..", d.path) dest := simpleJoin("..", d.dest) if filepath.IsAbs(d.dest) || os.IsPathSeparator(d.dest[0]) { dest = d.dest } if p, err := filepath.EvalSymlinks(path); err != nil { t.Errorf("EvalSymlinks(%q) error: %v", d.path, err) } else if filepath.Clean(p) != filepath.Clean(dest) { t.Errorf("EvalSymlinks(%q)=%q, want %q", path, p, dest) } }() // test EvalSymlinks where parameter is relative path func() { defer func() { err := os.Chdir(wd) if err != nil { t.Fatal(err) } }() err := os.Chdir(tmpDir) if err != nil { t.Error(err) return } if p, err := filepath.EvalSymlinks(d.path); err != nil { t.Errorf("EvalSymlinks(%q) error: %v", d.path, err) } else if filepath.Clean(p) != filepath.Clean(d.dest) { t.Errorf("EvalSymlinks(%q)=%q, want %q", d.path, p, d.dest) } }() } }