blob: 8a7e903eedc4aabf5814023f7e1ccc662c6d33a4 [file] [log] [blame]
Austin Schuhbd1fe9c2019-06-29 16:35:48 -07001#include "frc971/wpilib/loop_output_handler.h"
2
3#include <chrono>
4
5#include "gtest/gtest.h"
6
7#include "aos/events/simulated-event-loop.h"
8#include "aos/logging/logging.h"
9#include "aos/logging/queue_logging.h"
10#include "aos/testing/test_logging.h"
11#include "aos/time/time.h"
12#include "frc971/wpilib/loop_output_handler_test.q.h"
13
14namespace frc971 {
15namespace wpilib {
16namespace testing {
17namespace {
18namespace chrono = ::std::chrono;
19using ::aos::monotonic_clock;
20} // namespace
21
22class LoopOutputHandlerTest : public ::testing::Test {
23 public:
24 LoopOutputHandlerTest()
25 : ::testing::Test(),
26 loop_output_hander_event_loop_(event_loop_factory_.MakeEventLoop()),
27 test_event_loop_(event_loop_factory_.MakeEventLoop()) {
28 ::aos::testing::EnableTestLogging();
29 }
30
31 ::aos::SimulatedEventLoopFactory event_loop_factory_;
32 ::std::unique_ptr<::aos::EventLoop> loop_output_hander_event_loop_;
33 ::std::unique_ptr<::aos::EventLoop> test_event_loop_;
34};
35
36// Test loop output handler which logs and counts.
37class TestLoopOutputHandler
38 : public LoopOutputHandler<LoopOutputHandlerTestOutput> {
39 public:
40 TestLoopOutputHandler(::aos::EventLoop *event_loop, const ::std::string &name)
41 : LoopOutputHandler(event_loop, name) {}
42
43 ~TestLoopOutputHandler() { Stop(); }
44
45 int count() const { return count_; }
46
47 ::aos::monotonic_clock::time_point last_time() const { return last_time_; }
48 ::aos::monotonic_clock::time_point stop_time() const { return stop_time_; }
49
50 protected:
51 void Write(const LoopOutputHandlerTestOutput &output) override {
52 LOG_STRUCT(DEBUG, "output", output);
53 ++count_;
54 last_time_ = event_loop()->monotonic_now();
55 }
56
57 void Stop() override {
58 stop_time_ = event_loop()->monotonic_now();
59 LOG(DEBUG, "Stopping\n");
60 }
61
62 private:
63 int count_ = 0;
64
65 ::aos::monotonic_clock::time_point last_time_ =
66 ::aos::monotonic_clock::min_time;
67 ::aos::monotonic_clock::time_point stop_time_ =
68 ::aos::monotonic_clock::min_time;
69};
70
71// Test that the watchdog calls Stop at the right time.
72TEST_F(LoopOutputHandlerTest, WatchdogTest) {
73 TestLoopOutputHandler loop_output(loop_output_hander_event_loop_.get(),
74 ".test");
75
76 ::aos::Sender<LoopOutputHandlerTestOutput> output_sender =
77 test_event_loop_->MakeSender<LoopOutputHandlerTestOutput>(".test");
78
79 const monotonic_clock::time_point start_time =
80 test_event_loop_->monotonic_now();
81
82 int count = 0;
83 // Send outputs for 1 second.
84 ::aos::TimerHandler *timer_handle = test_event_loop_->AddTimer(
85 [this, &start_time, &output_sender, &loop_output, &count]() {
86 EXPECT_EQ(count, loop_output.count());
87 if (test_event_loop_->monotonic_now() <
88 start_time + chrono::seconds(1)) {
89 auto output = output_sender.MakeMessage();
90 output->voltage = 5.0;
91 EXPECT_TRUE(output.Send());
92
93 ++count;
94 }
95 LOG(INFO, "Ping\n");
96 });
97
98 // Kick off the ping timer handler.
99 test_event_loop_->OnRun([this, &timer_handle]() {
100 timer_handle->Setup(test_event_loop_->monotonic_now(),
101 chrono::milliseconds(5));
102 });
103
104 event_loop_factory_.RunFor(chrono::seconds(2));
105
106 // Confirm the watchdog
107 EXPECT_EQ(loop_output.stop_time(),
108 loop_output.last_time() + chrono::milliseconds(100));
109}
110
111} // namespace testing
112} // namespace wpilib
113} // namespace frc971