Browse code

refactor stats to not use internal data structures

- refactor to make it easier to split the api in the future
- addition to check the existing test case and make sure it contains
some expected output

Signed-off-by: Morgan Bauer <mbauer@us.ibm.com>

Morgan Bauer authored on 2015/09/17 06:16:55
Showing 3 changed files
... ...
@@ -59,16 +59,6 @@ func (s *Server) getContainersStats(ctx context.Context, w http.ResponseWriter,
59 59
 	}
60 60
 
61 61
 	stream := boolValueOrDefault(r, "stream", true)
62
-
63
-	// If the container is not running and requires no stream, return an empty stats.
64
-	container, err := s.daemon.Get(vars["name"])
65
-	if err != nil {
66
-		return err
67
-	}
68
-	if !container.IsRunning() && !stream {
69
-		return writeJSON(w, http.StatusOK, &types.Stats{})
70
-	}
71
-
72 62
 	var out io.Writer
73 63
 	if !stream {
74 64
 		w.Header().Set("Content-Type", "application/json")
... ...
@@ -90,7 +80,7 @@ func (s *Server) getContainersStats(ctx context.Context, w http.ResponseWriter,
90 90
 		Version:   version,
91 91
 	}
92 92
 
93
-	return s.daemon.ContainerStats(container, config)
93
+	return s.daemon.ContainerStats(vars["name"], config)
94 94
 }
95 95
 
96 96
 func (s *Server) getContainersLogs(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
... ...
@@ -22,7 +22,18 @@ type ContainerStatsConfig struct {
22 22
 
23 23
 // ContainerStats writes information about the container to the stream
24 24
 // given in the config object.
25
-func (daemon *Daemon) ContainerStats(container *Container, config *ContainerStatsConfig) error {
25
+func (daemon *Daemon) ContainerStats(prefixOrName string, config *ContainerStatsConfig) error {
26
+
27
+	container, err := daemon.Get(prefixOrName)
28
+	if err != nil {
29
+		return err
30
+	}
31
+
32
+	// If the container is not running and requires no stream, return an empty stats.
33
+	if !container.IsRunning() && !config.Stream {
34
+		return json.NewEncoder(config.OutStream).Encode(&types.Stats{})
35
+	}
36
+
26 37
 	updates, err := daemon.subscribeToContainerStats(container)
27 38
 	if err != nil {
28 39
 		return err
... ...
@@ -1,6 +1,7 @@
1 1
 package main
2 2
 
3 3
 import (
4
+	"bytes"
4 5
 	"os/exec"
5 6
 	"strings"
6 7
 	"time"
... ...
@@ -15,18 +16,28 @@ func (s *DockerSuite) TestCliStatsNoStream(c *check.C) {
15 15
 	c.Assert(waitRun(id), check.IsNil)
16 16
 
17 17
 	statsCmd := exec.Command(dockerBinary, "stats", "--no-stream", id)
18
-	chErr := make(chan error)
18
+	type output struct {
19
+		out []byte
20
+		err error
21
+	}
22
+
23
+	ch := make(chan output)
19 24
 	go func() {
20
-		chErr <- statsCmd.Run()
25
+		out, err := statsCmd.Output()
26
+		ch <- output{out, err}
21 27
 	}()
22 28
 
23 29
 	select {
24
-	case err := <-chErr:
25
-		if err != nil {
26
-			c.Fatalf("Error running stats: %v", err)
30
+	case outerr := <-ch:
31
+		if outerr.err != nil {
32
+			c.Fatalf("Error running stats: %v", outerr.err)
33
+		}
34
+		if !bytes.Contains(outerr.out, []byte(id)) {
35
+			c.Fatalf("running container wasn't present in output")
27 36
 		}
28 37
 	case <-time.After(3 * time.Second):
29 38
 		statsCmd.Process.Kill()
30 39
 		c.Fatalf("stats did not return immediately when not streaming")
31 40
 	}
41
+
32 42
 }