Skip to content

Commit

Permalink
Allow running multiple test binaries at once in parallel
Browse files Browse the repository at this point in the history
  • Loading branch information
aibor committed Oct 29, 2023
1 parent cfe6256 commit e7d457e
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 29 deletions.
33 changes: 17 additions & 16 deletions cmd/pidonetest/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (
"github.com/aibor/pidonetest/internal"
)

func parseArgs(args []string, testBinaryPath *string, qemuCmd *internal.QEMUCommand, standalone *bool) error {
func parseArgs(args []string, testBinaries *[]string, qemuCmd *internal.QEMUCommand, standalone *bool) error {
fsName := fmt.Sprintf("%s [flags...] [testbinary] [testflags...]", args[0])
fs := flag.NewFlagSet(fsName, flag.ContinueOnError)

Expand All @@ -25,29 +25,30 @@ func parseArgs(args []string, testBinaryPath *string, qemuCmd *internal.QEMUComm
return err
}

posArgs := fs.Args()
if len(posArgs) < 1 {
fmt.Fprintln(fs.Output(), "no testbinary given")
fs.Usage()
return fmt.Errorf("no testbinary given")
}

*testBinaryPath = posArgs[0]

// Catch coverage related paths and adjust them.
for i := 1; i < len(posArgs); i++ {
arg := posArgs[i]
splits := strings.Split(arg, "=")
for _, posArg := range fs.Args() {
splits := strings.Split(posArg, "=")
switch splits[0] {
case "-test.coverprofile":
qemuCmd.SerialFiles = append(qemuCmd.SerialFiles, splits[1])
splits[1] = "/dev/ttyS1"
arg = strings.Join(splits, "=")
posArg = strings.Join(splits, "=")
case "-test.gocoverdir":
splits[1] = "/tmp"
arg = strings.Join(splits, "=")
posArg = strings.Join(splits, "=")
}
qemuCmd.InitArgs = append(qemuCmd.InitArgs, arg)

if strings.HasPrefix(posArg, "-") {
qemuCmd.InitArgs = append(qemuCmd.InitArgs, posArg)
} else {
*testBinaries = append(*testBinaries, posArg)
}
}

if len(*testBinaries) < 1 {
fmt.Fprintln(fs.Output(), "no testbinary given")
fs.Usage()
return fmt.Errorf("no testbinary given")
}

return nil
Expand Down
42 changes: 29 additions & 13 deletions cmd/pidonetest/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"os/signal"
"path/filepath"
"runtime"
"slices"
"syscall"

"github.com/aibor/initramfs"
Expand All @@ -19,9 +20,9 @@ import (

func run() (int, error) {
var (
testBinaryPath string
err error
standalone bool
binaries []string
err error
standalone bool
)

qemuCmd, err := internal.NewQEMUCommand(runtime.GOARCH)
Expand All @@ -32,15 +33,17 @@ func run() (int, error) {
qemuCmd.Kernel = os.Getenv("PIDEONETEST_KERNEL")

// ParseArgs already prints errors, so we just exit.
if err := parseArgs(os.Args, &testBinaryPath, qemuCmd, &standalone); err != nil {
if err := parseArgs(os.Args, &binaries, qemuCmd, &standalone); err != nil {
if err == flag.ErrHelp {
return 0, nil
}
return 1, nil
}

if _, err := os.Stat(testBinaryPath); errors.Is(err, os.ErrNotExist) {
return 1, fmt.Errorf("testbinary file %s doesn't exist.", testBinaryPath)
for _, file := range binaries {
if _, err := os.Stat(file); errors.Is(err, os.ErrNotExist) {
return 1, fmt.Errorf("file %s doesn't exist.", file)
}
}

if qemuCmd.Kernel == "" {
Expand All @@ -52,18 +55,21 @@ func run() (int, error) {

var archive *internal.Initramfs
if standalone {
archive = internal.NewInitramfs(testBinaryPath)
archive = internal.NewInitramfs(binaries[0])
binaries = slices.Delete(binaries, 0, 1)
} else {
var self string
self, err = os.Executable()
if err != nil {
return 1, fmt.Errorf("get own path: %v", err)
}
archive = internal.NewInitramfs(self)
if err := archive.AddFile("test", testBinaryPath); err != nil {
return 1, fmt.Errorf("add test binary: %v", err)
}
}

if err := archive.AddFiles(binaries...); err != nil {
return 1, fmt.Errorf("add binares: %v", err)
}

qemuCmd.Initrd, err = archive.Write()
if err != nil {
return 1, fmt.Errorf("write initramfs: %v", err)
Expand Down Expand Up @@ -107,13 +113,23 @@ func runInit() (int, error) {
return 126, err
}

files, err := os.ReadDir(initramfs.FilesDir)
if err != nil {
return 125, err
}

paths := make([]string, len(files))
for idx, f := range files {
paths[idx] = filepath.Join(initramfs.FilesDir, f.Name())
}

rc := 0
path := filepath.Join(initramfs.FilesDir, "test")
err = sysinit.Exec(path, os.Args[1:], os.Stdout, os.Stderr)
err = sysinit.ExecParallel(paths, os.Args[1:], os.Stdout, os.Stderr)
if err != nil {
if !errors.Is(err, &exec.ExitError{}) {
return 125, err
return 124, err
}
err = nil
rc = 1
}
sysinit.PrintRC(rc)
Expand Down

0 comments on commit e7d457e

Please sign in to comment.