Add testing.set_fail_timeout

This commit is contained in:
gingerBill
2021-10-11 15:28:25 +01:00
parent 129a62d4f1
commit e64eb631df
3 changed files with 51 additions and 8 deletions
+6
View File
@@ -2,7 +2,13 @@
//+build !windows //+build !windows
package testing package testing
import "core:time"
run_internal_test :: proc(t: ^T, it: Internal_Test) { run_internal_test :: proc(t: ^T, it: Internal_Test) {
// TODO(bill): Catch panics on other platforms // TODO(bill): Catch panics on other platforms
it.p(t); it.p(t);
} }
_fail_timeout :: proc(t: ^T, duration: time.Duration, loc := #caller_location) {
}
+26 -4
View File
@@ -5,7 +5,8 @@ package testing
import win32 "core:sys/windows" import win32 "core:sys/windows"
import "core:runtime" import "core:runtime"
import "core:intrinsics" import "core:intrinsics"
import "core:time"
import "core:fmt"
Sema :: struct { Sema :: struct {
count: i32, count: i32,
@@ -57,6 +58,9 @@ Thread :: struct {
init_context: Maybe(runtime.Context), init_context: Maybe(runtime.Context),
creation_allocator: runtime.Allocator, creation_allocator: runtime.Allocator,
internal_fail_timeout: time.Duration,
internal_fail_timeout_loc: runtime.Source_Code_Location,
} }
Thread_Os_Specific :: struct { Thread_Os_Specific :: struct {
@@ -121,7 +125,21 @@ thread_terminate :: proc "contextless" (thread: ^Thread, exit_code: int) {
} }
_fail_timeout :: proc(t: ^T, duration: time.Duration, loc := #caller_location) {
thread := thread_create(proc(thread: ^Thread) {
t := thread.t
time.sleep(thread.internal_fail_timeout)
if !intrinsics.atomic_load(&t._is_done) {
fail_now(t, "TIMEOUT", thread.internal_fail_timeout_loc)
}
// NOTE(bill): Complete hack and probably not a good idea
thread_join_and_destroy(thread)
})
thread.internal_fail_timeout = duration
thread.internal_fail_timeout_loc = loc
thread.t = t
thread_start(thread)
}
global_threaded_runner_semaphore: Sema global_threaded_runner_semaphore: Sema
global_exception_handler: rawptr global_exception_handler: rawptr
@@ -152,8 +170,13 @@ run_internal_test :: proc(t: ^T, it: Internal_Test) {
errorf(t=global_current_t, format="%s %s", args={prefix, message}, loc=loc) errorf(t=global_current_t, format="%s %s", args={prefix, message}, loc=loc)
intrinsics.trap() intrinsics.trap()
} }
t := thread.t
thread.it.p(thread.t) t._fail_timeout_set = false
intrinsics.atomic_store(&t._is_done, false)
thread.it.p(t)
intrinsics.atomic_store(&t._is_done, true)
thread.success = true thread.success = true
sema_post(&global_threaded_runner_semaphore) sema_post(&global_threaded_runner_semaphore)
@@ -169,7 +192,6 @@ run_internal_test :: proc(t: ^T, it: Internal_Test) {
thread.t = t thread.t = t
thread.it = it thread.it = it
thread.success = false thread.success = false
thread_start(thread) thread_start(thread)
sema_wait(&global_threaded_runner_semaphore) sema_wait(&global_threaded_runner_semaphore)
+19 -4
View File
@@ -2,6 +2,7 @@ package testing
import "core:fmt" import "core:fmt"
import "core:io" import "core:io"
import "core:time"
// IMPORTANT NOTE: Compiler requires this layout // IMPORTANT NOTE: Compiler requires this layout
Test_Signature :: proc(^T) Test_Signature :: proc(^T)
@@ -27,6 +28,8 @@ T :: struct {
cleanups: [dynamic]Internal_Cleanup, cleanups: [dynamic]Internal_Cleanup,
_fail_now: proc() -> !, _fail_now: proc() -> !,
_is_done: bool,
_fail_timeout_set: bool,
} }
@@ -43,13 +46,18 @@ errorf :: proc(t: ^T, format: string, args: ..any, loc := #caller_location) {
t.error_count += 1 t.error_count += 1
} }
fail :: proc(t: ^T) { fail :: proc(t: ^T, loc := #caller_location) {
error(t, "FAIL") error(t=t, args={"FAIL"}, loc=loc)
t.error_count += 1 t.error_count += 1
} }
fail_now :: proc(t: ^T) { fail_now :: proc(t: ^T, msg := "", loc := #caller_location) {
fail(t) if msg != "" {
error(t=t, args={"FAIL:", msg}, loc=loc)
} else {
error(t=t, args={"FAIL"}, loc=loc)
}
t.error_count += 1
if t._fail_now != nil { if t._fail_now != nil {
t._fail_now() t._fail_now()
} }
@@ -81,3 +89,10 @@ expect :: proc(t: ^T, ok: bool, msg: string = "", loc := #caller_location) -> bo
} }
return ok return ok
} }
set_fail_timeout :: proc(t: ^T, duration: time.Duration, loc := #caller_location) {
assert(t._fail_timeout_set == false, "set_fail_timeout previously called", loc)
t._fail_timeout_set = true
_fail_timeout(t, duration, loc)
}