Browse Source

Move TearDownTest cleaning to environment package

Signed-off-by: Vincent Demeester <vincent@sbr.pm>
Vincent Demeester 8 years ago
parent
commit
1858656925

+ 9 - 21
integration-cli/check_test.go

@@ -34,9 +34,6 @@ const (
 var (
 var (
 	testEnv *environment.Execution
 	testEnv *environment.Execution
 
 
-	// FIXME(vdemeester) remove these and use environmentdaemonPid
-	protectedImages = map[string]struct{}{}
-
 	// the docker client binary to use
 	// the docker client binary to use
 	dockerBinary = "docker"
 	dockerBinary = "docker"
 )
 )
@@ -64,16 +61,6 @@ func TestMain(m *testing.M) {
 		os.Exit(1)
 		os.Exit(1)
 	}
 	}
 
 
-	cmd := exec.Command(dockerBinary, "images", "-f", "dangling=false", "--format", "{{.Repository}}:{{.Tag}}")
-	cmd.Env = appendBaseEnv(true)
-	out, err := cmd.CombinedOutput()
-	if err != nil {
-		panic(fmt.Errorf("err=%v\nout=%s\n", err, out))
-	}
-	images := strings.Split(strings.TrimSpace(string(out)), "\n")
-	for _, img := range images {
-		protectedImages[img] = struct{}{}
-	}
 	if testEnv.LocalDaemon() {
 	if testEnv.LocalDaemon() {
 		fmt.Println("INFO: Testing against a local daemon")
 		fmt.Println("INFO: Testing against a local daemon")
 	} else {
 	} else {
@@ -84,6 +71,14 @@ func TestMain(m *testing.M) {
 }
 }
 
 
 func Test(t *testing.T) {
 func Test(t *testing.T) {
+	cmd := exec.Command(dockerBinary, "images", "-f", "dangling=false", "--format", "{{.Repository}}:{{.Tag}}")
+	cmd.Env = appendBaseEnv(true)
+	out, err := cmd.CombinedOutput()
+	if err != nil {
+		panic(fmt.Errorf("err=%v\nout=%s\n", err, out))
+	}
+	images := strings.Split(strings.TrimSpace(string(out)), "\n")
+	testEnv.ProtectImage(t, images...)
 	if testEnv.DaemonPlatform() == "linux" {
 	if testEnv.DaemonPlatform() == "linux" {
 		ensureFrozenImagesLinux(t)
 		ensureFrozenImagesLinux(t)
 	}
 	}
@@ -104,14 +99,7 @@ func (s *DockerSuite) OnTimeout(c *check.C) {
 }
 }
 
 
 func (s *DockerSuite) TearDownTest(c *check.C) {
 func (s *DockerSuite) TearDownTest(c *check.C) {
-	unpauseAllContainers(c)
-	deleteAllContainers(c)
-	deleteAllImages(c)
-	deleteAllVolumes(c)
-	deleteAllNetworks(c)
-	if testEnv.DaemonPlatform() == "linux" {
-		deleteAllPlugins(c)
-	}
+	testEnv.Clean(c, dockerBinary)
 }
 }
 
 
 func init() {
 func init() {

+ 6 - 138
integration-cli/docker_utils_test.go

@@ -20,23 +20,19 @@ import (
 	"time"
 	"time"
 
 
 	"github.com/docker/docker/api/types"
 	"github.com/docker/docker/api/types"
-	volumetypes "github.com/docker/docker/api/types/volume"
 	"github.com/docker/docker/integration-cli/checker"
 	"github.com/docker/docker/integration-cli/checker"
 	"github.com/docker/docker/integration-cli/daemon"
 	"github.com/docker/docker/integration-cli/daemon"
+	"github.com/docker/docker/integration-cli/environment"
 	"github.com/docker/docker/integration-cli/registry"
 	"github.com/docker/docker/integration-cli/registry"
 	"github.com/docker/docker/integration-cli/request"
 	"github.com/docker/docker/integration-cli/request"
-	"github.com/docker/docker/opts"
 	"github.com/docker/docker/pkg/stringutils"
 	"github.com/docker/docker/pkg/stringutils"
 	icmd "github.com/docker/docker/pkg/testutil/cmd"
 	icmd "github.com/docker/docker/pkg/testutil/cmd"
 	"github.com/go-check/check"
 	"github.com/go-check/check"
 )
 )
 
 
+// Deprecated
 func daemonHost() string {
 func daemonHost() string {
-	daemonURLStr := "unix://" + opts.DefaultUnixSocket
-	if daemonHostVar := os.Getenv("DOCKER_HOST"); daemonHostVar != "" {
-		daemonURLStr = daemonHostVar
-	}
-	return daemonURLStr
+	return environment.DaemonHost()
 }
 }
 
 
 // FIXME(vdemeester) move this away are remove ignoreNoSuchContainer bool
 // FIXME(vdemeester) move this away are remove ignoreNoSuchContainer bool
@@ -58,6 +54,7 @@ func getAllContainers(c *check.C) string {
 	return result.Combined()
 	return result.Combined()
 }
 }
 
 
+// Deprecated
 func deleteAllContainers(c *check.C) {
 func deleteAllContainers(c *check.C) {
 	containers := getAllContainers(c)
 	containers := getAllContainers(c)
 	if containers != "" {
 	if containers != "" {
@@ -66,136 +63,6 @@ func deleteAllContainers(c *check.C) {
 	}
 	}
 }
 }
 
 
-func deleteAllNetworks(c *check.C) {
-	networks, err := getAllNetworks()
-	c.Assert(err, check.IsNil)
-	var errs []string
-	for _, n := range networks {
-		if n.Name == "bridge" || n.Name == "none" || n.Name == "host" {
-			continue
-		}
-		if testEnv.DaemonPlatform() == "windows" && strings.ToLower(n.Name) == "nat" {
-			// nat is a pre-defined network on Windows and cannot be removed
-			continue
-		}
-		status, b, err := request.SockRequest("DELETE", "/networks/"+n.Name, nil, daemonHost())
-		if err != nil {
-			errs = append(errs, err.Error())
-			continue
-		}
-		if status != http.StatusNoContent {
-			errs = append(errs, fmt.Sprintf("error deleting network %s: %s", n.Name, string(b)))
-		}
-	}
-	c.Assert(errs, checker.HasLen, 0, check.Commentf(strings.Join(errs, "\n")))
-}
-
-func getAllNetworks() ([]types.NetworkResource, error) {
-	var networks []types.NetworkResource
-	_, b, err := request.SockRequest("GET", "/networks", nil, daemonHost())
-	if err != nil {
-		return nil, err
-	}
-	if err := json.Unmarshal(b, &networks); err != nil {
-		return nil, err
-	}
-	return networks, nil
-}
-
-func deleteAllPlugins(c *check.C) {
-	plugins, err := getAllPlugins()
-	c.Assert(err, checker.IsNil)
-	var errs []string
-	for _, p := range plugins {
-		pluginName := p.Name
-		status, b, err := request.SockRequest("DELETE", "/plugins/"+pluginName+"?force=1", nil, daemonHost())
-		if err != nil {
-			errs = append(errs, err.Error())
-			continue
-		}
-		if status != http.StatusOK {
-			errs = append(errs, fmt.Sprintf("error deleting plugin %s: %s", p.Name, string(b)))
-		}
-	}
-	c.Assert(errs, checker.HasLen, 0, check.Commentf(strings.Join(errs, "\n")))
-}
-
-func getAllPlugins() (types.PluginsListResponse, error) {
-	var plugins types.PluginsListResponse
-	_, b, err := request.SockRequest("GET", "/plugins", nil, daemonHost())
-	if err != nil {
-		return nil, err
-	}
-	if err := json.Unmarshal(b, &plugins); err != nil {
-		return nil, err
-	}
-	return plugins, nil
-}
-
-func deleteAllVolumes(c *check.C) {
-	volumes, err := getAllVolumes()
-	c.Assert(err, checker.IsNil)
-	var errs []string
-	for _, v := range volumes {
-		status, b, err := request.SockRequest("DELETE", "/volumes/"+v.Name, nil, daemonHost())
-		if err != nil {
-			errs = append(errs, err.Error())
-			continue
-		}
-		if status != http.StatusNoContent {
-			errs = append(errs, fmt.Sprintf("error deleting volume %s: %s", v.Name, string(b)))
-		}
-	}
-	c.Assert(errs, checker.HasLen, 0, check.Commentf(strings.Join(errs, "\n")))
-}
-
-func getAllVolumes() ([]*types.Volume, error) {
-	var volumes volumetypes.VolumesListOKBody
-	_, b, err := request.SockRequest("GET", "/volumes", nil, daemonHost())
-	if err != nil {
-		return nil, err
-	}
-	if err := json.Unmarshal(b, &volumes); err != nil {
-		return nil, err
-	}
-	return volumes.Volumes, nil
-}
-
-func deleteAllImages(c *check.C) {
-	cmd := exec.Command(dockerBinary, "images", "--digests")
-	cmd.Env = appendBaseEnv(true)
-	out, err := cmd.CombinedOutput()
-	c.Assert(err, checker.IsNil)
-	lines := strings.Split(string(out), "\n")[1:]
-	imgMap := map[string]struct{}{}
-	for _, l := range lines {
-		if l == "" {
-			continue
-		}
-		fields := strings.Fields(l)
-		imgTag := fields[0] + ":" + fields[1]
-		if _, ok := protectedImages[imgTag]; !ok {
-			if fields[0] == "<none>" || fields[1] == "<none>" {
-				if fields[2] != "<none>" {
-					imgMap[fields[0]+"@"+fields[2]] = struct{}{}
-				} else {
-					imgMap[fields[3]] = struct{}{}
-				}
-				// continue
-			} else {
-				imgMap[imgTag] = struct{}{}
-			}
-		}
-	}
-	if len(imgMap) != 0 {
-		imgs := make([]string, 0, len(imgMap))
-		for k := range imgMap {
-			imgs = append(imgs, k)
-		}
-		dockerCmd(c, append([]string{"rmi", "-f"}, imgs...)...)
-	}
-}
-
 func getPausedContainers(c *check.C) []string {
 func getPausedContainers(c *check.C) []string {
 	result := icmd.RunCommand(dockerBinary, "ps", "-f", "status=paused", "-q", "-a")
 	result := icmd.RunCommand(dockerBinary, "ps", "-f", "status=paused", "-q", "-a")
 	result.Assert(c, icmd.Success)
 	result.Assert(c, icmd.Success)
@@ -206,6 +73,7 @@ func unpauseContainer(c *check.C, container string) {
 	dockerCmd(c, "unpause", container)
 	dockerCmd(c, "unpause", container)
 }
 }
 
 
+// Deprecated
 func unpauseAllContainers(c *check.C) {
 func unpauseAllContainers(c *check.C) {
 	containers := getPausedContainers(c)
 	containers := getPausedContainers(c)
 	for _, value := range containers {
 	for _, value := range containers {
@@ -487,7 +355,7 @@ func newRemoteFileServer(c *check.C, ctx *FakeContext) *remoteFileServer {
 		container = fmt.Sprintf("fileserver-cnt-%s", strings.ToLower(stringutils.GenerateRandomAlphaOnlyString(10)))
 		container = fmt.Sprintf("fileserver-cnt-%s", strings.ToLower(stringutils.GenerateRandomAlphaOnlyString(10)))
 	)
 	)
 
 
-	c.Assert(ensureHTTPServerImage(), checker.IsNil)
+	ensureHTTPServerImage(c)
 
 
 	// Build the image
 	// Build the image
 	fakeContextAddDockerfile(c, ctx, `FROM httpserver
 	fakeContextAddDockerfile(c, ctx, `FROM httpserver

+ 213 - 0
integration-cli/environment/clean.go

@@ -0,0 +1,213 @@
+package environment
+
+import (
+	"encoding/json"
+	"fmt"
+	"net/http"
+	"os"
+	"strings"
+
+	"github.com/docker/docker/api/types"
+	volumetypes "github.com/docker/docker/api/types/volume"
+	"github.com/docker/docker/integration-cli/request"
+	"github.com/docker/docker/opts"
+	icmd "github.com/docker/docker/pkg/testutil/cmd"
+)
+
+type testingT interface {
+	logT
+	Fatalf(string, ...interface{})
+}
+
+type logT interface {
+	Logf(string, ...interface{})
+}
+
+// Clean the environment, preserving protected objects (images, containers, ...)
+// and removing everything else. It's meant to run after any tests so that they don't
+// depend on each others.
+func (e *Execution) Clean(t testingT, dockerBinary string) {
+	unpauseAllContainers(t, dockerBinary)
+	deleteAllContainers(t, dockerBinary)
+	deleteAllImages(t, dockerBinary, e.protectedElements.images)
+	deleteAllVolumes(t, dockerBinary)
+	deleteAllNetworks(t, dockerBinary, e.DaemonPlatform())
+	if e.DaemonPlatform() == "linux" {
+		deleteAllPlugins(t, dockerBinary)
+	}
+}
+
+func unpauseAllContainers(t testingT, dockerBinary string) {
+	containers := getPausedContainers(t, dockerBinary)
+	if len(containers) > 0 {
+		icmd.RunCommand(dockerBinary, append([]string{"unpause"}, containers...)...).Assert(t, icmd.Success)
+	}
+}
+
+func getPausedContainers(t testingT, dockerBinary string) []string {
+	result := icmd.RunCommand(dockerBinary, "ps", "-f", "status=paused", "-q", "-a")
+	result.Assert(t, icmd.Success)
+	return strings.Fields(result.Combined())
+}
+
+func deleteAllContainers(t testingT, dockerBinary string) {
+	containers := getAllContainers(t, dockerBinary)
+	if len(containers) > 0 {
+		icmd.RunCommand(dockerBinary, append([]string{"rm", "-fv"}, containers...)...).Assert(t, icmd.Success)
+	}
+}
+
+func getAllContainers(t testingT, dockerBinary string) []string {
+	result := icmd.RunCommand(dockerBinary, "ps", "-q", "-a")
+	result.Assert(t, icmd.Success)
+	return strings.Fields(result.Combined())
+}
+
+func deleteAllImages(t testingT, dockerBinary string, protectedImages map[string]struct{}) {
+	result := icmd.RunCommand(dockerBinary, "images", "--digests")
+	result.Assert(t, icmd.Success)
+	lines := strings.Split(string(result.Combined()), "\n")[1:]
+	imgMap := map[string]struct{}{}
+	for _, l := range lines {
+		if l == "" {
+			continue
+		}
+		fields := strings.Fields(l)
+		imgTag := fields[0] + ":" + fields[1]
+		if _, ok := protectedImages[imgTag]; !ok {
+			if fields[0] == "<none>" || fields[1] == "<none>" {
+				if fields[2] != "<none>" {
+					imgMap[fields[0]+"@"+fields[2]] = struct{}{}
+				} else {
+					imgMap[fields[3]] = struct{}{}
+				}
+				// continue
+			} else {
+				imgMap[imgTag] = struct{}{}
+			}
+		}
+	}
+	if len(imgMap) != 0 {
+		imgs := make([]string, 0, len(imgMap))
+		for k := range imgMap {
+			imgs = append(imgs, k)
+		}
+		icmd.RunCommand(dockerBinary, append([]string{"rmi", "-f"}, imgs...)...).Assert(t, icmd.Success)
+	}
+}
+
+func deleteAllVolumes(t testingT, dockerBinary string) {
+	volumes, err := getAllVolumes()
+	if err != nil {
+		t.Fatalf("%v", err)
+	}
+	var errs []string
+	for _, v := range volumes {
+		status, b, err := request.SockRequest("DELETE", "/volumes/"+v.Name, nil, DaemonHost())
+		if err != nil {
+			errs = append(errs, err.Error())
+			continue
+		}
+		if status != http.StatusNoContent {
+			errs = append(errs, fmt.Sprintf("error deleting volume %s: %s", v.Name, string(b)))
+		}
+	}
+	if len(errs) > 0 {
+		t.Fatalf("%v", strings.Join(errs, "\n"))
+	}
+}
+
+func getAllVolumes() ([]*types.Volume, error) {
+	var volumes volumetypes.VolumesListOKBody
+	_, b, err := request.SockRequest("GET", "/volumes", nil, DaemonHost())
+	if err != nil {
+		return nil, err
+	}
+	if err := json.Unmarshal(b, &volumes); err != nil {
+		return nil, err
+	}
+	return volumes.Volumes, nil
+}
+
+func deleteAllNetworks(t testingT, dockerBinary string, daemonPlatform string) {
+	networks, err := getAllNetworks()
+	if err != nil {
+		t.Fatalf("%v", err)
+	}
+	var errs []string
+	for _, n := range networks {
+		if n.Name == "bridge" || n.Name == "none" || n.Name == "host" {
+			continue
+		}
+		if daemonPlatform == "windows" && strings.ToLower(n.Name) == "nat" {
+			// nat is a pre-defined network on Windows and cannot be removed
+			continue
+		}
+		status, b, err := request.SockRequest("DELETE", "/networks/"+n.Name, nil, DaemonHost())
+		if err != nil {
+			errs = append(errs, err.Error())
+			continue
+		}
+		if status != http.StatusNoContent {
+			errs = append(errs, fmt.Sprintf("error deleting network %s: %s", n.Name, string(b)))
+		}
+	}
+	if len(errs) > 0 {
+		t.Fatalf("%v", strings.Join(errs, "\n"))
+	}
+}
+
+func getAllNetworks() ([]types.NetworkResource, error) {
+	var networks []types.NetworkResource
+	_, b, err := request.SockRequest("GET", "/networks", nil, DaemonHost())
+	if err != nil {
+		return nil, err
+	}
+	if err := json.Unmarshal(b, &networks); err != nil {
+		return nil, err
+	}
+	return networks, nil
+}
+
+func deleteAllPlugins(t testingT, dockerBinary string) {
+	plugins, err := getAllPlugins()
+	if err != nil {
+		t.Fatalf("%v", err)
+	}
+	var errs []string
+	for _, p := range plugins {
+		pluginName := p.Name
+		status, b, err := request.SockRequest("DELETE", "/plugins/"+pluginName+"?force=1", nil, DaemonHost())
+		if err != nil {
+			errs = append(errs, err.Error())
+			continue
+		}
+		if status != http.StatusOK {
+			errs = append(errs, fmt.Sprintf("error deleting plugin %s: %s", p.Name, string(b)))
+		}
+	}
+	if len(errs) > 0 {
+		t.Fatalf("%v", strings.Join(errs, "\n"))
+	}
+}
+
+func getAllPlugins() (types.PluginsListResponse, error) {
+	var plugins types.PluginsListResponse
+	_, b, err := request.SockRequest("GET", "/plugins", nil, DaemonHost())
+	if err != nil {
+		return nil, err
+	}
+	if err := json.Unmarshal(b, &plugins); err != nil {
+		return nil, err
+	}
+	return plugins, nil
+}
+
+// DaemonHost return the daemon host string for this test execution
+func DaemonHost() string {
+	daemonURLStr := "unix://" + opts.DefaultUnixSocket
+	if daemonHostVar := os.Getenv("DOCKER_HOST"); daemonHostVar != "" {
+		daemonURLStr = daemonHostVar
+	}
+	return daemonURLStr
+}

+ 5 - 0
integration-cli/environment/environment.go

@@ -32,6 +32,8 @@ type Execution struct {
 	// baseImage is the name of the base image for testing
 	// baseImage is the name of the base image for testing
 	// Environment variable WINDOWS_BASE_IMAGE can override this
 	// Environment variable WINDOWS_BASE_IMAGE can override this
 	baseImage string
 	baseImage string
+
+	protectedElements protectedElements
 }
 }
 
 
 // New creates a new Execution struct
 // New creates a new Execution struct
@@ -100,6 +102,9 @@ func New() (*Execution, error) {
 		daemonPid:            daemonPid,
 		daemonPid:            daemonPid,
 		experimentalDaemon:   info.ExperimentalBuild,
 		experimentalDaemon:   info.ExperimentalBuild,
 		baseImage:            baseImage,
 		baseImage:            baseImage,
+		protectedElements: protectedElements{
+			images: map[string]struct{}{},
+		},
 	}, nil
 	}, nil
 }
 }
 func getDaemonDockerInfo() (types.Info, error) {
 func getDaemonDockerInfo() (types.Info, error) {

+ 12 - 0
integration-cli/environment/protect.go

@@ -0,0 +1,12 @@
+package environment
+
+// ProtectImage adds the specified image(s) to be protected in case of clean
+func (e *Execution) ProtectImage(t testingT, images ...string) {
+	for _, image := range images {
+		e.protectedElements.images[image] = struct{}{}
+	}
+}
+
+type protectedElements struct {
+	images map[string]struct{}
+}

+ 3 - 5
integration-cli/fixtures_linux_daemon_test.go

@@ -31,9 +31,7 @@ func ensureFrozenImagesLinux(t testingT) {
 		t.Logf(dockerCmdWithError("images"))
 		t.Logf(dockerCmdWithError("images"))
 		t.Fatalf("%+v", err)
 		t.Fatalf("%+v", err)
 	}
 	}
-	for _, img := range images {
-		protectedImages[img] = struct{}{}
-	}
+	defer testEnv.ProtectImage(t, images...)
 }
 }
 
 
 var ensureSyscallTestOnce sync.Once
 var ensureSyscallTestOnce sync.Once
@@ -46,7 +44,7 @@ func ensureSyscallTest(c *check.C) {
 	if !doIt {
 	if !doIt {
 		return
 		return
 	}
 	}
-	protectedImages["syscall-test:latest"] = struct{}{}
+	defer testEnv.ProtectImage(c, "syscall-test:latest")
 
 
 	// if no match, must build in docker, which is significantly slower
 	// if no match, must build in docker, which is significantly slower
 	// (slower mostly because of the vfs graphdriver)
 	// (slower mostly because of the vfs graphdriver)
@@ -104,7 +102,7 @@ func ensureSyscallTestBuild(c *check.C) {
 }
 }
 
 
 func ensureNNPTest(c *check.C) {
 func ensureNNPTest(c *check.C) {
-	protectedImages["nnp-test:latest"] = struct{}{}
+	defer testEnv.ProtectImage(c, "nnp-test:latest")
 	if testEnv.DaemonPlatform() != runtime.GOOS {
 	if testEnv.DaemonPlatform() != runtime.GOOS {
 		ensureNNPTestBuild(c)
 		ensureNNPTestBuild(c)
 		return
 		return

+ 9 - 11
integration-cli/fixtures_test.go

@@ -1,7 +1,6 @@
 package main
 package main
 
 
 import (
 import (
-	"fmt"
 	"io/ioutil"
 	"io/ioutil"
 	"os"
 	"os"
 	"os/exec"
 	"os/exec"
@@ -11,21 +10,21 @@ import (
 
 
 var ensureHTTPServerOnce sync.Once
 var ensureHTTPServerOnce sync.Once
 
 
-func ensureHTTPServerImage() error {
+func ensureHTTPServerImage(t testingT) {
 	var doIt bool
 	var doIt bool
 	ensureHTTPServerOnce.Do(func() {
 	ensureHTTPServerOnce.Do(func() {
 		doIt = true
 		doIt = true
 	})
 	})
 
 
 	if !doIt {
 	if !doIt {
-		return nil
+		return
 	}
 	}
 
 
-	protectedImages["httpserver:latest"] = struct{}{}
+	defer testEnv.ProtectImage(t, "httpserver:latest")
 
 
 	tmp, err := ioutil.TempDir("", "docker-http-server-test")
 	tmp, err := ioutil.TempDir("", "docker-http-server-test")
 	if err != nil {
 	if err != nil {
-		return fmt.Errorf("could not build http server: %v", err)
+		t.Fatalf("could not build http server: %v", err)
 	}
 	}
 	defer os.RemoveAll(tmp)
 	defer os.RemoveAll(tmp)
 
 
@@ -40,7 +39,7 @@ func ensureHTTPServerImage() error {
 
 
 	goCmd, lookErr := exec.LookPath("go")
 	goCmd, lookErr := exec.LookPath("go")
 	if lookErr != nil {
 	if lookErr != nil {
-		return fmt.Errorf("could not build http server: %v", lookErr)
+		t.Fatalf("could not build http server: %v", lookErr)
 	}
 	}
 
 
 	cmd := exec.Command(goCmd, "build", "-o", filepath.Join(tmp, "httpserver"), "github.com/docker/docker/contrib/httpserver")
 	cmd := exec.Command(goCmd, "build", "-o", filepath.Join(tmp, "httpserver"), "github.com/docker/docker/contrib/httpserver")
@@ -51,19 +50,18 @@ func ensureHTTPServerImage() error {
 	}...)
 	}...)
 	var out []byte
 	var out []byte
 	if out, err = cmd.CombinedOutput(); err != nil {
 	if out, err = cmd.CombinedOutput(); err != nil {
-		return fmt.Errorf("could not build http server: %s", string(out))
+		t.Fatalf("could not build http server: %s", string(out))
 	}
 	}
 
 
 	cpCmd, lookErr := exec.LookPath("cp")
 	cpCmd, lookErr := exec.LookPath("cp")
 	if lookErr != nil {
 	if lookErr != nil {
-		return fmt.Errorf("could not build http server: %v", lookErr)
+		t.Fatalf("could not build http server: %v", lookErr)
 	}
 	}
 	if out, err = exec.Command(cpCmd, "../contrib/httpserver/Dockerfile", filepath.Join(tmp, "Dockerfile")).CombinedOutput(); err != nil {
 	if out, err = exec.Command(cpCmd, "../contrib/httpserver/Dockerfile", filepath.Join(tmp, "Dockerfile")).CombinedOutput(); err != nil {
-		return fmt.Errorf("could not build http server: %v", string(out))
+		t.Fatalf("could not build http server: %v", string(out))
 	}
 	}
 
 
 	if out, err = exec.Command(dockerBinary, "build", "-q", "-t", "httpserver", tmp).CombinedOutput(); err != nil {
 	if out, err = exec.Command(dockerBinary, "build", "-q", "-t", "httpserver", tmp).CombinedOutput(); err != nil {
-		return fmt.Errorf("could not build http server: %v", string(out))
+		t.Fatalf("could not build http server: %v", string(out))
 	}
 	}
-	return nil
 }
 }