ソースを参照

Refactor of symlink tests to remove testdata dir

Signed-off-by: Tibor Vass <teabee89@gmail.com>
Tibor Vass 10 年 前
コミット
b7f352b0fb

+ 131 - 162
pkg/symlink/fs_test.go

@@ -3,248 +3,217 @@
 package symlink
 package symlink
 
 
 import (
 import (
+	"fmt"
 	"io/ioutil"
 	"io/ioutil"
 	"os"
 	"os"
 	"path/filepath"
 	"path/filepath"
 	"testing"
 	"testing"
 )
 )
 
 
-func abs(t *testing.T, p string) string {
-	o, err := filepath.Abs(p)
-	if err != nil {
-		t.Fatal(err)
-	}
-	return o
+type dirOrLink struct {
+	path   string
+	target string
 }
 }
 
 
-func TestFollowSymLinkNormal(t *testing.T) {
-	link := "testdata/fs/a/d/c/data"
+func makeFs(tmpdir string, fs []dirOrLink) error {
+	for _, s := range fs {
+		s.path = filepath.Join(tmpdir, s.path)
+		if s.target == "" {
+			os.MkdirAll(s.path, 0755)
+			continue
+		}
+		if err := os.MkdirAll(filepath.Dir(s.path), 0755); err != nil {
+			return err
+		}
+		if err := os.Symlink(s.target, s.path); err != nil && !os.IsExist(err) {
+			return err
+		}
+	}
+	return nil
+}
 
 
-	rewrite, err := FollowSymlinkInScope(link, "testdata")
+func testSymlink(tmpdir, path, expected, scope string) error {
+	rewrite, err := FollowSymlinkInScope(filepath.Join(tmpdir, path), filepath.Join(tmpdir, scope))
 	if err != nil {
 	if err != nil {
-		t.Fatal(err)
+		return err
 	}
 	}
-
-	if expected := abs(t, "testdata/b/c/data"); expected != rewrite {
-		t.Fatalf("Expected %s got %s", expected, rewrite)
+	expected, err = filepath.Abs(filepath.Join(tmpdir, expected))
+	if err != nil {
+		return err
 	}
 	}
+	if expected != rewrite {
+		return fmt.Errorf("Expected %q got %q", expected, rewrite)
+	}
+	return nil
 }
 }
 
 
