Convert control loop tests over to simulated event loop
This makes it so that we properly only use ShmEventLoop for running in
realtime on a robot. Very nice.
Change-Id: I46b770b336f59e08cfaf28511b3bd5689f72fff1
diff --git a/aos/events/BUILD b/aos/events/BUILD
index aaa1c86..330ad40 100644
--- a/aos/events/BUILD
+++ b/aos/events/BUILD
@@ -64,7 +64,8 @@
srcs = ["event-loop_param_test.cc"],
hdrs = ["event-loop_param_test.h"],
deps = [
- "event-loop",
+ ":event-loop",
+ "//aos/logging:queue_logging",
"//aos/testing:googletest",
],
)
diff --git a/aos/events/event-loop.h b/aos/events/event-loop.h
index 1435723..4d6fda5 100644
--- a/aos/events/event-loop.h
+++ b/aos/events/event-loop.h
@@ -131,9 +131,6 @@
// TODO(austin): OnExit
- // Stops receiving events
- virtual void Exit() = 0;
-
// Sets the scheduler priority to run the event loop at. This may not be
// called after we go into "real-time-mode".
virtual void SetRuntimeRealtimePriority(int priority) = 0;
diff --git a/aos/events/event-loop_param_test.cc b/aos/events/event-loop_param_test.cc
index d6f41ab..1dcc258 100644
--- a/aos/events/event-loop_param_test.cc
+++ b/aos/events/event-loop_param_test.cc
@@ -5,6 +5,8 @@
#include "gmock/gmock.h"
#include "gtest/gtest.h"
+#include "aos/logging/queue_logging.h"
+
namespace aos {
namespace testing {
namespace {
@@ -24,13 +26,6 @@
TestMessage() { Zero(); }
};
-// Ends the given event loop at the given time from now.
-void EndEventLoop(EventLoop *loop, ::std::chrono::milliseconds duration) {
- auto end_timer = loop->AddTimer([loop]() { loop->Exit(); });
- end_timer->Setup(loop->monotonic_now() +
- ::std::chrono::milliseconds(duration));
-}
-
// Tests that watcher can receive messages from a sender.
// Also tests that OnRun() works.
TEST_P(AbstractEventLoopTest, Basic) {
@@ -51,7 +46,7 @@
loop2->MakeWatcher("/test", [&](const TestMessage &message) {
EXPECT_EQ(message.msg_value, 200);
- loop2->Exit();
+ this->Exit();
});
EXPECT_FALSE(happened);
@@ -94,7 +89,7 @@
loop2->MakeWatcher("/test", [&](const TestMessage &message) {
values.push_back(message.msg_value);
if (values.size() == 2) {
- loop2->Exit();
+ this->Exit();
}
});
@@ -149,7 +144,7 @@
});
// Add a timer to actually quit.
- auto test_timer = loop2->AddTimer([&loop2]() { loop2->Exit(); });
+ auto test_timer = loop2->AddTimer([this]() { this->Exit(); });
loop2->OnRun([&test_timer, &loop2]() {
test_timer->Setup(loop2->monotonic_now(), ::std::chrono::milliseconds(100));
});
@@ -180,11 +175,11 @@
}
// Add a timer to actually quit.
- auto test_timer = loop2->AddTimer([&loop2, &fetcher, &values]() {
+ auto test_timer = loop2->AddTimer([&fetcher, &values, this]() {
while (fetcher.FetchNext()) {
values.push_back(fetcher->msg_value);
}
- loop2->Exit();
+ this->Exit();
});
loop2->OnRun([&test_timer, &loop2]() {
@@ -218,11 +213,11 @@
auto fetcher = loop2->MakeFetcher<TestMessage>("/test");
// Add a timer to actually quit.
- auto test_timer = loop2->AddTimer([&loop2, &fetcher, &values]() {
+ auto test_timer = loop2->AddTimer([&fetcher, &values, this]() {
while (fetcher.FetchNext()) {
values.push_back(fetcher->msg_value);
}
- loop2->Exit();
+ this->Exit();
});
loop2->OnRun([&test_timer, &loop2]() {
@@ -257,7 +252,7 @@
auto fetcher = loop2->MakeFetcher<TestMessage>("/test");
// Add a timer to actually quit.
- auto test_timer = loop2->AddTimer([&loop2, &fetcher, &values]() {
+ auto test_timer = loop2->AddTimer([&fetcher, &values, this]() {
if (fetcher.Fetch()) {
values.push_back(fetcher->msg_value);
}
@@ -265,7 +260,7 @@
if (fetcher.Fetch()) {
values.push_back(fetcher->msg_value);
}
- loop2->Exit();
+ this->Exit();
});
loop2->OnRun([&test_timer, &loop2]() {
@@ -299,7 +294,7 @@
auto fetcher = loop2->MakeFetcher<TestMessage>("/test");
// Add a timer to actually quit.
- auto test_timer = loop2->AddTimer([&loop2, &fetcher, &values, &sender]() {
+ auto test_timer = loop2->AddTimer([&fetcher, &values, &sender, this]() {
if (fetcher.Fetch()) {
values.push_back(fetcher->msg_value);
}
@@ -328,7 +323,7 @@
values.push_back(fetcher->msg_value);
}
- loop2->Exit();
+ this->Exit();
});
loop2->OnRun([&test_timer, &loop2]() {
@@ -444,7 +439,7 @@
loop2->MakeWatcher("/test1", [&](const TestMessage &) {});
loop2->MakeWatcher("/test2", [&](const TestMessage &message) {
EXPECT_EQ(message.msg_value, 200);
- loop2->Exit();
+ this->Exit();
});
auto sender = loop1->MakeSender<TestMessage>("/test2");
@@ -566,12 +561,12 @@
// Run kCount iterations.
loop1->AddPhasedLoop(
- [×, &loop1](int count) {
+ [×, &loop1, this](int count) {
EXPECT_EQ(count, 1);
times.push_back(loop1->monotonic_now());
LOG(INFO, "%zu\n", times.size());
if (times.size() == kCount) {
- loop1->Exit();
+ this->Exit();
}
},
chrono::seconds(1), kOffset);
@@ -627,7 +622,7 @@
auto sender = loop1->MakeSender<TestMessage>("/test");
auto fetcher = loop2->MakeFetcher<TestMessage>("/test");
- auto test_timer = loop1->AddTimer([&sender, &fetcher, &loop1]() {
+ auto test_timer = loop1->AddTimer([&sender, &fetcher, this]() {
for (int i = 0; i < 100000; ++i) {
auto msg = sender.MakeMessage();
msg->msg_value = i;
@@ -643,7 +638,7 @@
++last;
}
- loop1->Exit();
+ this->Exit();
});
loop1->OnRun([&test_timer, &loop1]() {
diff --git a/aos/events/event-loop_param_test.h b/aos/events/event-loop_param_test.h
index 26d869d..83f0b37 100644
--- a/aos/events/event-loop_param_test.h
+++ b/aos/events/event-loop_param_test.h
@@ -22,6 +22,9 @@
// Runs the loops until they quit.
virtual void Run() = 0;
+ // Quits the loops.
+ virtual void Exit() = 0;
+
// Advances time by sleeping. Can't be called from inside a loop.
virtual void SleepFor(::std::chrono::nanoseconds duration) = 0;
};
@@ -36,9 +39,19 @@
void Run() { return factory_->Run(); }
+ void Exit() { return factory_->Exit(); }
+
void SleepFor(::std::chrono::nanoseconds duration) {
return factory_->SleepFor(duration);
}
+
+ // Ends the given event loop at the given time from now.
+ void EndEventLoop(EventLoop *loop, ::std::chrono::milliseconds duration) {
+ auto end_timer = loop->AddTimer([this]() { this->Exit(); });
+ end_timer->Setup(loop->monotonic_now() +
+ ::std::chrono::milliseconds(duration));
+ }
+
// You can implement all the usual fixture class members here.
// To access the test parameter, call GetParam() from class
// TestWithParam<T>.
diff --git a/aos/events/raw-event-loop.h b/aos/events/raw-event-loop.h
index 7ab2810..d221a6e 100644
--- a/aos/events/raw-event-loop.h
+++ b/aos/events/raw-event-loop.h
@@ -156,12 +156,6 @@
const monotonic_clock::duration interval,
const monotonic_clock::duration offset = ::std::chrono::seconds(0)) = 0;
- // Stops receiving events.
- virtual void Exit() = 0;
-
- // TODO(austin): This shouldn't belong here.
- virtual void Run() = 0;
-
protected:
friend class EventScheduler;
void set_is_running(bool value) { is_running_.store(value); }
diff --git a/aos/events/shm-event-loop.cc b/aos/events/shm-event-loop.cc
index eead9f5..e44a54b 100644
--- a/aos/events/shm-event-loop.cc
+++ b/aos/events/shm-event-loop.cc
@@ -408,7 +408,10 @@
::aos::SetCurrentThreadName(thread_state_.name());
- // Now, all the threads are up. Go RT.
+ // Now, all the threads are up. Lock everything into memory and go RT.
+ if (thread_state_.priority_ != -1) {
+ ::aos::InitRT();
+ }
thread_state_.MaybeSetCurrentThreadRealtimePriority();
set_is_running(true);
diff --git a/aos/events/shm-event-loop.h b/aos/events/shm-event-loop.h
index 24cd909..5db8319 100644
--- a/aos/events/shm-event-loop.h
+++ b/aos/events/shm-event-loop.h
@@ -50,8 +50,8 @@
::std::chrono::seconds(0)) override;
void OnRun(::std::function<void()> on_run) override;
- void Run() override;
- void Exit() override;
+ void Run();
+ void Exit();
// TODO(austin): Add a function to register control-C call.
diff --git a/aos/events/shm-event-loop_test.cc b/aos/events/shm-event-loop_test.cc
index 8d0f552..8af00f0 100644
--- a/aos/events/shm-event-loop_test.cc
+++ b/aos/events/shm-event-loop_test.cc
@@ -24,6 +24,8 @@
void Run() override { CHECK_NOTNULL(primary_event_loop_)->Run(); }
+ void Exit() override { CHECK_NOTNULL(primary_event_loop_)->Exit(); }
+
void SleepFor(::std::chrono::nanoseconds duration) override {
::std::this_thread::sleep_for(duration);
}
@@ -80,10 +82,10 @@
bool did_timer = false;
bool did_watcher = false;
- auto timer = loop->AddTimer([&did_timer, &loop]() {
+ auto timer = loop->AddTimer([&did_timer, &loop, &factory]() {
EXPECT_TRUE(IsRealtime());
did_timer = true;
- loop->Exit();
+ factory.Exit();
});
loop->MakeWatcher("/test", [&did_watcher](const TestMessage &) {
@@ -118,7 +120,7 @@
constexpr chrono::milliseconds kOffset = chrono::milliseconds(400);
loop1->AddPhasedLoop(
- [×, &loop1, &kOffset](int count) {
+ [×, &loop1, &kOffset, &factory](int count) {
const ::aos::monotonic_clock::time_point monotonic_now =
loop1->monotonic_now();
@@ -143,7 +145,7 @@
times.push_back(loop1->monotonic_now());
if (times.size() == 2) {
- loop1->Exit();
+ factory.Exit();
}
// Now, add a large delay. This should push us up to 3 cycles.
diff --git a/aos/events/simulated-event-loop.cc b/aos/events/simulated-event-loop.cc
index 71b0c79..a3edd9b 100644
--- a/aos/events/simulated-event-loop.cc
+++ b/aos/events/simulated-event-loop.cc
@@ -231,13 +231,6 @@
void OnRun(::std::function<void()> on_run) override {
scheduler_->Schedule(scheduler_->monotonic_now(), on_run);
}
- void Run() override {
- LOG(FATAL, "Run from the factory instead\n");
- scheduler_->Run();
- }
- void Exit() override {
- scheduler_->Exit();
- }
void set_name(const char *name) override { name_ = name; }
diff --git a/aos/events/simulated-event-loop.h b/aos/events/simulated-event-loop.h
index 81b181f..0828382 100644
--- a/aos/events/simulated-event-loop.h
+++ b/aos/events/simulated-event-loop.h
@@ -189,11 +189,17 @@
public:
::std::unique_ptr<EventLoop> MakeEventLoop();
+ // Starts executing the event loops unconditionally.
void Run() { scheduler_.Run(); }
+ // Executes the event loops for a duration.
void RunFor(monotonic_clock::duration duration) {
scheduler_.RunFor(duration);
}
+ // Stops executing all event loops. Meant to be called from within an event
+ // loop handler.
+ void Exit() { scheduler_.Exit(); }
+
monotonic_clock::time_point monotonic_now() const {
return scheduler_.monotonic_now();
}
diff --git a/aos/events/simulated-event-loop_test.cc b/aos/events/simulated-event-loop_test.cc
index be52243..e987a11 100644
--- a/aos/events/simulated-event-loop_test.cc
+++ b/aos/events/simulated-event-loop_test.cc
@@ -17,6 +17,7 @@
}
void Run() override { event_loop_factory_.Run(); }
+ void Exit() override { event_loop_factory_.Exit(); }
// TODO(austin): Implement this. It's used currently for a phased loop test.
// I'm not sure how much that matters.