github.com/rentongzhang/docker@v1.8.2-rc1/integration-cli/docker_api_stats_test.go (about)

     1  package main
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"os/exec"
     7  	"runtime"
     8  	"strconv"
     9  	"strings"
    10  	"time"
    11  
    12  	"github.com/docker/docker/api/types"
    13  	"github.com/go-check/check"
    14  )
    15  
    16  func (s *DockerSuite) TestCliStatsNoStreamGetCpu(c *check.C) {
    17  	out, _ := dockerCmd(c, "run", "-d", "busybox", "/bin/sh", "-c", "while true;do echo 'Hello'; usleep 100000; done")
    18  
    19  	id := strings.TrimSpace(out)
    20  	err := waitRun(id)
    21  	c.Assert(err, check.IsNil)
    22  
    23  	resp, body, err := sockRequestRaw("GET", fmt.Sprintf("/containers/%s/stats?stream=false", id), nil, "")
    24  	c.Assert(err, check.IsNil)
    25  	c.Assert(resp.ContentLength > 0, check.Equals, true, check.Commentf("should not use chunked encoding"))
    26  	c.Assert(resp.Header.Get("Content-Type"), check.Equals, "application/json")
    27  
    28  	var v *types.Stats
    29  	err = json.NewDecoder(body).Decode(&v)
    30  	c.Assert(err, check.IsNil)
    31  	body.Close()
    32  
    33  	var cpuPercent = 0.0
    34  	cpuDelta := float64(v.CpuStats.CpuUsage.TotalUsage - v.PreCpuStats.CpuUsage.TotalUsage)
    35  	systemDelta := float64(v.CpuStats.SystemUsage - v.PreCpuStats.SystemUsage)
    36  	cpuPercent = (cpuDelta / systemDelta) * float64(len(v.CpuStats.CpuUsage.PercpuUsage)) * 100.0
    37  	if cpuPercent == 0 {
    38  		c.Fatalf("docker stats with no-stream get cpu usage failed: was %v", cpuPercent)
    39  	}
    40  }
    41  
    42  func (s *DockerSuite) TestStoppedContainerStatsGoroutines(c *check.C) {
    43  	out, _ := dockerCmd(c, "run", "-d", "busybox", "/bin/sh", "-c", "echo 1")
    44  	id := strings.TrimSpace(out)
    45  
    46  	getGoRoutines := func() int {
    47  		_, body, err := sockRequestRaw("GET", fmt.Sprintf("/info"), nil, "")
    48  		c.Assert(err, check.IsNil)
    49  		info := types.Info{}
    50  		err = json.NewDecoder(body).Decode(&info)
    51  		c.Assert(err, check.IsNil)
    52  		body.Close()
    53  		return info.NGoroutines
    54  	}
    55  
    56  	// When the HTTP connection is closed, the number of goroutines should not increase.
    57  	routines := getGoRoutines()
    58  	_, body, err := sockRequestRaw("GET", fmt.Sprintf("/containers/%s/stats", id), nil, "")
    59  	c.Assert(err, check.IsNil)
    60  	body.Close()
    61  
    62  	t := time.After(30 * time.Second)
    63  	for {
    64  		select {
    65  		case <-t:
    66  			c.Assert(getGoRoutines() <= routines, check.Equals, true)
    67  			return
    68  		default:
    69  			if n := getGoRoutines(); n <= routines {
    70  				return
    71  			}
    72  			time.Sleep(200 * time.Millisecond)
    73  		}
    74  	}
    75  }
    76  
    77  func (s *DockerSuite) TestApiNetworkStats(c *check.C) {
    78  	testRequires(c, SameHostDaemon)
    79  	// Run container for 30 secs
    80  	out, _ := dockerCmd(c, "run", "-d", "busybox", "top")
    81  	id := strings.TrimSpace(out)
    82  	err := waitRun(id)
    83  	c.Assert(err, check.IsNil)
    84  
    85  	// Retrieve the container address
    86  	contIP := findContainerIP(c, id)
    87  	numPings := 10
    88  
    89  	// Get the container networking stats before and after pinging the container
    90  	nwStatsPre := getNetworkStats(c, id)
    91  	countParam := "-c"
    92  	if runtime.GOOS == "windows" {
    93  		countParam = "-n" // Ping count parameter is -n on Windows
    94  	}
    95  	pingout, err := exec.Command("ping", contIP, countParam, strconv.Itoa(numPings)).Output()
    96  	pingouts := string(pingout[:])
    97  	c.Assert(err, check.IsNil)
    98  	nwStatsPost := getNetworkStats(c, id)
    99  
   100  	// Verify the stats contain at least the expected number of packets (account for ARP)
   101  	expRxPkts := 1 + nwStatsPre.RxPackets + uint64(numPings)
   102  	expTxPkts := 1 + nwStatsPre.TxPackets + uint64(numPings)
   103  	c.Assert(nwStatsPost.TxPackets >= expTxPkts, check.Equals, true,
   104  		check.Commentf("Reported less TxPackets than expected. Expected >= %d. Found %d. %s", expTxPkts, nwStatsPost.TxPackets, pingouts))
   105  	c.Assert(nwStatsPost.RxPackets >= expRxPkts, check.Equals, true,
   106  		check.Commentf("Reported less Txbytes than expected. Expected >= %d. Found %d. %s", expRxPkts, nwStatsPost.RxPackets, pingouts))
   107  }
   108  
   109  func getNetworkStats(c *check.C, id string) types.Network {
   110  	var st *types.Stats
   111  
   112  	_, body, err := sockRequestRaw("GET", fmt.Sprintf("/containers/%s/stats?stream=false", id), nil, "")
   113  	c.Assert(err, check.IsNil)
   114  
   115  	err = json.NewDecoder(body).Decode(&st)
   116  	c.Assert(err, check.IsNil)
   117  	body.Close()
   118  
   119  	return st.Network
   120  }