You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

113 lines
2.4 KiB

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