blob: a74b762f217dcedf1c250957a0d8ba4a3e69ee60 [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
Alex Perrycb7da4b2019-08-28 19:35:56 -07007#include "aos/events/simulated_event_loop.h"
Austin Schuhbd1fe9c2019-06-29 16:35:48 -07008#include "aos/logging/logging.h"
Austin Schuhbd1fe9c2019-06-29 16:35:48 -07009#include "aos/testing/test_logging.h"
10#include "aos/time/time.h"
Alex Perrycb7da4b2019-08-28 19:35:56 -070011#include "frc971/wpilib/loop_output_handler_test_generated.h"
Austin Schuhbd1fe9c2019-06-29 16:35:48 -070012
13namespace frc971 {
14namespace wpilib {
15namespace testing {
16namespace {
17namespace chrono = ::std::chrono;
18using ::aos::monotonic_clock;
19} // namespace
20
21class LoopOutputHandlerTest : public ::testing::Test {
22 public:
23 LoopOutputHandlerTest()
Austin Schuh00be38c2019-12-01 18:08:25 -080024 : configuration_(aos::configuration::ReadConfig(
25 "frc971/wpilib/loop_output_handler_test_config.json")),
Alex Perrycb7da4b2019-08-28 19:35:56 -070026 event_loop_factory_(&configuration_.message()),
Austin Schuh5f1cc5c2019-12-01 18:01:11 -080027 loop_output_hander_event_loop_(
28 event_loop_factory_.MakeEventLoop("output")),
29 test_event_loop_(event_loop_factory_.MakeEventLoop("test")) {
Austin Schuhbd1fe9c2019-06-29 16:35:48 -070030 ::aos::testing::EnableTestLogging();
31 }
32
Alex Perrycb7da4b2019-08-28 19:35:56 -070033 aos::FlatbufferDetachedBuffer<aos::Configuration> configuration_;
Austin Schuhbd1fe9c2019-06-29 16:35:48 -070034 ::aos::SimulatedEventLoopFactory event_loop_factory_;
35 ::std::unique_ptr<::aos::EventLoop> loop_output_hander_event_loop_;
36 ::std::unique_ptr<::aos::EventLoop> test_event_loop_;
37};
38
39// Test loop output handler which logs and counts.
40class TestLoopOutputHandler
41 : public LoopOutputHandler<LoopOutputHandlerTestOutput> {
42 public:
43 TestLoopOutputHandler(::aos::EventLoop *event_loop, const ::std::string &name)
44 : LoopOutputHandler(event_loop, name) {}
45
46 ~TestLoopOutputHandler() { Stop(); }
47
48 int count() const { return count_; }
49
50 ::aos::monotonic_clock::time_point last_time() const { return last_time_; }
51 ::aos::monotonic_clock::time_point stop_time() const { return stop_time_; }
52
53 protected:
54 void Write(const LoopOutputHandlerTestOutput &output) override {
Alex Perrycb7da4b2019-08-28 19:35:56 -070055 LOG(INFO) << "output " << aos::FlatbufferToJson(&output);
Austin Schuhbd1fe9c2019-06-29 16:35:48 -070056 ++count_;
57 last_time_ = event_loop()->monotonic_now();
58 }
59
60 void Stop() override {
61 stop_time_ = event_loop()->monotonic_now();
Alex Perrycb7da4b2019-08-28 19:35:56 -070062 LOG(INFO) << "Stopping";
Austin Schuhbd1fe9c2019-06-29 16:35:48 -070063 }
64
65 private:
66 int count_ = 0;
67
68 ::aos::monotonic_clock::time_point last_time_ =
69 ::aos::monotonic_clock::min_time;
70 ::aos::monotonic_clock::time_point stop_time_ =
71 ::aos::monotonic_clock::min_time;
72};
73
74// Test that the watchdog calls Stop at the right time.
75TEST_F(LoopOutputHandlerTest, WatchdogTest) {
76 TestLoopOutputHandler loop_output(loop_output_hander_event_loop_.get(),
Alex Perrycb7da4b2019-08-28 19:35:56 -070077 "/test");
Austin Schuhbd1fe9c2019-06-29 16:35:48 -070078
79 ::aos::Sender<LoopOutputHandlerTestOutput> output_sender =
Alex Perrycb7da4b2019-08-28 19:35:56 -070080 test_event_loop_->MakeSender<LoopOutputHandlerTestOutput>("/test");
Austin Schuhbd1fe9c2019-06-29 16:35:48 -070081
82 const monotonic_clock::time_point start_time =
83 test_event_loop_->monotonic_now();
84
85 int count = 0;
86 // Send outputs for 1 second.
87 ::aos::TimerHandler *timer_handle = test_event_loop_->AddTimer(
88 [this, &start_time, &output_sender, &loop_output, &count]() {
89 EXPECT_EQ(count, loop_output.count());
90 if (test_event_loop_->monotonic_now() <
91 start_time + chrono::seconds(1)) {
Alex Perrycb7da4b2019-08-28 19:35:56 -070092 auto builder = output_sender.MakeBuilder();
93 LoopOutputHandlerTestOutput::Builder output_builder =
94 builder.MakeBuilder<LoopOutputHandlerTestOutput>();
95 output_builder.add_voltage(5.0);
96 EXPECT_TRUE(builder.Send(output_builder.Finish()));
Austin Schuhbd1fe9c2019-06-29 16:35:48 -070097
98 ++count;
99 }
Alex Perrycb7da4b2019-08-28 19:35:56 -0700100 LOG(INFO) << "Ping";
Austin Schuhbd1fe9c2019-06-29 16:35:48 -0700101 });
102
103 // Kick off the ping timer handler.
104 test_event_loop_->OnRun([this, &timer_handle]() {
105 timer_handle->Setup(test_event_loop_->monotonic_now(),
106 chrono::milliseconds(5));
107 });
108
109 event_loop_factory_.RunFor(chrono::seconds(2));
110
111 // Confirm the watchdog
112 EXPECT_EQ(loop_output.stop_time(),
113 loop_output.last_time() + chrono::milliseconds(100));
114}
115
116} // namespace testing
117} // namespace wpilib
118} // namespace frc971