state_test.go 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. package container
  2. import (
  3. "sync/atomic"
  4. "testing"
  5. "time"
  6. "github.com/docker/docker/api/types"
  7. )
  8. func TestIsValidHealthString(t *testing.T) {
  9. contexts := []struct {
  10. Health string
  11. Expected bool
  12. }{
  13. {types.Healthy, true},
  14. {types.Unhealthy, true},
  15. {types.Starting, true},
  16. {types.NoHealthcheck, true},
  17. {"fail", false},
  18. }
  19. for _, c := range contexts {
  20. v := IsValidHealthString(c.Health)
  21. if v != c.Expected {
  22. t.Fatalf("Expected %t, but got %t", c.Expected, v)
  23. }
  24. }
  25. }
  26. func TestStateRunStop(t *testing.T) {
  27. s := NewState()
  28. for i := 1; i < 3; i++ { // full lifecycle two times
  29. s.Lock()
  30. s.SetRunning(i+100, false)
  31. s.Unlock()
  32. if !s.IsRunning() {
  33. t.Fatal("State not running")
  34. }
  35. if s.Pid != i+100 {
  36. t.Fatalf("Pid %v, expected %v", s.Pid, i+100)
  37. }
  38. if s.ExitCode() != 0 {
  39. t.Fatalf("ExitCode %v, expected 0", s.ExitCode())
  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.Lock()
  49. s.SetStopped(&ExitStatus{ExitCode: i})
  50. s.Unlock()
  51. if s.IsRunning() {
  52. t.Fatal("State is running")
  53. }
  54. if s.ExitCode() != i {
  55. t.Fatalf("ExitCode %v, expected %v", s.ExitCode(), i)
  56. }
  57. if s.Pid != 0 {
  58. t.Fatalf("Pid %v, expected 0", s.Pid)
  59. }
  60. select {
  61. case <-time.After(100 * time.Millisecond):
  62. t.Fatal("Stop callback doesn't fire in 100 milliseconds")
  63. case <-stopped:
  64. t.Log("Stop callback fired")
  65. }
  66. exitCode := int(atomic.LoadInt64(&exit))
  67. if exitCode != i {
  68. t.Fatalf("ExitCode %v, expected %v", exitCode, i)
  69. }
  70. if exitCode, err := s.WaitStop(-1 * time.Second); err != nil || exitCode != i {
  71. t.Fatalf("WaitStop returned exitCode: %v, err: %v, expected exitCode: %v, err: %v", exitCode, err, i, nil)
  72. }
  73. }
  74. }
  75. func TestStateTimeoutWait(t *testing.T) {
  76. s := NewState()
  77. stopped := make(chan struct{})
  78. go func() {
  79. s.WaitStop(100 * time.Millisecond)
  80. close(stopped)
  81. }()
  82. select {
  83. case <-time.After(200 * time.Millisecond):
  84. t.Fatal("Stop callback doesn't fire in 200 milliseconds")
  85. case <-stopped:
  86. t.Log("Stop callback fired")
  87. }
  88. s.Lock()
  89. s.SetStopped(&ExitStatus{ExitCode: 1})
  90. s.Unlock()
  91. stopped = make(chan struct{})
  92. go func() {
  93. s.WaitStop(100 * time.Millisecond)
  94. close(stopped)
  95. }()
  96. select {
  97. case <-time.After(200 * time.Millisecond):
  98. t.Fatal("Stop callback doesn't fire in 200 milliseconds")
  99. case <-stopped:
  100. t.Log("Stop callback fired")
  101. }
  102. }