blob: 16a1923d6f1097fff88f6e6ed326fec1d3a30349 [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) {
Austin Schuh39788ff2019-12-01 18:22:57 -080076 SimulatedEventLoopTestFactory factory;
77
78 SimulatedEventLoopFactory simulated_event_loop_factory(
79 factory.configuration());
Austin Schuh44019f92019-05-19 19:58:27 -070080 ::std::unique_ptr<EventLoop> event_loop =
Austin Schuh5f1cc5c2019-12-01 18:01:11 -080081 simulated_event_loop_factory.MakeEventLoop("loop");
Austin Schuh44019f92019-05-19 19:58:27 -070082
83 simulated_event_loop_factory.RunFor(chrono::seconds(1));
84
85 EXPECT_EQ(::aos::monotonic_clock::epoch() + chrono::seconds(1),
86 simulated_event_loop_factory.monotonic_now());
87 EXPECT_EQ(::aos::monotonic_clock::epoch() + chrono::seconds(1),
88 event_loop->monotonic_now());
89}
90
91// Test that running for a time with a periodic handler causes time to end
92// correctly.
93TEST(SimulatedEventLoopTest, RunForTimerHandler) {
Austin Schuh39788ff2019-12-01 18:22:57 -080094 SimulatedEventLoopTestFactory factory;
95
96 SimulatedEventLoopFactory simulated_event_loop_factory(
97 factory.configuration());
Austin Schuh44019f92019-05-19 19:58:27 -070098 ::std::unique_ptr<EventLoop> event_loop =
Austin Schuh5f1cc5c2019-12-01 18:01:11 -080099 simulated_event_loop_factory.MakeEventLoop("loop");
Austin Schuh44019f92019-05-19 19:58:27 -0700100
101 int counter = 0;
Alex Perrycb7da4b2019-08-28 19:35:56 -0700102 auto timer = event_loop->AddTimer([&counter]() { ++counter; });
Austin Schuh44019f92019-05-19 19:58:27 -0700103 event_loop->OnRun([&event_loop, &timer] {
104 timer->Setup(event_loop->monotonic_now() + chrono::milliseconds(50),
105 chrono::milliseconds(100));
106 });
107
108 simulated_event_loop_factory.RunFor(chrono::seconds(1));
109
110 EXPECT_EQ(::aos::monotonic_clock::epoch() + chrono::seconds(1),
111 simulated_event_loop_factory.monotonic_now());
112 EXPECT_EQ(::aos::monotonic_clock::epoch() + chrono::seconds(1),
113 event_loop->monotonic_now());
114 EXPECT_EQ(counter, 10);
115}
116
Neil Balchc8f41ed2018-01-20 22:06:53 -0800117} // namespace testing
118} // namespace aos