diff --git a/integration-cli/docker_cli_kill_test.go b/integration-cli/docker_cli_kill_test.go index b8265d8cfb..6ee246f5ff 100644 --- a/integration-cli/docker_cli_kill_test.go +++ b/integration-cli/docker_cli_kill_test.go @@ -34,3 +34,31 @@ func TestKillContainer(t *testing.T) { logDone("kill - kill container running sleep 10") } + +func TestKillDifferentUserContainer(t *testing.T) { + runCmd := exec.Command(dockerBinary, "run", "-u", "daemon", "-d", "busybox", "sh", "-c", "sleep 10") + out, _, err := runCommandWithOutput(runCmd) + errorOut(err, t, fmt.Sprintf("run failed with errors: %v", err)) + + cleanedContainerID := stripTrailingCharacters(out) + + inspectCmd := exec.Command(dockerBinary, "inspect", cleanedContainerID) + inspectOut, _, err := runCommandWithOutput(inspectCmd) + errorOut(err, t, fmt.Sprintf("out should've been a container id: %v %v", inspectOut, err)) + + killCmd := exec.Command(dockerBinary, "kill", cleanedContainerID) + out, _, err = runCommandWithOutput(killCmd) + errorOut(err, t, fmt.Sprintf("failed to kill container: %v %v", out, err)) + + listRunningContainersCmd := exec.Command(dockerBinary, "ps", "-q") + out, _, err = runCommandWithOutput(listRunningContainersCmd) + errorOut(err, t, fmt.Sprintf("failed to list running containers: %v", err)) + + if strings.Contains(out, cleanedContainerID) { + t.Fatal("killed container is still running") + } + + deleteContainer(cleanedContainerID) + + logDone("kill - kill container running sleep 10 from a different user") +} diff --git a/integration-cli/docker_cli_run_test.go b/integration-cli/docker_cli_run_test.go index 1021e152ab..7de2d334b1 100644 --- a/integration-cli/docker_cli_run_test.go +++ b/integration-cli/docker_cli_run_test.go @@ -6,6 +6,7 @@ import ( "io/ioutil" "os" "os/exec" + "path" "path/filepath" "reflect" "regexp" @@ -1644,3 +1645,64 @@ func TestRunWithBadDevice(t *testing.T) { } logDone("run - error with bad device") } + +func TestEntrypoint(t *testing.T) { + name := "entrypoint" + cmd := exec.Command(dockerBinary, "run", "--name", name, "--entrypoint", "/bin/echo", "busybox", "-n", "foobar") + out, _, err := runCommandWithOutput(cmd) + if err != nil { + t.Fatal(err, out) + } + expected := "foobar" + if out != expected { + t.Fatalf("Output should be %q, actual out: %q", expected, out) + } + logDone("run - entrypoint") +} + +func TestBindMounts(t *testing.T) { + tmpDir, err := ioutil.TempDir("", "docker-test-container") + if err != nil { + t.Fatal(err) + } + + defer os.RemoveAll(tmpDir) + writeFile(path.Join(tmpDir, "touch-me"), "", t) + + // Test reading from a read-only bind mount + cmd := exec.Command(dockerBinary, "run", "-v", fmt.Sprintf("%s:/tmp:ro", tmpDir), "busybox", "ls", "/tmp") + out, _, err := runCommandWithOutput(cmd) + if err != nil { + t.Fatal(err, out) + } + if !strings.Contains(out, "touch-me") { + t.Fatal("Container failed to read from bind mount") + } + + // test writing to bind mount + cmd = exec.Command(dockerBinary, "run", "-v", fmt.Sprintf("%s:/tmp:rw", tmpDir), "busybox", "touch", "/tmp/holla") + out, _, err = runCommandWithOutput(cmd) + if err != nil { + t.Fatal(err, out) + } + readFile(path.Join(tmpDir, "holla"), t) // Will fail if the file doesn't exist + + // test mounting to an illegal destination directory + cmd = exec.Command(dockerBinary, "run", "-v", fmt.Sprintf("%s:.", tmpDir), "busybox", "ls", ".") + _, err = runCommand(cmd) + if err == nil { + t.Fatal("Container bind mounted illegal directory") + } + + // test mount a file + cmd = exec.Command(dockerBinary, "run", "-v", fmt.Sprintf("%s/holla:/tmp/holla:rw", tmpDir), "busybox", "sh", "-c", "echo -n 'yotta' > /tmp/holla") + _, err = runCommand(cmd) + if err != nil { + t.Fatal(err, out) + } + content := readFile(path.Join(tmpDir, "holla"), t) // Will fail if the file doesn't exist + expected := "yotta" + if content != expected { + t.Fatalf("Output should be %q, actual out: %q", expected, content) + } +} diff --git a/integration-cli/docker_utils.go b/integration-cli/docker_utils.go index 5561fc24dc..cf1dd203f8 100644 --- a/integration-cli/docker_utils.go +++ b/integration-cli/docker_utils.go @@ -2,6 +2,7 @@ package main import ( "fmt" + "io" "io/ioutil" "net/http" "net/http/httptest" @@ -368,3 +369,36 @@ func fakeGIT(name string, files map[string]string) (*FakeGIT, error) { RepoURL: fmt.Sprintf("%s/%s.git", server.URL, name), }, nil } + +// Write `content` to the file at path `dst`, creating it if necessary, +// as well as any missing directories. +// The file is truncated if it already exists. +// Call t.Fatal() at the first error. +func writeFile(dst, content string, t *testing.T) { + // Create subdirectories if necessary + if err := os.MkdirAll(path.Dir(dst), 0700); err != nil && !os.IsExist(err) { + t.Fatal(err) + } + f, err := os.OpenFile(dst, os.O_CREATE|os.O_RDWR|os.O_TRUNC, 0700) + if err != nil { + t.Fatal(err) + } + // Write content (truncate if it exists) + if _, err := io.Copy(f, strings.NewReader(content)); err != nil { + t.Fatal(err) + } +} + +// Return the contents of file at path `src`. +// Call t.Fatal() at the first error (including if the file doesn't exist) +func readFile(src string, t *testing.T) (content string) { + f, err := os.Open(src) + if err != nil { + t.Fatal(err) + } + data, err := ioutil.ReadAll(f) + if err != nil { + t.Fatal(err) + } + return string(data) +} diff --git a/integration/auth_test.go b/integration/auth_test.go deleted file mode 100644 index 42cd1ac64d..0000000000 --- a/integration/auth_test.go +++ /dev/null @@ -1,75 +0,0 @@ -package docker - -import ( - "crypto/rand" - "encoding/hex" - "fmt" - "os" - "strings" - "testing" - - "github.com/docker/docker/registry" -) - -// FIXME: these tests have an external dependency on a staging index hosted -// on the docker.io infrastructure. That dependency should be removed. -// - Unit tests should have no side-effect dependencies. -// - Integration tests should have side-effects limited to the host environment being tested. - -func TestLogin(t *testing.T) { - t.Skip("FIXME: please remove dependency on external services") - os.Setenv("DOCKER_INDEX_URL", "https://registry-stage.hub.docker.com/v1/") - defer os.Setenv("DOCKER_INDEX_URL", "") - authConfig := ®istry.AuthConfig{ - Username: "unittester", - Password: "surlautrerivejetattendrai", - Email: "noise+unittester@docker.com", - ServerAddress: "https://registry-stage.hub.docker.com/v1/", - } - status, err := registry.Login(authConfig, nil) - if err != nil { - t.Fatal(err) - } - if status != "Login Succeeded" { - t.Fatalf("Expected status \"Login Succeeded\", found \"%s\" instead", status) - } -} - -func TestCreateAccount(t *testing.T) { - t.Skip("FIXME: please remove dependency on external services") - tokenBuffer := make([]byte, 16) - _, err := rand.Read(tokenBuffer) - if err != nil { - t.Fatal(err) - } - token := hex.EncodeToString(tokenBuffer)[:12] - username := "ut" + token - authConfig := ®istry.AuthConfig{ - Username: username, - Password: "test42", - Email: fmt.Sprintf("docker-ut+%s@example.com", token), - ServerAddress: "https://registry-stage.hub.docker.com/v1/", - } - status, err := registry.Login(authConfig, nil) - if err != nil { - t.Fatal(err) - } - expectedStatus := fmt.Sprintf( - "Account created. Please see the documentation of the registry %s for instructions how to activate it.", - authConfig.ServerAddress, - ) - if status != expectedStatus { - t.Fatalf("Expected status: \"%s\", found \"%s\" instead.", expectedStatus, status) - } - - status, err = registry.Login(authConfig, nil) - if err == nil { - t.Fatalf("Expected error but found nil instead") - } - - expectedError := "Login: Account is not Active" - - if !strings.Contains(err.Error(), expectedError) { - t.Fatalf("Expected message \"%s\" but found \"%s\" instead", expectedError, err) - } -} diff --git a/integration/container_test.go b/integration/container_test.go index 4462aba08d..60f3e55bc5 100644 --- a/integration/container_test.go +++ b/integration/container_test.go @@ -1,76 +1,14 @@ package docker import ( - "fmt" "io" "io/ioutil" - "os" - "path" - "strings" "testing" "time" "github.com/docker/docker/runconfig" ) -func TestKillDifferentUser(t *testing.T) { - daemon := mkDaemon(t) - defer nuke(daemon) - - container, _, err := daemon.Create(&runconfig.Config{ - Image: GetTestImage(daemon).ID, - Cmd: []string{"cat"}, - OpenStdin: true, - User: "daemon", - }, - "", - ) - if err != nil { - t.Fatal(err) - } - defer daemon.Destroy(container) - // FIXME @shykes: this seems redundant, but is very old, I'm leaving it in case - // there is a side effect I'm not seeing. - // defer container.stdin.Close() - - if container.State.IsRunning() { - t.Errorf("Container shouldn't be running") - } - if err := container.Start(); err != nil { - t.Fatal(err) - } - - setTimeout(t, "Waiting for the container to be started timed out", 2*time.Second, func() { - for !container.State.IsRunning() { - time.Sleep(10 * time.Millisecond) - } - }) - - setTimeout(t, "read/write assertion timed out", 2*time.Second, func() { - out, _ := container.StdoutPipe() - in, _ := container.StdinPipe() - if err := assertPipe("hello\n", "hello", out, in, 150); err != nil { - t.Fatal(err) - } - }) - - if err := container.Kill(); err != nil { - t.Fatal(err) - } - - if container.State.IsRunning() { - t.Errorf("Container shouldn't be running") - } - container.State.WaitStop(-1 * time.Second) - if container.State.IsRunning() { - t.Errorf("Container shouldn't be running") - } - // Try stopping twice - if err := container.Kill(); err != nil { - t.Fatal(err) - } -} - func TestRestartStdin(t *testing.T) { daemon := mkDaemon(t) defer nuke(daemon) @@ -237,53 +175,6 @@ func TestTty(t *testing.T) { } } -func TestEntrypoint(t *testing.T) { - daemon := mkDaemon(t) - defer nuke(daemon) - container, _, err := daemon.Create( - &runconfig.Config{ - Image: GetTestImage(daemon).ID, - Entrypoint: []string{"/bin/echo"}, - Cmd: []string{"-n", "foobar"}, - }, - "", - ) - if err != nil { - t.Fatal(err) - } - defer daemon.Destroy(container) - output, err := container.Output() - if err != nil { - t.Fatal(err) - } - if string(output) != "foobar" { - t.Error(string(output)) - } -} - -func TestEntrypointNoCmd(t *testing.T) { - daemon := mkDaemon(t) - defer nuke(daemon) - container, _, err := daemon.Create( - &runconfig.Config{ - Image: GetTestImage(daemon).ID, - Entrypoint: []string{"/bin/echo", "foobar"}, - }, - "", - ) - if err != nil { - t.Fatal(err) - } - defer daemon.Destroy(container) - output, err := container.Output() - if err != nil { - t.Fatal(err) - } - if strings.Trim(string(output), "\r\n") != "foobar" { - t.Error(string(output)) - } -} - func BenchmarkRunSequential(b *testing.B) { daemon := mkDaemon(b) defer nuke(daemon) @@ -361,43 +252,3 @@ func BenchmarkRunParallel(b *testing.B) { b.Fatal(errors) } } - -func tempDir(t *testing.T) string { - tmpDir, err := ioutil.TempDir("", "docker-test-container") - if err != nil { - t.Fatal(err) - } - return tmpDir -} - -func TestBindMounts(t *testing.T) { - eng := NewTestEngine(t) - r := mkDaemonFromEngine(eng, t) - defer r.Nuke() - - tmpDir := tempDir(t) - defer os.RemoveAll(tmpDir) - writeFile(path.Join(tmpDir, "touch-me"), "", t) - - // Test reading from a read-only bind mount - stdout, _ := runContainer(eng, r, []string{"-v", fmt.Sprintf("%s:/tmp:ro", tmpDir), "_", "ls", "/tmp"}, t) - if !strings.Contains(stdout, "touch-me") { - t.Fatal("Container failed to read from bind mount") - } - - // test writing to bind mount - runContainer(eng, r, []string{"-v", fmt.Sprintf("%s:/tmp:rw", tmpDir), "_", "touch", "/tmp/holla"}, t) - readFile(path.Join(tmpDir, "holla"), t) // Will fail if the file doesn't exist - - // test mounting to an illegal destination directory - if _, err := runContainer(eng, r, []string{"-v", fmt.Sprintf("%s:.", tmpDir), "_", "ls", "."}, nil); err == nil { - t.Fatal("Container bind mounted illegal directory") - } - - // test mount a file - runContainer(eng, r, []string{"-v", fmt.Sprintf("%s/holla:/tmp/holla:rw", tmpDir), "_", "sh", "-c", "echo -n 'yotta' > /tmp/holla"}, t) - content := readFile(path.Join(tmpDir, "holla"), t) // Will fail if the file doesn't exist - if content != "yotta" { - t.Fatal("Container failed to write to bind mount file") - } -}