main: use emulator exit code instead of parsing test output
This commit changes `tinygo test` to always look at the exit code of the running test, instead of looking for a "PASS" string at the end of the output. This is possible now that the binaries running under qemu-system-arm or qemu-system-riscv32 will signal the correct exit code when they exit. As a side effect, this also makes it possible to avoid the "PASS" line between successful tests. Before: $ tinygo test container/heap container/list PASS ok container/heap 0.001s PASS ok container/list 0.001s After: $ tinygo test container/heap container/list ok container/heap 0.001s ok container/list 0.001s The new behavior is more in line with upstream Go: go test container/heap container/list ok container/heap 0.004s ok container/list 0.004s
Этот коммит содержится в:
родитель
98f84a497d
коммит
4d5ec6c57b
3 изменённых файлов: 16 добавлений и 37 удалений
38
main.go
38
main.go
|
@ -212,6 +212,7 @@ func Test(pkgName string, options *compileopts.Options, testCompileOnly, testVer
|
||||||
// values are whether the test passed and any errors encountered while trying to
|
// values are whether the test passed and any errors encountered while trying to
|
||||||
// run the binary.
|
// run the binary.
|
||||||
func runPackageTest(config *compileopts.Config, result builder.BuildResult, testVerbose, testShort bool) (bool, error) {
|
func runPackageTest(config *compileopts.Config, result builder.BuildResult, testVerbose, testShort bool) (bool, error) {
|
||||||
|
var cmd *exec.Cmd
|
||||||
if len(config.Target.Emulator) == 0 {
|
if len(config.Target.Emulator) == 0 {
|
||||||
// Run directly.
|
// Run directly.
|
||||||
var flags []string
|
var flags []string
|
||||||
|
@ -221,11 +222,16 @@ func runPackageTest(config *compileopts.Config, result builder.BuildResult, test
|
||||||
if testShort {
|
if testShort {
|
||||||
flags = append(flags, "-test.short")
|
flags = append(flags, "-test.short")
|
||||||
}
|
}
|
||||||
|
cmd = executeCommand(config.Options, result.Binary, flags...)
|
||||||
cmd := executeCommand(config.Options, result.Binary, flags...)
|
cmd.Dir = result.MainDir
|
||||||
|
} else {
|
||||||
|
// Run in an emulator.
|
||||||
|
// TODO: pass the -test.v flag if needed.
|
||||||
|
args := append(config.Target.Emulator[1:], result.Binary)
|
||||||
|
cmd = executeCommand(config.Options, config.Target.Emulator[0], args...)
|
||||||
|
}
|
||||||
cmd.Stdout = os.Stdout
|
cmd.Stdout = os.Stdout
|
||||||
cmd.Stderr = os.Stderr
|
cmd.Stderr = os.Stderr
|
||||||
cmd.Dir = result.MainDir
|
|
||||||
err := cmd.Run()
|
err := cmd.Run()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if _, ok := err.(*exec.ExitError); ok {
|
if _, ok := err.(*exec.ExitError); ok {
|
||||||
|
@ -236,32 +242,6 @@ func runPackageTest(config *compileopts.Config, result builder.BuildResult, test
|
||||||
return false, &commandError{"failed to run compiled binary", result.Binary, err}
|
return false, &commandError{"failed to run compiled binary", result.Binary, err}
|
||||||
}
|
}
|
||||||
return true, nil
|
return true, nil
|
||||||
} else {
|
|
||||||
// Run in an emulator.
|
|
||||||
// TODO: pass the -test.v flag if needed.
|
|
||||||
args := append(config.Target.Emulator[1:], result.Binary)
|
|
||||||
cmd := executeCommand(config.Options, config.Target.Emulator[0], args...)
|
|
||||||
buf := &bytes.Buffer{}
|
|
||||||
w := io.MultiWriter(os.Stdout, buf)
|
|
||||||
cmd.Stdout = w
|
|
||||||
cmd.Stderr = os.Stderr
|
|
||||||
err := cmd.Run()
|
|
||||||
if err != nil {
|
|
||||||
if err, ok := err.(*exec.ExitError); !ok || !err.Exited() {
|
|
||||||
// Workaround for QEMU which always exits with an error.
|
|
||||||
return false, &commandError{"failed to run emulator with", result.Binary, err}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
testOutput := string(buf.Bytes())
|
|
||||||
if testOutput == "PASS\n" || strings.HasSuffix(testOutput, "\nPASS\n") {
|
|
||||||
// Test passed.
|
|
||||||
return true, nil
|
|
||||||
} else {
|
|
||||||
// Test failed, either by ending with the word "FAIL" or with a
|
|
||||||
// panic of some sort.
|
|
||||||
return false, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Flash builds and flashes the built binary to the given serial port.
|
// Flash builds and flashes the built binary to the given serial port.
|
||||||
|
|
|
@ -333,9 +333,6 @@ func runTestWithConfig(name string, t *testing.T, options compileopts.Options, c
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
err = cmd.Wait()
|
err = cmd.Wait()
|
||||||
if _, ok := err.(*exec.ExitError); ok && options.Target != "" {
|
|
||||||
err = nil // workaround for QEMU
|
|
||||||
}
|
|
||||||
close(runComplete)
|
close(runComplete)
|
||||||
|
|
||||||
if ranTooLong {
|
if ranTooLong {
|
||||||
|
|
|
@ -285,8 +285,10 @@ func (m *M) Run() int {
|
||||||
if failures > 0 {
|
if failures > 0 {
|
||||||
fmt.Println("FAIL")
|
fmt.Println("FAIL")
|
||||||
} else {
|
} else {
|
||||||
|
if flagVerbose {
|
||||||
fmt.Println("PASS")
|
fmt.Println("PASS")
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return failures
|
return failures
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче