blob: b2eb6340ffea14e18f7b14f341a976f0c0e32c0c [file] [log] [blame]
Alex Perrycb7da4b2019-08-28 19:35:56 -07001#include "aos/events/simulated_event_loop.h"
2
Austin Schuh5f1cc5c2019-12-01 18:01:11 -08003#include <string_view>
4
Alex Perrycb7da4b2019-08-28 19:35:56 -07005#include "aos/events/event_loop_param_test.h"
Neil Balchc8f41ed2018-01-20 22:06:53 -08006#include "gtest/gtest.h"
7
8namespace aos {
9namespace testing {
10
Austin Schuh7267c532019-05-19 19:55:53 -070011namespace chrono = ::std::chrono;
12
Neil Balchc8f41ed2018-01-20 22:06:53 -080013class SimulatedEventLoopTestFactory : public EventLoopTestFactory {
14 public:
Alex Perrycb7da4b2019-08-28 19:35:56 -070015 SimulatedEventLoopTestFactory() : event_loop_factory_(configuration()) {}
16
Austin Schuh5f1cc5c2019-12-01 18:01:11 -080017 ::std::unique_ptr<EventLoop> Make(std::string_view name) override {
18 return event_loop_factory_.MakeEventLoop(name);
Neil Balchc8f41ed2018-01-20 22:06:53 -080019 }
Austin Schuh5f1cc5c2019-12-01 18:01:11 -080020 ::std::unique_ptr<EventLoop> MakePrimary(std::string_view name) override {
21 return event_loop_factory_.MakeEventLoop(name);
Austin Schuh44019f92019-05-19 19:58:27 -070022 }
23
24 void Run() override { event_loop_factory_.Run(); }
Austin Schuh9fe68f72019-08-10 19:32:03 -070025 void Exit() override { event_loop_factory_.Exit(); }
Austin Schuh44019f92019-05-19 19:58:27 -070026
Austin Schuh52d325c2019-06-23 18:59:06 -070027 // TODO(austin): Implement this. It's used currently for a phased loop test.
28 // I'm not sure how much that matters.
29 void SleepFor(::std::chrono::nanoseconds /*duration*/) override {}
30
Neil Balchc8f41ed2018-01-20 22:06:53 -080031 private:
Austin Schuh44019f92019-05-19 19:58:27 -070032 SimulatedEventLoopFactory event_loop_factory_;
Neil Balchc8f41ed2018-01-20 22:06:53 -080033};
34
Austin Schuh6b6dfa52019-06-12 20:16:20 -070035INSTANTIATE_TEST_CASE_P(SimulatedEventLoopDeathTest, AbstractEventLoopDeathTest,
36 ::testing::Values([]() {
37 return new SimulatedEventLoopTestFactory();
38 }));
39
Neil Balchc8f41ed2018-01-20 22:06:53 -080040INSTANTIATE_TEST_CASE_P(SimulatedEventLoopTest, AbstractEventLoopTest,
41 ::testing::Values([]() {
42 return new SimulatedEventLoopTestFactory();
43 }));
44
45// Test that creating an event and running the scheduler runs the event.
46TEST(EventSchedulerTest, ScheduleEvent) {
47 int counter = 0;
48 EventScheduler scheduler;
49
50 scheduler.Schedule(::aos::monotonic_clock::now(),
51 [&counter]() { counter += 1; });
52 scheduler.Run();
53 EXPECT_EQ(counter, 1);
54 auto token = scheduler.Schedule(::aos::monotonic_clock::now(),
55 [&counter]() { counter += 1; });
56 scheduler.Deschedule(token);
57 scheduler.Run();
58 EXPECT_EQ(counter, 1);
59}
60
61// Test that descheduling an already scheduled event doesn't run the event.
62TEST(EventSchedulerTest, DescheduleEvent) {
63 int counter = 0;
64 EventScheduler scheduler;
65
66 auto token = scheduler.Schedule(::aos::monotonic_clock::now(),
67 [&counter]() { counter += 1; });
68 scheduler.Deschedule(token);
69 scheduler.Run();
70 EXPECT_EQ(counter, 0);
71}
Austin Schuh44019f92019-05-19 19:58:27 -070072
73// Test that running for a time period with no handlers causes time to progress
74// correctly.
75TEST(SimulatedEventLoopTest, RunForNoHandlers) {
Alex Perrycb7da4b2019-08-28 19:35:56 -070076 SimulatedEventLoopFactory simulated_event_loop_factory(nullptr);
Austin Schuh44019f92019-05-19 19:58:27 -070077 ::std::unique_ptr<EventLoop> event_loop =
Austin Schuh5f1cc5c2019-12-01 18:01:11 -080078 simulated_event_loop_factory.MakeEventLoop("loop");
Austin Schuh44019f92019-05-19 19:58:27 -070079
80 simulated_event_loop_factory.RunFor(chrono::seconds(1));
81
82 EXPECT_EQ(::aos::monotonic_clock::epoch() + chrono::seconds(1),
83 simulated_event_loop_factory.monotonic_now());
84 EXPECT_EQ(::aos::monotonic_clock::epoch() + chrono::seconds(1),
85 event_loop->monotonic_now());
86}
87
88// Test that running for a time with a periodic handler causes time to end
89// correctly.
90TEST(SimulatedEventLoopTest, RunForTimerHandler) {
Alex Perrycb7da4b2019-08-28 19:35:56 -070091 SimulatedEventLoopFactory simulated_event_loop_factory(nullptr);
Austin Schuh44019f92019-05-19 19:58:27 -070092 ::std::unique_ptr<EventLoop> event_loop =
Austin Schuh5f1cc5c2019-12-01 18:01:11 -080093 simulated_event_loop_factory.MakeEventLoop("loop");
Austin Schuh44019f92019-05-19 19:58:27 -070094
95 int counter = 0;
Alex Perrycb7da4b2019-08-28 19:35:56 -070096 auto timer = event_loop->AddTimer([&counter]() { ++counter; });
Austin Schuh44019f92019-05-19 19:58:27 -070097 event_loop->OnRun([&event_loop, &timer] {
98 timer->Setup(event_loop->monotonic_now() + chrono::milliseconds(50),
99 chrono::milliseconds(100));
100 });
101
102 simulated_event_loop_factory.RunFor(chrono::seconds(1));
103
104 EXPECT_EQ(::aos::monotonic_clock::epoch() + chrono::seconds(1),
105 simulated_event_loop_factory.monotonic_now());
106 EXPECT_EQ(::aos::monotonic_clock::epoch() + chrono::seconds(1),
107 event_loop->monotonic_now());
108 EXPECT_EQ(counter, 10);
109}
110
Neil Balchc8f41ed2018-01-20 22:06:53 -0800111} // namespace testing
112} // namespace aos