github.com/docker/docker@v299999999.0.0-20200612211812-aaf470eca7b5+incompatible/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 string) {
    53  		select {
    54  		case event := <-l:
    55  			ev := event.(eventtypes.Message)
    56  			if ev.Status != expected {
    57  				t.Errorf("Expecting event %#v, but got %#v\n", expected, ev.Status)
    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()
    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("health_status: unhealthy")
   101  
   102  	handleResult(c.State.StartedAt.Add(2*time.Second), 0)
   103  	expect("health_status: healthy")
   104  
   105  	handleResult(c.State.StartedAt.Add(3*time.Second), 1)
   106  	expect("health_status: unhealthy")
   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("health_status: unhealthy")
   123  
   124  	handleResult(c.State.StartedAt.Add(80*time.Second), 0)
   125  	expect("health_status: healthy")
   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("health_status: healthy")
   152  	if c.State.Health.FailingStreak != 0 {
   153  		t.Errorf("Expecting FailingStreak=0, but got %d\n", c.State.Health.FailingStreak)
   154  	}
   155  }