state_test.go 2.6 KB

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