Run validation in the selected module
This commit is contained in:
@@ -19,25 +19,38 @@ func TestRunUsesOneSuiteWithGoValidationSettings(t *testing.T) {
|
||||
name string
|
||||
race bool
|
||||
fullVet bool
|
||||
compile []Target
|
||||
}{
|
||||
{name: "default"},
|
||||
{name: "race", race: true},
|
||||
{name: "full vet", fullVet: true},
|
||||
{name: "race and full vet", race: true, fullVet: true},
|
||||
{name: "target compilation", compile: []Target{{OS: "linux", Arch: "amd64"}}},
|
||||
} {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
logPath := installGoShim(t, "", false)
|
||||
repositoryDir := t.TempDir()
|
||||
moduleDir := filepath.Join(repositoryDir, "nested module")
|
||||
if err := os.MkdirAll(moduleDir, 0o700); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
err := Run(context.Background(), Request{
|
||||
RepositoryDir: t.TempDir(),
|
||||
Settings: Settings{Race: test.race, FullVet: test.fullVet},
|
||||
RepositoryDir: repositoryDir,
|
||||
ModuleDir: moduleDir,
|
||||
Settings: Settings{Race: test.race, FullVet: test.fullVet, CompileTargets: test.compile},
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("Run() error = %v", err)
|
||||
}
|
||||
|
||||
commands := readGoShimLog(t, logPath)
|
||||
var tests, vets []string
|
||||
var testPosition, vetPosition int
|
||||
for _, directory := range readGoShimDirectories(t, os.Getenv("RELEASEKIT_GO_DIR_LOG")) {
|
||||
if directory != moduleDir {
|
||||
t.Errorf("Go command directory = %q, want selected module %q", directory, moduleDir)
|
||||
}
|
||||
}
|
||||
var tests, vets, builds []string
|
||||
var testPosition, vetPosition, buildPosition int
|
||||
for i, command := range commands {
|
||||
if strings.HasPrefix(command, "test ") {
|
||||
tests = append(tests, command)
|
||||
@@ -47,6 +60,10 @@ func TestRunUsesOneSuiteWithGoValidationSettings(t *testing.T) {
|
||||
vets = append(vets, command)
|
||||
vetPosition = i
|
||||
}
|
||||
if strings.HasPrefix(command, "build ") {
|
||||
builds = append(builds, command)
|
||||
buildPosition = i
|
||||
}
|
||||
}
|
||||
if len(tests) != 1 {
|
||||
t.Fatalf("Go test invocations = %q, want exactly one", tests)
|
||||
@@ -81,6 +98,27 @@ func TestRunUsesOneSuiteWithGoValidationSettings(t *testing.T) {
|
||||
t.Errorf("Go vet command %q did not follow the test suite %q", vets[0], tests[0])
|
||||
}
|
||||
}
|
||||
wantBuilds := 0
|
||||
if len(test.compile) != 0 {
|
||||
wantBuilds = len(test.compile)
|
||||
}
|
||||
if len(builds) != wantBuilds {
|
||||
t.Fatalf("Go build invocations = %q, want %d", builds, wantBuilds)
|
||||
}
|
||||
if wantBuilds != 0 {
|
||||
buildCommand := " " + builds[0] + " "
|
||||
for _, argument := range []string{"build", "-mod=readonly", "-o", os.DevNull, "./..."} {
|
||||
if !strings.Contains(buildCommand, " "+argument+" ") {
|
||||
t.Errorf("Go compile command %q does not contain %q", builds[0], argument)
|
||||
}
|
||||
}
|
||||
if buildPosition <= testPosition {
|
||||
t.Errorf("Go compile command %q did not follow the test suite %q", builds[0], tests[0])
|
||||
}
|
||||
if environments := readGoShimLog(t, os.Getenv("RELEASEKIT_GO_ENV_LOG")); len(environments) != 1 || environments[0] != "linux/amd64|0" {
|
||||
t.Errorf("Go compile baseline = %q, want linux/amd64|0", environments)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -111,6 +149,49 @@ func TestRunReportsRacePrerequisiteFailureWithoutFallback(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestRunValidatesOnlyTheSelectedModule(t *testing.T) {
|
||||
t.Setenv("GOENV", "off")
|
||||
repositoryDir := t.TempDir()
|
||||
nestedDir := filepath.Join(repositoryDir, "nested")
|
||||
siblingDir := filepath.Join(repositoryDir, "sibling")
|
||||
for _, directory := range []string{nestedDir, siblingDir} {
|
||||
if err := os.MkdirAll(directory, 0o700); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
writeModule := func(directory, name, testSource string) {
|
||||
t.Helper()
|
||||
files := map[string]string{
|
||||
"go.mod": "module " + name + "\n\ngo 1.25.0\n",
|
||||
"module_test.go": testSource,
|
||||
}
|
||||
for filename, contents := range files {
|
||||
if err := os.WriteFile(filepath.Join(directory, filename), []byte(contents), 0o600); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
passingTest := "package fixture\nimport \"testing\"\nfunc TestSelected(t *testing.T) {}\n"
|
||||
failingTest := "package fixture\nimport \"testing\"\nfunc TestSibling(t *testing.T) { t.Fatal(\"sibling suite ran\") }\n"
|
||||
writeModule(repositoryDir, "example.com/root", passingTest)
|
||||
writeModule(nestedDir, "example.com/nested", passingTest)
|
||||
writeModule(siblingDir, "example.com/sibling", failingTest)
|
||||
|
||||
if err := Run(context.Background(), Request{RepositoryDir: repositoryDir}); err != nil {
|
||||
t.Fatalf("root module validation: %v", err)
|
||||
}
|
||||
if err := Run(context.Background(), Request{RepositoryDir: repositoryDir, ModuleDir: nestedDir}); err != nil {
|
||||
t.Fatalf("nested module validation ran a sibling suite: %v", err)
|
||||
}
|
||||
|
||||
writeModule(nestedDir, "example.com/nested", failingTest)
|
||||
err := Run(context.Background(), Request{RepositoryDir: repositoryDir, ModuleDir: nestedDir})
|
||||
var failure *Failure
|
||||
if !errors.As(err, &failure) || failure.Check != GoTest {
|
||||
t.Fatalf("failing nested module result = %v, want Go test failure", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRunStopsAfterGoTestFailure(t *testing.T) {
|
||||
logPath := installGoShim(t, "test", false)
|
||||
err := Run(context.Background(), Request{
|
||||
@@ -214,6 +295,7 @@ func installGoShim(t *testing.T, failure string, delayVet bool) string {
|
||||
directory := t.TempDir()
|
||||
logPath := filepath.Join(directory, "go-commands")
|
||||
envLogPath := filepath.Join(directory, "go-environment")
|
||||
directoryLogPath := filepath.Join(directory, "go-directories")
|
||||
settings := map[string]string{
|
||||
"GOHOSTOS": runtime.GOOS,
|
||||
"GOHOSTARCH": runtime.GOARCH,
|
||||
@@ -263,6 +345,7 @@ fi
|
||||
script := fmt.Sprintf(`#!/bin/sh
|
||||
set -eu
|
||||
printf '%%s\n' "$*" >> "$RELEASEKIT_GO_LOG"
|
||||
pwd -P >> "$RELEASEKIT_GO_DIR_LOG"
|
||||
if [ "${1-}" = "env" ]; then
|
||||
printf '%%s\n' '%s'
|
||||
exit 0
|
||||
@@ -281,6 +364,7 @@ exit 0
|
||||
t.Setenv("PATH", path)
|
||||
t.Setenv("RELEASEKIT_GO_LOG", logPath)
|
||||
t.Setenv("RELEASEKIT_GO_ENV_LOG", envLogPath)
|
||||
t.Setenv("RELEASEKIT_GO_DIR_LOG", directoryLogPath)
|
||||
return logPath
|
||||
}
|
||||
|
||||
@@ -293,6 +377,15 @@ func readGoShimLog(t *testing.T, path string) []string {
|
||||
return strings.Split(strings.TrimSpace(string(contents)), "\n")
|
||||
}
|
||||
|
||||
func readGoShimDirectories(t *testing.T, path string) []string {
|
||||
t.Helper()
|
||||
contents, err := os.ReadFile(path)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
return strings.Split(strings.TrimSpace(string(contents)), "\n")
|
||||
}
|
||||
|
||||
func raceSupported(goos, goarch string) bool {
|
||||
switch goos {
|
||||
case "darwin":
|
||||
|
||||
@@ -57,6 +57,7 @@ type Request struct {
|
||||
Commit string
|
||||
Output io.Writer
|
||||
Settings Settings
|
||||
ToolOwner *gotool.Owner
|
||||
}
|
||||
|
||||
// ReadCandidateTree loads the committed-file inventory when a selected check
|
||||
@@ -87,7 +88,15 @@ func Run(ctx context.Context, request Request) (result error) {
|
||||
}
|
||||
}
|
||||
}
|
||||
tool, err := gotool.New(ctx, request.RepositoryDir)
|
||||
goDirectory := request.ModuleDir
|
||||
if goDirectory == "" {
|
||||
goDirectory = request.RepositoryDir
|
||||
}
|
||||
owner := request.ToolOwner
|
||||
if owner == nil {
|
||||
owner = gotool.NewOwner(goDirectory)
|
||||
}
|
||||
tool, err := owner.Acquire(ctx)
|
||||
if err != nil {
|
||||
return &Failure{Check: GoTest, Cause: err}
|
||||
}
|
||||
@@ -99,19 +108,19 @@ func Run(ctx context.Context, request Request) (result error) {
|
||||
args = append(args, "-vet=off")
|
||||
}
|
||||
args = append(args, "./...")
|
||||
err = tool.Run(ctx, request.RepositoryDir, gotool.Native, gotool.Target{}, request.Output, args...)
|
||||
err = tool.Run(ctx, goDirectory, gotool.Native, gotool.Target{}, request.Output, args...)
|
||||
if err != nil {
|
||||
return &Failure{Check: GoTest, Cause: err}
|
||||
}
|
||||
if request.Settings.FullVet {
|
||||
err = tool.Run(ctx, request.RepositoryDir, gotool.Native, gotool.Target{}, request.Output, "vet", "-mod=readonly", "./...")
|
||||
err = tool.Run(ctx, goDirectory, gotool.Native, gotool.Target{}, request.Output, "vet", "-mod=readonly", "./...")
|
||||
if err != nil {
|
||||
return &Failure{Check: GoVet, Cause: err}
|
||||
}
|
||||
}
|
||||
for _, target := range request.Settings.CompileTargets {
|
||||
selected := gotool.Target{OS: target.OS, Arch: target.Arch}
|
||||
err = tool.Run(ctx, request.RepositoryDir, gotool.Static, selected, request.Output,
|
||||
err = tool.Run(ctx, goDirectory, gotool.Static, selected, request.Output,
|
||||
"build", "-mod=readonly", "-o", os.DevNull, "./...")
|
||||
if err != nil {
|
||||
return &Failure{
|
||||
|
||||
Reference in New Issue
Block a user