From e6d0c8aa0450046e4fecfa4d88ce2f2a5e5d0b0b Mon Sep 17 00:00:00 2001 From: Christian Kreibich Date: Mon, 2 Dec 2024 13:35:25 -0800 Subject: [PATCH] Add sleep() BiF. Yes, really. :-) We've hit the need for this on occasion in very specific settings and always worked around it via ugly nested loops or similars. This has ample warning that folks normally won't want to use this. Not sure that ZAM btest should baseline the number of BiFs. --- src/script_opt/FuncInfo.cc | 1 + src/zeek.bif | 21 +++++++++++++++++++ .../Baseline.zam/opt.ZAM-bif-tracking/output | 2 +- testing/btest/Baseline/bifs.sleep/out | 1 + testing/btest/bifs/sleep.zeek | 21 +++++++++++++++++++ testing/btest/opt/ZAM-bif-tracking.zeek | 1 + 6 files changed, 46 insertions(+), 1 deletion(-) create mode 100644 testing/btest/Baseline/bifs.sleep/out create mode 100644 testing/btest/bifs/sleep.zeek 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",