github.com/ruphin/docker@v1.10.1/container/state_test.go (about) 1 package container 2 3 import ( 4 "sync/atomic" 5 "testing" 6 "time" 7 8 "github.com/docker/docker/daemon/execdriver" 9 ) 10 11 func TestStateRunStop(t *testing.T) { 12 s := NewState() 13 for i := 1; i < 3; i++ { // full lifecycle two times 14 started := make(chan struct{}) 15 var pid int64 16 go func() { 17 runPid, _ := s.waitRunning(-1 * time.Second) 18 atomic.StoreInt64(&pid, int64(runPid)) 19 close(started) 20 }() 21 s.Lock() 22 s.SetRunning(i + 100) 23 s.Unlock() 24 25 if !s.IsRunning() { 26 t.Fatal("State not running") 27 } 28 if s.Pid != i+100 { 29 t.Fatalf("Pid %v, expected %v", s.Pid, i+100) 30 } 31 if s.ExitCode != 0 { 32 t.Fatalf("ExitCode %v, expected 0", s.ExitCode) 33 } 34 select { 35 case <-time.After(100 * time.Millisecond): 36 t.Fatal("Start callback doesn't fire in 100 milliseconds") 37 case <-started: 38 t.Log("Start callback fired") 39 } 40 runPid := int(atomic.LoadInt64(&pid)) 41 if runPid != i+100 { 42 t.Fatalf("Pid %v, expected %v", runPid, i+100) 43 } 44 if pid, err := s.waitRunning(-1 * time.Second); err != nil || pid != i+100 { 45 t.Fatalf("waitRunning returned pid: %v, err: %v, expected pid: %v, err: %v", pid, err, i+100, nil) 46 } 47 48 stopped := make(chan struct{}) 49 var exit int64 50 go func() { 51 exitCode, _ := s.WaitStop(-1 * time.Second) 52 atomic.StoreInt64(&exit, int64(exitCode)) 53 close(stopped) 54 }() 55 s.SetStoppedLocking(&execdriver.ExitStatus{ExitCode: i}) 56 if s.IsRunning() { 57 t.Fatal("State is running") 58 } 59 if s.ExitCode != i { 60 t.Fatalf("ExitCode %v, expected %v", s.ExitCode, i) 61 } 62 if s.Pid != 0 { 63 t.Fatalf("Pid %v, expected 0", s.Pid) 64 } 65 select { 66 case <-time.After(100 * time.Millisecond): 67 t.Fatal("Stop callback doesn't fire in 100 milliseconds") 68 case <-stopped: 69 t.Log("Stop callback fired") 70 } 71 exitCode := int(atomic.LoadInt64(&exit)) 72 if exitCode != i { 73 t.Fatalf("ExitCode %v, expected %v", exitCode, i) 74 } 75 if exitCode, err := s.WaitStop(-1 * time.Second); err != nil || exitCode != i { 76 t.Fatalf("WaitStop returned exitCode: %v, err: %v, expected exitCode: %v, err: %v", exitCode, err, i, nil) 77 } 78 } 79 } 80 81 func TestStateTimeoutWait(t *testing.T) { 82 s := NewState() 83 started := make(chan struct{}) 84 go func() { 85 s.waitRunning(100 * time.Millisecond) 86 close(started) 87 }() 88 select { 89 case <-time.After(200 * time.Millisecond): 90 t.Fatal("Start callback doesn't fire in 100 milliseconds") 91 case <-started: 92 t.Log("Start callback fired") 93 } 94 95 s.Lock() 96 s.SetRunning(49) 97 s.Unlock() 98 99 stopped := make(chan struct{}) 100 go func() { 101 s.waitRunning(100 * time.Millisecond) 102 close(stopped) 103 }() 104 select { 105 case <-time.After(200 * time.Millisecond): 106 t.Fatal("Start callback doesn't fire in 100 milliseconds") 107 case <-stopped: 108 t.Log("Start callback fired") 109 } 110 111 }