github.com/ruphin/docker@v1.10.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/daemon/execdriver"
     9  )
    10  
    11  func TestStateRunStop(t *testing.T) {
    12  	s := NewState()
    13  	for i := 1; i < 3; i++ { // full lifecycle two times
    14  		started := make(chan struct{})
    15  		var pid int64
    16  		go func() {
    17  			runPid, _ := s.waitRunning(-1 * time.Second)
    18  			atomic.StoreInt64(&pid, int64(runPid))
    19  			close(started)
    20  		}()
    21  		s.Lock()
    22  		s.SetRunning(i + 100)
    23  		s.Unlock()
    24  
    25  		if !s.IsRunning() {
    26  			t.Fatal("State not running")
    27  		}
    28  		if s.Pid != i+100 {
    29  			t.Fatalf("Pid %v, expected %v", s.Pid, i+100)
    30  		}
    31  		if s.ExitCode != 0 {
    32  			t.Fatalf("ExitCode %v, expected 0", s.ExitCode)
    33  		}
    34  		select {
    35  		case <-time.After(100 * time.Millisecond):
    36  			t.Fatal("Start callback doesn't fire in 100 milliseconds")
    37  		case <-started:
    38  			t.Log("Start callback fired")
    39  		}
    40  		runPid := int(atomic.LoadInt64(&pid))
    41  		if runPid != i+100 {
    42  			t.Fatalf("Pid %v, expected %v", runPid, i+100)
    43  		}
    44  		if pid, err := s.waitRunning(-1 * time.Second); err != nil || pid != i+100 {
    45  			t.Fatalf("waitRunning returned pid: %v, err: %v, expected pid: %v, err: %v", pid, err, i+100, nil)
    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.SetStoppedLocking(&execdriver.ExitStatus{ExitCode: i})
    56  		if s.IsRunning() {
    57  			t.Fatal("State is running")
    58  		}
    59  		if s.ExitCode != i {
    60  			t.Fatalf("ExitCode %v, expected %v", s.ExitCode, i)
    61  		}
    62  		if s.Pid != 0 {
    63  			t.Fatalf("Pid %v, expected 0", s.Pid)
    64  		}
    65  		select {
    66  		case <-time.After(100 * time.Millisecond):
    67  			t.Fatal("Stop callback doesn't fire in 100 milliseconds")
    68  		case <-stopped:
    69  			t.Log("Stop callback fired")
    70  		}
    71  		exitCode := int(atomic.LoadInt64(&exit))
    72  		if exitCode != i {
    73  			t.Fatalf("ExitCode %v, expected %v", exitCode, i)
    74  		}
    75  		if exitCode, err := s.WaitStop(-1 * time.Second); err != nil || exitCode != i {
    76  			t.Fatalf("WaitStop returned exitCode: %v, err: %v, expected exitCode: %v, err: %v", exitCode, err, i, nil)
    77  		}
    78  	}
    79  }
    80  
    81  func TestStateTimeoutWait(t *testing.T) {
    82  	s := NewState()
    83  	started := make(chan struct{})
    84  	go func() {
    85  		s.waitRunning(100 * time.Millisecond)
    86  		close(started)
    87  	}()
    88  	select {
    89  	case <-time.After(200 * time.Millisecond):
    90  		t.Fatal("Start callback doesn't fire in 100 milliseconds")
    91  	case <-started:
    92  		t.Log("Start callback fired")
    93  	}
    94  
    95  	s.Lock()
    96  	s.SetRunning(49)
    97  	s.Unlock()
    98  
    99  	stopped := make(chan struct{})
   100  	go func() {
   101  		s.waitRunning(100 * time.Millisecond)
   102  		close(stopped)
   103  	}()
   104  	select {
   105  	case <-time.After(200 * time.Millisecond):
   106  		t.Fatal("Start callback doesn't fire in 100 milliseconds")
   107  	case <-stopped:
   108  		t.Log("Start callback fired")
   109  	}
   110  
   111  }