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  }