diff --git a/src/script_opt/FuncInfo.cc b/src/script_opt/FuncInfo.cc index 2516d1bd44..545f278f96 100644 --- a/src/script_opt/FuncInfo.cc +++ b/src/script_opt/FuncInfo.cc @@ -431,6 +431,7 @@ static std::unordered_map func_attrs = { {"skip_further_processing", ATTR_NO_SCRIPT_SIDE_EFFECTS}, {"skip_http_entity_data", ATTR_NO_SCRIPT_SIDE_EFFECTS}, {"skip_smtp_data", ATTR_NO_SCRIPT_SIDE_EFFECTS}, + {"sleep", ATTR_NO_SCRIPT_SIDE_EFFECTS}, {"split_string", ATTR_FOLDABLE}, {"split_string1", ATTR_FOLDABLE}, {"split_string_all", ATTR_FOLDABLE}, diff --git a/src/zeek.bif b/src/zeek.bif index ee14c0ddce..fbcf322c44 100644 --- a/src/zeek.bif +++ b/src/zeek.bif @@ -600,6 +600,27 @@ function piped_exec%(program: string, to_write: string%): bool return zeek::val_mgr->True(); %} +## Sleeps for the given amount of time. +## +## i: The time interval to sleep for. +## +## Returns: The :zeek:type:`interval` Zeek actually slept for. +## +## .. note:: +## +## This is a blocking sleep! Zeek will not run most of its processing +## during that time. You almost certainly DO NOT WANT THIS outside +## of specific testing/troubleshooting scenarios. To sleep asynchronously, +## :zeek:see:`schedule` an event, or consider :zeek:id:`Exec::run`. +function sleep%(i: interval%): interval + %{ + const auto start = std::chrono::high_resolution_clock::now(); + std::this_thread::sleep_for(std::chrono::duration(i)); + const auto end = std::chrono::high_resolution_clock::now(); + const auto slept = std::chrono::duration(end - start).count(); + return zeek::make_intrusive(slept); + %} + %%{ #include "zeek/OpaqueVal.h" %%} diff --git a/testing/btest/Baseline.zam/opt.ZAM-bif-tracking/output b/testing/btest/Baseline.zam/opt.ZAM-bif-tracking/output index 6f645f9525..0138aa7bfe 100644 --- a/testing/btest/Baseline.zam/opt.ZAM-bif-tracking/output +++ b/testing/btest/Baseline.zam/opt.ZAM-bif-tracking/output @@ -1,2 +1,2 @@ ### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. -539 seen BiFs, 0 unseen BiFs (), 0 new BiFs () +540 seen BiFs, 0 unseen BiFs (), 0 new BiFs () diff --git a/testing/btest/Baseline/bifs.sleep/out b/testing/btest/Baseline/bifs.sleep/out new file mode 100644 index 0000000000..49d861c74c --- /dev/null +++ b/testing/btest/Baseline/bifs.sleep/out @@ -0,0 +1 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. diff --git a/testing/btest/bifs/sleep.zeek b/testing/btest/bifs/sleep.zeek new file mode 100644 index 0000000000..7fbd3e6b46 --- /dev/null +++ b/testing/btest/bifs/sleep.zeek @@ -0,0 +1,21 @@ +# Verifies sleep()'s reported latencies. +# +# @TEST-EXEC: zeek -b %INPUT 2>out +# @TEST-EXEC: btest-diff out + +function test_sleep(i: interval) + { + local start = current_time(); + local sleep_delay = sleep(i); + local script_delay = current_time() - start; + + assert script_delay >= i, fmt("sleep() took %s, less than %s", script_delay, i); + assert sleep_delay >= i, fmt("slept for %s, less than %s", script_delay, i); + assert sleep_delay <= script_delay, fmt("sleep() claims %s, longer than %s", sleep_delay, script_delay); + } + +event zeek_init() + { + test_sleep(100msec); + test_sleep(1sec); + } diff --git a/testing/btest/opt/ZAM-bif-tracking.zeek b/testing/btest/opt/ZAM-bif-tracking.zeek index 627c21f444..e059f1f839 100644 --- a/testing/btest/opt/ZAM-bif-tracking.zeek +++ b/testing/btest/opt/ZAM-bif-tracking.zeek @@ -464,6 +464,7 @@ global known_BiFs = set( "skip_further_processing", "skip_http_entity_data", "skip_smtp_data", + "sleep", "sort", "split_string", "split_string1",