2015-02-13 11:45:04 -05:00
package main
import (
2015-10-03 08:53:25 -04:00
"bufio"
2015-02-13 11:45:04 -05:00
"os/exec"
2015-10-03 08:53:25 -04:00
"regexp"
2015-02-13 11:45:04 -05:00
"strings"
"time"
2016-12-30 12:23:00 -05:00
"github.com/docker/docker/integration-cli/checker"
2017-04-11 15:18:30 -04:00
"github.com/docker/docker/integration-cli/cli"
2015-02-13 11:45:04 -05:00
"github.com/go-check/check"
)
2015-09-17 12:20:25 -04:00
func ( s * DockerSuite ) TestStatsNoStream ( c * check . C ) {
2016-02-02 20:59:11 -05:00
// Windows does not support stats
2015-08-28 13:36:42 -04:00
testRequires ( c , DaemonIsLinux )
2015-07-20 02:44:22 -04:00
out , _ := dockerCmd ( c , "run" , "-d" , "busybox" , "top" )
2015-02-13 11:45:04 -05:00
id := strings . TrimSpace ( out )
2015-10-09 06:24:32 -04:00
c . Assert ( waitRun ( id ) , checker . IsNil )
2015-02-13 11:45:04 -05:00
statsCmd := exec . Command ( dockerBinary , "stats" , "--no-stream" , id )
2015-09-16 17:16:55 -04:00
type output struct {
out [ ] byte
err error
}
ch := make ( chan output )
2015-02-13 11:45:04 -05:00
go func ( ) {
2015-09-16 17:16:55 -04:00
out , err := statsCmd . Output ( )
ch <- output { out , err }
2015-02-13 11:45:04 -05:00
} ( )
select {
2015-09-16 17:16:55 -04:00
case outerr := <- ch :
2015-10-09 06:24:32 -04:00
c . Assert ( outerr . err , checker . IsNil , check . Commentf ( "Error running stats: %v" , outerr . err ) )
2017-10-04 16:43:00 -04:00
c . Assert ( string ( outerr . out ) , checker . Contains , id [ : 12 ] ) //running container wasn't present in output
2015-05-30 13:25:51 -04:00
case <- time . After ( 3 * time . Second ) :
2015-02-13 11:45:04 -05:00
statsCmd . Process . Kill ( )
c . Fatalf ( "stats did not return immediately when not streaming" )
}
2015-09-17 12:20:25 -04:00
}
func ( s * DockerSuite ) TestStatsContainerNotFound ( c * check . C ) {
2016-02-02 20:59:11 -05:00
// Windows does not support stats
2015-09-17 12:20:25 -04:00
testRequires ( c , DaemonIsLinux )
2015-09-16 17:16:55 -04:00
2015-09-17 12:20:25 -04:00
out , _ , err := dockerCmdWithError ( "stats" , "notfound" )
2015-10-09 06:24:32 -04:00
c . Assert ( err , checker . NotNil )
2015-12-04 02:00:08 -05:00
c . Assert ( out , checker . Contains , "No such container: notfound" , check . Commentf ( "Expected to fail on not found container stats, got %q instead" , out ) )
2015-09-17 12:20:25 -04:00
out , _ , err = dockerCmdWithError ( "stats" , "--no-stream" , "notfound" )
2015-10-09 06:24:32 -04:00
c . Assert ( err , checker . NotNil )
2015-12-04 02:00:08 -05:00
c . Assert ( out , checker . Contains , "No such container: notfound" , check . Commentf ( "Expected to fail on not found container stats with --no-stream, got %q instead" , out ) )
2015-02-13 11:45:04 -05:00
}
2015-10-03 08:53:25 -04:00
func ( s * DockerSuite ) TestStatsAllRunningNoStream ( c * check . C ) {
2016-02-02 20:59:11 -05:00
// Windows does not support stats
2015-10-03 08:53:25 -04:00
testRequires ( c , DaemonIsLinux )
out , _ := dockerCmd ( c , "run" , "-d" , "busybox" , "top" )
id1 := strings . TrimSpace ( out ) [ : 12 ]
c . Assert ( waitRun ( id1 ) , check . IsNil )
out , _ = dockerCmd ( c , "run" , "-d" , "busybox" , "top" )
id2 := strings . TrimSpace ( out ) [ : 12 ]
c . Assert ( waitRun ( id2 ) , check . IsNil )
out , _ = dockerCmd ( c , "run" , "-d" , "busybox" , "top" )
id3 := strings . TrimSpace ( out ) [ : 12 ]
c . Assert ( waitRun ( id3 ) , check . IsNil )
dockerCmd ( c , "stop" , id3 )
out , _ = dockerCmd ( c , "stats" , "--no-stream" )
if ! strings . Contains ( out , id1 ) || ! strings . Contains ( out , id2 ) {
c . Fatalf ( "Expected stats output to contain both %s and %s, got %s" , id1 , id2 , out )
}
if strings . Contains ( out , id3 ) {
c . Fatalf ( "Did not expect %s in stats, got %s" , id3 , out )
}
2016-03-01 02:09:48 -05:00
// check output contains real data, but not all zeros
reg , _ := regexp . Compile ( "[1-9]+" )
// split output with "\n", outLines[1] is id2's output
// outLines[2] is id1's output
outLines := strings . Split ( out , "\n" )
// check stat result of id2 contains real data
realData := reg . Find ( [ ] byte ( outLines [ 1 ] [ 12 : ] ) )
c . Assert ( realData , checker . NotNil , check . Commentf ( "stat result are empty: %s" , out ) )
// check stat result of id1 contains real data
realData = reg . Find ( [ ] byte ( outLines [ 2 ] [ 12 : ] ) )
c . Assert ( realData , checker . NotNil , check . Commentf ( "stat result are empty: %s" , out ) )
2015-10-03 08:53:25 -04:00
}
func ( s * DockerSuite ) TestStatsAllNoStream ( c * check . C ) {
2016-02-02 20:59:11 -05:00
// Windows does not support stats
2015-10-03 08:53:25 -04:00
testRequires ( c , DaemonIsLinux )
out , _ := dockerCmd ( c , "run" , "-d" , "busybox" , "top" )
id1 := strings . TrimSpace ( out ) [ : 12 ]
c . Assert ( waitRun ( id1 ) , check . IsNil )
dockerCmd ( c , "stop" , id1 )
out , _ = dockerCmd ( c , "run" , "-d" , "busybox" , "top" )
id2 := strings . TrimSpace ( out ) [ : 12 ]
c . Assert ( waitRun ( id2 ) , check . IsNil )
out , _ = dockerCmd ( c , "stats" , "--all" , "--no-stream" )
if ! strings . Contains ( out , id1 ) || ! strings . Contains ( out , id2 ) {
c . Fatalf ( "Expected stats output to contain both %s and %s, got %s" , id1 , id2 , out )
}
2016-03-01 02:09:48 -05:00
// check output contains real data, but not all zeros
reg , _ := regexp . Compile ( "[1-9]+" )
// split output with "\n", outLines[1] is id2's output
outLines := strings . Split ( out , "\n" )
// check stat result of id2 contains real data
realData := reg . Find ( [ ] byte ( outLines [ 1 ] [ 12 : ] ) )
c . Assert ( realData , checker . NotNil , check . Commentf ( "stat result of %s is empty: %s" , id2 , out ) )
// check stat result of id1 contains all zero
realData = reg . Find ( [ ] byte ( outLines [ 2 ] [ 12 : ] ) )
c . Assert ( realData , checker . IsNil , check . Commentf ( "stat result of %s should be empty : %s" , id1 , out ) )
2015-10-03 08:53:25 -04:00
}
func ( s * DockerSuite ) TestStatsAllNewContainersAdded ( c * check . C ) {
2016-02-02 20:59:11 -05:00
// Windows does not support stats
2016-03-01 17:10:13 -05:00
testRequires ( c , DaemonIsLinux )
2015-10-03 08:53:25 -04:00
id := make ( chan string )
addedChan := make ( chan struct { } )
2016-02-26 16:50:50 -05:00
runSleepingContainer ( c , "-d" )
2015-10-03 08:53:25 -04:00
statsCmd := exec . Command ( dockerBinary , "stats" )
stdout , err := statsCmd . StdoutPipe ( )
c . Assert ( err , check . IsNil )
c . Assert ( statsCmd . Start ( ) , check . IsNil )
defer statsCmd . Process . Kill ( )
go func ( ) {
containerID := <- id
matchID := regexp . MustCompile ( containerID )
scanner := bufio . NewScanner ( stdout )
for scanner . Scan ( ) {
switch {
case matchID . MatchString ( scanner . Text ( ) ) :
close ( addedChan )
2016-02-26 16:50:50 -05:00
return
2015-10-03 08:53:25 -04:00
}
}
} ( )
2017-04-16 17:39:30 -04:00
out := runSleepingContainer ( c , "-d" )
2016-01-08 04:02:08 -05:00
c . Assert ( waitRun ( strings . TrimSpace ( out ) ) , check . IsNil )
2015-10-03 08:53:25 -04:00
id <- strings . TrimSpace ( out ) [ : 12 ]
select {
2016-02-26 16:50:50 -05:00
case <- time . After ( 30 * time . Second ) :
2015-10-03 08:53:25 -04:00
c . Fatal ( "failed to observe new container created added to stats" )
case <- addedChan :
// ignore, done
}
}
2016-12-26 04:43:18 -05:00
func ( s * DockerSuite ) TestStatsFormatAll ( c * check . C ) {
// Windows does not support stats
testRequires ( c , DaemonIsLinux )
2017-04-11 15:18:30 -04:00
cli . DockerCmd ( c , "run" , "-d" , "--name=RunningOne" , "busybox" , "top" )
cli . WaitRun ( c , "RunningOne" )
cli . DockerCmd ( c , "run" , "-d" , "--name=ExitedOne" , "busybox" , "top" )
cli . DockerCmd ( c , "stop" , "ExitedOne" )
cli . WaitExited ( c , "ExitedOne" , 5 * time . Second )
2016-12-26 04:43:18 -05:00
2017-04-11 15:18:30 -04:00
out := cli . DockerCmd ( c , "stats" , "--no-stream" , "--format" , "{{.Name}}" ) . Combined ( )
2016-12-26 04:43:18 -05:00
c . Assert ( out , checker . Contains , "RunningOne" )
c . Assert ( out , checker . Not ( checker . Contains ) , "ExitedOne" )
2017-04-11 15:18:30 -04:00
out = cli . DockerCmd ( c , "stats" , "--all" , "--no-stream" , "--format" , "{{.Name}}" ) . Combined ( )
2016-12-26 04:43:18 -05:00
c . Assert ( out , checker . Contains , "RunningOne" )
c . Assert ( out , checker . Contains , "ExitedOne" )
}