github.com/Andyfoo/golang/x/sys@v0.0.0-20190901054642-57c1bf301704/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  // +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  	"io/ioutil"
    17  	"os"
    18  	"os/exec"
    19  	"path/filepath"
    20  	"testing"
    21  
    22  	"github.com/Andyfoo/golang/x/sys/unix"
    23  )
    24  
    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
    29  }
    30  
    31  var (
    32  	testProcs = map[string]testProc{}
    33  	procName  = ""
    34  )
    35  
    36  const (
    37  	optName = "sys-unix-internal-procname"
    38  )
    39  
    40  func init() {
    41  	flag.StringVar(&procName, optName, "", "internal use only")
    42  }
    43  
    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])
    48  	if err != nil {
    49  		return nil, err
    50  	}
    51  	cmd := exec.Command(exe, "-"+optName+"="+procName)
    52  	cmd.Stdout, cmd.Stderr = os.Stdout, os.Stderr
    53  	return cmd, nil
    54  }
    55  
    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)
    61  	defer func() {
    62  		if s.cleanup() != nil {
    63  			t.Fatalf("Failed to run cleanup for %s", procName)
    64  		}
    65  	}()
    66  	if err != nil {
    67  		t.Fatalf("Failed to construct command for %s", procName)
    68  	}
    69  	if (c.Run() == nil) != s.success {
    70  		result := "succeed"
    71  		if !s.success {
    72  			result = "fail"
    73  		}
    74  		t.Fatalf("Process did not %s when it was supposed to", result)
    75  	}
    76  }
    77  
    78  func TestMain(m *testing.M) {
    79  	flag.Parse()
    80  	if procName != "" {
    81  		testProcs[procName].fn()
    82  	}
    83  	os.Exit(m.Run())
    84  }
    85  
    86  // For example, add a test for pledge.
    87  func init() {
    88  	testProcs["pledge"] = testProc{
    89  		func() {
    90  			fmt.Println(unix.Pledge("", ""))
    91  			os.Exit(0)
    92  		},
    93  		func() error {
    94  			files, err := ioutil.ReadDir(".")
    95  			if err != nil {
    96  				return err
    97  			}
    98  			for _, file := range files {
    99  				if filepath.Ext(file.Name()) == ".core" {
   100  					if err := os.Remove(file.Name()); err != nil {
   101  						return err
   102  					}
   103  				}
   104  			}
   105  			return nil
   106  		},
   107  		false,
   108  	}
   109  }
   110  
   111  func TestPledge(t *testing.T) {
   112  	ExitsCorrectly("pledge", t)
   113  }