func (s *DockerSuite) TestAPIStatsContainerGetMemoryLimit(c *check.C) { testRequires(c, DaemonIsLinux, memoryLimitSupport) resp, body, err := request.SockRequestRaw("GET", "/info", nil, "application/json", daemonHost()) c.Assert(err, checker.IsNil) c.Assert(resp.StatusCode, checker.Equals, http.StatusOK) var info types.Info err = json.NewDecoder(body).Decode(&info) c.Assert(err, checker.IsNil) body.Close() // don't set a memory limit, the memory limit should be system memory conName := "foo" dockerCmd(c, "run", "-d", "--name", conName, "busybox", "top") c.Assert(waitRun(conName), checker.IsNil) resp, body, err = request.SockRequestRaw("GET", fmt.Sprintf("/containers/%s/stats?stream=false", conName), nil, "", daemonHost()) c.Assert(err, checker.IsNil) c.Assert(resp.StatusCode, checker.Equals, http.StatusOK) c.Assert(resp.Header.Get("Content-Type"), checker.Equals, "application/json") var v *types.Stats err = json.NewDecoder(body).Decode(&v) c.Assert(err, checker.IsNil) body.Close() c.Assert(fmt.Sprintf("%d", v.MemoryStats.Limit), checker.Equals, fmt.Sprintf("%d", info.MemTotal)) }
func (s *DockerSuite) TestAPIStatsStoppedContainerInGoroutines(c *check.C) { out, _ := dockerCmd(c, "run", "-d", "busybox", "/bin/sh", "-c", "echo 1") id := strings.TrimSpace(out) getGoRoutines := func() int { _, body, err := request.SockRequestRaw("GET", fmt.Sprintf("/info"), nil, "", daemonHost()) c.Assert(err, checker.IsNil) info := types.Info{} err = json.NewDecoder(body).Decode(&info) c.Assert(err, checker.IsNil) body.Close() return info.NGoroutines } // When the HTTP connection is closed, the number of goroutines should not increase. routines := getGoRoutines() _, body, err := request.SockRequestRaw("GET", fmt.Sprintf("/containers/%s/stats", id), nil, "", daemonHost()) c.Assert(err, checker.IsNil) body.Close() t := time.After(30 * time.Second) for { select { case <-t: c.Assert(getGoRoutines(), checker.LessOrEqualThan, routines) return default: if n := getGoRoutines(); n <= routines { return } time.Sleep(200 * time.Millisecond) } } }
// #20638 func (s *DockerSuite) TestExecAPIStartWithDetach(c *check.C) { name := "foo" runSleepingContainer(c, "-d", "-t", "--name", name) data := map[string]interface{}{ "cmd": []string{"true"}, "AttachStdin": true, } _, b, err := request.SockRequest("POST", fmt.Sprintf("/containers/%s/exec", name), data, daemonHost()) c.Assert(err, checker.IsNil, check.Commentf(string(b))) createResp := struct { ID string `json:"Id"` }{} c.Assert(json.Unmarshal(b, &createResp), checker.IsNil, check.Commentf(string(b))) _, body, err := request.SockRequestRaw("POST", fmt.Sprintf("/exec/%s/start", createResp.ID), strings.NewReader(`{"Detach": true}`), "application/json", daemonHost()) c.Assert(err, checker.IsNil) b, err = testutil.ReadBody(body) comment := check.Commentf("response body: %s", b) c.Assert(err, checker.IsNil, comment) resp, _, err := request.SockRequestRaw("GET", "/_ping", nil, "", daemonHost()) c.Assert(err, checker.IsNil) if resp.StatusCode != http.StatusOK { c.Fatal("daemon is down, it should alive") } }
func (s *DockerSuite) TestUpdateStats(c *check.C) { testRequires(c, DaemonIsLinux) testRequires(c, memoryLimitSupport) testRequires(c, cpuCfsQuota) name := "foo" dockerCmd(c, "run", "-d", "-ti", "--name", name, "-m", "500m", "busybox") c.Assert(waitRun(name), checker.IsNil) getMemLimit := func(id string) uint64 { resp, body, err := request.SockRequestRaw("GET", fmt.Sprintf("/containers/%s/stats?stream=false", id), nil, "", daemonHost()) c.Assert(err, checker.IsNil) c.Assert(resp.Header.Get("Content-Type"), checker.Equals, "application/json") var v *types.Stats err = json.NewDecoder(body).Decode(&v) c.Assert(err, checker.IsNil) body.Close() return v.MemoryStats.Limit } preMemLimit := getMemLimit(name) dockerCmd(c, "update", "--cpu-quota", "2000", name) curMemLimit := getMemLimit(name) c.Assert(preMemLimit, checker.Equals, curMemLimit) }
func (s *DockerSuite) TestBuildAPIDockerFileRemote(c *check.C) { testRequires(c, NotUserNamespace) var testD string if daemonPlatform == "windows" { testD = `FROM busybox COPY * /tmp/ RUN find / -name ba* RUN find /tmp/` } else { // -xdev is required because sysfs can cause EPERM testD = `FROM busybox COPY * /tmp/ RUN find / -xdev -name ba* RUN find /tmp/` } server, err := fakeStorage(map[string]string{"testD": testD}) c.Assert(err, checker.IsNil) defer server.Close() res, body, err := request.SockRequestRaw("POST", "/build?dockerfile=baz&remote="+server.URL()+"/testD", nil, "application/json", daemonHost()) c.Assert(err, checker.IsNil) c.Assert(res.StatusCode, checker.Equals, http.StatusOK) buf, err := testutil.ReadBody(body) c.Assert(err, checker.IsNil) // Make sure Dockerfile exists. // Make sure 'baz' doesn't exist ANYWHERE despite being mentioned in the URL out := string(buf) c.Assert(out, checker.Contains, "/tmp/Dockerfile") c.Assert(out, checker.Not(checker.Contains), "baz") }
func (s *DockerSuite) TestBuildAPIRemoteTarballContext(c *check.C) { buffer := new(bytes.Buffer) tw := tar.NewWriter(buffer) defer tw.Close() dockerfile := []byte("FROM busybox") err := tw.WriteHeader(&tar.Header{ Name: "Dockerfile", Size: int64(len(dockerfile)), }) // failed to write tar file header c.Assert(err, checker.IsNil) _, err = tw.Write(dockerfile) // failed to write tar file content c.Assert(err, checker.IsNil) // failed to close tar archive c.Assert(tw.Close(), checker.IsNil) server, err := fakeBinaryStorage(map[string]*bytes.Buffer{ "testT.tar": buffer, }) c.Assert(err, checker.IsNil) defer server.Close() res, b, err := request.SockRequestRaw("POST", "/build?remote="+server.URL()+"/testT.tar", nil, "application/tar", daemonHost()) c.Assert(err, checker.IsNil) c.Assert(res.StatusCode, checker.Equals, http.StatusOK) b.Close() }
func inspectExec(c *check.C, id string, out interface{}) { resp, body, err := request.SockRequestRaw("GET", fmt.Sprintf("/exec/%s/json", id), nil, "", daemonHost()) c.Assert(err, checker.IsNil) defer body.Close() c.Assert(resp.StatusCode, checker.Equals, http.StatusOK) err = json.NewDecoder(body).Decode(out) c.Assert(err, checker.IsNil) }
func startExec(c *check.C, id string, code int) { resp, body, err := request.SockRequestRaw("POST", fmt.Sprintf("/exec/%s/start", id), strings.NewReader(`{"Detach": true}`), "application/json", daemonHost()) c.Assert(err, checker.IsNil) b, err := testutil.ReadBody(body) comment := check.Commentf("response body: %s", b) c.Assert(err, checker.IsNil, comment) c.Assert(resp.StatusCode, checker.Equals, code, comment) }
func (s *DockerSuite) TestExecAPIStartEnsureHeaders(c *check.C) { testRequires(c, DaemonIsLinux) dockerCmd(c, "run", "-d", "--name", "test", "busybox", "top") id := createExec(c, "test") resp, _, err := request.SockRequestRaw("POST", fmt.Sprintf("/exec/%s/start", id), strings.NewReader(`{"Detach": true}`), "application/json", daemonHost()) c.Assert(err, checker.IsNil) c.Assert(resp.Header.Get("Server"), checker.Not(checker.Equals), "") }
// #14846 func (s *DockerSuite) TestAPIImagesSearchJSONContentType(c *check.C) { testRequires(c, Network) res, b, err := request.SockRequestRaw("GET", "/images/search?term=test", nil, "application/json", daemonHost()) c.Assert(err, check.IsNil) b.Close() c.Assert(res.StatusCode, checker.Equals, http.StatusOK) c.Assert(res.Header.Get("Content-Type"), checker.Equals, "application/json") }
func (s *DockerSuite) TestBuildAPIUnnormalizedTarPaths(c *check.C) { // Make sure that build context tars with entries of the form // x/./y don't cause caching false positives. buildFromTarContext := func(fileContents []byte) string { buffer := new(bytes.Buffer) tw := tar.NewWriter(buffer) defer tw.Close() dockerfile := []byte(`FROM busybox COPY dir /dir/`) err := tw.WriteHeader(&tar.Header{ Name: "Dockerfile", Size: int64(len(dockerfile)), }) //failed to write tar file header c.Assert(err, checker.IsNil) _, err = tw.Write(dockerfile) // failed to write Dockerfile in tar file content c.Assert(err, checker.IsNil) err = tw.WriteHeader(&tar.Header{ Name: "dir/./file", Size: int64(len(fileContents)), }) //failed to write tar file header c.Assert(err, checker.IsNil) _, err = tw.Write(fileContents) // failed to write file contents in tar file content c.Assert(err, checker.IsNil) // failed to close tar archive c.Assert(tw.Close(), checker.IsNil) res, body, err := request.SockRequestRaw("POST", "/build", buffer, "application/x-tar", daemonHost()) c.Assert(err, checker.IsNil) c.Assert(res.StatusCode, checker.Equals, http.StatusOK) out, err := testutil.ReadBody(body) c.Assert(err, checker.IsNil) lines := strings.Split(string(out), "\n") c.Assert(len(lines), checker.GreaterThan, 1) c.Assert(lines[len(lines)-2], checker.Matches, ".*Successfully built [0-9a-f]{12}.*") re := regexp.MustCompile("Successfully built ([0-9a-f]{12})") matches := re.FindStringSubmatch(lines[len(lines)-2]) return matches[1] } imageA := buildFromTarContext([]byte("abc")) imageB := buildFromTarContext([]byte("def")) c.Assert(imageA, checker.Not(checker.Equals), imageB) }
func (s *DockerSuite) TestAPIGetEnabledCORS(c *check.C) { res, body, err := request.SockRequestRaw("GET", "/version", nil, "", daemonHost()) c.Assert(err, checker.IsNil) c.Assert(res.StatusCode, checker.Equals, http.StatusOK) body.Close() // TODO: @runcom incomplete tests, why old integration tests had this headers // and here none of the headers below are in the response? //c.Log(res.Header) //c.Assert(res.Header.Get("Access-Control-Allow-Origin"), check.Equals, "*") //c.Assert(res.Header.Get("Access-Control-Allow-Headers"), check.Equals, "Origin, X-Requested-With, Content-Type, Accept, X-Registry-Auth") }
func (s *DockerSuite) TestBuildAPIRemoteTarballContextWithCustomDockerfile(c *check.C) { buffer := new(bytes.Buffer) tw := tar.NewWriter(buffer) defer tw.Close() dockerfile := []byte(`FROM busybox RUN echo 'wrong'`) err := tw.WriteHeader(&tar.Header{ Name: "Dockerfile", Size: int64(len(dockerfile)), }) // failed to write tar file header c.Assert(err, checker.IsNil) _, err = tw.Write(dockerfile) // failed to write tar file content c.Assert(err, checker.IsNil) custom := []byte(`FROM busybox RUN echo 'right' `) err = tw.WriteHeader(&tar.Header{ Name: "custom", Size: int64(len(custom)), }) // failed to write tar file header c.Assert(err, checker.IsNil) _, err = tw.Write(custom) // failed to write tar file content c.Assert(err, checker.IsNil) // failed to close tar archive c.Assert(tw.Close(), checker.IsNil) server, err := fakeBinaryStorage(map[string]*bytes.Buffer{ "testT.tar": buffer, }) c.Assert(err, checker.IsNil) defer server.Close() url := "/build?dockerfile=custom&remote=" + server.URL() + "/testT.tar" res, body, err := request.SockRequestRaw("POST", url, nil, "application/tar", daemonHost()) c.Assert(err, checker.IsNil) c.Assert(res.StatusCode, checker.Equals, http.StatusOK) defer body.Close() content, err := testutil.ReadBody(body) c.Assert(err, checker.IsNil) // Build used the wrong dockerfile. c.Assert(string(content), checker.Not(checker.Contains), "wrong") }
func getNetworkStats(c *check.C, id string) map[string]types.NetworkStats { var st *types.StatsJSON _, body, err := request.SockRequestRaw("GET", fmt.Sprintf("/containers/%s/stats?stream=false", id), nil, "", daemonHost()) c.Assert(err, checker.IsNil) err = json.NewDecoder(body).Decode(&st) c.Assert(err, checker.IsNil) body.Close() return st.Networks }
// getVersionedStats returns stats result for the // container with id using an API call with version apiVersion. Since the // stats result type differs between API versions, we simply return // map[string]interface{}. func getVersionedStats(c *check.C, id string, apiVersion string) map[string]interface{} { stats := make(map[string]interface{}) _, body, err := request.SockRequestRaw("GET", fmt.Sprintf("/%s/containers/%s/stats?stream=false", apiVersion, id), nil, "", daemonHost()) c.Assert(err, checker.IsNil) defer body.Close() err = json.NewDecoder(body).Decode(&stats) c.Assert(err, checker.IsNil, check.Commentf("failed to decode stat: %s", err)) return stats }
func (s *DockerSuite) TestExecAPIStartBackwardsCompatible(c *check.C) { testRequires(c, DaemonIsLinux) // Windows only supports 1.25 or later runSleepingContainer(c, "-d", "--name", "test") id := createExec(c, "test") resp, body, err := request.SockRequestRaw("POST", fmt.Sprintf("/v1.20/exec/%s/start", id), strings.NewReader(`{"Detach": true}`), "text/plain", daemonHost()) c.Assert(err, checker.IsNil) b, err := testutil.ReadBody(body) comment := check.Commentf("response body: %s", b) c.Assert(err, checker.IsNil, comment) c.Assert(resp.StatusCode, checker.Equals, http.StatusOK, comment) }
func (s *DockerSuite) TestAPIImagesSaveAndLoad(c *check.C) { // TODO Windows to Windows CI: Investigate further why this test fails. testRequires(c, Network) testRequires(c, DaemonIsLinux) out, err := buildImage("saveandload", "FROM busybox\nENV FOO bar", false) c.Assert(err, checker.IsNil) id := strings.TrimSpace(out) res, body, err := request.SockRequestRaw("GET", "/images/"+id+"/get", nil, "", daemonHost()) c.Assert(err, checker.IsNil) defer body.Close() c.Assert(res.StatusCode, checker.Equals, http.StatusOK) dockerCmd(c, "rmi", id) res, loadBody, err := request.SockRequestRaw("POST", "/images/load", body, "application/x-tar", daemonHost()) c.Assert(err, checker.IsNil) defer loadBody.Close() c.Assert(res.StatusCode, checker.Equals, http.StatusOK) inspectOut := inspectField(c, id, "Id") c.Assert(strings.TrimSpace(string(inspectOut)), checker.Equals, id, check.Commentf("load did not work properly")) }
// Regression test for #12704 func (s *DockerSuite) TestLogsAPIFollowEmptyOutput(c *check.C) { name := "logs_test" t0 := time.Now() dockerCmd(c, "run", "-d", "-t", "--name", name, "busybox", "sleep", "10") _, body, err := request.SockRequestRaw("GET", fmt.Sprintf("/containers/%s/logs?follow=1&stdout=1&stderr=1&tail=all", name), bytes.NewBuffer(nil), "", daemonHost()) t1 := time.Now() c.Assert(err, checker.IsNil) body.Close() elapsed := t1.Sub(t0).Seconds() if elapsed > 20.0 { c.Fatalf("HTTP response was not immediate (elapsed %.1fs)", elapsed) } }
// #14640 func (s *DockerSuite) TestDeprecatedPostContainersStartWithoutLinksInHostConfig(c *check.C) { // TODO Windows: Windows doesn't support supplying a hostconfig on start. // An alternate test could be written to validate the negative testing aspect of this testRequires(c, DaemonIsLinux) name := "test-host-config-links" dockerCmd(c, append([]string{"create", "--name", name, "busybox"}, sleepCommandForDaemonPlatform()...)...) hc := inspectFieldJSON(c, name, "HostConfig") config := `{"HostConfig":` + hc + `}` res, b, err := request.SockRequestRaw("POST", formatV123StartAPIURL("/containers/"+name+"/start"), strings.NewReader(config), "application/json", daemonHost()) c.Assert(err, checker.IsNil) c.Assert(res.StatusCode, checker.Equals, http.StatusNoContent) b.Close() }
func (s *DockerSuite) TestDeprecatedStartWithNilDNS(c *check.C) { // TODO Windows: Add once DNS is supported testRequires(c, DaemonIsLinux) out, _ := dockerCmd(c, "create", "busybox") containerID := strings.TrimSpace(out) config := `{"HostConfig": {"Dns": null}}` res, b, err := request.SockRequestRaw("POST", formatV123StartAPIURL("/containers/"+containerID+"/start"), strings.NewReader(config), "application/json", daemonHost()) c.Assert(err, checker.IsNil) c.Assert(res.StatusCode, checker.Equals, http.StatusNoContent) b.Close() dns := inspectFieldJSON(c, containerID, "HostConfig.Dns") c.Assert(dns, checker.Equals, "[]") }
// #14640 func (s *DockerSuite) TestDeprecatedPostContainersStartWithLinksInHostConfigIdLinked(c *check.C) { // Windows does not support links testRequires(c, DaemonIsLinux) name := "test-host-config-links" out, _ := dockerCmd(c, "run", "--name", "link0", "-d", "busybox", "top") id := strings.TrimSpace(out) dockerCmd(c, "create", "--name", name, "--link", id, "busybox", "top") hc := inspectFieldJSON(c, name, "HostConfig") config := `{"HostConfig":` + hc + `}` res, b, err := request.SockRequestRaw("POST", formatV123StartAPIURL("/containers/"+name+"/start"), strings.NewReader(config), "application/json", daemonHost()) c.Assert(err, checker.IsNil) c.Assert(res.StatusCode, checker.Equals, http.StatusNoContent) b.Close() }
// ReloadConfig asks the daemon to reload its configuration func (d *Daemon) ReloadConfig() error { if d.cmd == nil || d.cmd.Process == nil { return errors.New("daemon is not running") } errCh := make(chan error) started := make(chan struct{}) go func() { _, body, err := request.SockRequestRaw("GET", "/events", nil, "", d.Sock()) close(started) if err != nil { errCh <- err } defer body.Close() dec := json.NewDecoder(body) for { var e events.Message if err := dec.Decode(&e); err != nil { errCh <- err return } if e.Type != events.DaemonEventType { continue } if e.Action != "reload" { continue } close(errCh) // notify that we are done return } }() <-started if err := signalDaemonReload(d.cmd.Process.Pid); err != nil { return errors.Errorf("error signaling daemon reload: %v", err) } select { case err := <-errCh: if err != nil { return errors.Errorf("error waiting for daemon reload event: %v", err) } case <-time.After(30 * time.Second): return errors.New("timeout waiting for daemon reload event") } return nil }
func (s *DockerSuite) TestBuildAPILowerDockerfile(c *check.C) { git, err := newFakeGit("repo", map[string]string{ "dockerfile": `FROM busybox RUN echo from dockerfile`, }, false) c.Assert(err, checker.IsNil) defer git.Close() res, body, err := request.SockRequestRaw("POST", "/build?remote="+git.RepoURL, nil, "application/json", daemonHost()) c.Assert(err, checker.IsNil) c.Assert(res.StatusCode, checker.Equals, http.StatusOK) buf, err := testutil.ReadBody(body) c.Assert(err, checker.IsNil) out := string(buf) c.Assert(out, checker.Contains, "from dockerfile") }
func (s *DockerSuite) TestExecAPICreateNoValidContentType(c *check.C) { name := "exec_test" dockerCmd(c, "run", "-d", "-t", "--name", name, "busybox", "/bin/sh") jsonData := bytes.NewBuffer(nil) if err := json.NewEncoder(jsonData).Encode(map[string]interface{}{"Cmd": nil}); err != nil { c.Fatalf("Can not encode data to json %s", err) } res, body, err := request.SockRequestRaw("POST", fmt.Sprintf("/containers/%s/exec", name), jsonData, "text/plain", daemonHost()) c.Assert(err, checker.IsNil) c.Assert(res.StatusCode, checker.Equals, http.StatusInternalServerError) b, err := testutil.ReadBody(body) c.Assert(err, checker.IsNil) comment := check.Commentf("Expected message when creating exec command with invalid Content-Type specified") c.Assert(getErrorMessage(c, b), checker.Contains, "Content-Type specified", comment) }
func (s *DockerSuite) TestDeprecatedStartWithTooLowMemoryLimit(c *check.C) { // TODO Windows: Port once memory is supported testRequires(c, DaemonIsLinux) out, _ := dockerCmd(c, "create", "busybox") containerID := strings.TrimSpace(out) config := `{ "CpuShares": 100, "Memory": 524287 }` res, body, err := request.SockRequestRaw("POST", formatV123StartAPIURL("/containers/"+containerID+"/start"), strings.NewReader(config), "application/json", daemonHost()) c.Assert(err, checker.IsNil) b, err2 := testutil.ReadBody(body) c.Assert(err2, checker.IsNil) c.Assert(res.StatusCode, checker.Equals, http.StatusInternalServerError) c.Assert(string(b), checker.Contains, "Minimum memory limit allowed is 4MB") }
func (s *DockerSuite) TestEventsAPIEmptyOutput(c *check.C) { type apiResp struct { resp *http.Response err error } chResp := make(chan *apiResp) go func() { resp, body, err := request.SockRequestRaw("GET", "/events", nil, "", daemonHost()) body.Close() chResp <- &apiResp{resp, err} }() select { case r := <-chResp: c.Assert(r.err, checker.IsNil) c.Assert(r.resp.StatusCode, checker.Equals, http.StatusOK) case <-time.After(3 * time.Second): c.Fatal("timeout waiting for events api to respond, should have responded immediately") } }
func (s *DockerSuite) TestBuildAPIBuildGitWithF(c *check.C) { git, err := newFakeGit("repo", map[string]string{ "baz": `FROM busybox RUN echo from baz`, "Dockerfile": `FROM busybox RUN echo from Dockerfile`, }, false) c.Assert(err, checker.IsNil) defer git.Close() // Make sure it tries to 'dockerfile' query param value res, body, err := request.SockRequestRaw("POST", "/build?dockerfile=baz&remote="+git.RepoURL, nil, "application/json", daemonHost()) c.Assert(err, checker.IsNil) c.Assert(res.StatusCode, checker.Equals, http.StatusOK) buf, err := testutil.ReadBody(body) c.Assert(err, checker.IsNil) out := string(buf) c.Assert(out, checker.Contains, "from baz") }
func (s *DockerSuite) TestAPIStatsNoStreamGetCpu(c *check.C) { out, _ := dockerCmd(c, "run", "-d", "busybox", "/bin/sh", "-c", "while true;do echo 'Hello'; usleep 100000; done") id := strings.TrimSpace(out) c.Assert(waitRun(id), checker.IsNil) resp, body, err := request.SockRequestRaw("GET", fmt.Sprintf("/containers/%s/stats?stream=false", id), nil, "", daemonHost()) c.Assert(err, checker.IsNil) c.Assert(resp.StatusCode, checker.Equals, http.StatusOK) c.Assert(resp.Header.Get("Content-Type"), checker.Equals, "application/json") var v *types.Stats err = json.NewDecoder(body).Decode(&v) c.Assert(err, checker.IsNil) body.Close() var cpuPercent = 0.0 if daemonPlatform != "windows" { cpuDelta := float64(v.CPUStats.CPUUsage.TotalUsage - v.PreCPUStats.CPUUsage.TotalUsage) systemDelta := float64(v.CPUStats.SystemUsage - v.PreCPUStats.SystemUsage) cpuPercent = (cpuDelta / systemDelta) * float64(len(v.CPUStats.CPUUsage.PercpuUsage)) * 100.0 } else { // Max number of 100ns intervals between the previous time read and now possIntervals := uint64(v.Read.Sub(v.PreRead).Nanoseconds()) // Start with number of ns intervals possIntervals /= 100 // Convert to number of 100ns intervals possIntervals *= uint64(v.NumProcs) // Multiple by the number of processors // Intervals used intervalsUsed := v.CPUStats.CPUUsage.TotalUsage - v.PreCPUStats.CPUUsage.TotalUsage // Percentage avoiding divide-by-zero if possIntervals > 0 { cpuPercent = float64(intervalsUsed) / float64(possIntervals) * 100.0 } } c.Assert(cpuPercent, check.Not(checker.Equals), 0.0, check.Commentf("docker stats with no-stream get cpu usage failed: was %v", cpuPercent)) }
func (s *DockerSuite) TestLogsAPIWithStdout(c *check.C) { out, _ := dockerCmd(c, "run", "-d", "-t", "busybox", "/bin/sh", "-c", "while true; do echo hello; sleep 1; done") id := strings.TrimSpace(out) c.Assert(waitRun(id), checker.IsNil) type logOut struct { out string res *http.Response err error } chLog := make(chan logOut) go func() { res, body, err := request.SockRequestRaw("GET", fmt.Sprintf("/containers/%s/logs?follow=1&stdout=1×tamps=1", id), nil, "", daemonHost()) if err != nil { chLog <- logOut{"", nil, err} return } defer body.Close() out, err := bufio.NewReader(body).ReadString('\n') if err != nil { chLog <- logOut{"", nil, err} return } chLog <- logOut{strings.TrimSpace(out), res, err} }() select { case l := <-chLog: c.Assert(l.err, checker.IsNil) c.Assert(l.res.StatusCode, checker.Equals, http.StatusOK) if !strings.HasSuffix(l.out, "hello") { c.Fatalf("expected log output to container 'hello', but it does not") } case <-time.After(20 * time.Second): c.Fatal("timeout waiting for logs to exit") } }
func (s *DockerSuite) TestAPIStatsNoStreamConnectedContainers(c *check.C) { testRequires(c, DaemonIsLinux) out1, _ := runSleepingContainer(c) id1 := strings.TrimSpace(out1) c.Assert(waitRun(id1), checker.IsNil) out2, _ := runSleepingContainer(c, "--net", "container:"+id1) id2 := strings.TrimSpace(out2) c.Assert(waitRun(id2), checker.IsNil) ch := make(chan error) go func() { resp, body, err := request.SockRequestRaw("GET", fmt.Sprintf("/containers/%s/stats?stream=false", id2), nil, "", daemonHost()) defer body.Close() if err != nil { ch <- err } if resp.StatusCode != http.StatusOK { ch <- fmt.Errorf("Invalid StatusCode %v", resp.StatusCode) } if resp.Header.Get("Content-Type") != "application/json" { ch <- fmt.Errorf("Invalid 'Content-Type' %v", resp.Header.Get("Content-Type")) } var v *types.Stats if err := json.NewDecoder(body).Decode(&v); err != nil { ch <- err } ch <- nil }() select { case err := <-ch: c.Assert(err, checker.IsNil, check.Commentf("Error in stats Engine API: %v", err)) case <-time.After(15 * time.Second): c.Fatalf("Stats did not return after timeout") } }