github.com/Shopify/docker@v1.13.1/container/state_test.go (about)

     1  package container
     2  
     3  import (
     4  	"sync/atomic"
     5  	"testing"
     6  	"time"
     7  
     8  	"github.com/docker/docker/api/types"
     9  )
    10  
    11  func TestIsValidHealthString(t *testing.T) {
    12  	contexts := []struct {
    13  		Health   string
    14  		Expected bool
    15  	}{
    16  		{types.Healthy, true},
    17  		{types.Unhealthy, true},
    18  		{types.Starting, true},
    19  		{types.NoHealthcheck, true},
    20  		{"fail", false},
    21  	}
    22  
    23  	for _, c := range contexts {
    24  		v := IsValidHealthString(c.Health)
    25  		if v != c.Expected {
    26  			t.Fatalf("Expected %t, but got %t", c.Expected, v)
    27  		}
    28  	}
    29  }
    30  
    31  func TestStateRunStop(t *testing.T) {
    32  	s := NewState()
    33  	for i := 1; i < 3; i++ { // full lifecycle two times
    34  		s.Lock()
    35  		s.SetRunning(i+100, false)
    36  		s.Unlock()
    37  
    38  		if !s.IsRunning() {
    39  			t.Fatal("State not running")
    40  		}
    41  		if s.Pid != i+100 {
    42  			t.Fatalf("Pid %v, expected %v", s.Pid, i+100)
    43  		}
    44  		if s.ExitCode() != 0 {
    45  			t.Fatalf("ExitCode %v, expected 0", s.ExitCode())
    46  		}
    47  
    48  		stopped := make(chan struct{})
    49  		var exit int64
    50  		go func() {
    51  			exitCode, _ := s.WaitStop(-1 * time.Second)
    52  			atomic.StoreInt64(&exit, int64(exitCode))
    53  			close(stopped)
    54  		}()
    55  		s.Lock()
    56  		s.SetStopped(&ExitStatus{ExitCode: i})
    57  		s.Unlock()
    58  		if s.IsRunning() {
    59  			t.Fatal("State is running")
    60  		}
    61  		if s.ExitCode() != i {
    62  			t.Fatalf("ExitCode %v, expected %v", s.ExitCode(), i)
    63  		}
    64  		if s.Pid != 0 {
    65  			t.Fatalf("Pid %v, expected 0", s.Pid)
    66  		}
    67  		select {
    68  		case <-time.After(100 * time.Millisecond):
    69  			t.Fatal("Stop callback doesn't fire in 100 milliseconds")
    70  		case <-stopped:
    71  			t.Log("Stop callback fired")
    72  		}
    73  		exitCode := int(atomic.LoadInt64(&exit))
    74  		if exitCode != i {
    75  			t.Fatalf("ExitCode %v, expected %v", exitCode, i)
    76  		}
    77  		if exitCode, err := s.WaitStop(-1 * time.Second); err != nil || exitCode != i {
    78  			t.Fatalf("WaitStop returned exitCode: %v, err: %v, expected exitCode: %v, err: %v", exitCode, err, i, nil)
    79  		}
    80  	}
    81  }
    82  
    83  func TestStateTimeoutWait(t *testing.T) {
    84  	s := NewState()
    85  	stopped := make(chan struct{})
    86  	go func() {
    87  		s.WaitStop(100 * time.Millisecond)
    88  		close(stopped)
    89  	}()
    90  	select {
    91  	case <-time.After(200 * time.Millisecond):
    92  		t.Fatal("Stop callback doesn't fire in 200 milliseconds")
    93  	case <-stopped:
    94  		t.Log("Stop callback fired")
    95  	}
    96  
    97  	s.Lock()
    98  	s.SetStopped(&ExitStatus{ExitCode: 1})
    99  	s.Unlock()
   100  
   101  	stopped = make(chan struct{})
   102  	go func() {
   103  		s.WaitStop(100 * time.Millisecond)
   104  		close(stopped)
   105  	}()
   106  	select {
   107  	case <-time.After(200 * time.Millisecond):
   108  		t.Fatal("Stop callback doesn't fire in 100 milliseconds")
   109  	case <-stopped:
   110  		t.Log("Stop callback fired")
   111  	}
   112  
   113  }