mirror of
https://github.com/sipeed/picoclaw.git
synced 2026-05-25 16:00:35 +00:00
157 lines
3.5 KiB
Go
157 lines
3.5 KiB
Go
package integration
|
|
|
|
import (
|
|
"os"
|
|
"os/exec"
|
|
"path/filepath"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
func TestRunIntegrationTestsScriptExecutesSuiteCommand(t *testing.T) {
|
|
bashPath, err := exec.LookPath("bash")
|
|
if err != nil {
|
|
t.Skip("bash not available")
|
|
}
|
|
|
|
repoRoot := repoRootFromTestFile(t)
|
|
suitesRoot := filepath.Join(repoRoot, "integration", "suites")
|
|
suiteDir, err := os.MkdirTemp(suitesRoot, "runner-script-")
|
|
if err != nil {
|
|
t.Fatalf("MkdirTemp() error = %v", err)
|
|
}
|
|
t.Cleanup(func() {
|
|
_ = os.RemoveAll(suiteDir)
|
|
})
|
|
|
|
suiteName := filepath.Base(suiteDir)
|
|
err = os.WriteFile(
|
|
filepath.Join(suiteDir, "suite.env"),
|
|
[]byte("TEST_COMMAND='printf runner-ok'\n"),
|
|
0o644,
|
|
)
|
|
if err != nil {
|
|
t.Fatalf("WriteFile(suite.env) error = %v", err)
|
|
}
|
|
err = os.WriteFile(
|
|
filepath.Join(suiteDir, "docker-compose.yml"),
|
|
[]byte("services:\n fake-dependency:\n image: busybox\n"),
|
|
0o644,
|
|
)
|
|
if err != nil {
|
|
t.Fatalf("WriteFile(docker-compose.yml) error = %v", err)
|
|
}
|
|
|
|
stubDir := t.TempDir()
|
|
logPath := filepath.Join(t.TempDir(), "docker.log")
|
|
err = os.WriteFile(filepath.Join(stubDir, "docker"), []byte(`#!/bin/sh
|
|
set -eu
|
|
|
|
log_file="${DOCKER_LOG:?}"
|
|
{
|
|
printf '%s\n' '---'
|
|
for arg in "$@"; do
|
|
printf '%s\n' "$arg"
|
|
done
|
|
} >>"$log_file"
|
|
|
|
subcommand=""
|
|
for arg in "$@"; do
|
|
case "$arg" in
|
|
config|up|run|down)
|
|
subcommand="$arg"
|
|
;;
|
|
esac
|
|
done
|
|
|
|
case "$subcommand" in
|
|
config)
|
|
printf '%s\n' integration-runner fake-dependency
|
|
;;
|
|
up)
|
|
;;
|
|
run)
|
|
printf '%s\n' runner-ok
|
|
;;
|
|
down)
|
|
;;
|
|
*)
|
|
printf 'unexpected docker invocation: %s\n' "$*" >&2
|
|
exit 1
|
|
;;
|
|
esac
|
|
`), 0o755)
|
|
if err != nil {
|
|
t.Fatalf("WriteFile(docker stub) error = %v", err)
|
|
}
|
|
|
|
cmd := exec.Command(bashPath, filepath.Join(repoRoot, "scripts", "run-integration-tests.sh"), suiteName)
|
|
cmd.Dir = repoRoot
|
|
cmd.Env = append(os.Environ(),
|
|
"PATH="+stubDir+string(os.PathListSeparator)+os.Getenv("PATH"),
|
|
"DOCKER_LOG="+logPath,
|
|
)
|
|
|
|
output, err := cmd.CombinedOutput()
|
|
if err != nil {
|
|
t.Fatalf("run-integration-tests.sh error = %v\noutput:\n%s", err, output)
|
|
}
|
|
if !strings.Contains(string(output), "runner-ok") {
|
|
t.Fatalf("script output did not include runner output:\n%s", output)
|
|
}
|
|
|
|
logData, err := os.ReadFile(logPath)
|
|
if err != nil {
|
|
t.Fatalf("ReadFile(logPath) error = %v", err)
|
|
}
|
|
|
|
runArgs := findLoggedDockerInvocation(t, string(logData), "run")
|
|
if strings.Contains(strings.Join(runArgs, "\n"), "\nsh\n-c\n") {
|
|
t.Fatalf("docker compose run unexpectedly wrapped TEST_COMMAND with sh -c:\n%v", runArgs)
|
|
}
|
|
|
|
if !containsArg(runArgs, "integration-runner") {
|
|
t.Fatalf("docker compose run args missing runner service:\n%v", runArgs)
|
|
}
|
|
if !containsArg(runArgs, "printf runner-ok") {
|
|
t.Fatalf("docker compose run args missing suite command as a single argument:\n%v", runArgs)
|
|
}
|
|
}
|
|
|
|
func repoRootFromTestFile(t *testing.T) string {
|
|
t.Helper()
|
|
|
|
wd, err := os.Getwd()
|
|
if err != nil {
|
|
t.Fatalf("Getwd() error = %v", err)
|
|
}
|
|
return filepath.Dir(wd)
|
|
}
|
|
|
|
func findLoggedDockerInvocation(t *testing.T, logData, subcommand string) []string {
|
|
t.Helper()
|
|
|
|
for _, block := range strings.Split(logData, "---\n") {
|
|
block = strings.TrimSpace(block)
|
|
if block == "" {
|
|
continue
|
|
}
|
|
args := strings.Split(block, "\n")
|
|
if containsArg(args, subcommand) {
|
|
return args
|
|
}
|
|
}
|
|
|
|
t.Fatalf("did not find docker %q invocation in log:\n%s", subcommand, logData)
|
|
return nil
|
|
}
|
|
|
|
func containsArg(args []string, want string) bool {
|
|
for _, arg := range args {
|
|
if arg == want {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|