blob: 0af1b7146d4f603247b7a043a811a1a84500c4f9 [file] [log] [blame]
Lei YU12c9f4c2019-09-11 15:08:15 +08001#include "activation.hpp"
Lei YUffb36532019-10-15 13:55:24 +08002#include "mocked_activation_listener.hpp"
Lei YU7f2a2152019-09-16 16:50:18 +08003#include "mocked_association_interface.hpp"
Lei YUff83c2a2019-09-12 13:55:18 +08004#include "mocked_utils.hpp"
Lei YU12c9f4c2019-09-11 15:08:15 +08005
6#include <sdbusplus/test/sdbus_mock.hpp>
7
8#include <gmock/gmock.h>
9#include <gtest/gtest.h>
10
11using namespace phosphor::software::updater;
12
Lei YUff83c2a2019-09-12 13:55:18 +080013using ::testing::_;
14using ::testing::Return;
Lei YU9edb7332019-09-19 14:46:19 +080015using ::testing::StrEq;
16
Patrick Williamsb5f9b822022-06-16 17:26:17 -050017using std::any;
Lei YUff83c2a2019-09-12 13:55:18 +080018
Lei YU12c9f4c2019-09-11 15:08:15 +080019class TestActivation : public ::testing::Test
20{
21 public:
Lei YU9edb7332019-09-19 14:46:19 +080022 using PropertyType = utils::UtilsInterface::PropertyType;
Lei YUff83c2a2019-09-12 13:55:18 +080023 using Status = Activation::Status;
24 using RequestedStatus = Activation::RequestedActivations;
George Liu66a54ad2024-08-23 13:53:39 +080025
26 TestActivation(const TestActivation&) = delete;
27 TestActivation& operator=(const TestActivation&) = delete;
28 TestActivation(TestActivation&&) = delete;
29 TestActivation& operator=(TestActivation&&) = delete;
30
Lei YUff83c2a2019-09-12 13:55:18 +080031 TestActivation() :
32 mockedUtils(
33 reinterpret_cast<const utils::MockedUtils&>(utils::getUtils()))
Lei YU12c9f4c2019-09-11 15:08:15 +080034 {
Shawn McCarney46ea3882024-12-10 11:25:38 -060035 // By default make PSU present
36 ON_CALL(mockedUtils, getPropertyImpl(_, _, _, _, StrEq(PRESENT)))
37 .WillByDefault(Return(any(PropertyType(true))));
38
39 // By default make PSU compatible with the test software
Lei YU9edb7332019-09-19 14:46:19 +080040 ON_CALL(mockedUtils, getPropertyImpl(_, _, _, _, StrEq(MANUFACTURER)))
41 .WillByDefault(Return(any(PropertyType(std::string("TestManu")))));
Shawn McCarney783406e2024-11-17 21:49:37 -060042 ON_CALL(mockedUtils, getModel(_))
43 .WillByDefault(Return(std::string("TestModel")));
Lei YU63f9e712019-10-12 15:16:55 +080044 ON_CALL(mockedUtils, isAssociated(_, _)).WillByDefault(Return(false));
Lei YU12c9f4c2019-09-11 15:08:15 +080045 }
George Liu047d9942024-08-23 13:44:31 +080046 ~TestActivation() override
Lei YU12c9f4c2019-09-11 15:08:15 +080047 {
Lei YUc09155b2019-10-11 17:30:48 +080048 utils::freeUtils();
Lei YU12c9f4c2019-09-11 15:08:15 +080049 }
Lei YUff83c2a2019-09-12 13:55:18 +080050
George Liu71ae5352024-08-23 15:21:05 +080051 void onUpdateDone() const
Lei YUff83c2a2019-09-12 13:55:18 +080052 {
53 activation->onUpdateDone();
54 }
George Liu71ae5352024-08-23 15:21:05 +080055 void onUpdateFailed() const
Lei YUff83c2a2019-09-12 13:55:18 +080056 {
57 activation->onUpdateFailed();
58 }
George Liu71ae5352024-08-23 15:21:05 +080059 int getProgress() const
Lei YUff83c2a2019-09-12 13:55:18 +080060 {
61 return activation->activationProgress->progress();
62 }
George Liu71ae5352024-08-23 15:21:05 +080063 const auto& getPsuQueue() const
Lei YU9edb7332019-09-19 14:46:19 +080064 {
65 return activation->psuQueue;
66 }
George Liu71ae5352024-08-23 15:21:05 +080067 std::string getUpdateService(const std::string& psuInventoryPath) const
Lei YUe8945ea2019-09-29 17:25:31 +080068 {
69 return activation->getUpdateService(psuInventoryPath);
70 }
Lei YU9edb7332019-09-19 14:46:19 +080071
Lei YU12c9f4c2019-09-11 15:08:15 +080072 sdbusplus::SdBusMock sdbusMock;
Patrick Williams374fae52022-07-22 19:26:55 -050073 sdbusplus::bus_t mockedBus = sdbusplus::get_mocked_new(&sdbusMock);
Lei YUff83c2a2019-09-12 13:55:18 +080074 const utils::MockedUtils& mockedUtils;
Lei YU7f2a2152019-09-16 16:50:18 +080075 MockedAssociationInterface mockedAssociationInterface;
Lei YUffb36532019-10-15 13:55:24 +080076 MockedActivationListener mockedActivationListener;
Lei YU12c9f4c2019-09-11 15:08:15 +080077 std::unique_ptr<Activation> activation;
78 std::string versionId = "abcdefgh";
Lei YU9edb7332019-09-19 14:46:19 +080079 std::string extVersion = "manufacturer=TestManu,model=TestModel";
Lei YU63f9e712019-10-12 15:16:55 +080080 std::string filePath = "/tmp/images/abcdefgh";
Lei YU7f2a2152019-09-16 16:50:18 +080081 std::string dBusPath = std::string(SOFTWARE_OBJPATH) + "/" + versionId;
Lei YUff83c2a2019-09-12 13:55:18 +080082 Status status = Status::Ready;
Lei YU12c9f4c2019-09-11 15:08:15 +080083 AssociationList associations;
84};
85
86TEST_F(TestActivation, ctordtor)
87{
Lei YU99301372019-09-29 16:27:12 +080088 activation = std::make_unique<Activation>(
89 mockedBus, dBusPath, versionId, extVersion, status, associations,
Lei YUffb36532019-10-15 13:55:24 +080090 filePath, &mockedAssociationInterface, &mockedActivationListener);
Lei YU12c9f4c2019-09-11 15:08:15 +080091}
92
Lei YU58c26e32019-09-27 17:52:06 +080093TEST_F(TestActivation, ctorWithInvalidExtVersion)
94{
95 extVersion = "invalid text";
96 activation = std::make_unique<Activation>(
97 mockedBus, dBusPath, versionId, extVersion, status, associations,
Lei YUffb36532019-10-15 13:55:24 +080098 filePath, &mockedAssociationInterface, &mockedActivationListener);
Lei YU58c26e32019-09-27 17:52:06 +080099}
100
Lei YU12c9f4c2019-09-11 15:08:15 +0800101TEST_F(TestActivation, getUpdateService)
102{
103 std::string psuInventoryPath = "/com/example/inventory/powersupply1";
Lei YU12c9f4c2019-09-11 15:08:15 +0800104 std::string toCompare = "psu-update@-com-example-inventory-"
105 "powersupply1\\x20-tmp-images-12345678.service";
Lei YUe8945ea2019-09-29 17:25:31 +0800106 versionId = "12345678";
107 filePath = "/tmp/images/12345678";
Lei YU12c9f4c2019-09-11 15:08:15 +0800108
Lei YUe8945ea2019-09-29 17:25:31 +0800109 activation = std::make_unique<Activation>(
110 mockedBus, dBusPath, versionId, extVersion, status, associations,
Lei YUffb36532019-10-15 13:55:24 +0800111 filePath, &mockedAssociationInterface, &mockedActivationListener);
Lei YUe8945ea2019-09-29 17:25:31 +0800112
113 auto service = getUpdateService(psuInventoryPath);
Lei YU12c9f4c2019-09-11 15:08:15 +0800114 EXPECT_EQ(toCompare, service);
115}
Lei YUff83c2a2019-09-12 13:55:18 +0800116
117TEST_F(TestActivation, doUpdateWhenNoPSU)
118{
Lei YU99301372019-09-29 16:27:12 +0800119 activation = std::make_unique<Activation>(
120 mockedBus, dBusPath, versionId, extVersion, status, associations,
Lei YUffb36532019-10-15 13:55:24 +0800121 filePath, &mockedAssociationInterface, &mockedActivationListener);
Shawn McCarneyd57bd2f2024-12-02 18:40:28 -0600122 ON_CALL(mockedUtils, getPSUInventoryPaths(_))
Lei YUff83c2a2019-09-12 13:55:18 +0800123 .WillByDefault(
124 Return(std::vector<std::string>({}))); // No PSU inventory
125 activation->requestedActivation(RequestedStatus::Active);
126
Lei YU7f2a2152019-09-16 16:50:18 +0800127 EXPECT_CALL(mockedAssociationInterface, createActiveAssociation(dBusPath))
128 .Times(0);
129 EXPECT_CALL(mockedAssociationInterface, addFunctionalAssociation(dBusPath))
130 .Times(0);
Lei YUa8b966f2020-03-18 10:32:24 +0800131 EXPECT_CALL(mockedAssociationInterface, addUpdateableAssociation(dBusPath))
132 .Times(0);
Lei YUffb36532019-10-15 13:55:24 +0800133 EXPECT_CALL(mockedActivationListener, onUpdateDone(_, _)).Times(0);
Lei YUff83c2a2019-09-12 13:55:18 +0800134 EXPECT_EQ(Status::Failed, activation->activation());
135}
136
137TEST_F(TestActivation, doUpdateOnePSUOK)
138{
139 constexpr auto psu0 = "/com/example/inventory/psu0";
Lei YU99301372019-09-29 16:27:12 +0800140 activation = std::make_unique<Activation>(
141 mockedBus, dBusPath, versionId, extVersion, status, associations,
Lei YUffb36532019-10-15 13:55:24 +0800142 filePath, &mockedAssociationInterface, &mockedActivationListener);
Shawn McCarneyd57bd2f2024-12-02 18:40:28 -0600143 ON_CALL(mockedUtils, getPSUInventoryPaths(_))
Lei YUff83c2a2019-09-12 13:55:18 +0800144 .WillByDefault(
145 Return(std::vector<std::string>({psu0}))); // One PSU inventory
146 activation->requestedActivation(RequestedStatus::Active);
147
148 EXPECT_EQ(Status::Activating, activation->activation());
149
Lei YU7f2a2152019-09-16 16:50:18 +0800150 EXPECT_CALL(mockedAssociationInterface, createActiveAssociation(dBusPath))
151 .Times(1);
152 EXPECT_CALL(mockedAssociationInterface, addFunctionalAssociation(dBusPath))
153 .Times(1);
Lei YUa8b966f2020-03-18 10:32:24 +0800154 EXPECT_CALL(mockedAssociationInterface, addUpdateableAssociation(dBusPath))
155 .Times(1);
Lei YUffb36532019-10-15 13:55:24 +0800156 EXPECT_CALL(mockedActivationListener,
157 onUpdateDone(StrEq(versionId), StrEq(psu0)))
158 .Times(1);
Lei YUff83c2a2019-09-12 13:55:18 +0800159 onUpdateDone();
160 EXPECT_EQ(Status::Active, activation->activation());
161}
162
163TEST_F(TestActivation, doUpdateFourPSUsOK)
164{
165 constexpr auto psu0 = "/com/example/inventory/psu0";
166 constexpr auto psu1 = "/com/example/inventory/psu1";
167 constexpr auto psu2 = "/com/example/inventory/psu2";
168 constexpr auto psu3 = "/com/example/inventory/psu3";
Lei YU99301372019-09-29 16:27:12 +0800169 activation = std::make_unique<Activation>(
170 mockedBus, dBusPath, versionId, extVersion, status, associations,
Lei YUffb36532019-10-15 13:55:24 +0800171 filePath, &mockedAssociationInterface, &mockedActivationListener);
Shawn McCarneyd57bd2f2024-12-02 18:40:28 -0600172 ON_CALL(mockedUtils, getPSUInventoryPaths(_))
Lei YUff83c2a2019-09-12 13:55:18 +0800173 .WillByDefault(Return(
174 std::vector<std::string>({psu0, psu1, psu2, psu3}))); // 4 PSUs
175 activation->requestedActivation(RequestedStatus::Active);
176
177 EXPECT_EQ(Status::Activating, activation->activation());
178 EXPECT_EQ(10, getProgress());
179
Lei YUffb36532019-10-15 13:55:24 +0800180 EXPECT_CALL(mockedActivationListener,
181 onUpdateDone(StrEq(versionId), StrEq(psu0)))
182 .Times(1);
Lei YUff83c2a2019-09-12 13:55:18 +0800183 onUpdateDone();
184 EXPECT_EQ(Status::Activating, activation->activation());
185 EXPECT_EQ(30, getProgress());
186
Lei YUffb36532019-10-15 13:55:24 +0800187 EXPECT_CALL(mockedActivationListener,
188 onUpdateDone(StrEq(versionId), StrEq(psu1)))
189 .Times(1);
Lei YUff83c2a2019-09-12 13:55:18 +0800190 onUpdateDone();
191 EXPECT_EQ(Status::Activating, activation->activation());
192 EXPECT_EQ(50, getProgress());
193
Lei YUffb36532019-10-15 13:55:24 +0800194 EXPECT_CALL(mockedActivationListener,
195 onUpdateDone(StrEq(versionId), StrEq(psu2)))
196 .Times(1);
Lei YUff83c2a2019-09-12 13:55:18 +0800197 onUpdateDone();
198 EXPECT_EQ(Status::Activating, activation->activation());
199 EXPECT_EQ(70, getProgress());
200
Lei YU7f2a2152019-09-16 16:50:18 +0800201 EXPECT_CALL(mockedAssociationInterface, createActiveAssociation(dBusPath))
202 .Times(1);
203 EXPECT_CALL(mockedAssociationInterface, addFunctionalAssociation(dBusPath))
204 .Times(1);
Lei YUa8b966f2020-03-18 10:32:24 +0800205 EXPECT_CALL(mockedAssociationInterface, addUpdateableAssociation(dBusPath))
206 .Times(1);
Lei YU7f2a2152019-09-16 16:50:18 +0800207
Lei YUffb36532019-10-15 13:55:24 +0800208 EXPECT_CALL(mockedActivationListener,
209 onUpdateDone(StrEq(versionId), StrEq(psu3)))
210 .Times(1);
Lei YUff83c2a2019-09-12 13:55:18 +0800211 onUpdateDone();
212 EXPECT_EQ(Status::Active, activation->activation());
213}
214
215TEST_F(TestActivation, doUpdateFourPSUsFailonSecond)
216{
217 constexpr auto psu0 = "/com/example/inventory/psu0";
218 constexpr auto psu1 = "/com/example/inventory/psu1";
219 constexpr auto psu2 = "/com/example/inventory/psu2";
220 constexpr auto psu3 = "/com/example/inventory/psu3";
Lei YU99301372019-09-29 16:27:12 +0800221 activation = std::make_unique<Activation>(
222 mockedBus, dBusPath, versionId, extVersion, status, associations,
Lei YUffb36532019-10-15 13:55:24 +0800223 filePath, &mockedAssociationInterface, &mockedActivationListener);
Shawn McCarneyd57bd2f2024-12-02 18:40:28 -0600224 ON_CALL(mockedUtils, getPSUInventoryPaths(_))
Lei YUff83c2a2019-09-12 13:55:18 +0800225 .WillByDefault(Return(
226 std::vector<std::string>({psu0, psu1, psu2, psu3}))); // 4 PSUs
227 activation->requestedActivation(RequestedStatus::Active);
228
229 EXPECT_EQ(Status::Activating, activation->activation());
230 EXPECT_EQ(10, getProgress());
231
Lei YUffb36532019-10-15 13:55:24 +0800232 EXPECT_CALL(mockedActivationListener,
233 onUpdateDone(StrEq(versionId), StrEq(psu0)))
234 .Times(1);
Lei YUff83c2a2019-09-12 13:55:18 +0800235 onUpdateDone();
236 EXPECT_EQ(Status::Activating, activation->activation());
237 EXPECT_EQ(30, getProgress());
238
Lei YU7f2a2152019-09-16 16:50:18 +0800239 EXPECT_CALL(mockedAssociationInterface, createActiveAssociation(dBusPath))
240 .Times(0);
241 EXPECT_CALL(mockedAssociationInterface, addFunctionalAssociation(dBusPath))
242 .Times(0);
Lei YUa8b966f2020-03-18 10:32:24 +0800243 EXPECT_CALL(mockedAssociationInterface, addUpdateableAssociation(dBusPath))
244 .Times(0);
Lei YUffb36532019-10-15 13:55:24 +0800245 EXPECT_CALL(mockedActivationListener, onUpdateDone(_, _)).Times(0);
Lei YUff83c2a2019-09-12 13:55:18 +0800246 onUpdateFailed();
247 EXPECT_EQ(Status::Failed, activation->activation());
248}
249
250TEST_F(TestActivation, doUpdateOnExceptionFromDbus)
251{
252 constexpr auto psu0 = "/com/example/inventory/psu0";
Lei YU99301372019-09-29 16:27:12 +0800253 activation = std::make_unique<Activation>(
254 mockedBus, dBusPath, versionId, extVersion, status, associations,
Lei YUffb36532019-10-15 13:55:24 +0800255 filePath, &mockedAssociationInterface, &mockedActivationListener);
Shawn McCarneyd57bd2f2024-12-02 18:40:28 -0600256 ON_CALL(mockedUtils, getPSUInventoryPaths(_))
Lei YUff83c2a2019-09-12 13:55:18 +0800257 .WillByDefault(
258 Return(std::vector<std::string>({psu0}))); // One PSU inventory
259 ON_CALL(sdbusMock, sd_bus_call(_, _, _, _, nullptr))
260 .WillByDefault(Return(-1)); // Make sdbus call failure
261 activation->requestedActivation(RequestedStatus::Active);
262
263 EXPECT_EQ(Status::Failed, activation->activation());
264}
Lei YU9edb7332019-09-19 14:46:19 +0800265
Shawn McCarney46ea3882024-12-10 11:25:38 -0600266TEST_F(TestActivation, doUpdateOnePSUNotPresent)
267{
268 constexpr auto psu0 = "/com/example/inventory/psu0";
269 activation = std::make_unique<Activation>(
270 mockedBus, dBusPath, versionId, extVersion, status, associations,
271 filePath, &mockedAssociationInterface, &mockedActivationListener);
272 ON_CALL(mockedUtils, getPSUInventoryPaths(_))
273 .WillByDefault(Return(std::vector<std::string>({psu0})));
274 EXPECT_CALL(mockedUtils, getPropertyImpl(_, _, _, _, StrEq(PRESENT)))
275 .WillOnce(Return(any(PropertyType(false)))); // not present
276 activation->requestedActivation(RequestedStatus::Active);
277
278 EXPECT_EQ(Status::Ready, activation->activation());
279}
280
Lei YU9edb7332019-09-19 14:46:19 +0800281TEST_F(TestActivation, doUpdateOnePSUModelNotCompatible)
282{
283 constexpr auto psu0 = "/com/example/inventory/psu0";
284 extVersion = "manufacturer=TestManu,model=DifferentModel";
Lei YU99301372019-09-29 16:27:12 +0800285 activation = std::make_unique<Activation>(
286 mockedBus, dBusPath, versionId, extVersion, status, associations,
Lei YUffb36532019-10-15 13:55:24 +0800287 filePath, &mockedAssociationInterface, &mockedActivationListener);
Shawn McCarneyd57bd2f2024-12-02 18:40:28 -0600288 ON_CALL(mockedUtils, getPSUInventoryPaths(_))
Lei YU9edb7332019-09-19 14:46:19 +0800289 .WillByDefault(Return(std::vector<std::string>({psu0})));
290 activation->requestedActivation(RequestedStatus::Active);
291
Lei YU63f9e712019-10-12 15:16:55 +0800292 EXPECT_EQ(Status::Ready, activation->activation());
Lei YU9edb7332019-09-19 14:46:19 +0800293}
294
295TEST_F(TestActivation, doUpdateOnePSUManufactureNotCompatible)
296{
297 constexpr auto psu0 = "/com/example/inventory/psu0";
298 extVersion = "manufacturer=DifferentManu,model=TestModel";
Lei YU99301372019-09-29 16:27:12 +0800299 activation = std::make_unique<Activation>(
300 mockedBus, dBusPath, versionId, extVersion, status, associations,
Lei YUffb36532019-10-15 13:55:24 +0800301 filePath, &mockedAssociationInterface, &mockedActivationListener);
Shawn McCarneyd57bd2f2024-12-02 18:40:28 -0600302 ON_CALL(mockedUtils, getPSUInventoryPaths(_))
Lei YU9edb7332019-09-19 14:46:19 +0800303 .WillByDefault(Return(std::vector<std::string>({psu0})));
304 activation->requestedActivation(RequestedStatus::Active);
305
Lei YU63f9e712019-10-12 15:16:55 +0800306 EXPECT_EQ(Status::Ready, activation->activation());
Lei YU9edb7332019-09-19 14:46:19 +0800307}
308
309TEST_F(TestActivation, doUpdateOnePSUSelfManufactureIsEmpty)
310{
311 ON_CALL(mockedUtils, getPropertyImpl(_, _, _, _, StrEq(MANUFACTURER)))
312 .WillByDefault(Return(any(PropertyType(std::string("")))));
313 extVersion = "manufacturer=AnyManu,model=TestModel";
314 // Below is the same as doUpdateOnePSUOK case
315 constexpr auto psu0 = "/com/example/inventory/psu0";
Lei YU99301372019-09-29 16:27:12 +0800316 activation = std::make_unique<Activation>(
317 mockedBus, dBusPath, versionId, extVersion, status, associations,
Lei YUffb36532019-10-15 13:55:24 +0800318 filePath, &mockedAssociationInterface, &mockedActivationListener);
Shawn McCarneyd57bd2f2024-12-02 18:40:28 -0600319 ON_CALL(mockedUtils, getPSUInventoryPaths(_))
Lei YU9edb7332019-09-19 14:46:19 +0800320 .WillByDefault(
321 Return(std::vector<std::string>({psu0}))); // One PSU inventory
322 activation->requestedActivation(RequestedStatus::Active);
323
324 EXPECT_EQ(Status::Activating, activation->activation());
325
326 EXPECT_CALL(mockedAssociationInterface, createActiveAssociation(dBusPath))
327 .Times(1);
328 EXPECT_CALL(mockedAssociationInterface, addFunctionalAssociation(dBusPath))
329 .Times(1);
Lei YUa8b966f2020-03-18 10:32:24 +0800330 EXPECT_CALL(mockedAssociationInterface, addUpdateableAssociation(dBusPath))
331 .Times(1);
Lei YU9edb7332019-09-19 14:46:19 +0800332 onUpdateDone();
333 EXPECT_EQ(Status::Active, activation->activation());
334}
335
336TEST_F(TestActivation, doUpdateFourPSUsSecondPSUNotCompatible)
337{
338 constexpr auto psu0 = "/com/example/inventory/psu0";
339 constexpr auto psu1 = "/com/example/inventory/psu1";
340 constexpr auto psu2 = "/com/example/inventory/psu2";
341 constexpr auto psu3 = "/com/example/inventory/psu3";
Shawn McCarney783406e2024-11-17 21:49:37 -0600342 ON_CALL(mockedUtils, getModel(StrEq(psu1)))
343 .WillByDefault(Return(std::string("DifferentModel")));
Lei YU99301372019-09-29 16:27:12 +0800344 activation = std::make_unique<Activation>(
345 mockedBus, dBusPath, versionId, extVersion, status, associations,
Lei YUffb36532019-10-15 13:55:24 +0800346 filePath, &mockedAssociationInterface, &mockedActivationListener);
Shawn McCarneyd57bd2f2024-12-02 18:40:28 -0600347 ON_CALL(mockedUtils, getPSUInventoryPaths(_))
Lei YU9edb7332019-09-19 14:46:19 +0800348 .WillByDefault(Return(
349 std::vector<std::string>({psu0, psu1, psu2, psu3}))); // 4 PSUs
350 activation->requestedActivation(RequestedStatus::Active);
351
352 const auto& psuQueue = getPsuQueue();
George Liu22c2fbd2024-08-23 15:23:21 +0800353 EXPECT_EQ(3U, psuQueue.size());
Lei YU9edb7332019-09-19 14:46:19 +0800354
355 // Only 3 PSUs shall be updated, and psu1 shall be skipped
356 EXPECT_EQ(Status::Activating, activation->activation());
357 EXPECT_EQ(10, getProgress());
358
359 onUpdateDone();
360 EXPECT_EQ(Status::Activating, activation->activation());
361 EXPECT_EQ(36, getProgress());
362
363 onUpdateDone();
364 EXPECT_EQ(Status::Activating, activation->activation());
365 EXPECT_EQ(62, getProgress());
366
367 EXPECT_CALL(mockedAssociationInterface, createActiveAssociation(dBusPath))
368 .Times(1);
369 EXPECT_CALL(mockedAssociationInterface, addFunctionalAssociation(dBusPath))
370 .Times(1);
Lei YUa8b966f2020-03-18 10:32:24 +0800371 EXPECT_CALL(mockedAssociationInterface, addUpdateableAssociation(dBusPath))
372 .Times(1);
Lei YU9edb7332019-09-19 14:46:19 +0800373
374 onUpdateDone();
375 EXPECT_EQ(Status::Active, activation->activation());
376}
Lei YU63f9e712019-10-12 15:16:55 +0800377
378TEST_F(TestActivation, doUpdateWhenNoFilePathInActiveState)
379{
380 filePath = "";
381 status = Status::Active; // Typically, a running PSU software is active
382 // without file path
383 constexpr auto psu0 = "/com/example/inventory/psu0";
384 activation = std::make_unique<Activation>(
385 mockedBus, dBusPath, versionId, extVersion, status, associations,
Lei YUffb36532019-10-15 13:55:24 +0800386 filePath, &mockedAssociationInterface, &mockedActivationListener);
Lei YU63f9e712019-10-12 15:16:55 +0800387
Shawn McCarneyd57bd2f2024-12-02 18:40:28 -0600388 ON_CALL(mockedUtils, getPSUInventoryPaths(_))
Lei YU63f9e712019-10-12 15:16:55 +0800389 .WillByDefault(
390 Return(std::vector<std::string>({psu0}))); // One PSU inventory
391
392 // There shall be no DBus call to start update service
393 EXPECT_CALL(sdbusMock, sd_bus_message_new_method_call(_, _, _, _, _,
394 StrEq("StartUnit")))
395 .Times(0);
396
397 activation->requestedActivation(RequestedStatus::Active);
398 EXPECT_EQ(Status::Active, activation->activation());
399}
400
401TEST_F(TestActivation, doUpdateWhenNoFilePathInReadyState)
402{
403 filePath = "";
404 status = Status::Ready; // Usually a Ready activation should have file path,
405 // but we are testing this case as well
406 constexpr auto psu0 = "/com/example/inventory/psu0";
407 activation = std::make_unique<Activation>(
408 mockedBus, dBusPath, versionId, extVersion, status, associations,
Lei YUffb36532019-10-15 13:55:24 +0800409 filePath, &mockedAssociationInterface, &mockedActivationListener);
Lei YU63f9e712019-10-12 15:16:55 +0800410
Shawn McCarneyd57bd2f2024-12-02 18:40:28 -0600411 ON_CALL(mockedUtils, getPSUInventoryPaths(_))
Lei YU63f9e712019-10-12 15:16:55 +0800412 .WillByDefault(
413 Return(std::vector<std::string>({psu0}))); // One PSU inventory
414
415 // There shall be no DBus call to start update service
416 EXPECT_CALL(sdbusMock, sd_bus_message_new_method_call(_, _, _, _, _,
417 StrEq("StartUnit")))
418 .Times(0);
419
420 activation->requestedActivation(RequestedStatus::Active);
421 EXPECT_EQ(Status::Ready, activation->activation());
422}
423
424TEST_F(TestActivation, doUpdateWhenPSUIsAssociated)
425{
426 constexpr auto psu0 = "/com/example/inventory/psu0";
427 status = Status::Active; // Typically, a running PSU software is associated
428 activation = std::make_unique<Activation>(
429 mockedBus, dBusPath, versionId, extVersion, status, associations,
Lei YUffb36532019-10-15 13:55:24 +0800430 filePath, &mockedAssociationInterface, &mockedActivationListener);
Lei YU63f9e712019-10-12 15:16:55 +0800431
Shawn McCarneyd57bd2f2024-12-02 18:40:28 -0600432 ON_CALL(mockedUtils, getPSUInventoryPaths(_))
Lei YU63f9e712019-10-12 15:16:55 +0800433 .WillByDefault(
434 Return(std::vector<std::string>({psu0}))); // One PSU inventory
435
436 // When PSU is already associated, there shall be no DBus call to start
437 // update service
438 EXPECT_CALL(mockedUtils, isAssociated(StrEq(psu0), _))
439 .WillOnce(Return(true));
440 EXPECT_CALL(sdbusMock, sd_bus_message_new_method_call(_, _, _, _, _,
441 StrEq("StartUnit")))
442 .Times(0);
443
444 activation->requestedActivation(RequestedStatus::Active);
445 EXPECT_EQ(Status::Active, activation->activation());
446}