test: support non-host tests
For example, for running tests with -target=wasm or -target=cortex-m-qemu. It looks at the output to determine whether tests were successful in the absence of a status code.
Этот коммит содержится в:
родитель
1096596b69
коммит
b713001313
6 изменённых файлов: 72 добавлений и 14 удалений
54
main.go
54
main.go
|
@ -128,22 +128,50 @@ func Test(pkgName string, options *compileopts.Options) error {
|
|||
}
|
||||
|
||||
return builder.Build(pkgName, ".elf", config, func(result builder.BuildResult) error {
|
||||
cmd := exec.Command(result.Binary)
|
||||
cmd.Stdout = os.Stdout
|
||||
cmd.Stderr = os.Stderr
|
||||
cmd.Dir = result.MainDir
|
||||
err := cmd.Run()
|
||||
if err != nil {
|
||||
// Propagate the exit code
|
||||
if err, ok := err.(*exec.ExitError); ok {
|
||||
if status, ok := err.Sys().(syscall.WaitStatus); ok {
|
||||
os.Exit(status.ExitStatus())
|
||||
if len(config.Target.Emulator) == 0 {
|
||||
// Run directly.
|
||||
cmd := exec.Command(result.Binary)
|
||||
cmd.Stdout = os.Stdout
|
||||
cmd.Stderr = os.Stderr
|
||||
cmd.Dir = result.MainDir
|
||||
err := cmd.Run()
|
||||
if err != nil {
|
||||
// Propagate the exit code
|
||||
if err, ok := err.(*exec.ExitError); ok {
|
||||
if status, ok := err.Sys().(syscall.WaitStatus); ok {
|
||||
os.Exit(status.ExitStatus())
|
||||
}
|
||||
os.Exit(1)
|
||||
}
|
||||
os.Exit(1)
|
||||
return &commandError{"failed to run compiled binary", result.Binary, err}
|
||||
}
|
||||
return nil
|
||||
} else {
|
||||
// Run in an emulator.
|
||||
args := append(config.Target.Emulator[1:], result.Binary)
|
||||
cmd := exec.Command(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 &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 nil
|
||||
} else {
|
||||
// Test failed, either by ending with the word "FAIL" or with a
|
||||
// panic of some sort.
|
||||
os.Exit(1)
|
||||
return nil // unreachable
|
||||
}
|
||||
return &commandError{"failed to run compiled binary", result.Binary, err}
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -39,4 +39,9 @@ func libc_free(ptr unsafe.Pointer) {
|
|||
free(ptr)
|
||||
}
|
||||
|
||||
//go:linkname syscall_Exit syscall.Exit
|
||||
func syscall_Exit(code int) {
|
||||
abort()
|
||||
}
|
||||
|
||||
const baremetal = true
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// +build cortexm,!nxp
|
||||
// +build cortexm,!nxp,!qemu
|
||||
|
||||
package runtime
|
||||
|
||||
|
|
|
@ -21,6 +21,8 @@ func postinit() {}
|
|||
func main() {
|
||||
preinit()
|
||||
run()
|
||||
|
||||
// Signal successful exit.
|
||||
arm.SemihostingCall(arm.SemihostingReportException, arm.SemihostingApplicationExit)
|
||||
abort()
|
||||
}
|
||||
|
@ -54,3 +56,13 @@ func putchar(c byte) {
|
|||
func waitForEvents() {
|
||||
arm.Asm("wfe")
|
||||
}
|
||||
|
||||
func abort() {
|
||||
// Signal an abnormal exit.
|
||||
arm.SemihostingCall(arm.SemihostingReportException, arm.SemihostingRunTimeErrorUnknown)
|
||||
|
||||
// Lock up forever (should be unreachable).
|
||||
for {
|
||||
arm.Asm("wfi")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -195,6 +195,8 @@ func (m *M) Run() int {
|
|||
if failures > 0 {
|
||||
fmt.Printf("exit status %d\n", failures)
|
||||
fmt.Println("FAIL")
|
||||
} else {
|
||||
fmt.Println("PASS")
|
||||
}
|
||||
return failures
|
||||
}
|
||||
|
|
|
@ -289,6 +289,17 @@
|
|||
setTimeout(this._inst.exports.go_scheduler, timeout);
|
||||
},
|
||||
|
||||
// func Exit(code int)
|
||||
"syscall.Exit": (code) => {
|
||||
if (global.process) {
|
||||
// Node.js
|
||||
process.exit(code);
|
||||
} else {
|
||||
// Can't exit in a browser.
|
||||
throw 'trying to exit with code ' + code;
|
||||
}
|
||||
},
|
||||
|
||||
// func finalizeRef(v ref)
|
||||
"syscall/js.finalizeRef": (sp) => {
|
||||
// Note: TinyGo does not support finalizers so this should never be
|
||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче