Browse code

Extra testing for engine.Shutdown

Signed-off-by: Solomon Hykes <solomon@docker.com>

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