blob: 356c25bf6a689357734fcb64a58c7cfe55a4d7ef [file] [log] [blame]
Alex Perrycb7da4b2019-08-28 19:35:56 -07001#include "aos/events/simulated_event_loop.h"
2
3#include "aos/events/event_loop_param_test.h"
Neil Balchc8f41ed2018-01-20 22:06:53 -08004#include "gtest/gtest.h"
5
6namespace aos {
7namespace testing {
8
Austin Schuh7267c532019-05-19 19:55:53 -07009namespace chrono = ::std::chrono;
10
Neil Balchc8f41ed2018-01-20 22:06:53 -080011class SimulatedEventLoopTestFactory : public EventLoopTestFactory {
12 public:
Alex Perrycb7da4b2019-08-28 19:35:56 -070013 SimulatedEventLoopTestFactory() : event_loop_factory_(configuration()) {}
14
Austin Schuh7267c532019-05-19 19:55:53 -070015 ::std::unique_ptr<EventLoop> Make() override {
Austin Schuh44019f92019-05-19 19:58:27 -070016 return event_loop_factory_.MakeEventLoop();
Neil Balchc8f41ed2018-01-20 22:06:53 -080017 }
Austin Schuh44019f92019-05-19 19:58:27 -070018 ::std::unique_ptr<EventLoop> MakePrimary() override {
19 return event_loop_factory_.MakeEventLoop();
20 }
21
22 void Run() override { event_loop_factory_.Run(); }
Austin Schuh9fe68f72019-08-10 19:32:03 -070023 void Exit() override { event_loop_factory_.Exit(); }
Austin Schuh44019f92019-05-19 19:58:27 -070024
Austin Schuh52d325c2019-06-23 18:59:06 -070025 // TODO(austin): Implement this. It's used currently for a phased loop test.
26 // I'm not sure how much that matters.
27 void SleepFor(::std::chrono::nanoseconds /*duration*/) override {}
28
Neil Balchc8f41ed2018-01-20 22:06:53 -080029 private:
Austin Schuh44019f92019-05-19 19:58:27 -070030 SimulatedEventLoopFactory event_loop_factory_;
Neil Balchc8f41ed2018-01-20 22:06:53 -080031};
32
Austin Schuh6b6dfa52019-06-12 20:16:20 -070033INSTANTIATE_TEST_CASE_P(SimulatedEventLoopDeathTest, AbstractEventLoopDeathTest,
34 ::testing::Values([]() {
35 return new SimulatedEventLoopTestFactory();
36 }));
37
Neil Balchc8f41ed2018-01-20 22:06:53 -080038INSTANTIATE_TEST_CASE_P(SimulatedEventLoopTest, AbstractEventLoopTest,
39 ::testing::Values([]() {
40 return new SimulatedEventLoopTestFactory();
41 }));
42
43// Test that creating an event and running the scheduler runs the event.
44TEST(EventSchedulerTest, ScheduleEvent) {
45 int counter = 0;
46 EventScheduler scheduler;
47
48 scheduler.Schedule(::aos::monotonic_clock::now(),
49 [&counter]() { counter += 1; });
50 scheduler.Run();
51 EXPECT_EQ(counter, 1);
52 auto token = scheduler.Schedule(::aos::monotonic_clock::now(),
53 [&counter]() { counter += 1; });
54 scheduler.Deschedule(token);
55 scheduler.Run();
56 EXPECT_EQ(counter, 1);
57}
58
59// Test that descheduling an already scheduled event doesn't run the event.
60TEST(EventSchedulerTest, DescheduleEvent) {
61 int counter = 0;
62 EventScheduler scheduler;
63
64 auto token = scheduler.Schedule(::aos::monotonic_clock::now(),
65 [&counter]() { counter += 1; });
66 scheduler.Deschedule(token);
67 scheduler.Run();
68 EXPECT_EQ(counter, 0);
69}
Austin Schuh44019f92019-05-19 19:58:27 -070070
71// Test that running for a time period with no handlers causes time to progress
72// correctly.
73TEST(SimulatedEventLoopTest, RunForNoHandlers) {
Alex Perrycb7da4b2019-08-28 19:35:56 -070074 SimulatedEventLoopFactory simulated_event_loop_factory(nullptr);
Austin Schuh44019f92019-05-19 19:58:27 -070075 ::std::unique_ptr<EventLoop> event_loop =
76 simulated_event_loop_factory.MakeEventLoop();
77
78 simulated_event_loop_factory.RunFor(chrono::seconds(1));
79
80 EXPECT_EQ(::aos::monotonic_clock::epoch() + chrono::seconds(1),
81 simulated_event_loop_factory.monotonic_now());
82 EXPECT_EQ(::aos::monotonic_clock::epoch() + chrono::seconds(1),
83 event_loop->monotonic_now());
84}
85
86// Test that running for a time with a periodic handler causes time to end
87// correctly.
88TEST(SimulatedEventLoopTest, RunForTimerHandler) {
Alex Perrycb7da4b2019-08-28 19:35:56 -070089 SimulatedEventLoopFactory simulated_event_loop_factory(nullptr);
Austin Schuh44019f92019-05-19 19:58:27 -070090 ::std::unique_ptr<EventLoop> event_loop =
91 simulated_event_loop_factory.MakeEventLoop();
92
93 int counter = 0;
Alex Perrycb7da4b2019-08-28 19:35:56 -070094 auto timer = event_loop->AddTimer([&counter]() { ++counter; });
Austin Schuh44019f92019-05-19 19:58:27 -070095 event_loop->OnRun([&event_loop, &timer] {
96 timer->Setup(event_loop->monotonic_now() + chrono::milliseconds(50),
97 chrono::milliseconds(100));
98 });
99
100 simulated_event_loop_factory.RunFor(chrono::seconds(1));
101
102 EXPECT_EQ(::aos::monotonic_clock::epoch() + chrono::seconds(1),
103 simulated_event_loop_factory.monotonic_now());
104 EXPECT_EQ(::aos::monotonic_clock::epoch() + chrono::seconds(1),
105 event_loop->monotonic_now());
106 EXPECT_EQ(counter, 10);
107}
108
Neil Balchc8f41ed2018-01-20 22:06:53 -0800109} // namespace testing
110} // namespace aos