gvisor.dev/gvisor@v0.0.0-20240520182842-f9d4d51c7e0f/test/runtimes/proctor/lib/go.go (about)

     1  // Copyright 2019 The gVisor Authors.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package lib
    16  
    17  import (
    18  	"fmt"
    19  	"os"
    20  	"os/exec"
    21  	"regexp"
    22  	"strings"
    23  )
    24  
    25  var (
    26  	goTestRegEx = regexp.MustCompile(`^.+\.go$`)
    27  
    28  	// Directories with .dir contain helper files for tests.
    29  	// Exclude benchmarks and stress tests.
    30  	goDirFilter = regexp.MustCompile(`^(bench|stress)\/.+$|^.+\.dir.+$`)
    31  )
    32  
    33  // Location of Go tests on disk.
    34  const goTestDir = "/usr/local/go/test"
    35  
    36  // goRunner implements TestRunner for Go.
    37  //
    38  // There are two types of Go tests: "Go tool tests" and "Go tests on disk".
    39  // "Go tool tests" are found and executed using `go tool dist test`. "Go tests
    40  // on disk" are found in the /usr/local/go/test directory and are executed
    41  // using `go run run.go`.
    42  type goRunner struct{}
    43  
    44  var _ TestRunner = goRunner{}
    45  
    46  // ListTests implements TestRunner.ListTests.
    47  func (goRunner) ListTests() ([]string, error) {
    48  	// Go tool dist test tests.
    49  	args := []string{"run", "cmd/dist", "test", "-list"}
    50  	cmd := exec.Command("go", args...)
    51  	cmd.Stderr = os.Stderr
    52  	out, err := cmd.Output()
    53  	if err != nil {
    54  		return nil, fmt.Errorf("failed to list: %v", err)
    55  	}
    56  	var toolSlice []string
    57  	for _, test := range strings.Split(string(out), "\n") {
    58  		toolSlice = append(toolSlice, test)
    59  	}
    60  
    61  	// Go tests on disk.
    62  	diskSlice, err := Search(goTestDir, goTestRegEx)
    63  	if err != nil {
    64  		return nil, err
    65  	}
    66  	// Remove items from /bench/, /stress/ and .dir files
    67  	diskFiltered := diskSlice[:0]
    68  	for _, file := range diskSlice {
    69  		if !goDirFilter.MatchString(file) {
    70  			diskFiltered = append(diskFiltered, file)
    71  		}
    72  	}
    73  
    74  	return append(toolSlice, diskFiltered...), nil
    75  }
    76  
    77  // TestCmds implements TestRunner.TestCmds.
    78  func (goRunner) TestCmds(tests []string) []*exec.Cmd {
    79  	var toolTests, onDiskTests []string
    80  	for _, test := range tests {
    81  		if strings.HasSuffix(test, ".go") {
    82  			onDiskTests = append(onDiskTests, test)
    83  		} else {
    84  			toolTests = append(toolTests, "^"+test+"$")
    85  		}
    86  	}
    87  
    88  	var cmds []*exec.Cmd
    89  	if len(toolTests) > 0 {
    90  		cmd := exec.Command("go", "run", "cmd/dist", "test", "-v", "-no-rebuild", "-run", strings.Join(toolTests, "|"))
    91  		// Bump up timeout. Some go tool tests take more than 3 minutes to run.
    92  		// golang/go/src/cmd/dist/test.go:registerStdTest() sets default timeout to
    93  		// 3 minutes which can only be increased via GO_TEST_TIMEOUT_SCALE.
    94  		cmd.Env = append(cmd.Environ(), "GO_TEST_TIMEOUT_SCALE=2")
    95  		cmds = append(cmds, cmd)
    96  	}
    97  	if len(onDiskTests) > 0 {
    98  		cmd := exec.Command("go", []string{"test", "cmd/internal/testdir", fmt.Sprintf("-run='Test/(%s)'", strings.Join(onDiskTests, "|"))}...)
    99  		cmds = append(cmds, cmd)
   100  	}
   101  
   102  	return cmds
   103  }