2018-03-01 22:51:11 +00:00
package container // import "github.com/docker/docker/integration/container"
2018-01-31 19:41:31 +00:00
import (
"context"
"testing"
"time"
2018-02-09 18:37:55 +00:00
containertypes "github.com/docker/docker/api/types/container"
2018-01-31 19:41:31 +00:00
"github.com/docker/docker/client"
2018-02-09 18:37:55 +00:00
"github.com/docker/docker/integration/internal/container"
2018-02-09 18:13:26 +00:00
"github.com/docker/docker/integration/internal/request"
2018-01-31 19:41:31 +00:00
"github.com/gotestyourself/gotestyourself/poll"
"github.com/gotestyourself/gotestyourself/skip"
2018-02-09 13:02:36 +00:00
"github.com/stretchr/testify/assert"
2018-01-31 19:41:31 +00:00
"github.com/stretchr/testify/require"
)
func TestKillContainerInvalidSignal ( t * testing . T ) {
defer setupTest ( t ) ( )
client := request . NewAPIClient ( t )
ctx := context . Background ( )
2018-02-09 18:37:55 +00:00
id := container . Run ( t , ctx , client )
2018-01-31 19:41:31 +00:00
2018-02-09 18:37:55 +00:00
err := client . ContainerKill ( ctx , id , "0" )
2018-01-31 19:41:31 +00:00
require . EqualError ( t , err , "Error response from daemon: Invalid signal: 0" )
2018-02-22 10:30:51 +00:00
poll . WaitOn ( t , container . IsInState ( ctx , client , id , "running" ) , poll . WithDelay ( 100 * time . Millisecond ) )
2018-01-31 19:41:31 +00:00
2018-02-09 18:37:55 +00:00
err = client . ContainerKill ( ctx , id , "SIG42" )
2018-01-31 19:41:31 +00:00
require . EqualError ( t , err , "Error response from daemon: Invalid signal: SIG42" )
2018-02-22 10:30:51 +00:00
poll . WaitOn ( t , container . IsInState ( ctx , client , id , "running" ) , poll . WithDelay ( 100 * time . Millisecond ) )
2018-01-31 19:41:31 +00:00
}
func TestKillContainer ( t * testing . T ) {
defer setupTest ( t ) ( )
client := request . NewAPIClient ( t )
testCases := [ ] struct {
doc string
signal string
status string
} {
{
doc : "no signal" ,
signal : "" ,
status : "exited" ,
} ,
{
doc : "non killing signal" ,
signal : "SIGWINCH" ,
status : "running" ,
} ,
{
doc : "killing signal" ,
signal : "SIGTERM" ,
status : "exited" ,
} ,
}
for _ , tc := range testCases {
tc := tc
t . Run ( tc . doc , func ( t * testing . T ) {
ctx := context . Background ( )
2018-02-09 18:37:55 +00:00
id := container . Run ( t , ctx , client )
err := client . ContainerKill ( ctx , id , tc . signal )
2018-01-31 19:41:31 +00:00
require . NoError ( t , err )
2018-02-22 10:30:51 +00:00
poll . WaitOn ( t , container . IsInState ( ctx , client , id , tc . status ) , poll . WithDelay ( 100 * time . Millisecond ) )
2018-01-31 19:41:31 +00:00
} )
}
}
func TestKillWithStopSignalAndRestartPolicies ( t * testing . T ) {
skip . If ( t , testEnv . OSType != "linux" , "Windows only supports 1.25 or later" )
defer setupTest ( t ) ( )
client := request . NewAPIClient ( t )
testCases := [ ] struct {
doc string
stopsignal string
status string
} {
{
doc : "same-signal-disables-restart-policy" ,
stopsignal : "TERM" ,
status : "exited" ,
} ,
{
doc : "different-signal-keep-restart-policy" ,
stopsignal : "CONT" ,
status : "running" ,
} ,
}
for _ , tc := range testCases {
tc := tc
t . Run ( tc . doc , func ( t * testing . T ) {
ctx := context . Background ( )
2018-02-09 18:37:55 +00:00
id := container . Run ( t , ctx , client , func ( c * container . TestContainerConfig ) {
c . Config . StopSignal = tc . stopsignal
c . HostConfig . RestartPolicy = containertypes . RestartPolicy {
Name : "always" ,
}
} )
err := client . ContainerKill ( ctx , id , "TERM" )
2018-01-31 19:41:31 +00:00
require . NoError ( t , err )
2018-02-22 10:30:51 +00:00
poll . WaitOn ( t , container . IsInState ( ctx , client , id , tc . status ) , poll . WithDelay ( 100 * time . Millisecond ) )
2018-01-31 19:41:31 +00:00
} )
}
}
func TestKillStoppedContainer ( t * testing . T ) {
skip . If ( t , testEnv . OSType != "linux" ) // Windows only supports 1.25 or later
defer setupTest ( t ) ( )
ctx := context . Background ( )
client := request . NewAPIClient ( t )
2018-02-09 18:37:55 +00:00
id := container . Create ( t , ctx , client )
err := client . ContainerKill ( ctx , id , "SIGKILL" )
2018-01-31 19:41:31 +00:00
require . Error ( t , err )
require . Contains ( t , err . Error ( ) , "is not running" )
}
func TestKillStoppedContainerAPIPre120 ( t * testing . T ) {
skip . If ( t , testEnv . OSType != "linux" ) // Windows only supports 1.25 or later
defer setupTest ( t ) ( )
ctx := context . Background ( )
client := request . NewAPIClient ( t , client . WithVersion ( "1.19" ) )
2018-02-09 18:37:55 +00:00
id := container . Create ( t , ctx , client )
err := client . ContainerKill ( ctx , id , "SIGKILL" )
2018-01-31 19:41:31 +00:00
require . NoError ( t , err )
}
2018-02-09 12:46:38 +00:00
func TestKillDifferentUserContainer ( t * testing . T ) {
// TODO Windows: Windows does not yet support -u (Feb 2016).
skip . If ( t , testEnv . OSType != "linux" , "User containers (container.Config.User) are not yet supported on %q platform" , testEnv . OSType )
defer setupTest ( t ) ( )
ctx := context . Background ( )
client := request . NewAPIClient ( t , client . WithVersion ( "1.19" ) )
2018-02-09 18:37:55 +00:00
id := container . Run ( t , ctx , client , func ( c * container . TestContainerConfig ) {
c . Config . User = "daemon"
2018-02-09 12:46:38 +00:00
} )
2018-02-22 10:30:51 +00:00
poll . WaitOn ( t , container . IsInState ( ctx , client , id , "running" ) , poll . WithDelay ( 100 * time . Millisecond ) )
2018-02-09 12:46:38 +00:00
2018-02-09 18:37:55 +00:00
err := client . ContainerKill ( ctx , id , "SIGKILL" )
2018-02-09 12:46:38 +00:00
require . NoError ( t , err )
2018-02-22 10:30:51 +00:00
poll . WaitOn ( t , container . IsInState ( ctx , client , id , "exited" ) , poll . WithDelay ( 100 * time . Millisecond ) )
2018-02-09 12:46:38 +00:00
}
2018-02-09 13:02:36 +00:00
func TestInspectOomKilledTrue ( t * testing . T ) {
skip . If ( t , testEnv . DaemonInfo . OSType != "linux" || ! testEnv . DaemonInfo . MemoryLimit || ! testEnv . DaemonInfo . SwapLimit )
defer setupTest ( t ) ( )
ctx := context . Background ( )
client := request . NewAPIClient ( t )
name := "testoomkilled"
cID := container . Run ( t , ctx , client , container . WithName ( name ) , container . WithCmd ( "sh" , "-c" , "x=a; while true; do x=$x$x$x$x; done" ) , func ( c * container . TestContainerConfig ) {
c . HostConfig . Resources . Memory = 32 * 1024 * 1024
} )
2018-02-22 10:30:51 +00:00
poll . WaitOn ( t , container . IsInState ( ctx , client , cID , "exited" ) , poll . WithDelay ( 100 * time . Millisecond ) )
2018-02-09 13:02:36 +00:00
inspect , err := client . ContainerInspect ( ctx , cID )
require . NoError ( t , err )
assert . Equal ( t , inspect . State . OOMKilled , true )
}
func TestInspectOomKilledFalse ( t * testing . T ) {
skip . If ( t , testEnv . DaemonInfo . OSType != "linux" || ! testEnv . DaemonInfo . MemoryLimit || ! testEnv . DaemonInfo . SwapLimit )
defer setupTest ( t ) ( )
ctx := context . Background ( )
client := request . NewAPIClient ( t )
name := "testoomkilled"
cID := container . Run ( t , ctx , client , container . WithName ( name ) , container . WithCmd ( "sh" , "-c" , "echo hello world" ) )
2018-02-22 10:30:51 +00:00
poll . WaitOn ( t , container . IsInState ( ctx , client , cID , "exited" ) , poll . WithDelay ( 100 * time . Millisecond ) )
2018-02-09 13:02:36 +00:00
inspect , err := client . ContainerInspect ( ctx , cID )
require . NoError ( t , err )
assert . Equal ( t , inspect . State . OOMKilled , false )
}