github.com/noxiouz/docker@v0.7.3-0.20160629055221-3d231c78e8c5/daemon/health_test.go (about)

     1  package daemon
     2  
     3  import (
     4  	"testing"
     5  	"time"
     6  
     7  	"github.com/docker/docker/container"
     8  	"github.com/docker/docker/daemon/events"
     9  	"github.com/docker/engine-api/types"
    10  	containertypes "github.com/docker/engine-api/types/container"
    11  	eventtypes "github.com/docker/engine-api/types/events"
    12  )
    13  
    14  func reset(c *container.Container) {
    15  	c.State = &container.State{}
    16  	c.State.Health = &container.Health{}
    17  	c.State.Health.Status = types.Starting
    18  }
    19  
    20  func TestHealthStates(t *testing.T) {
    21  	e := events.New()
    22  	_, l, _ := e.Subscribe()
    23  	defer e.Evict(l)
    24  
    25  	expect := func(expected string) {
    26  		select {
    27  		case event := <-l:
    28  			ev := event.(eventtypes.Message)
    29  			if ev.Status != expected {
    30  				t.Errorf("Expecting event %#v, but got %#v\n", expected, ev.Status)
    31  			}
    32  		case <-time.After(1 * time.Second):
    33  			t.Errorf("Expecting event %#v, but got nothing\n", expected)
    34  		}
    35  	}
    36  
    37  	c := &container.Container{
    38  		CommonContainer: container.CommonContainer{
    39  			ID:   "container_id",
    40  			Name: "container_name",
    41  			Config: &containertypes.Config{
    42  				Image: "image_name",
    43  			},
    44  		},
    45  	}
    46  	daemon := &Daemon{
    47  		EventsService: e,
    48  	}
    49  
    50  	c.Config.Healthcheck = &containertypes.HealthConfig{
    51  		Retries: 1,
    52  	}
    53  
    54  	reset(c)
    55  
    56  	handleResult := func(startTime time.Time, exitCode int) {
    57  		handleProbeResult(daemon, c, &types.HealthcheckResult{
    58  			Start:    startTime,
    59  			End:      startTime,
    60  			ExitCode: exitCode,
    61  		})
    62  	}
    63  
    64  	// starting -> failed -> success -> failed
    65  
    66  	handleResult(c.State.StartedAt.Add(1*time.Second), 1)
    67  	expect("health_status: unhealthy")
    68  
    69  	handleResult(c.State.StartedAt.Add(2*time.Second), 0)
    70  	expect("health_status: healthy")
    71  
    72  	handleResult(c.State.StartedAt.Add(3*time.Second), 1)
    73  	expect("health_status: unhealthy")
    74  
    75  	// starting -> starting -> starting ->
    76  	// healthy -> starting (invalid transition)
    77  
    78  	reset(c)
    79  
    80  	handleResult(c.State.StartedAt.Add(20*time.Second), 2)
    81  	handleResult(c.State.StartedAt.Add(40*time.Second), 2)
    82  	if c.State.Health.Status != types.Starting {
    83  		t.Errorf("Expecting starting, but got %#v\n", c.State.Health.Status)
    84  	}
    85  
    86  	handleResult(c.State.StartedAt.Add(50*time.Second), 0)
    87  	expect("health_status: healthy")
    88  	handleResult(c.State.StartedAt.Add(60*time.Second), 2)
    89  	expect("health_status: unhealthy")
    90  
    91  	// Test retries
    92  
    93  	reset(c)
    94  	c.Config.Healthcheck.Retries = 3
    95  
    96  	handleResult(c.State.StartedAt.Add(20*time.Second), 1)
    97  	handleResult(c.State.StartedAt.Add(40*time.Second), 1)
    98  	if c.State.Health.Status != types.Starting {
    99  		t.Errorf("Expecting starting, but got %#v\n", c.State.Health.Status)
   100  	}
   101  	if c.State.Health.FailingStreak != 2 {
   102  		t.Errorf("Expecting FailingStreak=2, but got %d\n", c.State.Health.FailingStreak)
   103  	}
   104  	handleResult(c.State.StartedAt.Add(60*time.Second), 1)
   105  	expect("health_status: unhealthy")
   106  
   107  	handleResult(c.State.StartedAt.Add(80*time.Second), 0)
   108  	expect("health_status: healthy")
   109  	if c.State.Health.FailingStreak != 0 {
   110  		t.Errorf("Expecting FailingStreak=0, but got %d\n", c.State.Health.FailingStreak)
   111  	}
   112  }