Convert all year's robots to proper event loops
Each robot has a couple of event loops, one per thread. Each of these
threads corresponds to the threads from before the change. y2016 has
been tested on real hardware.
Change-Id: I99f726a8bc0498204c1a3b99f15508119eed9ad3
diff --git a/frc971/wpilib/loop_output_handler_test.cc b/frc971/wpilib/loop_output_handler_test.cc
new file mode 100644
index 0000000..8a7e903
--- /dev/null
+++ b/frc971/wpilib/loop_output_handler_test.cc
@@ -0,0 +1,113 @@
+#include "frc971/wpilib/loop_output_handler.h"
+
+#include <chrono>
+
+#include "gtest/gtest.h"
+
+#include "aos/events/simulated-event-loop.h"
+#include "aos/logging/logging.h"
+#include "aos/logging/queue_logging.h"
+#include "aos/testing/test_logging.h"
+#include "aos/time/time.h"
+#include "frc971/wpilib/loop_output_handler_test.q.h"
+
+namespace frc971 {
+namespace wpilib {
+namespace testing {
+namespace {
+namespace chrono = ::std::chrono;
+using ::aos::monotonic_clock;
+} // namespace
+
+class LoopOutputHandlerTest : public ::testing::Test {
+ public:
+ LoopOutputHandlerTest()
+ : ::testing::Test(),
+ loop_output_hander_event_loop_(event_loop_factory_.MakeEventLoop()),
+ test_event_loop_(event_loop_factory_.MakeEventLoop()) {
+ ::aos::testing::EnableTestLogging();
+ }
+
+ ::aos::SimulatedEventLoopFactory event_loop_factory_;
+ ::std::unique_ptr<::aos::EventLoop> loop_output_hander_event_loop_;
+ ::std::unique_ptr<::aos::EventLoop> test_event_loop_;
+};
+
+// Test loop output handler which logs and counts.
+class TestLoopOutputHandler
+ : public LoopOutputHandler<LoopOutputHandlerTestOutput> {
+ public:
+ TestLoopOutputHandler(::aos::EventLoop *event_loop, const ::std::string &name)
+ : LoopOutputHandler(event_loop, name) {}
+
+ ~TestLoopOutputHandler() { Stop(); }
+
+ int count() const { return count_; }
+
+ ::aos::monotonic_clock::time_point last_time() const { return last_time_; }
+ ::aos::monotonic_clock::time_point stop_time() const { return stop_time_; }
+
+ protected:
+ void Write(const LoopOutputHandlerTestOutput &output) override {
+ LOG_STRUCT(DEBUG, "output", output);
+ ++count_;
+ last_time_ = event_loop()->monotonic_now();
+ }
+
+ void Stop() override {
+ stop_time_ = event_loop()->monotonic_now();
+ LOG(DEBUG, "Stopping\n");
+ }
+
+ private:
+ int count_ = 0;
+
+ ::aos::monotonic_clock::time_point last_time_ =
+ ::aos::monotonic_clock::min_time;
+ ::aos::monotonic_clock::time_point stop_time_ =
+ ::aos::monotonic_clock::min_time;
+};
+
+// Test that the watchdog calls Stop at the right time.
+TEST_F(LoopOutputHandlerTest, WatchdogTest) {
+ TestLoopOutputHandler loop_output(loop_output_hander_event_loop_.get(),
+ ".test");
+
+ ::aos::Sender<LoopOutputHandlerTestOutput> output_sender =
+ test_event_loop_->MakeSender<LoopOutputHandlerTestOutput>(".test");
+
+ const monotonic_clock::time_point start_time =
+ test_event_loop_->monotonic_now();
+
+ int count = 0;
+ // Send outputs for 1 second.
+ ::aos::TimerHandler *timer_handle = test_event_loop_->AddTimer(
+ [this, &start_time, &output_sender, &loop_output, &count]() {
+ EXPECT_EQ(count, loop_output.count());
+ if (test_event_loop_->monotonic_now() <
+ start_time + chrono::seconds(1)) {
+ auto output = output_sender.MakeMessage();
+ output->voltage = 5.0;
+ EXPECT_TRUE(output.Send());
+
+ ++count;
+ }
+ LOG(INFO, "Ping\n");
+ });
+
+ // Kick off the ping timer handler.
+ test_event_loop_->OnRun([this, &timer_handle]() {
+ timer_handle->Setup(test_event_loop_->monotonic_now(),
+ chrono::milliseconds(5));
+ });
+
+ event_loop_factory_.RunFor(chrono::seconds(2));
+
+ // Confirm the watchdog
+ EXPECT_EQ(loop_output.stop_time(),
+ loop_output.last_time() + chrono::milliseconds(100));
+}
+
+} // namespace testing
+} // namespace wpilib
+} // namespace frc971