77c86e509b
Since the containers can handle the out of memory kernel kills gracefully, docker will only provide out of memory information as an additional metadata as part of container status. Docker-DCO-1.1-Signed-off-by: Vishnu Kannan <vishnuk@google.com> (github: vishh) Upstream-commit: f96e04ffc7973e290653044cc86dbc1efb18276d Component: engine
105 lines
2.6 KiB
Go
105 lines
2.6 KiB
Go
package daemon
|
|
|
|
import (
|
|
"sync/atomic"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/docker/docker/daemon/execdriver"
|
|
)
|
|
|
|
func TestStateRunStop(t *testing.T) {
|
|
s := NewState()
|
|
for i := 1; i < 3; i++ { // full lifecycle two times
|
|
started := make(chan struct{})
|
|
var pid int64
|
|
go func() {
|
|
runPid, _ := s.WaitRunning(-1 * time.Second)
|
|
atomic.StoreInt64(&pid, int64(runPid))
|
|
close(started)
|
|
}()
|
|
s.SetRunning(i + 100)
|
|
if !s.IsRunning() {
|
|
t.Fatal("State not running")
|
|
}
|
|
if s.Pid != i+100 {
|
|
t.Fatalf("Pid %v, expected %v", s.Pid, i+100)
|
|
}
|
|
if s.ExitCode != 0 {
|
|
t.Fatalf("ExitCode %v, expected 0", s.ExitCode)
|
|
}
|
|
select {
|
|
case <-time.After(100 * time.Millisecond):
|
|
t.Fatal("Start callback doesn't fire in 100 milliseconds")
|
|
case <-started:
|
|
t.Log("Start callback fired")
|
|
}
|
|
runPid := int(atomic.LoadInt64(&pid))
|
|
if runPid != i+100 {
|
|
t.Fatalf("Pid %v, expected %v", runPid, i+100)
|
|
}
|
|
if pid, err := s.WaitRunning(-1 * time.Second); err != nil || pid != i+100 {
|
|
t.Fatalf("WaitRunning returned pid: %v, err: %v, expected pid: %v, err: %v", pid, err, i+100, nil)
|
|
}
|
|
|
|
stopped := make(chan struct{})
|
|
var exit int64
|
|
go func() {
|
|
exitCode, _ := s.WaitStop(-1 * time.Second)
|
|
atomic.StoreInt64(&exit, int64(exitCode))
|
|
close(stopped)
|
|
}()
|
|
s.SetStopped(&execdriver.ExitStatus{i, false})
|
|
if s.IsRunning() {
|
|
t.Fatal("State is running")
|
|
}
|
|
if s.ExitCode != i {
|
|
t.Fatalf("ExitCode %v, expected %v", s.ExitCode, i)
|
|
}
|
|
if s.Pid != 0 {
|
|
t.Fatalf("Pid %v, expected 0", s.Pid)
|
|
}
|
|
select {
|
|
case <-time.After(100 * time.Millisecond):
|
|
t.Fatal("Stop callback doesn't fire in 100 milliseconds")
|
|
case <-stopped:
|
|
t.Log("Stop callback fired")
|
|
}
|
|
exitCode := int(atomic.LoadInt64(&exit))
|
|
if exitCode != i {
|
|
t.Fatalf("ExitCode %v, expected %v", exitCode, i)
|
|
}
|
|
if exitCode, err := s.WaitStop(-1 * time.Second); err != nil || exitCode != i {
|
|
t.Fatalf("WaitStop returned exitCode: %v, err: %v, expected exitCode: %v, err: %v", exitCode, err, i, nil)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestStateTimeoutWait(t *testing.T) {
|
|
s := NewState()
|
|
started := make(chan struct{})
|
|
go func() {
|
|
s.WaitRunning(100 * time.Millisecond)
|
|
close(started)
|
|
}()
|
|
select {
|
|
case <-time.After(200 * time.Millisecond):
|
|
t.Fatal("Start callback doesn't fire in 100 milliseconds")
|
|
case <-started:
|
|
t.Log("Start callback fired")
|
|
}
|
|
s.SetRunning(42)
|
|
stopped := make(chan struct{})
|
|
go func() {
|
|
s.WaitRunning(100 * time.Millisecond)
|
|
close(stopped)
|
|
}()
|
|
select {
|
|
case <-time.After(200 * time.Millisecond):
|
|
t.Fatal("Start callback doesn't fire in 100 milliseconds")
|
|
case <-stopped:
|
|
t.Log("Start callback fired")
|
|
}
|
|
|
|
}
|