-func TestFollowSymLinkRelativePath(t *testing.T) {
-	link := "testdata/fs/i"
-
-	rewrite, err := FollowSymlinkInScope(link, "testdata")
+func TestFollowSymlinkNormal(t *testing.T) {
+	tmpdir, err := ioutil.TempDir("", "TestFollowSymlinkNormal")
 	if err != nil {
 	if err != nil {
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}
-
-	if expected := abs(t, "testdata/fs/a"); expected != rewrite {
-		t.Fatalf("Expected %s got %s", expected, rewrite)
+	defer os.RemoveAll(tmpdir)
+	if err := makeFs(tmpdir, []dirOrLink{{path: "testdata/fs/a/d", target: "/b"}}); err != nil {
+		t.Fatal(err)
+	}
+	if err := testSymlink(tmpdir, "testdata/fs/a/d/c/data", "testdata/b/c/data", "testdata"); err != nil {
+		t.Fatal(err)
 	}
 	}
 }
 }
 
 
-func TestFollowSymLinkUnderLinkedDir(t *testing.T) {
-	dir, err := ioutil.TempDir("", "docker-fs-test")
+func TestFollowSymlinkRelativePath(t *testing.T) {
+	tmpdir, err := ioutil.TempDir("", "TestFollowSymlinkRelativePath")
 	if err != nil {
 	if err != nil {
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}
-	defer os.RemoveAll(dir)
-
-	os.Mkdir(filepath.Join(dir, "realdir"), 0700)
-	os.Symlink("realdir", filepath.Join(dir, "linkdir"))
-
-	linkDir := filepath.Join(dir, "linkdir", "foo")
-	dirUnderLinkDir := filepath.Join(dir, "linkdir", "foo", "bar")
-	os.MkdirAll(dirUnderLinkDir, 0700)
+	defer os.RemoveAll(tmpdir)
+	if err := makeFs(tmpdir, []dirOrLink{{path: "testdata/fs/i", target: "a"}}); err != nil {
+		t.Fatal(err)
+	}
+	if err := testSymlink(tmpdir, "testdata/fs/i", "testdata/fs/a", "testdata"); err != nil {
+		t.Fatal(err)
+	}
+}
 
 
-	rewrite, err := FollowSymlinkInScope(dirUnderLinkDir, linkDir)
+func TestFollowSymlinkUnderLinkedDir(t *testing.T) {
+	tmpdir, err := ioutil.TempDir("", "TestFollowSymlinkUnderLinkedDir")
 	if err != nil {
 	if err != nil {
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}
-
-	if rewrite != dirUnderLinkDir {
-		t.Fatalf("Expected %s got %s", dirUnderLinkDir, rewrite)
+	defer os.RemoveAll(tmpdir)
+	if err := makeFs(tmpdir, []dirOrLink{
+		{path: "linkdir", target: "realdir"},
+		{path: "linkdir/foo/bar"},
+	}); err != nil {
+		t.Fatal(err)
+	}
+	if err := testSymlink(tmpdir, "linkdir/foo/bar", "linkdir/foo/bar", "linkdir/foo"); err != nil {
+		t.Fatal(err)
 	}
 	}
 }
 }
 
 
-func TestFollowSymLinkRandomString(t *testing.T) {
+func TestFollowSymlinkRandomString(t *testing.T) {
 	if _, err := FollowSymlinkInScope("toto", "testdata"); err == nil {
 	if _, err := FollowSymlinkInScope("toto", "testdata"); err == nil {
 		t.Fatal("Random string should fail but didn't")
 		t.Fatal("Random string should fail but didn't")
 	}
 	}
 }
 }
 
 
-func TestFollowSymLinkLastLink(t *testing.T) {
-	link := "testdata/fs/a/d"
-
-	rewrite, err := FollowSymlinkInScope(link, "testdata")
+func TestFollowSymlinkLastLink(t *testing.T) {
+	tmpdir, err := ioutil.TempDir("", "TestFollowSymlinkLastLink")
 	if err != nil {
 	if err != nil {
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}
-
-	if expected := abs(t, "testdata/b"); expected != rewrite {
-		t.Fatalf("Expected %s got %s", expected, rewrite)
+	defer os.RemoveAll(tmpdir)
+	if err := makeFs(tmpdir, []dirOrLink{{path: "testdata/fs/a/d", target: "/b"}}); err != nil {
+		t.Fatal(err)
+	}
+	if err := testSymlink(tmpdir, "testdata/fs/a/d", "testdata/b", "testdata"); err != nil {
+		t.Fatal(err)
 	}
 	}
 }
 }
 
 
-func TestFollowSymLinkRelativeLink(t *testing.T) {
-	link := "testdata/fs/a/e/c/data"
-
-	rewrite, err := FollowSymlinkInScope(link, "testdata")
+func TestFollowSymlinkRelativeLink(t *testing.T) {
+	tmpdir, err := ioutil.TempDir("", "TestFollowSymlinkRelativeLink")
 	if err != nil {
 	if err != nil {
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}
-
-	if expected := abs(t, "testdata/fs/b/c/data"); expected != rewrite {
-		t.Fatalf("Expected %s got %s", expected, rewrite)
+	defer os.RemoveAll(tmpdir)
+	if err := makeFs(tmpdir, []dirOrLink{{path: "testdata/fs/a/e", target: "../b"}}); err != nil {
+		t.Fatal(err)
+	}
+	if err := testSymlink(tmpdir, "testdata/fs/a/e/c/data", "testdata/fs/b/c/data", "testdata"); err != nil {
+		t.Fatal(err)
 	}
 	}
 }
 }
 
 
-func TestFollowSymLinkRelativeLinkScope(t *testing.T) {
+func TestFollowSymlinkRelativeLinkScope(t *testing.T) {
+	tmpdir, err := ioutil.TempDir("", "TestFollowSymlinkRelativeLinkScope")
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer os.RemoveAll(tmpdir)
+
+	if err := makeFs(tmpdir, []dirOrLink{{path: "testdata/fs/a/f", target: "../../../../test"}}); err != nil {
+		t.Fatal(err)
+	}
 	// avoid letting symlink f lead us out of the "testdata" scope
 	// avoid letting symlink f lead us out of the "testdata" scope
 	// we don't normalize because symlink f is in scope and there is no
 	// we don't normalize because symlink f is in scope and there is no
 	// information leak
 	// information leak
-	{
-		link := "testdata/fs/a/f"
-
-		rewrite, err := FollowSymlinkInScope(link, "testdata")
-		if err != nil {
-			t.Fatal(err)
-		}
-
-		if expected := abs(t, "testdata/test"); expected != rewrite {
-			t.Fatalf("Expected %s got %s", expected, rewrite)
-		}
+	if err := testSymlink(tmpdir, "testdata/fs/a/f", "testdata/test", "testdata"); err != nil {
+		t.Fatal(err)
 	}
 	}
-
 	// avoid letting symlink f lead us out of the "testdata/fs" scope
 	// avoid letting symlink f lead us out of the "testdata/fs" scope
 	// we don't normalize because symlink f is in scope and there is no
 	// we don't normalize because symlink f is in scope and there is no
 	// information leak
 	// information leak
-	{
-		link := "testdata/fs/a/f"
-
-		rewrite, err := FollowSymlinkInScope(link, "testdata/fs")
-		if err != nil {
-			t.Fatal(err)
-		}
-
-		if expected := abs(t, "testdata/fs/test"); expected != rewrite {
-			t.Fatalf("Expected %s got %s", expected, rewrite)
-		}
+	if err := testSymlink(tmpdir, "testdata/fs/a/f", "testdata/fs/test", "testdata/fs"); err != nil {
+		t.Fatal(err)
 	}
 	}
 
 
 	// avoid letting symlink g (pointed at by symlink h) take out of scope
 	// avoid letting symlink g (pointed at by symlink h) take out of scope
 	// TODO: we should probably normalize to scope here because ../[....]/root
 	// TODO: we should probably normalize to scope here because ../[....]/root
 	// is out of scope and we leak information
 	// is out of scope and we leak information
-	{
-		link := "testdata/fs/b/h"
-
-		rewrite, err := FollowSymlinkInScope(link, "testdata")
-		if err != nil {
-			t.Fatal(err)
-		}
-
-		if expected := abs(t, "testdata/root"); expected != rewrite {
-			t.Fatalf("Expected %s got %s", expected, rewrite)
-		}
+	if err := makeFs(tmpdir, []dirOrLink{
+		{path: "testdata/fs/b/h", target: "../g"},
+		{path: "testdata/fs/g", target: "../../../../../../../../../../../../root"},
+	}); err != nil {
+		t.Fatal(err)
+	}
+	if err := testSymlink(tmpdir, "testdata/fs/b/h", "testdata/root", "testdata"); err != nil {
+		t.Fatal(err)
 	}
 	}
 
 
 	// avoid letting allowing symlink e lead us to ../b
 	// avoid letting allowing symlink e lead us to ../b
 	// normalize to the "testdata/fs/a"
 	// normalize to the "testdata/fs/a"
-	{
-		link := "testdata/fs/a/e"
-
-		rewrite, err := FollowSymlinkInScope(link, "testdata/fs/a")
-		if err != nil {
-			t.Fatal(err)
-		}
-
-		if expected := abs(t, "testdata/fs/a"); expected != rewrite {
-			t.Fatalf("Expected %s got %s", expected, rewrite)
-		}
+	if err := makeFs(tmpdir, []dirOrLink{
+		{path: "testdata/fs/a/e", target: "../b"},
+	}); err != nil {
+		t.Fatal(err)
+	}
+	if err := testSymlink(tmpdir, "testdata/fs/a/e", "testdata/fs/a/b", "testdata/fs/a"); err != nil {
+		t.Fatal(err)
 	}
 	}
 
 
 	// avoid letting symlink -> ../directory/file escape from scope
 	// avoid letting symlink -> ../directory/file escape from scope
 	// normalize to "testdata/fs/j"
 	// normalize to "testdata/fs/j"
-	{
-		link := "testdata/fs/j/k"
-
-		rewrite, err := FollowSymlinkInScope(link, "testdata/fs/j")
-		if err != nil {
-			t.Fatal(err)
-		}
-
-		if expected := abs(t, "testdata/fs/j"); expected != rewrite {
-			t.Fatalf("Expected %s got %s", expected, rewrite)
-		}
+	if err := makeFs(tmpdir, []dirOrLink{{path: "testdata/fs/j/k", target: "../i/a"}}); err != nil {
+		t.Fatal(err)
+	}
+	if err := testSymlink(tmpdir, "testdata/fs/j/k", "testdata/fs/j/i/a", "testdata/fs/j"); err != nil {
+		t.Fatal(err)
 	}
 	}
 
 
 	// make sure we don't allow escaping to /
 	// make sure we don't allow escaping to /
 	// normalize to dir
 	// normalize to dir
-	{
-		dir, err := ioutil.TempDir("", "docker-fs-test")
-		if err != nil {
-			t.Fatal(err)
-		}
-		defer os.RemoveAll(dir)
-
-		linkFile := filepath.Join(dir, "foo")
-		os.Mkdir(filepath.Join(dir, ""), 0700)
-		os.Symlink("/", linkFile)
-
-		rewrite, err := FollowSymlinkInScope(linkFile, dir)
-		if err != nil {
-			t.Fatal(err)
-		}
-
-		if rewrite != dir {
-			t.Fatalf("Expected %s got %s", dir, rewrite)
-		}
+	if err := makeFs(tmpdir, []dirOrLink{{path: "foo", target: "/"}}); err != nil {
+		t.Fatal(err)
+	}
+	if err := testSymlink(tmpdir, "foo", "", ""); err != nil {
+		t.Fatal(err)
 	}
 	}
 
 
 	// make sure we don't allow escaping to /
 	// make sure we don't allow escaping to /
 	// normalize to dir
 	// normalize to dir
-	{
-		dir, err := ioutil.TempDir("", "docker-fs-test")
-		if err != nil {
-			t.Fatal(err)
-		}
-		defer os.RemoveAll(dir)
-
-		linkFile := filepath.Join(dir, "foo")
-		os.Mkdir(filepath.Join(dir, ""), 0700)
-		os.Symlink("/../../", linkFile)
-
-		rewrite, err := FollowSymlinkInScope(linkFile, dir)
-		if err != nil {
-			t.Fatal(err)
-		}
-
-		if rewrite != dir {
-			t.Fatalf("Expected %s got %s", dir, rewrite)
-		}
+	if err := makeFs(filepath.Join(tmpdir, "dir", "subdir"), []dirOrLink{{path: "foo", target: "/../../"}}); err != nil {
+		t.Fatal(err)
+	}
+	if err := testSymlink(tmpdir, "foo", "", ""); err != nil {
+		t.Fatal(err)
 	}
 	}
 
 
 	// make sure we stay in scope without leaking information
 	// make sure we stay in scope without leaking information
 	// this also checks for escaping to /
 	// this also checks for escaping to /
 	// normalize to dir
 	// normalize to dir
-	{
-		dir, err := ioutil.TempDir("", "docker-fs-test")
-		if err != nil {
-			t.Fatal(err)
-		}
-		defer os.RemoveAll(dir)
-
-		linkFile := filepath.Join(dir, "foo")
-		os.Mkdir(filepath.Join(dir, ""), 0700)
-		os.Symlink("../../", linkFile)
-
-		rewrite, err := FollowSymlinkInScope(linkFile, dir)
-		if err != nil {
-			t.Fatal(err)
-		}
+	if err := makeFs(filepath.Join(tmpdir, "dir", "subdir"), []dirOrLink{{path: "foo", target: "../../"}}); err != nil {
+		t.Fatal(err)
+	}
+	if err := testSymlink(tmpdir, "foo", "", ""); err != nil {
+		t.Fatal(err)
+	}
 
 
-		if rewrite != dir {
-			t.Fatalf("Expected %s got %s", dir, rewrite)
-		}
+	if err := makeFs(tmpdir, []dirOrLink{{path: "bar/foo", target: "baz/target"}}); err != nil {
+		t.Fatal(err)
+	}
+	if err := testSymlink(tmpdir, "bar/foo", "bar/baz/target", ""); err != nil {
+		t.Fatal(err)
 	}
 	}
 }
 }

+ 0 - 1
pkg/symlink/testdata/fs/a/d

@@ -1 +0,0 @@
-/b

+ 0 - 1
pkg/symlink/testdata/fs/a/e

@@ -1 +0,0 @@
-../b

+ 0 - 1
pkg/symlink/testdata/fs/a/f

@@ -1 +0,0 @@
-../../../../test

+ 0 - 1
pkg/symlink/testdata/fs/b/h

@@ -1 +0,0 @@
-../g

+ 0 - 1
pkg/symlink/testdata/fs/g

@@ -1 +0,0 @@
-../../../../../../../../../../../../root

+ 0 - 1
pkg/symlink/testdata/fs/i

@@ -1 +0,0 @@
-a

+ 0 - 1
pkg/symlink/testdata/fs/j/k

@@ -1 +0,0 @@
-../i/a