github.com/ojongerius/docker@v1.11.2/container/state_test.go (about)

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