1 #include "dbus_environment.hpp"
2 #include "helpers.hpp"
3 #include "mocks/trigger_factory_mock.hpp"
4 #include "mocks/trigger_mock.hpp"
5 #include "params/trigger_params.hpp"
6 #include "trigger_manager.hpp"
7 
8 using namespace testing;
9 
10 class TestTriggerManager : public Test
11 {
12   public:
13     std::pair<boost::system::error_code, std::string>
14         addTrigger(const TriggerParams& params)
15     {
16         std::promise<std::pair<boost::system::error_code, std::string>>
17             addTriggerPromise;
18         DbusEnvironment::getBus()->async_method_call(
19             [&addTriggerPromise](boost::system::error_code ec,
20                                  const std::string& path) {
21                 addTriggerPromise.set_value({ec, path});
22             },
23             DbusEnvironment::serviceName(), TriggerManager::triggerManagerPath,
24             TriggerManager::triggerManagerIfaceName, "AddTrigger",
25             params.name(), params.isDiscrete(), params.logToJournal(),
26             params.logToRedfish(), params.updateReport(), params.sensors(),
27             params.reportNames(), params.thresholdParams());
28         return DbusEnvironment::waitForFuture(addTriggerPromise.get_future());
29     }
30 
31     TriggerParams triggerParams;
32     std::unique_ptr<TriggerFactoryMock> triggerFactoryMockPtr =
33         std::make_unique<NiceMock<TriggerFactoryMock>>();
34     TriggerFactoryMock& triggerFactoryMock = *triggerFactoryMockPtr;
35     std::unique_ptr<TriggerMock> triggerMockPtr =
36         std::make_unique<NiceMock<TriggerMock>>(triggerParams.name());
37     TriggerMock& triggerMock = *triggerMockPtr;
38     std::unique_ptr<TriggerManager> sut = std::make_unique<TriggerManager>(
39         std::move(triggerFactoryMockPtr),
40         std::move(DbusEnvironment::getObjServer()));
41     MockFunction<void(std::string)> checkPoint;
42 };
43 
44 TEST_F(TestTriggerManager, addTrigger)
45 {
46     triggerFactoryMock.expectMake(triggerParams, Ref(*sut))
47         .WillOnce(Return(ByMove(std::move(triggerMockPtr))));
48 
49     auto [ec, path] = addTrigger(triggerParams);
50     EXPECT_THAT(ec.value(), Eq(boost::system::errc::success));
51     EXPECT_THAT(path, Eq(triggerMock.getPath()));
52 }
53 
54 TEST_F(TestTriggerManager, addTriggerWithDiscreteThresholds)
55 {
56     TriggerParams triggerParamsDiscrete;
57     auto thresholds = std::vector<discrete::ThresholdParam>{
58         {"discrete_threshold1",
59          discrete::severityToString(discrete::Severity::ok), 10, 11.0},
60         {"discrete_threshold2",
61          discrete::severityToString(discrete::Severity::warning), 10, 12.0},
62         {"discrete_threshold3",
63          discrete::severityToString(discrete::Severity::critical), 10, 13.0}};
64 
65     triggerParamsDiscrete.thresholdParams(thresholds).isDiscrete(true);
66 
67     auto [ec, path] = addTrigger(triggerParamsDiscrete);
68     EXPECT_THAT(ec.value(), Eq(boost::system::errc::success));
69     EXPECT_THAT(path, Eq(triggerMock.getPath()));
70 }
71 
72 TEST_F(TestTriggerManager, addDiscreteTriggerWithoutThresholds)
73 {
74     TriggerParams triggerParamsDiscrete;
75     auto thresholds = std::vector<discrete::ThresholdParam>();
76 
77     triggerParamsDiscrete.thresholdParams(thresholds).isDiscrete(true);
78 
79     auto [ec, path] = addTrigger(triggerParamsDiscrete);
80     EXPECT_THAT(ec.value(), Eq(boost::system::errc::success));
81     EXPECT_THAT(path, Eq(triggerMock.getPath()));
82 }
83 
84 TEST_F(TestTriggerManager, DISABLED_failToAddTriggerTwice)
85 {
86     triggerFactoryMock.expectMake(triggerParams, Ref(*sut))
87         .WillOnce(Return(ByMove(std::move(triggerMockPtr))));
88 
89     addTrigger(triggerParams);
90 
91     auto [ec, path] = addTrigger(triggerParams);
92     EXPECT_THAT(ec.value(), Eq(boost::system::errc::file_exists));
93     EXPECT_THAT(path, Eq(std::string()));
94 }
95 
96 TEST_F(TestTriggerManager, DISABLED_failToAddTriggerWhenMaxTriggerIsReached)
97 {
98     triggerFactoryMock.expectMake(std::nullopt, Ref(*sut))
99         .Times(TriggerManager::maxTriggers);
100 
101     for (size_t i = 0; i < TriggerManager::maxTriggers; i++)
102     {
103         triggerParams.name(triggerParams.name() + std::to_string(i));
104 
105         auto [ec, path] = addTrigger(triggerParams);
106         EXPECT_THAT(ec.value(), Eq(boost::system::errc::success));
107     }
108 
109     triggerParams.name(triggerParams.name() +
110                        std::to_string(TriggerManager::maxTriggers));
111     auto [ec, path] = addTrigger(triggerParams);
112     EXPECT_THAT(ec.value(), Eq(boost::system::errc::too_many_files_open));
113     EXPECT_THAT(path, Eq(std::string()));
114 }
115 
116 TEST_F(TestTriggerManager, removeTrigger)
117 {
118     {
119         InSequence seq;
120         triggerFactoryMock.expectMake(triggerParams, Ref(*sut))
121             .WillOnce(Return(ByMove(std::move(triggerMockPtr))));
122         EXPECT_CALL(triggerMock, Die());
123         EXPECT_CALL(checkPoint, Call("end"));
124     }
125 
126     addTrigger(triggerParams);
127     sut->removeTrigger(&triggerMock);
128     checkPoint.Call("end");
129 }
130 
131 TEST_F(TestTriggerManager, removingTriggerThatIsNotInContainerHasNoEffect)
132 {
133     {
134         InSequence seq;
135         EXPECT_CALL(checkPoint, Call("end"));
136         EXPECT_CALL(triggerMock, Die());
137     }
138 
139     sut->removeTrigger(&triggerMock);
140     checkPoint.Call("end");
141 }
142 
143 TEST_F(TestTriggerManager, removingSameTriggerTwiceHasNoSideEffect)
144 {
145     {
146         InSequence seq;
147         triggerFactoryMock.expectMake(triggerParams, Ref(*sut))
148             .WillOnce(Return(ByMove(std::move(triggerMockPtr))));
149         EXPECT_CALL(triggerMock, Die());
150         EXPECT_CALL(checkPoint, Call("end"));
151     }
152 
153     addTrigger(triggerParams);
154     sut->removeTrigger(&triggerMock);
155     sut->removeTrigger(&triggerMock);
156     checkPoint.Call("end");
157 }
158