-
-
Notifications
You must be signed in to change notification settings - Fork 216
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Use virtual time in TaskQueue unit tests #435
Comments
Hi, can I work on this issue? |
Sure, you're welcome! |
I have several questions:
Initially, I planned to replace timestamp() with a task_.timestamp_imp() but task_ could be null so it doesn't seem viable. For reference, task_ is a public field of TaskHandler with type TaskQueue::Task* Do I add a public field time_ and set_time() to ctl::TestHandler, similar to pipeline::TestPipeLine? The problem with this approach is we have to manually pass reasonable values to handler.expect_after() in the unit tests.
Thank you! |
I think I got it but it seems like my solution's very hacky. It's basically manipulating the virtual clock to pass the task_queue tests. Especially for tests like schedule_at_shuffled or schedule_and_async_cancel. Right now it has passed all the tests. But with the cost of several lines code to set the virtual time clock to the task's scheduled time whenever wait_called() is called. I will be playing around, cleaning up, and doing more testing before issuing a pull request. Also, is there a need for an option that allows user to pick whether to use real / virtual time testing? Please let me know what you think. |
Yes.
TestHandler uses core::timestamp() to check when TaskQueue actually calls the handler. So with virtual clock approach, I think the most clean way would be to make TestHandler checking the current (virtual) time in TaskQueue instead of having its own time. We could pass a reference to TestTaskQueue to TestHandler ctor, so that it can call TestTaskQueue::get_time(). Or we can extract virtual clock into separate class (e.g. TestClock), with get_time() and set_time() methods, and pass it to both TestTaskQueue and TestHandler.
IIRC only StartTime and per-task deadline matter.
In addition to getting rid of TestHandler::set_time (see above), we could also replace TestTaskQueue::set_time() with TestTaskQueue::add_time(), i.e. pass delta instead of abs value. I think this will make tests cleaner or at least more similar to original tests with sleep calls.
I think no. We should use virtual time in tests and real time in benchmarks. |
Unassigned so that someone could pick it up again. See also discussion in PR linked above regarding core::Timer: #437 UPD: I've updated task description to address what was discussed in PR. |
Last revised: Oct 2023
Update: The task is still relevant. Description is updated to address problems discussed in unfinished PR, linked below.
Currently unit tests for ctl::ControlTaskQueue (test_task_queue.cpp) are partially bound to real clock time (
core::timestamp()
andcore::Timer
) and due to this they can fail on loaded system, e.g. slow CI runners.We can make them 100% reliable by using virtual clock instead of real time, i.e. clock that is fully controlled by unit tests.
We already use such approach in unit tests for pipeline::PipelineLoop (test_pipeline_loop.cpp). PipelineLoop doesn't call
core::timestamp()
directly. Instead, it have a protected virtual method to get time:In
test_pipeline_loop.cpp
we inherit PipelineLoop, override this method to return virtual (fake) time, and test this derived class instead of original PipelineLoop.Now we could use the same approach
test_task_queue.cpp
:In
ctl::ControlTaskQueue
, add virtual methods that isolate calls tocore::timestamp()
andcore::Timer
For example, we can add 3 methods:
core::nanoseconds_t timestamp_imp()
bool try_set_deadline(nanoseconds_t)
void wait_deadline()
Default implementations will just call
core::timestamp()
andTimer
methods.In
test_task_queue.cpp
, add a class that inheritsctl::ControlTaskQueue
, overrides these 3 methods to work with virtual/fake time, and adds helpers to control that fake time.Adjust tests to work with virtual time instead of real time, i.e. don't use sleep and instead call helpers to control fake time.
The text was updated successfully, but these errors were encountered: