blob: aabab68fdb7400c9ab5c1cb76b5c64c41903d005 [file] [log] [blame]
Brian Silverman74b92d52021-10-14 13:12:02 -07001#include "aos/events/glib_main_loop.h"
2
3#include <thread>
4
Brian Silverman74b92d52021-10-14 13:12:02 -07005#include "glib-2.0/glib.h"
6#include "glog/logging.h"
7#include "gtest/gtest.h"
8
Philipp Schrader790cb542023-07-05 21:06:52 -07009#include "aos/configuration.h"
10#include "aos/events/shm_event_loop.h"
11#include "aos/testing/path.h"
12
Brian Silverman74b92d52021-10-14 13:12:02 -070013namespace aos {
14namespace testing {
15using aos::testing::ArtifactPath;
16
17const FlatbufferDetachedBuffer<Configuration> &Config() {
18 static const FlatbufferDetachedBuffer<Configuration> result =
Austin Schuhc5fa6d92022-02-25 14:36:28 -080019 configuration::ReadConfig(ArtifactPath("aos/events/aos_config.json"));
Brian Silverman74b92d52021-10-14 13:12:02 -070020 return result;
21}
22
23// Tests just creating and destroying without running.
24TEST(GlibMainLoopTest, CreateDestroy) {
25 ShmEventLoop event_loop(Config());
26 GlibMainLoop glib_main_loop(&event_loop);
27}
28
29// Tests just creating, running, and then destroying, without adding any
30// events from the glib side.
31TEST(GlibMainLoopTest, CreateRunDestroy) {
32 ShmEventLoop event_loop(Config());
33 GlibMainLoop glib_main_loop(&event_loop);
34 bool ran = false;
35 event_loop
36 .AddTimer([&event_loop, &ran]() {
37 event_loop.Exit();
38 ran = true;
39 })
Philipp Schradera6712522023-07-05 20:25:11 -070040 ->Schedule(event_loop.monotonic_now() + std::chrono::milliseconds(100));
Brian Silverman74b92d52021-10-14 13:12:02 -070041 event_loop.Run();
42 EXPECT_TRUE(ran);
43}
44
45// Tests just a single idle source.
46TEST(GlibMainLoopTest, IdleSource) {
47 ShmEventLoop event_loop(Config());
48 GlibMainLoop glib_main_loop(&event_loop);
49 int runs = 0;
50 const auto callback =
51 glib_main_loop.AddIdle([&event_loop, &runs]() -> gboolean {
52 if (runs++ >= 100) {
53 event_loop.Exit();
54 }
55 return true;
56 });
57 event_loop.Run();
58 EXPECT_GT(runs, 100);
59 // It can run a few extra times, but not too many.
60 EXPECT_LT(runs, 110);
61}
62
63// Tests just a single timeout which calls exit on the ShmEventLoop side.
64TEST(GlibMainLoopTest, TimeoutExitShm) {
65 ShmEventLoop event_loop(Config());
66 GlibMainLoop glib_main_loop(&event_loop);
67 int runs = 0;
68 const auto callback = glib_main_loop.AddTimeout(
69 [&event_loop, &runs]() -> gboolean {
70 if (runs++ >= 3) {
71 event_loop.Exit();
72 }
73 return true;
74 },
75 50);
76 const auto before = event_loop.monotonic_now();
77 event_loop.Run();
78 const auto after = event_loop.monotonic_now();
79 EXPECT_EQ(runs, 4);
80 // Verify it took at least this long, but don't bother putting an upper bound
81 // because it can take arbitrarily long due to scheduling delays.
82 EXPECT_GE(after - before, std::chrono::milliseconds(200));
83}
84
85// Tests just a single timeout which calls exit on the glib side.
86TEST(GlibMainLoopTest, TimeoutExitGlib) {
87 ShmEventLoop event_loop(Config());
88 GlibMainLoop glib_main_loop(&event_loop);
89 int runs = 0;
90 const auto callback = glib_main_loop.AddTimeout(
91 [&glib_main_loop, &runs]() -> gboolean {
92 if (runs++ >= 3) {
93 g_main_loop_quit(glib_main_loop.g_main_loop());
94 }
95 return true;
96 },
97 50);
98 const auto before = event_loop.monotonic_now();
99 event_loop.Run();
100 const auto after = event_loop.monotonic_now();
101 EXPECT_EQ(runs, 4);
102 // Verify it took at least this long, but don't bother putting an upper bound
103 // because it can take arbitrarily long due to scheduling delays.
104 EXPECT_GE(after - before, std::chrono::milliseconds(200));
105}
106
107// Tests a single timeout which removes itself, and a ShmEventLoop timer to end
108// the test.
109TEST(GlibMainLoopTest, TimeoutRemoveSelf) {
110 ShmEventLoop event_loop(Config());
111 GlibMainLoop glib_main_loop(&event_loop);
112 int runs = 0;
113 const auto callback = glib_main_loop.AddTimeout(
114 [&runs]() -> gboolean {
115 ++runs;
116 return false;
117 },
118 50);
119 bool ran = false;
120 event_loop
121 .AddTimer([&event_loop, &ran]() {
122 event_loop.Exit();
123 ran = true;
124 })
Philipp Schradera6712522023-07-05 20:25:11 -0700125 ->Schedule(event_loop.monotonic_now() + std::chrono::milliseconds(100));
Brian Silverman74b92d52021-10-14 13:12:02 -0700126 event_loop.Run();
127 EXPECT_TRUE(ran);
128 EXPECT_EQ(runs, 1);
129}
130
131} // namespace testing
132} // namespace aos