github.com/docker/engine@v22.0.0-20211208180946-d456264580cf+incompatible/integration-cli/docker_cli_stats_test.go (about) 1 package main 2 3 import ( 4 "bufio" 5 "os/exec" 6 "regexp" 7 "strings" 8 "testing" 9 "time" 10 11 "github.com/docker/docker/integration-cli/cli" 12 "gotest.tools/v3/assert" 13 is "gotest.tools/v3/assert/cmp" 14 ) 15 16 func (s *DockerSuite) TestStatsNoStream(c *testing.T) { 17 // Windows does not support stats 18 testRequires(c, DaemonIsLinux) 19 out, _ := dockerCmd(c, "run", "-d", "busybox", "top") 20 id := strings.TrimSpace(out) 21 assert.NilError(c, waitRun(id)) 22 23 statsCmd := exec.Command(dockerBinary, "stats", "--no-stream", id) 24 type output struct { 25 out []byte 26 err error 27 } 28 29 ch := make(chan output, 1) 30 go func() { 31 out, err := statsCmd.Output() 32 ch <- output{out, err} 33 }() 34 35 select { 36 case outerr := <-ch: 37 assert.NilError(c, outerr.err, "Error running stats: %v", outerr.err) 38 assert.Assert(c, is.Contains(string(outerr.out), id[:12]), "running container wasn't present in output") 39 case <-time.After(3 * time.Second): 40 statsCmd.Process.Kill() 41 c.Fatalf("stats did not return immediately when not streaming") 42 } 43 } 44 45 func (s *DockerSuite) TestStatsContainerNotFound(c *testing.T) { 46 // Windows does not support stats 47 testRequires(c, DaemonIsLinux) 48 49 out, _, err := dockerCmdWithError("stats", "notfound") 50 assert.ErrorContains(c, err, "") 51 assert.Assert(c, is.Contains(out, "No such container: notfound"), "Expected to fail on not found container stats, got %q instead", out) 52 53 out, _, err = dockerCmdWithError("stats", "--no-stream", "notfound") 54 assert.ErrorContains(c, err, "") 55 assert.Assert(c, is.Contains(out, "No such container: notfound"), "Expected to fail on not found container stats with --no-stream, got %q instead", out) 56 } 57 58 func (s *DockerSuite) TestStatsAllRunningNoStream(c *testing.T) { 59 // Windows does not support stats 60 testRequires(c, DaemonIsLinux) 61 62 out, _ := dockerCmd(c, "run", "-d", "busybox", "top") 63 id1 := strings.TrimSpace(out)[:12] 64 assert.NilError(c, waitRun(id1)) 65 out, _ = dockerCmd(c, "run", "-d", "busybox", "top") 66 id2 := strings.TrimSpace(out)[:12] 67 assert.NilError(c, waitRun(id2)) 68 out, _ = dockerCmd(c, "run", "-d", "busybox", "top") 69 id3 := strings.TrimSpace(out)[:12] 70 assert.NilError(c, waitRun(id3)) 71 dockerCmd(c, "stop", id3) 72 73 out, _ = dockerCmd(c, "stats", "--no-stream") 74 if !strings.Contains(out, id1) || !strings.Contains(out, id2) { 75 c.Fatalf("Expected stats output to contain both %s and %s, got %s", id1, id2, out) 76 } 77 if strings.Contains(out, id3) { 78 c.Fatalf("Did not expect %s in stats, got %s", id3, out) 79 } 80 81 // check output contains real data, but not all zeros 82 reg, _ := regexp.Compile("[1-9]+") 83 // split output with "\n", outLines[1] is id2's output 84 // outLines[2] is id1's output 85 outLines := strings.Split(out, "\n") 86 // check stat result of id2 contains real data 87 realData := reg.Find([]byte(outLines[1][12:])) 88 assert.Assert(c, realData != nil, "stat result are empty: %s", out) 89 // check stat result of id1 contains real data 90 realData = reg.Find([]byte(outLines[2][12:])) 91 assert.Assert(c, realData != nil, "stat result are empty: %s", out) 92 } 93 94 func (s *DockerSuite) TestStatsAllNoStream(c *testing.T) { 95 // Windows does not support stats 96 testRequires(c, DaemonIsLinux) 97 98 out, _ := dockerCmd(c, "run", "-d", "busybox", "top") 99 id1 := strings.TrimSpace(out)[:12] 100 assert.NilError(c, waitRun(id1)) 101 dockerCmd(c, "stop", id1) 102 out, _ = dockerCmd(c, "run", "-d", "busybox", "top") 103 id2 := strings.TrimSpace(out)[:12] 104 assert.NilError(c, waitRun(id2)) 105 106 out, _ = dockerCmd(c, "stats", "--all", "--no-stream") 107 if !strings.Contains(out, id1) || !strings.Contains(out, id2) { 108 c.Fatalf("Expected stats output to contain both %s and %s, got %s", id1, id2, out) 109 } 110 111 // check output contains real data, but not all zeros 112 reg, _ := regexp.Compile("[1-9]+") 113 // split output with "\n", outLines[1] is id2's output 114 outLines := strings.Split(out, "\n") 115 // check stat result of id2 contains real data 116 realData := reg.Find([]byte(outLines[1][12:])) 117 assert.Assert(c, realData != nil, "stat result of %s is empty: %s", id2, out) 118 119 // check stat result of id1 contains all zero 120 realData = reg.Find([]byte(outLines[2][12:])) 121 assert.Assert(c, realData == nil, "stat result of %s should be empty : %s", id1, out) 122 } 123 124 func (s *DockerSuite) TestStatsAllNewContainersAdded(c *testing.T) { 125 // Windows does not support stats 126 testRequires(c, DaemonIsLinux) 127 128 id := make(chan string) 129 addedChan := make(chan struct{}) 130 131 runSleepingContainer(c, "-d") 132 statsCmd := exec.Command(dockerBinary, "stats") 133 stdout, err := statsCmd.StdoutPipe() 134 assert.NilError(c, err) 135 assert.NilError(c, statsCmd.Start()) 136 go statsCmd.Wait() 137 defer statsCmd.Process.Kill() 138 139 go func() { 140 containerID := <-id 141 matchID := regexp.MustCompile(containerID) 142 143 scanner := bufio.NewScanner(stdout) 144 for scanner.Scan() { 145 switch { 146 case matchID.MatchString(scanner.Text()): 147 close(addedChan) 148 return 149 } 150 } 151 }() 152 153 out := runSleepingContainer(c, "-d") 154 assert.NilError(c, waitRun(strings.TrimSpace(out))) 155 id <- strings.TrimSpace(out)[:12] 156 157 select { 158 case <-time.After(30 * time.Second): 159 c.Fatal("failed to observe new container created added to stats") 160 case <-addedChan: 161 // ignore, done 162 } 163 } 164 165 func (s *DockerSuite) TestStatsFormatAll(c *testing.T) { 166 // Windows does not support stats 167 testRequires(c, DaemonIsLinux) 168 169 cli.DockerCmd(c, "run", "-d", "--name=RunningOne", "busybox", "top") 170 cli.WaitRun(c, "RunningOne") 171 cli.DockerCmd(c, "run", "-d", "--name=ExitedOne", "busybox", "top") 172 cli.DockerCmd(c, "stop", "ExitedOne") 173 cli.WaitExited(c, "ExitedOne", 5*time.Second) 174 175 out := cli.DockerCmd(c, "stats", "--no-stream", "--format", "{{.Name}}").Combined() 176 assert.Assert(c, is.Contains(out, "RunningOne")) 177 assert.Assert(c, !strings.Contains(out, "ExitedOne")) 178 179 out = cli.DockerCmd(c, "stats", "--all", "--no-stream", "--format", "{{.Name}}").Combined() 180 assert.Assert(c, is.Contains(out, "RunningOne")) 181 assert.Assert(c, is.Contains(out, "ExitedOne")) 182 }