github.com/eatbyte/docker@v1.6.0/engine/shutdown_test.go (about)

     1  package engine
     2  
     3  import (
     4  	"testing"
     5  	"time"
     6  )
     7  
     8  func TestShutdownEmpty(t *testing.T) {
     9  	eng := New()
    10  	if eng.IsShutdown() {
    11  		t.Fatalf("IsShutdown should be false")
    12  	}
    13  	eng.Shutdown()
    14  	if !eng.IsShutdown() {
    15  		t.Fatalf("IsShutdown should be true")
    16  	}
    17  }
    18  
    19  func TestShutdownAfterRun(t *testing.T) {
    20  	eng := New()
    21  	var called bool
    22  	eng.Register("foo", func(job *Job) Status {
    23  		called = true
    24  		return StatusOK
    25  	})
    26  	if err := eng.Job("foo").Run(); err != nil {
    27  		t.Fatal(err)
    28  	}
    29  	eng.Shutdown()
    30  	if err := eng.Job("foo").Run(); err == nil {
    31  		t.Fatalf("%#v", *eng)
    32  	}
    33  }
    34  
    35  // An approximate and racy, but better-than-nothing test that
    36  //
    37  func TestShutdownDuringRun(t *testing.T) {
    38  	var (
    39  		jobDelay     time.Duration = 500 * time.Millisecond
    40  		jobDelayLow  time.Duration = 100 * time.Millisecond
    41  		jobDelayHigh time.Duration = 700 * time.Millisecond
    42  	)
    43  	eng := New()
    44  	var completed bool
    45  	eng.Register("foo", func(job *Job) Status {
    46  		time.Sleep(jobDelay)
    47  		completed = true
    48  		return StatusOK
    49  	})
    50  	go eng.Job("foo").Run()
    51  	time.Sleep(50 * time.Millisecond)
    52  	done := make(chan struct{})
    53  	var startShutdown time.Time
    54  	go func() {
    55  		startShutdown = time.Now()
    56  		eng.Shutdown()
    57  		close(done)
    58  	}()
    59  	time.Sleep(50 * time.Millisecond)
    60  	if err := eng.Job("foo").Run(); err == nil {
    61  		t.Fatalf("run on shutdown should fail: %#v", *eng)
    62  	}
    63  	<-done
    64  	// Verify that Shutdown() blocks for roughly 500ms, instead
    65  	// of returning almost instantly.
    66  	//
    67  	// We use >100ms to leave ample margin for race conditions between
    68  	// goroutines. It's possible (but unlikely in reasonable testing
    69  	// conditions), that this test will cause a false positive or false
    70  	// negative. But it's probably better than not having any test
    71  	// for the 99.999% of time where testing conditions are reasonable.
    72  	if d := time.Since(startShutdown); d.Nanoseconds() < jobDelayLow.Nanoseconds() {
    73  		t.Fatalf("shutdown did not block long enough: %v", d)
    74  	} else if d.Nanoseconds() > jobDelayHigh.Nanoseconds() {
    75  		t.Fatalf("shutdown blocked too long: %v", d)
    76  	}
    77  	if !completed {
    78  		t.Fatalf("job did not complete")
    79  	}
    80  }