github.com/attic-labs/noms@v0.0.0-20210827224422-e5fa29d95e8b/tools/runner/serial_test.go (about) 1 // Copyright 2016 Attic Labs, Inc. All rights reserved. 2 // Licensed under the Apache License, version 2.0: 3 // http://www.apache.org/licenses/LICENSE-2.0 4 5 package runner 6 7 import ( 8 "bytes" 9 "fmt" 10 "io" 11 "io/ioutil" 12 "os" 13 "path/filepath" 14 "runtime" 15 "strings" 16 "testing" 17 18 "github.com/stretchr/testify/suite" 19 ) 20 21 const ( 22 boilerplate = ` 23 from __future__ import print_function 24 import os, sys 25 26 %s 27 ` 28 buildFileBasename = "build.py" 29 ) 30 31 func TestSerialRunnerTestSuite(t *testing.T) { 32 suite.Run(t, &SerialRunnerTestSuite{}) 33 } 34 35 type SerialRunnerTestSuite struct { 36 suite.Suite 37 dir string 38 index int 39 } 40 41 func (suite *SerialRunnerTestSuite) SetupTest() { 42 var err error 43 suite.dir, err = ioutil.TempDir(os.TempDir(), "") 44 suite.NoError(err) 45 } 46 47 func (suite *SerialRunnerTestSuite) TearDownTest() { 48 os.Remove(suite.dir) 49 } 50 51 func (suite *SerialRunnerTestSuite) TestForceRunInDir() { 52 scriptPath := filepath.Join(suite.dir, buildFileBasename) 53 suite.makeTestBuildFile(scriptPath, []string{"print(os.getcwd(), file=sys.stdout)"}) 54 55 old := os.Stdout // keep backup of the real stdout 56 r, w, err := os.Pipe() 57 suite.NoError(err) 58 os.Stdout = w 59 defer func() { os.Stdout = old }() 60 defer r.Close() 61 62 outC := make(chan string) 63 // copy the output in a separate goroutine so printing can't block indefinitely 64 go func() { 65 buf := &bytes.Buffer{} 66 io.Copy(buf, r) 67 outC <- buf.String() 68 }() 69 70 ForceRunInDir(suite.dir, nil, "python", scriptPath) 71 72 w.Close() 73 out := strings.TrimSpace(<-outC) 74 actualSuiteDir, err := filepath.EvalSymlinks(suite.dir) 75 suite.NoError(err) 76 suite.Equal(actualSuiteDir, out) 77 } 78 79 func (suite *SerialRunnerTestSuite) TestRunInDir() { 80 scriptPath := filepath.Join(suite.dir, buildFileBasename) 81 suite.makeTestBuildFile(scriptPath, []string{ 82 "print(os.getcwd(), file=sys.stdout)", 83 "print('error', file=sys.stderr)", 84 }) 85 86 stdout := &bytes.Buffer{} 87 stderr := &bytes.Buffer{} 88 RunInDir(stdout, stderr, suite.dir, "python", scriptPath) 89 actualSuiteDir, err := filepath.EvalSymlinks(suite.dir) 90 suite.NoError(err) 91 suite.Equal(actualSuiteDir, strings.TrimSpace(string(stdout.Bytes()))) 92 suite.Equal("error", strings.TrimSpace(string(stderr.Bytes()))) 93 } 94 95 func (suite *SerialRunnerTestSuite) TestEnvVars() { 96 makeEnvVarPrintBuildFile := func(path, varname string) { 97 fmtStatement := fmt.Sprintf(`print(os.environ['%s'], file=sys.stdout)`, varname) 98 suite.makeTestBuildFile(path, []string{fmtStatement}) 99 } 100 101 type testCase struct { 102 path, varname, expected string 103 } 104 env := Env{ 105 "PATH": os.Getenv("PATH"), 106 "GOPATH": os.Getenv("GOPATH"), 107 "NOMS_CHECKOUT_PATH": "/where/noms/is", 108 "ATTIC_CHECKOUT_PATH": "/where/attic/is", 109 } 110 tests := []testCase{} 111 for n, v := range env { 112 tc := testCase{suite.uniqueBuildFile(), n, v} 113 makeEnvVarPrintBuildFile(tc.path, tc.varname) 114 tests = append(tests, tc) 115 } 116 gorootTestCase := testCase{suite.uniqueBuildFile(), "GOROOT", runtime.GOROOT()} 117 makeEnvVarPrintBuildFile(gorootTestCase.path, gorootTestCase.varname) 118 tests = append(tests, gorootTestCase) 119 120 log := &bytes.Buffer{} 121 if suite.True(Serial(log, log, env, suite.dir, buildFileBasename), "Serial() should have succeeded! logs:\n%s", string(log.Bytes())) { 122 logText := string(log.Bytes()) 123 for _, tc := range tests { 124 suite.Contains(logText, tc.expected) 125 } 126 } 127 } 128 129 func (suite *SerialRunnerTestSuite) TestFailure() { 130 type testCase struct { 131 path, expected string 132 } 133 tests := []testCase{ 134 {suite.uniqueBuildFile(), "Scoobaz"}, 135 {suite.uniqueBuildFile(), "at the disco"}, 136 } 137 goodOne := testCase{suite.uniqueBuildFile(), "All's well"} 138 139 suite.makeTestBuildFile(tests[0].path, []string{"Scoobaz() # Won't compile."}) 140 suite.makeTestBuildFile(tests[1].path, []string{`assert(False, "at the disco") # Won't run.`}) 141 suite.makeTestBuildFile(goodOne.path, []string{fmt.Sprintf(`print "%s"`, goodOne.expected)}) 142 143 log := &bytes.Buffer{} 144 suite.False(Serial(log, log, Env{}, suite.dir, buildFileBasename)) 145 logText := string(log.Bytes()) 146 suite.Contains(logText, tests[0].expected) 147 suite.Contains(logText, tests[1].expected) 148 } 149 150 func (suite *SerialRunnerTestSuite) uniqueBuildFile() string { 151 suite.index++ 152 return filepath.Join(suite.dir, fmt.Sprintf("%d", suite.index), buildFileBasename) 153 } 154 155 func (suite *SerialRunnerTestSuite) makeTestBuildFile(path string, statements []string) { 156 buf := &bytes.Buffer{} 157 fmt.Fprintf(buf, boilerplate, strings.Join(statements, "\n")) 158 err := os.MkdirAll(filepath.Dir(path), 0777) 159 suite.NoError(err) 160 err = ioutil.WriteFile(path, buf.Bytes(), 0755) 161 suite.NoError(err) 162 }