1 // Copyright 2016 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
7 // This, on the face of it, bizarre testing mechanism is necessary because
8 // the only reliable way to gauge whether or not a pledge(2) call has succeeded
9 // is that the program has been killed as a result of breaking its pledge.
22 "golang.org/x/sys/unix"
25 type testProc struct {
26 fn func() // should always exit instead of returning
27 cleanup func() error // for instance, delete coredumps from testing pledge
28 success bool // whether zero-exit means success or failure
32 testProcs = map[string]testProc{}
37 optName = "sys-unix-internal-procname"
41 flag.StringVar(&procName, optName, "", "internal use only")
44 // testCmd generates a proper command that, when executed, runs the test
45 // corresponding to the given key.
46 func testCmd(procName string) (*exec.Cmd, error) {
47 exe, err := filepath.Abs(os.Args[0])
51 cmd := exec.Command(exe, "-"+optName+"="+procName)
52 cmd.Stdout, cmd.Stderr = os.Stdout, os.Stderr
56 // ExitsCorrectly is a comprehensive, one-line-of-use wrapper for testing
57 // a testProc with a key.
58 func ExitsCorrectly(procName string, t *testing.T) {
59 s := testProcs[procName]
60 c, err := testCmd(procName)
62 if s.cleanup() != nil {
63 t.Fatalf("Failed to run cleanup for %s", procName)
67 t.Fatalf("Failed to construct command for %s", procName)
69 if (c.Run() == nil) != s.success {
74 t.Fatalf("Process did not %s when it was supposed to", result)
78 func TestMain(m *testing.M) {
81 testProcs[procName].fn()
86 // For example, add a test for pledge.
88 testProcs["pledge"] = testProc{
90 fmt.Println(unix.Pledge("", nil))
94 files, err := ioutil.ReadDir(".")
98 for _, file := range files {
99 if filepath.Ext(file.Name()) == ".core" {
100 if err := os.Remove(file.Name()); err != nil {
111 func TestPledge(t *testing.T) {
112 ExitsCorrectly("pledge", t)