summaryrefslogtreecommitdiff
path: root/daemon/state_test.go
blob: 7b02f3aeac8140b501b07379853cd76eaf694233 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
package daemon

import (
	"sync/atomic"
	"testing"
	"time"
)

func TestStateRunStop(t *testing.T) {
	s := NewState()
	for i := 1; i < 3; i++ { // full lifecycle two times
		started := make(chan struct{})
		var pid int64
		go func() {
			runPid, _ := s.WaitRunning(-1 * time.Second)
			atomic.StoreInt64(&pid, int64(runPid))
			close(started)
		}()
		s.SetRunning(i + 100)
		if !s.IsRunning() {
			t.Fatal("State not running")
		}
		if s.Pid != i+100 {
			t.Fatalf("Pid %v, expected %v", s.Pid, i+100)
		}
		if s.ExitCode != 0 {
			t.Fatalf("ExitCode %v, expected 0", s.ExitCode)
		}
		select {
		case <-time.After(100 * time.Millisecond):
			t.Fatal("Start callback doesn't fire in 100 milliseconds")
		case <-started:
			t.Log("Start callback fired")
		}
		runPid := int(atomic.LoadInt64(&pid))
		if runPid != i+100 {
			t.Fatalf("Pid %v, expected %v", runPid, i+100)
		}
		if pid, err := s.WaitRunning(-1 * time.Second); err != nil || pid != i+100 {
			t.Fatal("WaitRunning returned pid: %v, err: %v, expected pid: %v, err: %v", pid, err, i+100, nil)
		}

		stopped := make(chan struct{})
		var exit int64
		go func() {
			exitCode, _ := s.WaitStop(-1 * time.Second)
			atomic.StoreInt64(&exit, int64(exitCode))
			close(stopped)
		}()
		s.SetStopped(i)
		if s.IsRunning() {
			t.Fatal("State is running")
		}
		if s.ExitCode != i {
			t.Fatalf("ExitCode %v, expected %v", s.ExitCode, i)
		}
		if s.Pid != 0 {
			t.Fatalf("Pid %v, expected 0", s.Pid)
		}
		select {
		case <-time.After(100 * time.Millisecond):
			t.Fatal("Stop callback doesn't fire in 100 milliseconds")
		case <-stopped:
			t.Log("Stop callback fired")
		}
		exitCode := int(atomic.LoadInt64(&exit))
		if exitCode != i {
			t.Fatalf("ExitCode %v, expected %v", exitCode, i)
		}
		if exitCode, err := s.WaitStop(-1 * time.Second); err != nil || exitCode != i {
			t.Fatal("WaitStop returned exitCode: %v, err: %v, expected exitCode: %v, err: %v", exitCode, err, i, nil)
		}
	}
}

func TestStateTimeoutWait(t *testing.T) {
	s := NewState()
	started := make(chan struct{})
	go func() {
		s.WaitRunning(100 * time.Millisecond)
		close(started)
	}()
	select {
	case <-time.After(200 * time.Millisecond):
		t.Fatal("Start callback doesn't fire in 100 milliseconds")
	case <-started:
		t.Log("Start callback fired")
	}
	s.SetRunning(42)
	stopped := make(chan struct{})
	go func() {
		s.WaitRunning(100 * time.Millisecond)
		close(stopped)
	}()
	select {
	case <-time.After(200 * time.Millisecond):
		t.Fatal("Start callback doesn't fire in 100 milliseconds")
	case <-stopped:
		t.Log("Start callback fired")
	}

}