github.com/feiyang21687/docker@v1.5.0/daemon/state_test.go (about)

     1  package daemon
     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.SetRunning(i + 100)
    22  		if !s.IsRunning() {
    23  			t.Fatal("State not running")
    24  		}
    25  		if s.Pid != i+100 {
    26  			t.Fatalf("Pid %v, expected %v", s.Pid, i+100)
    27  		}
    28  		if s.ExitCode != 0 {
    29  			t.Fatalf("ExitCode %v, expected 0", s.ExitCode)
    30  		}
    31  		select {
    32  		case <-time.After(100 * time.Millisecond):
    33  			t.Fatal("Start callback doesn't fire in 100 milliseconds")
    34  		case <-started:
    35  			t.Log("Start callback fired")
    36  		}
    37  		runPid := int(atomic.LoadInt64(&pid))
    38  		if runPid != i+100 {
    39  			t.Fatalf("Pid %v, expected %v", runPid, i+100)
    40  		}
    41  		if pid, err := s.WaitRunning(-1 * time.Second); err != nil || pid != i+100 {
    42  			t.Fatalf("WaitRunning returned pid: %v, err: %v, expected pid: %v, err: %v", pid, err, i+100, nil)
    43  		}
    44  
    45  		stopped := make(chan struct{})
    46  		var exit int64
    47  		go func() {
    48  			exitCode, _ := s.WaitStop(-1 * time.Second)
    49  			atomic.StoreInt64(&exit, int64(exitCode))
    50  			close(stopped)
    51  		}()
    52  		s.SetStopped(&execdriver.ExitStatus{ExitCode: i})
    53  		if s.IsRunning() {
    54  			t.Fatal("State is running")
    55  		}
    56  		if s.ExitCode != i {
    57  			t.Fatalf("ExitCode %v, expected %v", s.ExitCode, i)
    58  		}
    59  		if s.Pid != 0 {
    60  			t.Fatalf("Pid %v, expected 0", s.Pid)
    61  		}
    62  		select {
    63  		case <-time.After(100 * time.Millisecond):
    64  			t.Fatal("Stop callback doesn't fire in 100 milliseconds")
    65  		case <-stopped:
    66  			t.Log("Stop callback fired")
    67  		}
    68  		exitCode := int(atomic.LoadInt64(&exit))
    69  		if exitCode != i {
    70  			t.Fatalf("ExitCode %v, expected %v", exitCode, i)
    71  		}
    72  		if exitCode, err := s.WaitStop(-1 * time.Second); err != nil || exitCode != i {
    73  			t.Fatalf("WaitStop returned exitCode: %v, err: %v, expected exitCode: %v, err: %v", exitCode, err, i, nil)
    74  		}
    75  	}
    76  }
    77  
    78  func TestStateTimeoutWait(t *testing.T) {
    79  	s := NewState()
    80  	started := make(chan struct{})
    81  	go func() {
    82  		s.WaitRunning(100 * time.Millisecond)
    83  		close(started)
    84  	}()
    85  	select {
    86  	case <-time.After(200 * time.Millisecond):
    87  		t.Fatal("Start callback doesn't fire in 100 milliseconds")
    88  	case <-started:
    89  		t.Log("Start callback fired")
    90  	}
    91  	s.SetRunning(42)
    92  	stopped := make(chan struct{})
    93  	go func() {
    94  		s.WaitRunning(100 * time.Millisecond)
    95  		close(stopped)
    96  	}()
    97  	select {
    98  	case <-time.After(200 * time.Millisecond):
    99  		t.Fatal("Start callback doesn't fire in 100 milliseconds")
   100  	case <-stopped:
   101  		t.Log("Start callback fired")
   102  	}
   103  
   104  }