golang.org/x/sys@v0.20.1-0.20240517151509-673e0f94c16d/unix/openbsd_test.go (about) 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. 4 5 //go:build openbsd 6 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. 10 11 package unix_test 12 13 import ( 14 "flag" 15 "fmt" 16 "os" 17 "os/exec" 18 "path/filepath" 19 "testing" 20 21 "golang.org/x/sys/unix" 22 ) 23 24 type testProc struct { 25 fn func() // should always exit instead of returning 26 cleanup func() error // for instance, delete coredumps from testing pledge 27 success bool // whether zero-exit means success or failure 28 } 29 30 var ( 31 testProcs = map[string]testProc{} 32 procName = "" 33 ) 34 35 const ( 36 optName = "sys-unix-internal-procname" 37 ) 38 39 func init() { 40 flag.StringVar(&procName, optName, "", "internal use only") 41 } 42 43 // testCmd generates a proper command that, when executed, runs the test 44 // corresponding to the given key. 45 func testCmd(procName string) (*exec.Cmd, error) { 46 exe, err := filepath.Abs(os.Args[0]) 47 if err != nil { 48 return nil, err 49 } 50 cmd := exec.Command(exe, "-"+optName+"="+procName) 51 cmd.Stdout, cmd.Stderr = os.Stdout, os.Stderr 52 return cmd, nil 53 } 54 55 // ExitsCorrectly is a comprehensive, one-line-of-use wrapper for testing 56 // a testProc with a key. 57 func ExitsCorrectly(procName string, t *testing.T) { 58 s := testProcs[procName] 59 c, err := testCmd(procName) 60 defer func() { 61 if s.cleanup() != nil { 62 t.Fatalf("Failed to run cleanup for %s", procName) 63 } 64 }() 65 if err != nil { 66 t.Fatalf("Failed to construct command for %s", procName) 67 } 68 if (c.Run() == nil) != s.success { 69 result := "succeed" 70 if !s.success { 71 result = "fail" 72 } 73 t.Fatalf("Process did not %s when it was supposed to", result) 74 } 75 } 76 77 func TestMain(m *testing.M) { 78 flag.Parse() 79 if procName != "" { 80 testProcs[procName].fn() 81 } 82 os.Exit(m.Run()) 83 } 84 85 // For example, add a test for pledge. 86 func init() { 87 testProcs["pledge"] = testProc{ 88 func() { 89 fmt.Println(unix.Pledge("", "")) 90 os.Exit(0) 91 }, 92 func() error { 93 files, err := os.ReadDir(".") 94 if err != nil { 95 return err 96 } 97 for _, file := range files { 98 if filepath.Ext(file.Name()) == ".core" { 99 if err := os.Remove(file.Name()); err != nil { 100 return err 101 } 102 } 103 } 104 return nil 105 }, 106 false, 107 } 108 } 109 110 func TestPledge(t *testing.T) { 111 ExitsCorrectly("pledge", t) 112 }