Skip to content

Commit 0c1a1cf

Browse files
committed
hmon: add C++ HMON unit tests
- Rename previous test to `integrated_test`. - Reimplement Rust unit tests into C++.
1 parent 96b3bc2 commit 0c1a1cf

2 files changed

Lines changed: 337 additions & 105 deletions

File tree

src/health_monitoring_lib/cpp/tests/health_monitor_test.cpp

Lines changed: 214 additions & 105 deletions
Original file line numberDiff line numberDiff line change
@@ -10,114 +10,223 @@
1010
*
1111
* SPDX-License-Identifier: Apache-2.0
1212
********************************************************************************/
13+
1314
#include "score/hm/health_monitor.h"
14-
#include "score/hm/common.h"
15-
#include "score/hm/tag.h"
16-
#include <gmock/gmock.h>
15+
#include "score/hm/deadline/deadline_monitor.h"
16+
#include "score/hm/heartbeat/heartbeat_monitor.h"
17+
#include "score/hm/logic/logic_monitor.h"
1718
#include <gtest/gtest.h>
1819

1920
using namespace score::hm;
21+
using namespace score::hm::deadline;
22+
using namespace score::hm::heartbeat;
23+
using namespace score::hm::logic;
24+
25+
HeartbeatMonitorBuilder def_heartbeat_monitor_builder()
26+
{
27+
using namespace std::chrono_literals;
28+
TimeRange range{100ms, 200ms};
29+
return HeartbeatMonitorBuilder{range};
30+
}
31+
32+
LogicMonitorBuilder def_logic_monitor_builder()
33+
{
34+
StateTag state1{"state1"};
35+
StateTag state2{"state2"};
36+
return LogicMonitorBuilder{state1}.add_state(state1, {state2}).add_state(state2, {state1});
37+
}
38+
39+
TEST(HealthMonitorBuilder, New_Succeeds)
40+
{
41+
// Check able to construct and destruct only.
42+
HealthMonitorBuilder health_monitor_builder;
43+
}
44+
45+
TEST(HealthMonitorBuilder, Build_Succeeds)
46+
{
47+
MonitorTag deadline_monitor_tag{"deadline_monitor"};
48+
DeadlineMonitorBuilder deadline_monitor_builder;
49+
MonitorTag heartbeat_monitor_tag{"heartbeat_monitor"};
50+
auto heartbeat_monitor_builder{def_heartbeat_monitor_builder()};
51+
MonitorTag logic_monitor_tag{"heartbeat_monitor"};
52+
auto logic_monitor_builder{def_logic_monitor_builder()};
53+
54+
auto result{HealthMonitorBuilder{}
55+
.add_deadline_monitor(deadline_monitor_tag, std::move(deadline_monitor_builder))
56+
.add_heartbeat_monitor(heartbeat_monitor_tag, std::move(heartbeat_monitor_builder))
57+
.add_logic_monitor(logic_monitor_tag, std::move(logic_monitor_builder))
58+
.build()};
59+
ASSERT_TRUE(result.has_value());
60+
}
61+
62+
TEST(HealthMonitorBuilder, Build_InvalidCycles)
63+
{
64+
using namespace std::chrono_literals;
65+
auto result{HealthMonitorBuilder{}.with_supervisor_api_cycle(123ms).with_internal_processing_cycle(100ms).build()};
66+
ASSERT_FALSE(result.has_value());
67+
ASSERT_EQ(result.error(), Error::InvalidArgument);
68+
}
69+
70+
TEST(HealthMonitorBuilder, Build_NoMonitors)
71+
{
72+
auto result{HealthMonitorBuilder{}.build()};
73+
ASSERT_FALSE(result.has_value());
74+
ASSERT_EQ(result.error(), Error::WrongState);
75+
}
76+
77+
TEST(HealthMonitor, GetDeadlineMonitor_Available)
78+
{
79+
MonitorTag deadline_monitor_tag{"deadline_monitor"};
80+
DeadlineMonitorBuilder deadline_monitor_builder;
81+
auto health_monitor{HealthMonitorBuilder{}
82+
.add_deadline_monitor(deadline_monitor_tag, std::move(deadline_monitor_builder))
83+
.build()
84+
.value()};
85+
86+
auto result{health_monitor.get_deadline_monitor(deadline_monitor_tag)};
87+
ASSERT_TRUE(result.has_value());
88+
}
89+
90+
TEST(HealthMonitor, GetDeadlineMonitor_Taken)
91+
{
92+
MonitorTag deadline_monitor_tag{"deadline_monitor"};
93+
DeadlineMonitorBuilder deadline_monitor_builder;
94+
auto health_monitor{HealthMonitorBuilder{}
95+
.add_deadline_monitor(deadline_monitor_tag, std::move(deadline_monitor_builder))
96+
.build()
97+
.value()};
98+
99+
health_monitor.get_deadline_monitor(deadline_monitor_tag);
100+
auto result{health_monitor.get_deadline_monitor(deadline_monitor_tag)};
101+
ASSERT_FALSE(result.has_value());
102+
}
103+
104+
TEST(HealthMonitor, GetDeadlineMonitor_Unknown)
105+
{
106+
MonitorTag deadline_monitor_tag{"deadline_monitor"};
107+
DeadlineMonitorBuilder deadline_monitor_builder;
108+
auto health_monitor{HealthMonitorBuilder{}
109+
.add_deadline_monitor(deadline_monitor_tag, std::move(deadline_monitor_builder))
110+
.build()
111+
.value()};
112+
113+
auto result{health_monitor.get_deadline_monitor(MonitorTag{"undefined_monitor"})};
114+
ASSERT_FALSE(result.has_value());
115+
}
116+
117+
TEST(HealthMonitor, GetHeartbeatMonitor_Available)
118+
{
119+
MonitorTag heartbeat_monitor_tag{"heartbeat_monitor"};
120+
auto heartbeat_monitor_builder{def_heartbeat_monitor_builder()};
121+
auto health_monitor{HealthMonitorBuilder{}
122+
.add_heartbeat_monitor(heartbeat_monitor_tag, std::move(heartbeat_monitor_builder))
123+
.build()
124+
.value()};
125+
126+
auto result{health_monitor.get_heartbeat_monitor(heartbeat_monitor_tag)};
127+
ASSERT_TRUE(result.has_value());
128+
}
129+
130+
TEST(HealthMonitor, GetHeartbeatMonitor_Taken)
131+
{
132+
MonitorTag heartbeat_monitor_tag{"heartbeat_monitor"};
133+
HeartbeatMonitorBuilder heartbeat_monitor_builder{def_heartbeat_monitor_builder()};
134+
auto health_monitor{HealthMonitorBuilder{}
135+
.add_heartbeat_monitor(heartbeat_monitor_tag, std::move(heartbeat_monitor_builder))
136+
.build()
137+
.value()};
138+
139+
health_monitor.get_heartbeat_monitor(heartbeat_monitor_tag);
140+
auto result{health_monitor.get_heartbeat_monitor(heartbeat_monitor_tag)};
141+
ASSERT_FALSE(result.has_value());
142+
}
143+
144+
TEST(HealthMonitor, GetHeartbeatMonitor_Unknown)
145+
{
146+
MonitorTag heartbeat_monitor_tag{"heartbeat_monitor"};
147+
HeartbeatMonitorBuilder heartbeat_monitor_builder{def_heartbeat_monitor_builder()};
148+
auto health_monitor{HealthMonitorBuilder{}
149+
.add_heartbeat_monitor(heartbeat_monitor_tag, std::move(heartbeat_monitor_builder))
150+
.build()
151+
.value()};
152+
153+
auto result{health_monitor.get_heartbeat_monitor(MonitorTag{"undefined_monitor"})};
154+
ASSERT_FALSE(result.has_value());
155+
}
156+
157+
TEST(HealthMonitor, GetLogicMonitor_Available)
158+
{
159+
MonitorTag logic_monitor_tag{"logic_monitor"};
160+
auto logic_monitor_builder{def_logic_monitor_builder()};
161+
auto health_monitor{
162+
HealthMonitorBuilder{}.add_logic_monitor(logic_monitor_tag, std::move(logic_monitor_builder)).build().value()};
20163

21-
class HealthMonitorTest : public ::testing::Test
22-
{
23-
protected:
24-
void SetUp() override
25-
{
26-
RecordProperty("TestType", "interface-test");
27-
RecordProperty("DerivationTechnique", "explorative-testing ");
28-
}
29-
};
30-
31-
// For first review round, only single test case to show up API
32-
TEST_F(HealthMonitorTest, TestName)
33-
{
34-
RecordProperty(
35-
"Description",
36-
"This test demonstrates the usage of HealthMonitor and DeadlineMonitor APIs. It creates a HealthMonitor with a "
37-
"DeadlineMonitor, retrieves the DeadlineMonitor, and tests starting a deadline.");
38-
// Setup deadline monitor construction.
39-
const MonitorTag deadline_monitor_tag{"deadline_monitor"};
40-
auto deadline_monitor_builder =
41-
deadline::DeadlineMonitorBuilder()
42-
.add_deadline(DeadlineTag("deadline_1"),
43-
TimeRange(std::chrono::milliseconds(100), std::chrono::milliseconds(200)))
44-
.add_deadline(DeadlineTag("deadline_2"),
45-
TimeRange(std::chrono::milliseconds(100), std::chrono::milliseconds(200)));
46-
47-
// Setup heartbeat monitor construction.
48-
const MonitorTag heartbeat_monitor_tag{"heartbeat_monitor"};
49-
const TimeRange heartbeat_range{std::chrono::milliseconds{100}, std::chrono::milliseconds{200}};
50-
auto heartbeat_monitor_builder = heartbeat::HeartbeatMonitorBuilder(heartbeat_range);
51-
52-
// Setup logic monitor construction.
53-
const MonitorTag logic_monitor_tag{"logic_monitor"};
54-
StateTag from_state{"from_state"};
55-
StateTag to_state{"to_state"};
56-
auto logic_monitor_builder =
57-
logic::LogicMonitorBuilder{from_state}.add_state(from_state, std::vector{to_state}).add_state(to_state, {});
58-
59-
auto hmon_result{HealthMonitorBuilder()
60-
.add_deadline_monitor(deadline_monitor_tag, std::move(deadline_monitor_builder))
61-
.add_heartbeat_monitor(heartbeat_monitor_tag, std::move(heartbeat_monitor_builder))
62-
.add_logic_monitor(logic_monitor_tag, std::move(logic_monitor_builder))
63-
.with_internal_processing_cycle(std::chrono::milliseconds(50))
64-
.with_supervisor_api_cycle(std::chrono::milliseconds(50))
65-
.build()};
66-
EXPECT_TRUE(hmon_result.has_value());
67-
auto hm{std::move(hmon_result.value())};
68-
69-
// Obtain deadline monitor from HMON.
70-
auto deadline_monitor_res = hm.get_deadline_monitor(deadline_monitor_tag);
71-
EXPECT_TRUE(deadline_monitor_res.has_value());
72-
73-
{
74-
// Try again to get the same monitor.
75-
auto deadline_monitor_res = hm.get_deadline_monitor(deadline_monitor_tag);
76-
EXPECT_FALSE(deadline_monitor_res.has_value());
77-
}
78-
79-
auto deadline_mon = std::move(*deadline_monitor_res);
80-
81-
// Obtain heartbeat monitor from HMON.
82-
auto heartbeat_monitor_res{hm.get_heartbeat_monitor(heartbeat_monitor_tag)};
83-
EXPECT_TRUE(heartbeat_monitor_res.has_value());
84-
85-
{
86-
// Try again to get the same monitor.
87-
auto heartbeat_monitor_res{hm.get_heartbeat_monitor(heartbeat_monitor_tag)};
88-
EXPECT_FALSE(heartbeat_monitor_res.has_value());
89-
}
90-
91-
auto heartbeat_monitor{std::move(*heartbeat_monitor_res)};
92-
93-
// Obtain logic monitor from HMON.
94-
auto logic_monitor_res{hm.get_logic_monitor(logic_monitor_tag)};
95-
EXPECT_TRUE(logic_monitor_res.has_value());
96-
97-
{
98-
// Try again to get the same monitor.
99-
auto logic_monitor_res{hm.get_logic_monitor(logic_monitor_tag)};
100-
EXPECT_FALSE(logic_monitor_res.has_value());
101-
}
102-
103-
auto logic_monitor{std::move(*logic_monitor_res)};
104-
105-
// Start HMON.
106-
hm.start();
107-
108-
heartbeat_monitor.heartbeat();
109-
110-
EXPECT_TRUE(logic_monitor.transition(to_state).has_value());
111-
auto current_state_res{logic_monitor.state()};
112-
EXPECT_TRUE(current_state_res.has_value());
113-
EXPECT_EQ(current_state_res.value(), to_state);
114-
115-
auto deadline_res = deadline_mon.get_deadline(DeadlineTag("deadline_1"));
116-
117-
{
118-
auto deadline_guard = deadline_res.value().start().value();
119-
120-
EXPECT_EQ(deadline_res.value().start().error(), ::score::hm::Error::WrongState);
121-
deadline_guard.stop();
122-
}
164+
auto result{health_monitor.get_logic_monitor(logic_monitor_tag)};
165+
ASSERT_TRUE(result.has_value());
166+
}
167+
168+
TEST(HealthMonitor, GetLogicMonitor_Taken)
169+
{
170+
MonitorTag logic_monitor_tag{"logic_monitor"};
171+
LogicMonitorBuilder logic_monitor_builder{def_logic_monitor_builder()};
172+
auto health_monitor{
173+
HealthMonitorBuilder{}.add_logic_monitor(logic_monitor_tag, std::move(logic_monitor_builder)).build().value()};
174+
175+
health_monitor.get_logic_monitor(logic_monitor_tag);
176+
auto result{health_monitor.get_logic_monitor(logic_monitor_tag)};
177+
ASSERT_FALSE(result.has_value());
178+
}
179+
180+
TEST(HealthMonitor, GetLogicMonitor_Unknown)
181+
{
182+
MonitorTag logic_monitor_tag{"logic_monitor"};
183+
LogicMonitorBuilder logic_monitor_builder{def_logic_monitor_builder()};
184+
auto health_monitor{
185+
HealthMonitorBuilder{}.add_logic_monitor(logic_monitor_tag, std::move(logic_monitor_builder)).build().value()};
186+
187+
auto result{health_monitor.get_logic_monitor(MonitorTag{"undefined_monitor"})};
188+
ASSERT_FALSE(result.has_value());
189+
}
190+
191+
TEST(HealthMonitor, Start_Succeeds)
192+
{
193+
MonitorTag deadline_monitor_tag{"deadline_monitor"};
194+
DeadlineMonitorBuilder deadline_monitor_builder;
195+
MonitorTag heartbeat_monitor_tag{"heartbeat_monitor"};
196+
auto heartbeat_monitor_builder{def_heartbeat_monitor_builder()};
197+
MonitorTag logic_monitor_tag{"logic_monitor"};
198+
auto logic_monitor_builder{def_logic_monitor_builder()};
199+
200+
auto health_monitor{HealthMonitorBuilder{}
201+
.add_deadline_monitor(deadline_monitor_tag, std::move(deadline_monitor_builder))
202+
.add_heartbeat_monitor(heartbeat_monitor_tag, std::move(heartbeat_monitor_builder))
203+
.add_logic_monitor(logic_monitor_tag, std::move(logic_monitor_builder))
204+
.build()
205+
.value()};
206+
207+
health_monitor.get_deadline_monitor(deadline_monitor_tag);
208+
health_monitor.get_heartbeat_monitor(heartbeat_monitor_tag);
209+
health_monitor.get_logic_monitor(logic_monitor_tag);
210+
211+
health_monitor.start();
212+
}
213+
214+
TEST(HealthMonitor, Start_MonitorsNotTaken)
215+
{
216+
MonitorTag deadline_monitor_tag{"deadline_monitor"};
217+
DeadlineMonitorBuilder deadline_monitor_builder;
218+
MonitorTag heartbeat_monitor_tag{"heartbeat_monitor"};
219+
auto heartbeat_monitor_builder{def_heartbeat_monitor_builder()};
220+
MonitorTag logic_monitor_tag{"logic_monitor"};
221+
auto logic_monitor_builder{def_logic_monitor_builder()};
222+
223+
auto health_monitor{HealthMonitorBuilder{}
224+
.add_deadline_monitor(deadline_monitor_tag, std::move(deadline_monitor_builder))
225+
.add_heartbeat_monitor(heartbeat_monitor_tag, std::move(heartbeat_monitor_builder))
226+
.add_logic_monitor(logic_monitor_tag, std::move(logic_monitor_builder))
227+
.build()
228+
.value()};
229+
230+
// `SIGABRT` is expected.
231+
ASSERT_DEATH({ health_monitor.start(); }, "");
123232
}

0 commit comments

Comments
 (0)