diff options
| author | gingerBill <bill@gingerbill.org> | 2021-10-11 15:28:25 +0100 |
|---|---|---|
| committer | gingerBill <bill@gingerbill.org> | 2021-10-11 15:28:25 +0100 |
| commit | e64eb631dffd244c81d37b7294f1d4b5c36eb4d5 (patch) | |
| tree | 8273e83514ab3a488d17ee9dfb633470622f1eeb /core/testing | |
| parent | 129a62d4f120d5c16c357f11a44d204c58982913 (diff) | |
Add `testing.set_fail_timeout`
Diffstat (limited to 'core/testing')
| -rw-r--r-- | core/testing/runner_other.odin | 6 | ||||
| -rw-r--r-- | core/testing/runner_windows.odin | 30 | ||||
| -rw-r--r-- | core/testing/testing.odin | 23 |
3 files changed, 51 insertions, 8 deletions
diff --git a/core/testing/runner_other.odin b/core/testing/runner_other.odin index 0bd95e10a..3978a3c83 100644 --- a/core/testing/runner_other.odin +++ b/core/testing/runner_other.odin @@ -2,7 +2,13 @@ //+build !windows package testing +import "core:time" + run_internal_test :: proc(t: ^T, it: Internal_Test) { // TODO(bill): Catch panics on other platforms it.p(t); } + +_fail_timeout :: proc(t: ^T, duration: time.Duration, loc := #caller_location) { + +}
\ No newline at end of file diff --git a/core/testing/runner_windows.odin b/core/testing/runner_windows.odin index 5d2db5250..feb297691 100644 --- a/core/testing/runner_windows.odin +++ b/core/testing/runner_windows.odin @@ -5,7 +5,8 @@ package testing import win32 "core:sys/windows" import "core:runtime" import "core:intrinsics" - +import "core:time" +import "core:fmt" Sema :: struct { count: i32, @@ -57,6 +58,9 @@ Thread :: struct { init_context: Maybe(runtime.Context), creation_allocator: runtime.Allocator, + + internal_fail_timeout: time.Duration, + internal_fail_timeout_loc: runtime.Source_Code_Location, } 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_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) 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 sema_post(&global_threaded_runner_semaphore) @@ -169,7 +192,6 @@ run_internal_test :: proc(t: ^T, it: Internal_Test) { thread.t = t thread.it = it thread.success = false - thread_start(thread) sema_wait(&global_threaded_runner_semaphore) diff --git a/core/testing/testing.odin b/core/testing/testing.odin index 0d3c1dd43..0f91c7020 100644 --- a/core/testing/testing.odin +++ b/core/testing/testing.odin @@ -2,6 +2,7 @@ package testing import "core:fmt" import "core:io" +import "core:time" // IMPORTANT NOTE: Compiler requires this layout Test_Signature :: proc(^T) @@ -27,6 +28,8 @@ T :: struct { cleanups: [dynamic]Internal_Cleanup, _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 } -fail :: proc(t: ^T) { - error(t, "FAIL") +fail :: proc(t: ^T, loc := #caller_location) { + error(t=t, args={"FAIL"}, loc=loc) t.error_count += 1 } -fail_now :: proc(t: ^T) { - fail(t) +fail_now :: proc(t: ^T, msg := "", loc := #caller_location) { + 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 { t._fail_now() } @@ -81,3 +89,10 @@ expect :: proc(t: ^T, ok: bool, msg: string = "", loc := #caller_location) -> bo } 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) +}
\ No newline at end of file |