Browse Source

Merge pull request #33450 from naveed-jamil-tenpearls/pkg/signal/trap

Add test coverage to signal/trap.go
Yong Tang 8 years ago
parent
commit
479cc38bb9
2 changed files with 125 additions and 0 deletions
  1. 43 0
      pkg/signal/testfiles/main.go
  2. 82 0
      pkg/signal/trap_linux_test.go

+ 43 - 0
pkg/signal/testfiles/main.go

@@ -0,0 +1,43 @@
+package main
+
+import (
+	"os"
+	"syscall"
+	"time"
+
+	"github.com/docker/docker/pkg/signal"
+	"github.com/sirupsen/logrus"
+)
+
+func main() {
+	sigmap := map[string]os.Signal{
+		"TERM": syscall.SIGTERM,
+		"QUIT": syscall.SIGQUIT,
+		"INT":  os.Interrupt,
+	}
+	signal.Trap(func() {
+		time.Sleep(time.Second)
+		os.Exit(99)
+	}, logrus.StandardLogger())
+	go func() {
+		p, err := os.FindProcess(os.Getpid())
+		if err != nil {
+			panic(err)
+		}
+		s := os.Getenv("SIGNAL_TYPE")
+		multiple := os.Getenv("IF_MULTIPLE")
+		switch s {
+		case "TERM", "INT":
+			if multiple == "1" {
+				for {
+					p.Signal(sigmap[s])
+				}
+			} else {
+				p.Signal(sigmap[s])
+			}
+		case "QUIT":
+			p.Signal(sigmap[s])
+		}
+	}()
+	time.Sleep(2 * time.Second)
+}

+ 82 - 0
pkg/signal/trap_linux_test.go

@@ -0,0 +1,82 @@
+// +build linux
+
+package signal
+
+import (
+	"fmt"
+	"io/ioutil"
+	"os"
+	"os/exec"
+	"syscall"
+	"testing"
+
+	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/require"
+)
+
+func buildTestBinary(t *testing.T, tmpdir string, prefix string) (string, string) {
+	tmpDir, err := ioutil.TempDir(tmpdir, prefix)
+	require.NoError(t, err)
+	exePath := tmpDir + "/" + prefix
+	wd, _ := os.Getwd()
+	testHelperCode := wd + "/testfiles/main.go"
+	cmd := exec.Command("go", "build", "-o", exePath, testHelperCode)
+	err = cmd.Run()
+	require.NoError(t, err)
+	return exePath, tmpDir
+}
+
+func TestTrap(t *testing.T) {
+	var sigmap = []struct {
+		name     string
+		signal   os.Signal
+		multiple bool
+	}{
+		{"TERM", syscall.SIGTERM, false},
+		{"QUIT", syscall.SIGQUIT, true},
+		{"INT", os.Interrupt, false},
+		{"TERM", syscall.SIGTERM, true},
+		{"INT", os.Interrupt, true},
+	}
+	exePath, tmpDir := buildTestBinary(t, "", "main")
+	defer os.RemoveAll(tmpDir)
+
+	for _, v := range sigmap {
+		cmd := exec.Command(exePath)
+		cmd.Env = append(os.Environ(), fmt.Sprintf("SIGNAL_TYPE=%s", v.name))
+		if v.multiple {
+			cmd.Env = append(cmd.Env, "IF_MULTIPLE=1")
+		}
+		err := cmd.Start()
+		require.NoError(t, err)
+		err = cmd.Wait()
+		if e, ok := err.(*exec.ExitError); ok {
+			code := e.Sys().(syscall.WaitStatus).ExitStatus()
+			if v.multiple {
+				assert.Equal(t, 128+int(v.signal.(syscall.Signal)), code)
+			} else {
+				assert.Equal(t, 99, code)
+			}
+			continue
+		}
+		t.Fatal("process didn't end with any error")
+	}
+
+}
+
+func TestDumpStacks(t *testing.T) {
+	directory, err := ioutil.TempDir("", "test-dump-tasks")
+	assert.NoError(t, err)
+	defer os.RemoveAll(directory)
+	dumpPath, err := DumpStacks(directory)
+	assert.NoError(t, err)
+	readFile, _ := ioutil.ReadFile(dumpPath)
+	fileData := string(readFile)
+	assert.Contains(t, fileData, "goroutine")
+}
+
+func TestDumpStacksWithEmptyInput(t *testing.T) {
+	path, err := DumpStacks("")
+	assert.NoError(t, err)
+	assert.Equal(t, os.Stderr.Name(), path)
+}