1// +build !windows
2
3package container // import "github.com/docker/docker/daemon/cluster/executor/container"
4
5import (
6	"context"
7	"testing"
8	"time"
9
10	containertypes "github.com/docker/docker/api/types/container"
11	"github.com/docker/docker/container"
12	"github.com/docker/docker/daemon"
13	"github.com/docker/docker/daemon/events"
14	"github.com/docker/swarmkit/api"
15)
16
17func TestHealthStates(t *testing.T) {
18
19	// set up environment: events, task, container ....
20	e := events.New()
21	_, l, _ := e.Subscribe()
22	defer e.Evict(l)
23
24	task := &api.Task{
25		ID:        "id",
26		ServiceID: "sid",
27		Spec: api.TaskSpec{
28			Runtime: &api.TaskSpec_Container{
29				Container: &api.ContainerSpec{
30					Image: "image_name",
31					Labels: map[string]string{
32						"com.docker.swarm.task.id": "id",
33					},
34				},
35			},
36		},
37		Annotations: api.Annotations{Name: "name"},
38	}
39
40	c := &container.Container{
41		ID:   "id",
42		Name: "name",
43		Config: &containertypes.Config{
44			Image: "image_name",
45			Labels: map[string]string{
46				"com.docker.swarm.task.id": "id",
47			},
48		},
49	}
50
51	daemon := &daemon.Daemon{
52		EventsService: e,
53	}
54
55	controller, err := newController(daemon, nil, nil, task, nil, nil)
56	if err != nil {
57		t.Fatalf("create controller fail %v", err)
58	}
59
60	errChan := make(chan error, 1)
61	ctx, cancel := context.WithCancel(context.Background())
62	defer cancel()
63
64	// fire checkHealth
65	go func() {
66		err := controller.checkHealth(ctx)
67		select {
68		case errChan <- err:
69		case <-ctx.Done():
70		}
71	}()
72
73	// send an event and expect to get expectedErr
74	// if expectedErr is nil, shouldn't get any error
75	logAndExpect := func(msg string, expectedErr error) {
76		daemon.LogContainerEvent(c, msg)
77
78		timer := time.NewTimer(1 * time.Second)
79		defer timer.Stop()
80
81		select {
82		case err := <-errChan:
83			if err != expectedErr {
84				t.Fatalf("expect error %v, but get %v", expectedErr, err)
85			}
86		case <-timer.C:
87			if expectedErr != nil {
88				t.Fatal("time limit exceeded, didn't get expected error")
89			}
90		}
91	}
92
93	// events that are ignored by checkHealth
94	logAndExpect("health_status: running", nil)
95	logAndExpect("health_status: healthy", nil)
96	logAndExpect("die", nil)
97
98	// unhealthy event will be caught by checkHealth
99	logAndExpect("health_status: unhealthy", ErrContainerUnhealthy)
100}
101