Browse code

Add test coverage to signal/trap.go

Signed-off-by: Naveed Jamil <naveed.jamil@tenpearls.com>

Naveed Jamil authored on 2017/06/01 15:39:35
Showing 2 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,43 @@
0
+package main
1
+
2
+import (
3
+	"os"
4
+	"syscall"
5
+	"time"
6
+
7
+	"github.com/docker/docker/pkg/signal"
8
+	"github.com/sirupsen/logrus"
9
+)
10
+
11
+func main() {
12
+	sigmap := map[string]os.Signal{
13
+		"TERM": syscall.SIGTERM,
14
+		"QUIT": syscall.SIGQUIT,
15
+		"INT":  os.Interrupt,
16
+	}
17
+	signal.Trap(func() {
18
+		time.Sleep(time.Second)
19
+		os.Exit(99)
20
+	}, logrus.StandardLogger())
21
+	go func() {
22
+		p, err := os.FindProcess(os.Getpid())
23
+		if err != nil {
24
+			panic(err)
25
+		}
26
+		s := os.Getenv("SIGNAL_TYPE")
27
+		multiple := os.Getenv("IF_MULTIPLE")
28
+		switch s {
29
+		case "TERM", "INT":
30
+			if multiple == "1" {
31
+				for {
32
+					p.Signal(sigmap[s])
33
+				}
34
+			} else {
35
+				p.Signal(sigmap[s])
36
+			}
37
+		case "QUIT":
38
+			p.Signal(sigmap[s])
39
+		}
40
+	}()
41
+	time.Sleep(2 * time.Second)
42
+}
0 43
new file mode 100644
... ...
@@ -0,0 +1,82 @@
0
+// +build linux
1
+
2
+package signal
3
+
4
+import (
5
+	"fmt"
6
+	"io/ioutil"
7
+	"os"
8
+	"os/exec"
9
+	"syscall"
10
+	"testing"
11
+
12
+	"github.com/stretchr/testify/assert"
13
+	"github.com/stretchr/testify/require"
14
+)
15
+
16
+func buildTestBinary(t *testing.T, tmpdir string, prefix string) (string, string) {
17
+	tmpDir, err := ioutil.TempDir(tmpdir, prefix)
18
+	require.NoError(t, err)
19
+	exePath := tmpDir + "/" + prefix
20
+	wd, _ := os.Getwd()
21
+	testHelperCode := wd + "/testfiles/main.go"
22
+	cmd := exec.Command("go", "build", "-o", exePath, testHelperCode)
23
+	err = cmd.Run()
24
+	require.NoError(t, err)
25
+	return exePath, tmpDir
26
+}
27
+
28
+func TestTrap(t *testing.T) {
29
+	var sigmap = []struct {
30
+		name     string
31
+		signal   os.Signal
32
+		multiple bool
33
+	}{
34
+		{"TERM", syscall.SIGTERM, false},
35
+		{"QUIT", syscall.SIGQUIT, true},
36
+		{"INT", os.Interrupt, false},
37
+		{"TERM", syscall.SIGTERM, true},
38
+		{"INT", os.Interrupt, true},
39
+	}
40
+	exePath, tmpDir := buildTestBinary(t, "", "main")
41
+	defer os.RemoveAll(tmpDir)
42
+
43
+	for _, v := range sigmap {
44
+		cmd := exec.Command(exePath)
45
+		cmd.Env = append(os.Environ(), fmt.Sprintf("SIGNAL_TYPE=%s", v.name))
46
+		if v.multiple {
47
+			cmd.Env = append(cmd.Env, "IF_MULTIPLE=1")
48
+		}
49
+		err := cmd.Start()
50
+		require.NoError(t, err)
51
+		err = cmd.Wait()
52
+		if e, ok := err.(*exec.ExitError); ok {
53
+			code := e.Sys().(syscall.WaitStatus).ExitStatus()
54
+			if v.multiple {
55
+				assert.Equal(t, 128+int(v.signal.(syscall.Signal)), code)
56
+			} else {
57
+				assert.Equal(t, 99, code)
58
+			}
59
+			continue
60
+		}
61
+		t.Fatal("process didn't end with any error")
62
+	}
63
+
64
+}
65
+
66
+func TestDumpStacks(t *testing.T) {
67
+	directory, err := ioutil.TempDir("", "test-dump-tasks")
68
+	assert.NoError(t, err)
69
+	defer os.RemoveAll(directory)
70
+	dumpPath, err := DumpStacks(directory)
71
+	assert.NoError(t, err)
72
+	readFile, _ := ioutil.ReadFile(dumpPath)
73
+	fileData := string(readFile)
74
+	assert.Contains(t, fileData, "goroutine")
75
+}
76
+
77
+func TestDumpStacksWithEmptyInput(t *testing.T) {
78
+	path, err := DumpStacks("")
79
+	assert.NoError(t, err)
80
+	assert.Equal(t, os.Stderr.Name(), path)
81
+}