blob: c79611697504cee2957decbfdab96de922a24e4a [file] [log] [blame]
Brian Silverman41cdd3e2019-01-19 19:48:58 -08001/*----------------------------------------------------------------------------*/
2/* Copyright (c) 2018 FIRST. All Rights Reserved. */
3/* Open Source Software - may be modified and shared by FRC teams. The code */
4/* must be accompanied by the FIRST BSD license file in the root directory of */
5/* the project. */
6/*----------------------------------------------------------------------------*/
7
8#include "frc/Watchdog.h" // NOLINT(build/include_order)
9
10#include <stdint.h>
11
12#include <thread>
13
14#include <wpi/raw_ostream.h>
15
16#include "gtest/gtest.h"
17
18using namespace frc;
19
20TEST(WatchdogTest, EnableDisable) {
21 uint32_t watchdogCounter = 0;
22
23 Watchdog watchdog(0.4, [&] { watchdogCounter++; });
24
25 wpi::outs() << "Run 1\n";
26 watchdog.Enable();
27 std::this_thread::sleep_for(std::chrono::milliseconds(200));
28 watchdog.Disable();
29
30 EXPECT_EQ(0u, watchdogCounter) << "Watchdog triggered early";
31
32 wpi::outs() << "Run 2\n";
33 watchdogCounter = 0;
34 watchdog.Enable();
35 std::this_thread::sleep_for(std::chrono::milliseconds(600));
36 watchdog.Disable();
37
38 EXPECT_EQ(1u, watchdogCounter)
39 << "Watchdog either didn't trigger or triggered more than once";
40
41 wpi::outs() << "Run 3\n";
42 watchdogCounter = 0;
43 watchdog.Enable();
44 std::this_thread::sleep_for(std::chrono::milliseconds(1000));
45 watchdog.Disable();
46
47 EXPECT_EQ(1u, watchdogCounter)
48 << "Watchdog either didn't trigger or triggered more than once";
49}
50
51TEST(WatchdogTest, Reset) {
52 uint32_t watchdogCounter = 0;
53
54 Watchdog watchdog(0.4, [&] { watchdogCounter++; });
55
56 watchdog.Enable();
57 std::this_thread::sleep_for(std::chrono::milliseconds(200));
58 watchdog.Reset();
59 std::this_thread::sleep_for(std::chrono::milliseconds(200));
60 watchdog.Disable();
61
62 EXPECT_EQ(0u, watchdogCounter) << "Watchdog triggered early";
63}
64
65TEST(WatchdogTest, SetTimeout) {
66 uint32_t watchdogCounter = 0;
67
68 Watchdog watchdog(1.0, [&] { watchdogCounter++; });
69
70 watchdog.Enable();
71 std::this_thread::sleep_for(std::chrono::milliseconds(200));
72 watchdog.SetTimeout(0.2);
73
74 EXPECT_EQ(0.2, watchdog.GetTimeout());
75 EXPECT_EQ(0u, watchdogCounter) << "Watchdog triggered early";
76
77 std::this_thread::sleep_for(std::chrono::milliseconds(300));
78 watchdog.Disable();
79
80 EXPECT_EQ(1u, watchdogCounter)
81 << "Watchdog either didn't trigger or triggered more than once";
82}
83
84TEST(WatchdogTest, IsExpired) {
85 Watchdog watchdog(0.2, [] {});
Brian Silverman60246092019-03-02 13:29:58 -080086 EXPECT_FALSE(watchdog.IsExpired());
Brian Silverman41cdd3e2019-01-19 19:48:58 -080087 watchdog.Enable();
88
89 EXPECT_FALSE(watchdog.IsExpired());
90 std::this_thread::sleep_for(std::chrono::milliseconds(300));
91 EXPECT_TRUE(watchdog.IsExpired());
Brian Silverman60246092019-03-02 13:29:58 -080092
93 watchdog.Disable();
94 EXPECT_TRUE(watchdog.IsExpired());
95
96 watchdog.Reset();
97 EXPECT_FALSE(watchdog.IsExpired());
Brian Silverman41cdd3e2019-01-19 19:48:58 -080098}
99
100TEST(WatchdogTest, Epochs) {
101 uint32_t watchdogCounter = 0;
102
103 Watchdog watchdog(0.4, [&] { watchdogCounter++; });
104
105 wpi::outs() << "Run 1\n";
106 watchdog.Enable();
107 watchdog.AddEpoch("Epoch 1");
108 std::this_thread::sleep_for(std::chrono::milliseconds(100));
109 watchdog.AddEpoch("Epoch 2");
110 std::this_thread::sleep_for(std::chrono::milliseconds(100));
111 watchdog.AddEpoch("Epoch 3");
112 watchdog.Disable();
113
114 EXPECT_EQ(0u, watchdogCounter) << "Watchdog triggered early";
115
116 wpi::outs() << "Run 2\n";
117 watchdog.Enable();
118 watchdog.AddEpoch("Epoch 1");
119 std::this_thread::sleep_for(std::chrono::milliseconds(200));
120 watchdog.Reset();
121 std::this_thread::sleep_for(std::chrono::milliseconds(200));
122 watchdog.AddEpoch("Epoch 2");
123 watchdog.Disable();
124
125 EXPECT_EQ(0u, watchdogCounter) << "Watchdog triggered early";
126}
127
Brian Silverman60246092019-03-02 13:29:58 -0800128#ifdef __APPLE__
129TEST(WatchdogTest, DISABLED_MultiWatchdog) {
130#else
Brian Silverman41cdd3e2019-01-19 19:48:58 -0800131TEST(WatchdogTest, MultiWatchdog) {
Brian Silverman60246092019-03-02 13:29:58 -0800132#endif
Brian Silverman41cdd3e2019-01-19 19:48:58 -0800133 uint32_t watchdogCounter1 = 0;
134 uint32_t watchdogCounter2 = 0;
135
136 Watchdog watchdog1(0.2, [&] { watchdogCounter1++; });
137 Watchdog watchdog2(0.6, [&] { watchdogCounter2++; });
138
139 watchdog2.Enable();
140 std::this_thread::sleep_for(std::chrono::milliseconds(200));
141 EXPECT_EQ(0u, watchdogCounter1) << "Watchdog triggered early";
142 EXPECT_EQ(0u, watchdogCounter2) << "Watchdog triggered early";
143
144 // Sleep enough such that only the watchdog enabled later times out first
145 watchdog1.Enable();
146 std::this_thread::sleep_for(std::chrono::milliseconds(300));
147 watchdog1.Disable();
148 watchdog2.Disable();
149
150 EXPECT_EQ(1u, watchdogCounter1)
151 << "Watchdog either didn't trigger or triggered more than once";
152 EXPECT_EQ(0u, watchdogCounter2) << "Watchdog triggered early";
153}