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