health_test.go 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. package daemon // import "github.com/docker/docker/daemon"
  2. import (
  3. "testing"
  4. "time"
  5. "github.com/docker/docker/api/types"
  6. containertypes "github.com/docker/docker/api/types/container"
  7. eventtypes "github.com/docker/docker/api/types/events"
  8. "github.com/docker/docker/container"
  9. "github.com/docker/docker/daemon/events"
  10. )
  11. func reset(c *container.Container) {
  12. c.State = &container.State{}
  13. c.State.Health = &container.Health{}
  14. c.State.Health.SetStatus(types.Starting)
  15. }
  16. func TestNoneHealthcheck(t *testing.T) {
  17. c := &container.Container{
  18. ID: "container_id",
  19. Name: "container_name",
  20. Config: &containertypes.Config{
  21. Image: "image_name",
  22. Healthcheck: &containertypes.HealthConfig{
  23. Test: []string{"NONE"},
  24. },
  25. },
  26. State: &container.State{},
  27. }
  28. store, err := container.NewViewDB()
  29. if err != nil {
  30. t.Fatal(err)
  31. }
  32. daemon := &Daemon{
  33. containersReplica: store,
  34. }
  35. daemon.initHealthMonitor(c)
  36. if c.State.Health != nil {
  37. t.Error("Expecting Health to be nil, but was not")
  38. }
  39. }
  40. // FIXME(vdemeester) This takes around 3s… This is *way* too long
  41. func TestHealthStates(t *testing.T) {
  42. e := events.New()
  43. _, l, _ := e.Subscribe()
  44. defer e.Evict(l)
  45. expect := func(expected eventtypes.Action) {
  46. select {
  47. case event := <-l:
  48. ev := event.(eventtypes.Message)
  49. if ev.Action != expected {
  50. t.Errorf("Expecting event %#v, but got %#v\n", expected, ev.Action)
  51. }
  52. case <-time.After(1 * time.Second):
  53. t.Errorf("Expecting event %#v, but got nothing\n", expected)
  54. }
  55. }
  56. c := &container.Container{
  57. ID: "container_id",
  58. Name: "container_name",
  59. Config: &containertypes.Config{
  60. Image: "image_name",
  61. },
  62. }
  63. store, err := container.NewViewDB()
  64. if err != nil {
  65. t.Fatal(err)
  66. }
  67. daemon := &Daemon{
  68. EventsService: e,
  69. containersReplica: store,
  70. }
  71. muteLogs(t)
  72. c.Config.Healthcheck = &containertypes.HealthConfig{
  73. Retries: 1,
  74. }
  75. reset(c)
  76. handleResult := func(startTime time.Time, exitCode int) {
  77. handleProbeResult(daemon, c, &types.HealthcheckResult{
  78. Start: startTime,
  79. End: startTime,
  80. ExitCode: exitCode,
  81. }, nil)
  82. }
  83. // starting -> failed -> success -> failed
  84. handleResult(c.State.StartedAt.Add(1*time.Second), 1)
  85. expect(eventtypes.ActionHealthStatusUnhealthy)
  86. handleResult(c.State.StartedAt.Add(2*time.Second), 0)
  87. expect(eventtypes.ActionHealthStatusHealthy)
  88. handleResult(c.State.StartedAt.Add(3*time.Second), 1)
  89. expect(eventtypes.ActionHealthStatusUnhealthy)
  90. // Test retries
  91. reset(c)
  92. c.Config.Healthcheck.Retries = 3
  93. handleResult(c.State.StartedAt.Add(20*time.Second), 1)
  94. handleResult(c.State.StartedAt.Add(40*time.Second), 1)
  95. if status := c.State.Health.Status(); status != types.Starting {
  96. t.Errorf("Expecting starting, but got %#v\n", status)
  97. }
  98. if c.State.Health.FailingStreak != 2 {
  99. t.Errorf("Expecting FailingStreak=2, but got %d\n", c.State.Health.FailingStreak)
  100. }
  101. handleResult(c.State.StartedAt.Add(60*time.Second), 1)
  102. expect(eventtypes.ActionHealthStatusUnhealthy)
  103. handleResult(c.State.StartedAt.Add(80*time.Second), 0)
  104. expect(eventtypes.ActionHealthStatusHealthy)
  105. if c.State.Health.FailingStreak != 0 {
  106. t.Errorf("Expecting FailingStreak=0, but got %d\n", c.State.Health.FailingStreak)
  107. }
  108. // Test start period
  109. reset(c)
  110. c.Config.Healthcheck.Retries = 2
  111. c.Config.Healthcheck.StartPeriod = 30 * time.Second
  112. handleResult(c.State.StartedAt.Add(20*time.Second), 1)
  113. if status := c.State.Health.Status(); status != types.Starting {
  114. t.Errorf("Expecting starting, but got %#v\n", status)
  115. }
  116. if c.State.Health.FailingStreak != 0 {
  117. t.Errorf("Expecting FailingStreak=0, but got %d\n", c.State.Health.FailingStreak)
  118. }
  119. handleResult(c.State.StartedAt.Add(50*time.Second), 1)
  120. if status := c.State.Health.Status(); status != types.Starting {
  121. t.Errorf("Expecting starting, but got %#v\n", status)
  122. }
  123. if c.State.Health.FailingStreak != 1 {
  124. t.Errorf("Expecting FailingStreak=1, but got %d\n", c.State.Health.FailingStreak)
  125. }
  126. handleResult(c.State.StartedAt.Add(80*time.Second), 0)
  127. expect(eventtypes.ActionHealthStatusHealthy)
  128. if c.State.Health.FailingStreak != 0 {
  129. t.Errorf("Expecting FailingStreak=0, but got %d\n", c.State.Health.FailingStreak)
  130. }
  131. }