mirror of
https://github.com/tinygo-org/tinygo.git
synced 2026-08-03 10:37:46 +00:00
runtime, testing: support Goexit, SkipNow, FailNow
Keep a pending Goexit separate from the active panic state so recovered deferred panics do not cancel the original Goexit unwind. Goexit should also ignore -panic=trap, since it is not a panic. Wire testing.FailNow and SkipNow through runtime.Goexit, and run tests and benchmarks in goroutines. This lets Goexit terminate the user function without skipping test bookkeeping. Add Goexit/recover coverage and enable crypto/ecdh in the Linux stdlib test list.
This commit is contained in:
Vendored
+10
@@ -0,0 +1,10 @@
|
||||
package main
|
||||
|
||||
import "runtime"
|
||||
|
||||
func main() {
|
||||
defer func() {
|
||||
panic("panic after Goexit")
|
||||
}()
|
||||
runtime.Goexit()
|
||||
}
|
||||
Vendored
+65
@@ -158,6 +158,71 @@ func runtimeGoexit() {
|
||||
runtime.Goexit()
|
||||
}()
|
||||
wg.Wait()
|
||||
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
runtimeGoexitRecoveredPanic()
|
||||
println("unreachable after Goexit helper")
|
||||
}()
|
||||
wg.Wait()
|
||||
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
runtimeGoexitNestedRecoveredPanic()
|
||||
println("unreachable after nested Goexit helper")
|
||||
}()
|
||||
wg.Wait()
|
||||
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
runtimeGoexitLoopDefers()
|
||||
println("unreachable after loop Goexit helper")
|
||||
}()
|
||||
wg.Wait()
|
||||
}
|
||||
|
||||
func runtimeGoexitRecoveredPanic() {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
printitf("Goexit recovered deferred panic:", r)
|
||||
}
|
||||
}()
|
||||
defer func() {
|
||||
panic("panic during Goexit")
|
||||
}()
|
||||
runtime.Goexit()
|
||||
}
|
||||
|
||||
func runtimeGoexitNestedRecoveredPanic() {
|
||||
defer func() {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
printitf("Goexit nested recovered deferred panic:", r)
|
||||
}
|
||||
}()
|
||||
panic("nested panic during Goexit")
|
||||
}()
|
||||
runtime.Goexit()
|
||||
}
|
||||
|
||||
func runtimeGoexitLoopDefers() {
|
||||
for i := 0; i < 2; i++ {
|
||||
defer func() {
|
||||
println("Goexit loop defer")
|
||||
}()
|
||||
}
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
printitf("Goexit loop recovered deferred panic:", r)
|
||||
}
|
||||
}()
|
||||
defer func() {
|
||||
panic("loop panic during Goexit")
|
||||
}()
|
||||
runtime.Goexit()
|
||||
}
|
||||
|
||||
// Test that a repanic inside a deferred function propagates correctly
|
||||
|
||||
Vendored
+5
@@ -33,6 +33,11 @@ indirect recover returned: indirect panic
|
||||
|
||||
# runtime.Goexit
|
||||
Goexit deferred function, recover is nil: true
|
||||
Goexit recovered deferred panic: panic during Goexit
|
||||
Goexit nested recovered deferred panic: nested panic during Goexit
|
||||
Goexit loop recovered deferred panic: loop panic during Goexit
|
||||
Goexit loop defer
|
||||
Goexit loop defer
|
||||
|
||||
# repanic
|
||||
inner, repanicking
|
||||
|
||||
Vendored
+21
@@ -0,0 +1,21 @@
|
||||
--- FAIL: TestBar (0.00s)
|
||||
log Bar
|
||||
log g
|
||||
h
|
||||
i
|
||||
|
||||
--- FAIL: TestBar/Bar2 (0.00s)
|
||||
log Bar2
|
||||
a
|
||||
b
|
||||
c
|
||||
failed
|
||||
after failed
|
||||
log Bar end
|
||||
--- FAIL: TestAllLowercase (0.00s)
|
||||
--- FAIL: TestAllLowercase/BETA (0.00s)
|
||||
expected lowercase name, got BETA
|
||||
--- FAIL: TestAllLowercase/BELTA (0.00s)
|
||||
expected lowercase name, got BELTA
|
||||
FAIL
|
||||
exitcode: 1
|
||||
Vendored
+12
-1
@@ -6,6 +6,7 @@ import (
|
||||
"errors"
|
||||
"flag"
|
||||
"io"
|
||||
"runtime"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
@@ -25,11 +26,21 @@ func TestBar(t *testing.T) {
|
||||
t.Log("after failed")
|
||||
})
|
||||
t.Run("Bar3", func(t *testing.T) {})
|
||||
if runtime.GOARCH != "wasm" {
|
||||
t.Run("Bar4", func(t *testing.T) {
|
||||
t.Fatal("fatal")
|
||||
t.Log("after fatal")
|
||||
})
|
||||
t.Run("Bar5", func(t *testing.T) {
|
||||
t.SkipNow()
|
||||
t.Error("after skip")
|
||||
})
|
||||
}
|
||||
t.Log("log Bar end")
|
||||
}
|
||||
|
||||
func TestAllLowercase(t *testing.T) {
|
||||
names := []string {
|
||||
names := []string{
|
||||
"alpha",
|
||||
"BETA",
|
||||
"gamma",
|
||||
|
||||
Vendored
+2
@@ -11,6 +11,8 @@
|
||||
c
|
||||
failed
|
||||
after failed
|
||||
--- FAIL: TestBar/Bar4 (0.00s)
|
||||
fatal
|
||||
log Bar end
|
||||
--- FAIL: TestAllLowercase (0.00s)
|
||||
--- FAIL: TestAllLowercase/BETA (0.00s)
|
||||
|
||||
Reference in New Issue
Block a user