Преглед изворни кода

Test pulling remote files using ADD in a buildfile.

Caleb Spare пре 12 година
родитељ
комит
f236e62d9d
1 измењених фајлова са 80 додато и 23 уклоњено
  1. 80 23
      buildfile_test.go

+ 80 - 23
buildfile_test.go

@@ -3,13 +3,17 @@ package docker
 import (
 	"fmt"
 	"io/ioutil"
+	"net"
+	"net/http"
+	"net/http/httptest"
+	"strings"
 	"testing"
 )
 
 // mkTestContext generates a build context from the contents of the provided dockerfile.
 // This context is suitable for use as an argument to BuildFile.Build()
 func mkTestContext(dockerfile string, files [][2]string, t *testing.T) Archive {
-	context, err := mkBuildContext(fmt.Sprintf(dockerfile, unitTestImageID), files)
+	context, err := mkBuildContext(dockerfile, files)
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -22,6 +26,8 @@ type testContextTemplate struct {
 	dockerfile string
 	// Additional files in the context, eg [][2]string{"./passwd", "gordon"}
 	files [][2]string
+	// Additional remote files to host on a local HTTP server.
+	remoteFiles [][2]string
 }
 
 // A table of all the contexts to build and test.
@@ -29,27 +35,31 @@ type testContextTemplate struct {
 var testContexts = []testContextTemplate{
 	{
 		`
-from   %s
+from   {IMAGE}
 run    sh -c 'echo root:testpass > /tmp/passwd'
 run    mkdir -p /var/run/sshd
 run    [ "$(cat /tmp/passwd)" = "root:testpass" ]
 run    [ "$(ls -d /var/run/sshd)" = "/var/run/sshd" ]
 `,
 		nil,
+		nil,
 	},
 
 	{
 		`
-from %s
+from {IMAGE}
 add foo /usr/lib/bla/bar
-run [ "$(cat /usr/lib/bla/bar)" = 'hello world!' ]
+run [ "$(cat /usr/lib/bla/bar)" = 'hello' ]
+add http://{SERVERADDR}/baz /usr/lib/baz/quux
+run [ "$(cat /usr/lib/baz/quux)" = 'world!' ]
 `,
-		[][2]string{{"foo", "hello world!"}},
+		[][2]string{{"foo", "hello"}},
+		[][2]string{{"/baz", "world!"}},
 	},
 
 	{
 		`
-from %s
+from {IMAGE}
 add f /
 run [ "$(cat /f)" = "hello" ]
 add f /abc
@@ -71,38 +81,70 @@ run [ "$(cat /somewheeeere/over/the/rainbooow/ga)" = "bu" ]
 			{"f", "hello"},
 			{"d/ga", "bu"},
 		},
+		nil,
 	},
 
 	{
 		`
-from %s
+from   {IMAGE}
 env    FOO BAR
 run    [ "$FOO" = "BAR" ]
 `,
 		nil,
+		nil,
 	},
 
 	{
 		`
-from %s
+from {IMAGE}
 ENTRYPOINT /bin/echo
 CMD Hello world
 `,
 		nil,
+		nil,
 	},
 
 	{
 		`
-from %s
+from {IMAGE}
 VOLUME /test
 CMD Hello world
 `,
 		nil,
+		nil,
 	},
 }
 
 // FIXME: test building with 2 successive overlapping ADD commands
 
+func constructDockerfile(template string, ip net.IP, port string) string {
+	serverAddr := fmt.Sprintf("%s:%s", ip, port)
+	replacer := strings.NewReplacer("{IMAGE}", unitTestImageID, "{SERVERADDR}", serverAddr)
+	return replacer.Replace(template)
+}
+
+func mkTestingFileServer(files [][2]string) (*httptest.Server, error) {
+	mux := http.NewServeMux()
+	for _, file := range files {
+		name, contents := file[0], file[1]
+		mux.HandleFunc(name, func(w http.ResponseWriter, r *http.Request) {
+			w.Write([]byte(contents))
+		})
+	}
+
+	// This is how httptest.NewServer sets up a net.Listener, except that our listener must accept remote
+	// connections (from the container).
+	listener, err := net.Listen("tcp", ":0")
+	if err != nil {
+		return nil, err
+	}
+
+	s := httptest.NewUnstartedServer(mux)
+	s.Listener = listener
+	s.Start()
+	return s, nil
+}
+
 func TestBuild(t *testing.T) {
 	for _, ctx := range testContexts {
 		buildImage(ctx, t)
@@ -121,9 +163,24 @@ func buildImage(context testContextTemplate, t *testing.T) *Image {
 		pullingPool: make(map[string]struct{}),
 		pushingPool: make(map[string]struct{}),
 	}
-	buildfile := NewBuildFile(srv, ioutil.Discard, false)
 
-	id, err := buildfile.Build(mkTestContext(context.dockerfile, context.files, t))
+	httpServer, err := mkTestingFileServer(context.remoteFiles)
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer httpServer.Close()
+
+	idx := strings.LastIndex(httpServer.URL, ":")
+	if idx < 0 {
+		t.Fatalf("could not get port from test http server address %s", httpServer.URL)
+	}
+	port := httpServer.URL[idx+1:]
+
+	ip := runtime.networkManager.bridgeNetwork.IP
+	dockerfile := constructDockerfile(context.dockerfile, ip, port)
+
+	buildfile := NewBuildFile(srv, ioutil.Discard, false)
+	id, err := buildfile.Build(mkTestContext(dockerfile, context.files, t))
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -137,10 +194,10 @@ func buildImage(context testContextTemplate, t *testing.T) *Image {
 
 func TestVolume(t *testing.T) {
 	img := buildImage(testContextTemplate{`
-        from %s
+        from {IMAGE}
         volume /test
         cmd Hello world
-    `, nil}, t)
+    `, nil, nil}, t)
 
 	if len(img.Config.Volumes) == 0 {
 		t.Fail()
@@ -154,9 +211,9 @@ func TestVolume(t *testing.T) {
 
 func TestBuildMaintainer(t *testing.T) {
 	img := buildImage(testContextTemplate{`
-        from %s
+        from {IMAGE}
         maintainer dockerio
-    `, nil}, t)
+    `, nil, nil}, t)
 
 	if img.Author != "dockerio" {
 		t.Fail()
@@ -165,10 +222,10 @@ func TestBuildMaintainer(t *testing.T) {
 
 func TestBuildEnv(t *testing.T) {
 	img := buildImage(testContextTemplate{`
-        from %s
+        from {IMAGE}
         env port 4243
         `,
-		nil}, t)
+		nil, nil}, t)
 
 	if img.Config.Env[0] != "port=4243" {
 		t.Fail()
@@ -177,10 +234,10 @@ func TestBuildEnv(t *testing.T) {
 
 func TestBuildCmd(t *testing.T) {
 	img := buildImage(testContextTemplate{`
-        from %s
+        from {IMAGE}
         cmd ["/bin/echo", "Hello World"]
         `,
-		nil}, t)
+		nil, nil}, t)
 
 	if img.Config.Cmd[0] != "/bin/echo" {
 		t.Log(img.Config.Cmd[0])
@@ -194,10 +251,10 @@ func TestBuildCmd(t *testing.T) {
 
 func TestBuildExpose(t *testing.T) {
 	img := buildImage(testContextTemplate{`
-        from %s
+        from {IMAGE}
         expose 4243
         `,
-		nil}, t)
+		nil, nil}, t)
 
 	if img.Config.PortSpecs[0] != "4243" {
 		t.Fail()
@@ -206,10 +263,10 @@ func TestBuildExpose(t *testing.T) {
 
 func TestBuildEntrypoint(t *testing.T) {
 	img := buildImage(testContextTemplate{`
-        from %s
+        from {IMAGE}
         entrypoint ["/bin/echo"]
         `,
-		nil}, t)
+		nil, nil}, t)
 
 	if img.Config.Entrypoint[0] != "/bin/echo" {
 	}