// ensure docker version works func (s *DockerSuite) TestVersionEnsureSucceeds(c *check.C) { versionCmd := exec.Command(dockerBinary, "version") out, _, err := runCommandWithOutput(versionCmd) if err != nil { c.Fatalf("failed to execute docker version: %s, %v", out, err) } stringsToCheck := []string{ "Client version:", "Client API version:", "Go version (client):", "Git commit (client):", "OS/Arch (client):", "Server version:", "Server API version:", "Go version (server):", "Git commit (server):", "OS/Arch (server):", } for _, linePrefix := range stringsToCheck { if !strings.Contains(out, linePrefix) { c.Errorf("couldn't find string %v in output", linePrefix) } } }
func (s *DockerDaemonSuite) TestExecAfterDaemonRestart(c *check.C) { testRequires(c, SameHostDaemon) if err := s.d.StartWithBusybox(); err != nil { c.Fatalf("Could not start daemon with busybox: %v", err) } if out, err := s.d.Cmd("run", "-d", "--name", "top", "-p", "80", "busybox:latest", "top"); err != nil { c.Fatalf("Could not run top: err=%v\n%s", err, out) } if err := s.d.Restart(); err != nil { c.Fatalf("Could not restart daemon: %v", err) } if out, err := s.d.Cmd("start", "top"); err != nil { c.Fatalf("Could not start top after daemon restart: err=%v\n%s", err, out) } out, err := s.d.Cmd("exec", "top", "echo", "hello") if err != nil { c.Fatalf("Could not exec on container top: err=%v\n%s", err, out) } outStr := strings.TrimSpace(string(out)) if outStr != "hello" { c.Errorf("container should've printed hello, instead printed %q", outStr) } }
func (s *DockerSuite) TestExecAfterContainerRestart(c *check.C) { runCmd := exec.Command(dockerBinary, "run", "-d", "busybox", "top") out, _, err := runCommandWithOutput(runCmd) if err != nil { c.Fatal(out, err) } cleanedContainerID := strings.TrimSpace(out) runCmd = exec.Command(dockerBinary, "restart", cleanedContainerID) if out, _, err = runCommandWithOutput(runCmd); err != nil { c.Fatal(out, err) } runCmd = exec.Command(dockerBinary, "exec", cleanedContainerID, "echo", "hello") out, _, err = runCommandWithOutput(runCmd) if err != nil { c.Fatal(out, err) } outStr := strings.TrimSpace(out) if outStr != "hello" { c.Errorf("container should've printed hello, instead printed %q", outStr) } }
// regression test for #12546 func (s *DockerSuite) TestExecInteractiveStdinClose(c *check.C) { testRequires(c, DaemonIsLinux) out, _ := dockerCmd(c, "run", "-itd", "busybox", "/bin/cat") contID := strings.TrimSpace(out) cmd := exec.Command(dockerBinary, "exec", "-i", contID, "echo", "-n", "hello") p, err := pty.Start(cmd) if err != nil { c.Fatal(err) } b := bytes.NewBuffer(nil) go io.Copy(b, p) ch := make(chan error) go func() { ch <- cmd.Wait() }() select { case err := <-ch: if err != nil { c.Errorf("cmd finished with error %v", err) } if output := b.String(); strings.TrimSpace(output) != "hello" { c.Fatalf("Unexpected output %s", output) } case <-time.After(1 * time.Second): c.Fatal("timed out running docker exec") } }
func (cs *ContainerdSuite) TearDownSuite(c *check.C) { // tell containerd to stop if cs.cd != nil { cs.cd.Process.Signal(os.Interrupt) done := false for done == false { select { case err := <-cs.syncChild: if err != nil { c.Errorf("master containerd did not exit cleanly: %v", err) } done = true case <-time.After(3 * time.Second): fmt.Println("Timeout while waiting for containerd to exit, killing it!") cs.cd.Process.Kill() } } } if cs.logFile != nil { cs.logFile.Close() } }
// test to ensure GH #3840 doesn't occur any more func (s *DockerSuite) TestDiffEnsureDockerinitFilesAreIgnored(c *check.C) { // this is a list of files which shouldn't show up in `docker diff` dockerinitFiles := []string{"/etc/resolv.conf", "/etc/hostname", "/etc/hosts", "/.dockerinit", "/.dockerenv"} containerCount := 5 // we might not run into this problem from the first run, so start a few containers for i := 0; i < containerCount; i++ { containerCmd := `echo foo > /root/bar` runCmd := exec.Command(dockerBinary, "run", "-d", "busybox", "sh", "-c", containerCmd) out, _, err := runCommandWithOutput(runCmd) if err != nil { c.Fatal(out, err) } cleanCID := strings.TrimSpace(out) diffCmd := exec.Command(dockerBinary, "diff", cleanCID) out, _, err = runCommandWithOutput(diffCmd) if err != nil { c.Fatalf("failed to run diff: %s, %v", out, err) } for _, filename := range dockerinitFiles { if strings.Contains(out, filename) { c.Errorf("found file which should've been ignored %v in diff output", filename) } } } }
// ensure that an added file shows up in docker diff func (s *DockerSuite) TestDiffFilenameShownInOutput(c *check.C) { containerCmd := `echo foo > /root/bar` runCmd := exec.Command(dockerBinary, "run", "-d", "busybox", "sh", "-c", containerCmd) out, _, err := runCommandWithOutput(runCmd) if err != nil { c.Fatalf("failed to start the container: %s, %v", out, err) } cleanCID := strings.TrimSpace(out) diffCmd := exec.Command(dockerBinary, "diff", cleanCID) out, _, err = runCommandWithOutput(diffCmd) if err != nil { c.Fatalf("failed to run diff: %s %v", out, err) } found := false for _, line := range strings.Split(out, "\n") { if strings.Contains("A /root/bar", line) { found = true break } } if !found { c.Errorf("couldn't find the new file in docker diff's output: %v", out) } }
func cleanContainers(c *check.C) *docker.Project { client, err := dockerclient.NewEnvClient() c.Assert(err, check.IsNil) filterArgs := filters.NewArgs() filterArgs, err = filters.ParseFlag(d.KermitLabelFilter, filterArgs) c.Assert(err, check.IsNil) containers, err := client.ContainerList(context.Background(), types.ContainerListOptions{ All: true, Filter: filterArgs, }) c.Assert(err, check.IsNil) for _, container := range containers { c.Logf("cleaning container %s…", container.ID) if err := client.ContainerRemove(context.Background(), container.ID, types.ContainerRemoveOptions{ Force: true, }); err != nil { c.Errorf("Error while removing container %s : %v\n", container.ID, err) } } return docker.NewProject(client) }
func (s *DockerSuite) TestDiffEnsureOnlyKmsgAndPtmx(c *check.C) { testRequires(c, DaemonIsLinux) out, _ := dockerCmd(c, "run", "-d", "busybox", "sleep", "0") cleanCID := strings.TrimSpace(out) out, _ = dockerCmd(c, "diff", cleanCID) expected := map[string]bool{ "C /dev": true, "A /dev/full": true, // busybox "C /dev/ptmx": true, // libcontainer "A /dev/mqueue": true, // lxc "A /dev/kmsg": true, // lxc "A /dev/fd": true, "A /dev/fuse": true, "A /dev/ptmx": true, "A /dev/null": true, "A /dev/random": true, "A /dev/stdout": true, "A /dev/stderr": true, "A /dev/tty1": true, "A /dev/stdin": true, "A /dev/tty": true, "A /dev/urandom": true, "A /dev/zero": true, } for _, line := range strings.Split(out, "\n") { if line != "" && !expected[line] { c.Errorf("%q is shown in the diff but shouldn't", line) } } }
func (s *DockerSuite) TestLinksEtcHostsRegularFile(c *check.C) { testRequires(c, DaemonIsLinux) out, _ := dockerCmd(c, "run", "--net=host", "busybox", "ls", "-la", "/etc/hosts") if !strings.HasPrefix(out, "-") { c.Errorf("/etc/hosts should be a regular file") } }
func (s *DockerSuite) TestImportDisplay(c *check.C) { runCmd := exec.Command(dockerBinary, "run", "-d", "busybox", "true") out, _, err := runCommandWithOutput(runCmd) if err != nil { c.Fatal("failed to create a container", out, err) } cleanedContainerID := strings.TrimSpace(out) out, _, err = runCommandPipelineWithOutput( exec.Command(dockerBinary, "export", cleanedContainerID), exec.Command(dockerBinary, "import", "-"), ) if err != nil { c.Errorf("import failed with errors: %v, output: %q", err, out) } if n := strings.Count(out, "\n"); n != 1 { c.Fatalf("display is messed up: %d '\\n' instead of 1:\n%s", n, out) } image := strings.TrimSpace(out) runCmd = exec.Command(dockerBinary, "run", "--rm", image, "true") out, _, err = runCommandWithOutput(runCmd) if err != nil { c.Fatal("failed to create a container", out, err) } if out != "" { c.Fatalf("command output should've been nothing, was %q", out) } }
func (s *DockerSuite) TestInfoApi(c *check.C) { endpoint := "/info" status, body, err := sockRequest("GET", endpoint, nil) c.Assert(status, check.Equals, http.StatusOK) c.Assert(err, check.IsNil) // always shown fields stringsToCheck := []string{ "ID", "Containers", "Images", "ExecutionDriver", "LoggingDriver", "OperatingSystem", "NCPU", "MemTotal", "KernelVersion", "Driver"} out := string(body) for _, linePrefix := range stringsToCheck { if !strings.Contains(out, linePrefix) { c.Errorf("couldn't find string %v in output", linePrefix) } } }
func (s *DockerSuite) TestCommitChange(c *check.C) { cmd := exec.Command(dockerBinary, "run", "--name", "test", "busybox", "true") if _, err := runCommand(cmd); err != nil { c.Fatal(err) } cmd = exec.Command(dockerBinary, "commit", "--change", "EXPOSE 8080", "--change", "ENV DEBUG true", "--change", "ENV test 1", "--change", "ENV PATH /foo", "test", "test-commit") imageId, _, err := runCommandWithOutput(cmd) if err != nil { c.Fatal(imageId, err) } imageId = strings.Trim(imageId, "\r\n") expected := map[string]string{ "Config.ExposedPorts": "map[8080/tcp:{}]", "Config.Env": "[DEBUG=true test=1 PATH=/foo]", } for conf, value := range expected { res, err := inspectField(imageId, conf) c.Assert(err, check.IsNil) if res != value { c.Errorf("%s('%s'), expected %s", conf, res, value) } } }
func (s *DockerRegistrySuite) TestPushEmptyLayer(c *check.C) { repoName := fmt.Sprintf("%v/dockercli/emptylayer", privateRegistryURL) emptyTarball, err := ioutil.TempFile("", "empty_tarball") if err != nil { c.Fatalf("Unable to create test file: %v", err) } tw := tar.NewWriter(emptyTarball) err = tw.Close() if err != nil { c.Fatalf("Error creating empty tarball: %v", err) } freader, err := os.Open(emptyTarball.Name()) if err != nil { c.Fatalf("Could not open test tarball: %v", err) } importCmd := exec.Command(dockerBinary, "import", "-", repoName) importCmd.Stdin = freader out, _, err := runCommandWithOutput(importCmd) if err != nil { c.Errorf("import failed with errors: %v, output: %q", err, out) } // Now verify we can push it if out, _, err := dockerCmdWithError("push", repoName); err != nil { c.Fatalf("pushing the image to the private registry has failed: %s, %v", out, err) } }
// ensure docker info succeeds func (s *DockerSuite) TestInfoEnsureSucceeds(c *check.C) { versionCmd := exec.Command(dockerBinary, "info") out, exitCode, err := runCommandWithOutput(versionCmd) if err != nil || exitCode != 0 { c.Fatalf("failed to execute docker info: %s, %v", out, err) } // always shown fields stringsToCheck := []string{ "ID:", "Containers:", "Images:", "Execution Driver:", "Logging Driver:", "Operating System:", "CPUs:", "Total Memory:", "Kernel Version:", "Storage Driver:"} for _, linePrefix := range stringsToCheck { if !strings.Contains(out, linePrefix) { c.Errorf("couldn't find string %v in output", linePrefix) } } }
// ensure docker info succeeds func (s *DockerSuite) TestInfoEnsureSucceeds(c *check.C) { out, _ := dockerCmd(c, "info") // always shown fields stringsToCheck := []string{ "ID:", "Containers:", "Images:", "Execution Driver:", "Logging Driver:", "Operating System:", "CPUs:", "Total Memory:", "Kernel Version:", "Storage Driver:", } if utils.ExperimentalBuild() { stringsToCheck = append(stringsToCheck, "Experimental: true") } for _, linePrefix := range stringsToCheck { if !strings.Contains(out, linePrefix) { c.Errorf("couldn't find string %v in output", linePrefix) } } }
// "test" should be printed func (s *DockerSuite) TestRunEchoStdoutWitCPUShares(c *check.C) { testRequires(c, cpuShare) out, _ := dockerCmd(c, "run", "--cpu-shares", "1000", "busybox", "echo", "test") if out != "test\n" { c.Errorf("container should've printed 'test', got %q instead", out) } }
// "test" should be printed func (s *DockerSuite) TestRunEchoStdoutWithCPUSharesAndMemoryLimit(c *check.C) { testRequires(c, cpuShare) testRequires(c, memoryLimitSupport) out, _, _ := dockerCmdWithStdoutStderr(c, "run", "--cpu-shares", "1000", "-m", "32m", "busybox", "echo", "test") if out != "test\n" { c.Errorf("container should've printed 'test', got %q instead", out) } }
// assertAuthHeaders validates authentication headers are removed func assertAuthHeaders(c *check.C, headers map[string]string) error { for k := range headers { if strings.Contains(strings.ToLower(k), "auth") || strings.Contains(strings.ToLower(k), "x-registry") { c.Errorf("Found authentication headers in request '%v'", headers) } } return nil }
// Test for #5619 // Check that symlinks which are part of the resource path are still relative to the container's rootfs func (s *DockerSuite) TestCpSymlinkComponent(c *check.C) { testRequires(c, DaemonIsLinux) out, exitCode := dockerCmd(c, "run", "-d", "busybox", "/bin/sh", "-c", "mkdir -p '"+cpTestPath+"' && echo -n '"+cpContainerContents+"' > "+cpFullPath+" && ln -s "+cpTestPath+" container_path") if exitCode != 0 { c.Fatal("failed to create a container", out) } cleanedContainerID := strings.TrimSpace(out) out, _ = dockerCmd(c, "wait", cleanedContainerID) if strings.TrimSpace(out) != "0" { c.Fatal("failed to set up container", out) } if err := os.MkdirAll(cpTestPath, os.ModeDir); err != nil { c.Fatal(err) } hostFile, err := os.Create(cpFullPath) if err != nil { c.Fatal(err) } defer hostFile.Close() defer os.RemoveAll(cpTestPathParent) fmt.Fprintf(hostFile, "%s", cpHostContents) tmpdir, err := ioutil.TempDir("", "docker-integration") if err != nil { c.Fatal(err) } tmpname := filepath.Join(tmpdir, cpTestName) defer os.RemoveAll(tmpdir) path := path.Join("/", "container_path", cpTestName) dockerCmd(c, "cp", cleanedContainerID+":"+path, tmpdir) file, _ := os.Open(tmpname) defer file.Close() test, err := ioutil.ReadAll(file) if err != nil { c.Fatal(err) } if string(test) == cpHostContents { c.Errorf("output matched host file -- symlink path component can escape container rootfs") } if string(test) != cpContainerContents { c.Errorf("output doesn't match the input for symlink path component") } }
// Check that symlinks to a directory behave as expected when copying one from // a container. func (s *DockerSuite) TestCpFromSymlinkToDirectory(c *check.C) { testRequires(c, DaemonIsLinux) out, exitCode := dockerCmd(c, "run", "-d", "busybox", "/bin/sh", "-c", "mkdir -p '"+cpTestPath+"' && echo -n '"+cpContainerContents+"' > "+cpFullPath+" && ln -s "+cpTestPathParent+" /dir_link") if exitCode != 0 { c.Fatal("failed to create a container", out) } cleanedContainerID := strings.TrimSpace(out) out, _ = dockerCmd(c, "wait", cleanedContainerID) if strings.TrimSpace(out) != "0" { c.Fatal("failed to set up container", out) } testDir, err := ioutil.TempDir("", "test-cp-from-symlink-to-dir-") if err != nil { c.Fatal(err) } defer os.RemoveAll(testDir) // This copy command should copy the symlink, not the target, into the // temporary directory. dockerCmd(c, "cp", cleanedContainerID+":"+"/dir_link", testDir) expectedPath := filepath.Join(testDir, "dir_link") linkTarget, err := os.Readlink(expectedPath) if err != nil { c.Fatalf("unable to read symlink at %q: %v", expectedPath, err) } if linkTarget != filepath.FromSlash(cpTestPathParent) { c.Errorf("symlink target was %q, but expected: %q", linkTarget, cpTestPathParent) } os.Remove(expectedPath) // This copy command should resolve the symlink (note the trailing // separator), copying the target into the temporary directory. dockerCmd(c, "cp", cleanedContainerID+":"+"/dir_link/", testDir) // It *should not* have copied the directory using the target's name, but // used the given name instead. unexpectedPath := filepath.Join(testDir, cpTestPathParent) if stat, err := os.Lstat(unexpectedPath); err == nil { c.Fatalf("target name was copied: %q - %q", stat.Mode(), stat.Name()) } // It *should* have copied the directory using the asked name "dir_link". stat, err := os.Lstat(expectedPath) if err != nil { c.Fatalf("unable to stat resource at %q: %v", expectedPath, err) } if !stat.IsDir() { c.Errorf("should have copied a directory but got %q instead", stat.Mode()) } }
func (s *DockerSuite) TestExec(c *check.C) { dockerCmd(c, "run", "-d", "--name", "testing", "busybox", "sh", "-c", "echo test > /tmp/file && top") out, _ := dockerCmd(c, "exec", "testing", "cat", "/tmp/file") out = strings.Trim(out, "\r\n") if out != "test" { c.Errorf("container exec should've printed test but printed %q", out) } }
func (s *DockerSwarmSuite) TestApiSwarmPromoteDemote(c *check.C) { d1 := s.AddDaemon(c, false, false) c.Assert(d1.Init(swarm.InitRequest{ Spec: swarm.Spec{ AcceptancePolicy: swarm.AcceptancePolicy{ Policies: []swarm.Policy{ {Role: swarm.NodeRoleWorker, Autoaccept: true}, {Role: swarm.NodeRoleManager}, }, }, }, }), checker.IsNil) d2 := s.AddDaemon(c, true, false) info, err := d2.info() c.Assert(err, checker.IsNil) c.Assert(info.ControlAvailable, checker.Equals, false) c.Assert(info.LocalNodeState, checker.Equals, swarm.LocalNodeStateActive) d1.updateNode(c, d2.NodeID, func(n *swarm.Node) { n.Spec.Role = swarm.NodeRoleManager }) for i := 0; ; i++ { info, err := d2.info() c.Assert(err, checker.IsNil) c.Assert(info.LocalNodeState, checker.Equals, swarm.LocalNodeStateActive) if info.ControlAvailable { break } if i > 100 { c.Errorf("node did not turn into manager") } time.Sleep(100 * time.Millisecond) } d1.updateNode(c, d2.NodeID, func(n *swarm.Node) { n.Spec.Role = swarm.NodeRoleWorker }) for i := 0; ; i++ { info, err := d2.info() c.Assert(err, checker.IsNil) c.Assert(info.LocalNodeState, checker.Equals, swarm.LocalNodeStateActive) if !info.ControlAvailable { break } if i > 100 { c.Errorf("node did not turn into worker") } time.Sleep(100 * time.Millisecond) } // todo: test raft qourum stability }
func (s *DockerSuite) TestExecAfterContainerRestart(c *check.C) { out, _ := dockerCmd(c, "run", "-d", "busybox", "top") cleanedContainerID := strings.TrimSpace(out) dockerCmd(c, "restart", cleanedContainerID) out, _ = dockerCmd(c, "exec", cleanedContainerID, "echo", "hello") outStr := strings.TrimSpace(out) if outStr != "hello" { c.Errorf("container should've printed hello, instead printed %q", outStr) } }
// Regression test for #9155, #9044 func (s *DockerSuite) TestExecEnv(c *check.C) { dockerCmd(c, "run", "-e", "LALA=value1", "-e", "LALA=value2", "-d", "--name", "testing", "busybox", "top") out, _ := dockerCmd(c, "exec", "testing", "env") if strings.Contains(out, "LALA=value1") || !strings.Contains(out, "LALA=value2") || !strings.Contains(out, "HOME=/root") { c.Errorf("exec env(%q), expect %q, %q", out, "LALA=value2", "HOME=/root") } }
func (s *DockerSuite) TestLinksEtcHostsRegularFile(c *check.C) { runCmd := exec.Command(dockerBinary, "run", "--net=host", "busybox", "ls", "-la", "/etc/hosts") out, _, _, err := runCommandWithStdoutStderr(runCmd) if err != nil { c.Fatal(out, err) } if !strings.HasPrefix(out, "-") { c.Errorf("/etc/hosts should be a regular file") } }
// ensure we allow the use of valid tags func (s *DockerSuite) TestTagValidPrefixedRepo(c *check.C) { validRepos := []string{"fooo/bar", "fooaa/test", "foooo:t", "HOSTNAME.DOMAIN.COM:443/foo/bar"} for _, repo := range validRepos { _, _, err := dockerCmdWithError("tag", "busybox:latest", repo) if err != nil { c.Errorf("tag busybox %v should have worked: %s", repo, err) continue } deleteImages(repo) } }
// Regression test for #9155, #9044 func (s *DockerSuite) TestExecEnv(c *check.C) { testRequires(c, DaemonIsLinux) dockerCmd(c, "run", "-e", "LALA=value1", "-e", "LALA=value2", "-d", "--name", "testing", "busybox", "top") c.Assert(waitRun("testing"), check.IsNil) out, _ := dockerCmd(c, "exec", "testing", "env") if strings.Contains(out, "LALA=value1") || !strings.Contains(out, "LALA=value2") || !strings.Contains(out, "HOME=/root") { c.Errorf("exec env(%q), expect %q, %q", out, "LALA=value2", "HOME=/root") } }
// "test123" should be printed by docker create + start func (s *DockerSuite) TestCreateEchoStdout(c *check.C) { out, _ := dockerCmd(c, "create", "busybox", "echo", "test123") cleanedContainerID := strings.TrimSpace(out) out, _ = dockerCmd(c, "start", "-ai", cleanedContainerID) if out != "test123\n" { c.Errorf("container should've printed 'test123', got %q", out) } }
func (s *DockerSuite) TestEventsImageImport(c *check.C) { since := daemonTime(c).Unix() id := make(chan string) eventImport := make(chan struct{}) eventsCmd := exec.Command(dockerBinary, "events", "--since", strconv.FormatInt(since, 10)) stdout, err := eventsCmd.StdoutPipe() if err != nil { c.Fatal(err) } if err := eventsCmd.Start(); err != nil { c.Fatal(err) } defer eventsCmd.Process.Kill() go func() { containerID := <-id matchImport := regexp.MustCompile(containerID + `: import$`) scanner := bufio.NewScanner(stdout) for scanner.Scan() { if matchImport.MatchString(scanner.Text()) { close(eventImport) } } }() runCmd := exec.Command(dockerBinary, "run", "-d", "busybox", "true") out, _, err := runCommandWithOutput(runCmd) if err != nil { c.Fatal("failed to create a container", out, err) } cleanedContainerID := strings.TrimSpace(out) out, _, err = runCommandPipelineWithOutput( exec.Command(dockerBinary, "export", cleanedContainerID), exec.Command(dockerBinary, "import", "-"), ) if err != nil { c.Errorf("import failed with errors: %v, output: %q", err, out) } newContainerID := strings.TrimSpace(out) id <- newContainerID select { case <-time.After(5 * time.Second): c.Fatal("failed to observe image import in timely fashion") case <-eventImport: // ignore, done } }