blob: 273f132b3b8d450d990bdf81a3f855066ebb6491 [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 {
Lei YU9edb7332019-09-19 14:46:19 +080035 // By default make it compatible with the test software
36 ON_CALL(mockedUtils, getPropertyImpl(_, _, _, _, StrEq(MANUFACTURER)))
37 .WillByDefault(Return(any(PropertyType(std::string("TestManu")))));
Shawn McCarney783406e2024-11-17 21:49:37 -060038 ON_CALL(mockedUtils, getModel(_))
39 .WillByDefault(Return(std::string("TestModel")));
Lei YU63f9e712019-10-12 15:16:55 +080040 ON_CALL(mockedUtils, isAssociated(_, _)).WillByDefault(Return(false));
Lei YU12c9f4c2019-09-11 15:08:15 +080041 }
George Liu047d9942024-08-23 13:44:31 +080042 ~TestActivation() override
Lei YU12c9f4c2019-09-11 15:08:15 +080043 {
Lei YUc09155b2019-10-11 17:30:48 +080044 utils::freeUtils();
Lei YU12c9f4c2019-09-11 15:08:15 +080045 }
Lei YUff83c2a2019-09-12 13:55:18 +080046
George Liu71ae5352024-08-23 15:21:05 +080047 void onUpdateDone() const
Lei YUff83c2a2019-09-12 13:55:18 +080048 {
49 activation->onUpdateDone();
50 }
George Liu71ae5352024-08-23 15:21:05 +080051 void onUpdateFailed() const
Lei YUff83c2a2019-09-12 13:55:18 +080052 {
53 activation->onUpdateFailed();
54 }
George Liu71ae5352024-08-23 15:21:05 +080055 int getProgress() const
Lei YUff83c2a2019-09-12 13:55:18 +080056 {
57 return activation->activationProgress->progress();
58 }
George Liu71ae5352024-08-23 15:21:05 +080059 const auto& getPsuQueue() const
Lei YU9edb7332019-09-19 14:46:19 +080060 {
61 return activation->psuQueue;
62 }
George Liu71ae5352024-08-23 15:21:05 +080063 std::string getUpdateService(const std::string& psuInventoryPath) const
Lei YUe8945ea2019-09-29 17:25:31 +080064 {
65 return activation->getUpdateService(psuInventoryPath);
66 }
Lei YU9edb7332019-09-19 14:46:19 +080067
Lei YU12c9f4c2019-09-11 15:08:15 +080068 sdbusplus::SdBusMock sdbusMock;
Patrick Williams374fae52022-07-22 19:26:55 -050069 sdbusplus::bus_t mockedBus = sdbusplus::get_mocked_new(&sdbusMock);
Lei YUff83c2a2019-09-12 13:55:18 +080070 const utils::MockedUtils& mockedUtils;
Lei YU7f2a2152019-09-16 16:50:18 +080071 MockedAssociationInterface mockedAssociationInterface;
Lei YUffb36532019-10-15 13:55:24 +080072 MockedActivationListener mockedActivationListener;
Lei YU12c9f4c2019-09-11 15:08:15 +080073 std::unique_ptr<Activation> activation;
74 std::string versionId = "abcdefgh";
Lei YU9edb7332019-09-19 14:46:19 +080075 std::string extVersion = "manufacturer=TestManu,model=TestModel";
Lei YU63f9e712019-10-12 15:16:55 +080076 std::string filePath = "/tmp/images/abcdefgh";
Lei YU7f2a2152019-09-16 16:50:18 +080077 std::string dBusPath = std::string(SOFTWARE_OBJPATH) + "/" + versionId;
Lei YUff83c2a2019-09-12 13:55:18 +080078 Status status = Status::Ready;
Lei YU12c9f4c2019-09-11 15:08:15 +080079 AssociationList associations;
80};
81
82TEST_F(TestActivation, ctordtor)
83{
Lei YU99301372019-09-29 16:27:12 +080084 activation = std::make_unique<Activation>(
85 mockedBus, dBusPath, versionId, extVersion, status, associations,
Lei YUffb36532019-10-15 13:55:24 +080086 filePath, &mockedAssociationInterface, &mockedActivationListener);
Lei YU12c9f4c2019-09-11 15:08:15 +080087}
88
Lei YU58c26e32019-09-27 17:52:06 +080089TEST_F(TestActivation, ctorWithInvalidExtVersion)
90{
91 extVersion = "invalid text";
92 activation = std::make_unique<Activation>(
93 mockedBus, dBusPath, versionId, extVersion, status, associations,
Lei YUffb36532019-10-15 13:55:24 +080094 filePath, &mockedAssociationInterface, &mockedActivationListener);
Lei YU58c26e32019-09-27 17:52:06 +080095}
96
Lei YU12c9f4c2019-09-11 15:08:15 +080097TEST_F(TestActivation, getUpdateService)
98{
99 std::string psuInventoryPath = "/com/example/inventory/powersupply1";
Lei YU12c9f4c2019-09-11 15:08:15 +0800100 std::string toCompare = "psu-update@-com-example-inventory-"
101 "powersupply1\\x20-tmp-images-12345678.service";
Lei YUe8945ea2019-09-29 17:25:31 +0800102 versionId = "12345678";
103 filePath = "/tmp/images/12345678";
Lei YU12c9f4c2019-09-11 15:08:15 +0800104
Lei YUe8945ea2019-09-29 17:25:31 +0800105 activation = std::make_unique<Activation>(
106 mockedBus, dBusPath, versionId, extVersion, status, associations,
Lei YUffb36532019-10-15 13:55:24 +0800107 filePath, &mockedAssociationInterface, &mockedActivationListener);
Lei YUe8945ea2019-09-29 17:25:31 +0800108
109 auto service = getUpdateService(psuInventoryPath);
Lei YU12c9f4c2019-09-11 15:08:15 +0800110 EXPECT_EQ(toCompare, service);
111}
Lei YUff83c2a2019-09-12 13:55:18 +0800112
113TEST_F(TestActivation, doUpdateWhenNoPSU)
114{
Lei YU99301372019-09-29 16:27:12 +0800115 activation = std::make_unique<Activation>(
116 mockedBus, dBusPath, versionId, extVersion, status, associations,
Lei YUffb36532019-10-15 13:55:24 +0800117 filePath, &mockedAssociationInterface, &mockedActivationListener);
Shawn McCarneyd57bd2f2024-12-02 18:40:28 -0600118 ON_CALL(mockedUtils, getPSUInventoryPaths(_))
Lei YUff83c2a2019-09-12 13:55:18 +0800119 .WillByDefault(
120 Return(std::vector<std::string>({}))); // No PSU inventory
121 activation->requestedActivation(RequestedStatus::Active);
122
Lei YU7f2a2152019-09-16 16:50:18 +0800123 EXPECT_CALL(mockedAssociationInterface, createActiveAssociation(dBusPath))
124 .Times(0);
125 EXPECT_CALL(mockedAssociationInterface, addFunctionalAssociation(dBusPath))
126 .Times(0);
Lei YUa8b966f2020-03-18 10:32:24 +0800127 EXPECT_CALL(mockedAssociationInterface, addUpdateableAssociation(dBusPath))
128 .Times(0);
Lei YUffb36532019-10-15 13:55:24 +0800129 EXPECT_CALL(mockedActivationListener, onUpdateDone(_, _)).Times(0);
Lei YUff83c2a2019-09-12 13:55:18 +0800130 EXPECT_EQ(Status::Failed, activation->activation());
131}
132
133TEST_F(TestActivation, doUpdateOnePSUOK)
134{
135 constexpr auto psu0 = "/com/example/inventory/psu0";
Lei YU99301372019-09-29 16:27:12 +0800136 activation = std::make_unique<Activation>(
137 mockedBus, dBusPath, versionId, extVersion, status, associations,
Lei YUffb36532019-10-15 13:55:24 +0800138 filePath, &mockedAssociationInterface, &mockedActivationListener);
Shawn McCarneyd57bd2f2024-12-02 18:40:28 -0600139 ON_CALL(mockedUtils, getPSUInventoryPaths(_))
Lei YUff83c2a2019-09-12 13:55:18 +0800140 .WillByDefault(
141 Return(std::vector<std::string>({psu0}))); // One PSU inventory
142 activation->requestedActivation(RequestedStatus::Active);
143
144 EXPECT_EQ(Status::Activating, activation->activation());
145
Lei YU7f2a2152019-09-16 16:50:18 +0800146 EXPECT_CALL(mockedAssociationInterface, createActiveAssociation(dBusPath))
147 .Times(1);
148 EXPECT_CALL(mockedAssociationInterface, addFunctionalAssociation(dBusPath))
149 .Times(1);
Lei YUa8b966f2020-03-18 10:32:24 +0800150 EXPECT_CALL(mockedAssociationInterface, addUpdateableAssociation(dBusPath))
151 .Times(1);
Lei YUffb36532019-10-15 13:55:24 +0800152 EXPECT_CALL(mockedActivationListener,
153 onUpdateDone(StrEq(versionId), StrEq(psu0)))
154 .Times(1);
Lei YUff83c2a2019-09-12 13:55:18 +0800155 onUpdateDone();
156 EXPECT_EQ(Status::Active, activation->activation());
157}
158
159TEST_F(TestActivation, doUpdateFourPSUsOK)
160{
161 constexpr auto psu0 = "/com/example/inventory/psu0";
162 constexpr auto psu1 = "/com/example/inventory/psu1";
163 constexpr auto psu2 = "/com/example/inventory/psu2";
164 constexpr auto psu3 = "/com/example/inventory/psu3";
Lei YU99301372019-09-29 16:27:12 +0800165 activation = std::make_unique<Activation>(
166 mockedBus, dBusPath, versionId, extVersion, status, associations,
Lei YUffb36532019-10-15 13:55:24 +0800167 filePath, &mockedAssociationInterface, &mockedActivationListener);
Shawn McCarneyd57bd2f2024-12-02 18:40:28 -0600168 ON_CALL(mockedUtils, getPSUInventoryPaths(_))
Lei YUff83c2a2019-09-12 13:55:18 +0800169 .WillByDefault(Return(
170 std::vector<std::string>({psu0, psu1, psu2, psu3}))); // 4 PSUs
171 activation->requestedActivation(RequestedStatus::Active);
172
173 EXPECT_EQ(Status::Activating, activation->activation());
174 EXPECT_EQ(10, getProgress());
175
Lei YUffb36532019-10-15 13:55:24 +0800176 EXPECT_CALL(mockedActivationListener,
177 onUpdateDone(StrEq(versionId), StrEq(psu0)))
178 .Times(1);
Lei YUff83c2a2019-09-12 13:55:18 +0800179 onUpdateDone();
180 EXPECT_EQ(Status::Activating, activation->activation());
181 EXPECT_EQ(30, getProgress());
182
Lei YUffb36532019-10-15 13:55:24 +0800183 EXPECT_CALL(mockedActivationListener,
184 onUpdateDone(StrEq(versionId), StrEq(psu1)))
185 .Times(1);
Lei YUff83c2a2019-09-12 13:55:18 +0800186 onUpdateDone();
187 EXPECT_EQ(Status::Activating, activation->activation());
188 EXPECT_EQ(50, getProgress());
189
Lei YUffb36532019-10-15 13:55:24 +0800190 EXPECT_CALL(mockedActivationListener,
191 onUpdateDone(StrEq(versionId), StrEq(psu2)))
192 .Times(1);
Lei YUff83c2a2019-09-12 13:55:18 +0800193 onUpdateDone();
194 EXPECT_EQ(Status::Activating, activation->activation());
195 EXPECT_EQ(70, getProgress());
196
Lei YU7f2a2152019-09-16 16:50:18 +0800197 EXPECT_CALL(mockedAssociationInterface, createActiveAssociation(dBusPath))
198 .Times(1);
199 EXPECT_CALL(mockedAssociationInterface, addFunctionalAssociation(dBusPath))
200 .Times(1);
Lei YUa8b966f2020-03-18 10:32:24 +0800201 EXPECT_CALL(mockedAssociationInterface, addUpdateableAssociation(dBusPath))
202 .Times(1);
Lei YU7f2a2152019-09-16 16:50:18 +0800203
Lei YUffb36532019-10-15 13:55:24 +0800204 EXPECT_CALL(mockedActivationListener,
205 onUpdateDone(StrEq(versionId), StrEq(psu3)))
206 .Times(1);
Lei YUff83c2a2019-09-12 13:55:18 +0800207 onUpdateDone();
208 EXPECT_EQ(Status::Active, activation->activation());
209}
210
211TEST_F(TestActivation, doUpdateFourPSUsFailonSecond)
212{
213 constexpr auto psu0 = "/com/example/inventory/psu0";
214 constexpr auto psu1 = "/com/example/inventory/psu1";
215 constexpr auto psu2 = "/com/example/inventory/psu2";
216 constexpr auto psu3 = "/com/example/inventory/psu3";
Lei YU99301372019-09-29 16:27:12 +0800217 activation = std::make_unique<Activation>(
218 mockedBus, dBusPath, versionId, extVersion, status, associations,
Lei YUffb36532019-10-15 13:55:24 +0800219 filePath, &mockedAssociationInterface, &mockedActivationListener);
Shawn McCarneyd57bd2f2024-12-02 18:40:28 -0600220 ON_CALL(mockedUtils, getPSUInventoryPaths(_))
Lei YUff83c2a2019-09-12 13:55:18 +0800221 .WillByDefault(Return(
222 std::vector<std::string>({psu0, psu1, psu2, psu3}))); // 4 PSUs
223 activation->requestedActivation(RequestedStatus::Active);
224
225 EXPECT_EQ(Status::Activating, activation->activation());
226 EXPECT_EQ(10, getProgress());
227
Lei YUffb36532019-10-15 13:55:24 +0800228 EXPECT_CALL(mockedActivationListener,
229 onUpdateDone(StrEq(versionId), StrEq(psu0)))
230 .Times(1);
Lei YUff83c2a2019-09-12 13:55:18 +0800231 onUpdateDone();
232 EXPECT_EQ(Status::Activating, activation->activation());
233 EXPECT_EQ(30, getProgress());
234
Lei YU7f2a2152019-09-16 16:50:18 +0800235 EXPECT_CALL(mockedAssociationInterface, createActiveAssociation(dBusPath))
236 .Times(0);
237 EXPECT_CALL(mockedAssociationInterface, addFunctionalAssociation(dBusPath))
238 .Times(0);
Lei YUa8b966f2020-03-18 10:32:24 +0800239 EXPECT_CALL(mockedAssociationInterface, addUpdateableAssociation(dBusPath))
240 .Times(0);
Lei YUffb36532019-10-15 13:55:24 +0800241 EXPECT_CALL(mockedActivationListener, onUpdateDone(_, _)).Times(0);
Lei YUff83c2a2019-09-12 13:55:18 +0800242 onUpdateFailed();
243 EXPECT_EQ(Status::Failed, activation->activation());
244}
245
246TEST_F(TestActivation, doUpdateOnExceptionFromDbus)
247{
248 constexpr auto psu0 = "/com/example/inventory/psu0";
Lei YU99301372019-09-29 16:27:12 +0800249 activation = std::make_unique<Activation>(
250 mockedBus, dBusPath, versionId, extVersion, status, associations,
Lei YUffb36532019-10-15 13:55:24 +0800251 filePath, &mockedAssociationInterface, &mockedActivationListener);
Shawn McCarneyd57bd2f2024-12-02 18:40:28 -0600252 ON_CALL(mockedUtils, getPSUInventoryPaths(_))
Lei YUff83c2a2019-09-12 13:55:18 +0800253 .WillByDefault(
254 Return(std::vector<std::string>({psu0}))); // One PSU inventory
255 ON_CALL(sdbusMock, sd_bus_call(_, _, _, _, nullptr))
256 .WillByDefault(Return(-1)); // Make sdbus call failure
257 activation->requestedActivation(RequestedStatus::Active);
258
259 EXPECT_EQ(Status::Failed, activation->activation());
260}
Lei YU9edb7332019-09-19 14:46:19 +0800261
262TEST_F(TestActivation, doUpdateOnePSUModelNotCompatible)
263{
264 constexpr auto psu0 = "/com/example/inventory/psu0";
265 extVersion = "manufacturer=TestManu,model=DifferentModel";
Lei YU99301372019-09-29 16:27:12 +0800266 activation = std::make_unique<Activation>(
267 mockedBus, dBusPath, versionId, extVersion, status, associations,
Lei YUffb36532019-10-15 13:55:24 +0800268 filePath, &mockedAssociationInterface, &mockedActivationListener);
Shawn McCarneyd57bd2f2024-12-02 18:40:28 -0600269 ON_CALL(mockedUtils, getPSUInventoryPaths(_))
Lei YU9edb7332019-09-19 14:46:19 +0800270 .WillByDefault(Return(std::vector<std::string>({psu0})));
271 activation->requestedActivation(RequestedStatus::Active);
272
Lei YU63f9e712019-10-12 15:16:55 +0800273 EXPECT_EQ(Status::Ready, activation->activation());
Lei YU9edb7332019-09-19 14:46:19 +0800274}
275
276TEST_F(TestActivation, doUpdateOnePSUManufactureNotCompatible)
277{
278 constexpr auto psu0 = "/com/example/inventory/psu0";
279 extVersion = "manufacturer=DifferentManu,model=TestModel";
Lei YU99301372019-09-29 16:27:12 +0800280 activation = std::make_unique<Activation>(
281 mockedBus, dBusPath, versionId, extVersion, status, associations,
Lei YUffb36532019-10-15 13:55:24 +0800282 filePath, &mockedAssociationInterface, &mockedActivationListener);
Shawn McCarneyd57bd2f2024-12-02 18:40:28 -0600283 ON_CALL(mockedUtils, getPSUInventoryPaths(_))
Lei YU9edb7332019-09-19 14:46:19 +0800284 .WillByDefault(Return(std::vector<std::string>({psu0})));
285 activation->requestedActivation(RequestedStatus::Active);
286
Lei YU63f9e712019-10-12 15:16:55 +0800287 EXPECT_EQ(Status::Ready, activation->activation());
Lei YU9edb7332019-09-19 14:46:19 +0800288}
289
290TEST_F(TestActivation, doUpdateOnePSUSelfManufactureIsEmpty)
291{
292 ON_CALL(mockedUtils, getPropertyImpl(_, _, _, _, StrEq(MANUFACTURER)))
293 .WillByDefault(Return(any(PropertyType(std::string("")))));
294 extVersion = "manufacturer=AnyManu,model=TestModel";
295 // Below is the same as doUpdateOnePSUOK case
296 constexpr auto psu0 = "/com/example/inventory/psu0";
Lei YU99301372019-09-29 16:27:12 +0800297 activation = std::make_unique<Activation>(
298 mockedBus, dBusPath, versionId, extVersion, status, associations,
Lei YUffb36532019-10-15 13:55:24 +0800299 filePath, &mockedAssociationInterface, &mockedActivationListener);
Shawn McCarneyd57bd2f2024-12-02 18:40:28 -0600300 ON_CALL(mockedUtils, getPSUInventoryPaths(_))
Lei YU9edb7332019-09-19 14:46:19 +0800301 .WillByDefault(
302 Return(std::vector<std::string>({psu0}))); // One PSU inventory
303 activation->requestedActivation(RequestedStatus::Active);
304
305 EXPECT_EQ(Status::Activating, activation->activation());
306
307 EXPECT_CALL(mockedAssociationInterface, createActiveAssociation(dBusPath))
308 .Times(1);
309 EXPECT_CALL(mockedAssociationInterface, addFunctionalAssociation(dBusPath))
310 .Times(1);
Lei YUa8b966f2020-03-18 10:32:24 +0800311 EXPECT_CALL(mockedAssociationInterface, addUpdateableAssociation(dBusPath))
312 .Times(1);
Lei YU9edb7332019-09-19 14:46:19 +0800313 onUpdateDone();
314 EXPECT_EQ(Status::Active, activation->activation());
315}
316
317TEST_F(TestActivation, doUpdateFourPSUsSecondPSUNotCompatible)
318{
319 constexpr auto psu0 = "/com/example/inventory/psu0";
320 constexpr auto psu1 = "/com/example/inventory/psu1";
321 constexpr auto psu2 = "/com/example/inventory/psu2";
322 constexpr auto psu3 = "/com/example/inventory/psu3";
Shawn McCarney783406e2024-11-17 21:49:37 -0600323 ON_CALL(mockedUtils, getModel(StrEq(psu1)))
324 .WillByDefault(Return(std::string("DifferentModel")));
Lei YU99301372019-09-29 16:27:12 +0800325 activation = std::make_unique<Activation>(
326 mockedBus, dBusPath, versionId, extVersion, status, associations,
Lei YUffb36532019-10-15 13:55:24 +0800327 filePath, &mockedAssociationInterface, &mockedActivationListener);
Shawn McCarneyd57bd2f2024-12-02 18:40:28 -0600328 ON_CALL(mockedUtils, getPSUInventoryPaths(_))
Lei YU9edb7332019-09-19 14:46:19 +0800329 .WillByDefault(Return(
330 std::vector<std::string>({psu0, psu1, psu2, psu3}))); // 4 PSUs
331 activation->requestedActivation(RequestedStatus::Active);
332
333 const auto& psuQueue = getPsuQueue();
George Liu22c2fbd2024-08-23 15:23:21 +0800334 EXPECT_EQ(3U, psuQueue.size());
Lei YU9edb7332019-09-19 14:46:19 +0800335
336 // Only 3 PSUs shall be updated, and psu1 shall be skipped
337 EXPECT_EQ(Status::Activating, activation->activation());
338 EXPECT_EQ(10, getProgress());
339
340 onUpdateDone();
341 EXPECT_EQ(Status::Activating, activation->activation());
342 EXPECT_EQ(36, getProgress());
343
344 onUpdateDone();
345 EXPECT_EQ(Status::Activating, activation->activation());
346 EXPECT_EQ(62, getProgress());
347
348 EXPECT_CALL(mockedAssociationInterface, createActiveAssociation(dBusPath))
349 .Times(1);
350 EXPECT_CALL(mockedAssociationInterface, addFunctionalAssociation(dBusPath))
351 .Times(1);
Lei YUa8b966f2020-03-18 10:32:24 +0800352 EXPECT_CALL(mockedAssociationInterface, addUpdateableAssociation(dBusPath))
353 .Times(1);
Lei YU9edb7332019-09-19 14:46:19 +0800354
355 onUpdateDone();
356 EXPECT_EQ(Status::Active, activation->activation());
357}
Lei YU63f9e712019-10-12 15:16:55 +0800358
359TEST_F(TestActivation, doUpdateWhenNoFilePathInActiveState)
360{
361 filePath = "";
362 status = Status::Active; // Typically, a running PSU software is active
363 // without file path
364 constexpr auto psu0 = "/com/example/inventory/psu0";
365 activation = std::make_unique<Activation>(
366 mockedBus, dBusPath, versionId, extVersion, status, associations,
Lei YUffb36532019-10-15 13:55:24 +0800367 filePath, &mockedAssociationInterface, &mockedActivationListener);
Lei YU63f9e712019-10-12 15:16:55 +0800368
Shawn McCarneyd57bd2f2024-12-02 18:40:28 -0600369 ON_CALL(mockedUtils, getPSUInventoryPaths(_))
Lei YU63f9e712019-10-12 15:16:55 +0800370 .WillByDefault(
371 Return(std::vector<std::string>({psu0}))); // One PSU inventory
372
373 // There shall be no DBus call to start update service
374 EXPECT_CALL(sdbusMock, sd_bus_message_new_method_call(_, _, _, _, _,
375 StrEq("StartUnit")))
376 .Times(0);
377
378 activation->requestedActivation(RequestedStatus::Active);
379 EXPECT_EQ(Status::Active, activation->activation());
380}
381
382TEST_F(TestActivation, doUpdateWhenNoFilePathInReadyState)
383{
384 filePath = "";
385 status = Status::Ready; // Usually a Ready activation should have file path,
386 // but we are testing this case as well
387 constexpr auto psu0 = "/com/example/inventory/psu0";
388 activation = std::make_unique<Activation>(
389 mockedBus, dBusPath, versionId, extVersion, status, associations,
Lei YUffb36532019-10-15 13:55:24 +0800390 filePath, &mockedAssociationInterface, &mockedActivationListener);
Lei YU63f9e712019-10-12 15:16:55 +0800391
Shawn McCarneyd57bd2f2024-12-02 18:40:28 -0600392 ON_CALL(mockedUtils, getPSUInventoryPaths(_))
Lei YU63f9e712019-10-12 15:16:55 +0800393 .WillByDefault(
394 Return(std::vector<std::string>({psu0}))); // One PSU inventory
395
396 // There shall be no DBus call to start update service
397 EXPECT_CALL(sdbusMock, sd_bus_message_new_method_call(_, _, _, _, _,
398 StrEq("StartUnit")))
399 .Times(0);
400
401 activation->requestedActivation(RequestedStatus::Active);
402 EXPECT_EQ(Status::Ready, activation->activation());
403}
404
405TEST_F(TestActivation, doUpdateWhenPSUIsAssociated)
406{
407 constexpr auto psu0 = "/com/example/inventory/psu0";
408 status = Status::Active; // Typically, a running PSU software is associated
409 activation = std::make_unique<Activation>(
410 mockedBus, dBusPath, versionId, extVersion, status, associations,
Lei YUffb36532019-10-15 13:55:24 +0800411 filePath, &mockedAssociationInterface, &mockedActivationListener);
Lei YU63f9e712019-10-12 15:16:55 +0800412
Shawn McCarneyd57bd2f2024-12-02 18:40:28 -0600413 ON_CALL(mockedUtils, getPSUInventoryPaths(_))
Lei YU63f9e712019-10-12 15:16:55 +0800414 .WillByDefault(
415 Return(std::vector<std::string>({psu0}))); // One PSU inventory
416
417 // When PSU is already associated, there shall be no DBus call to start
418 // update service
419 EXPECT_CALL(mockedUtils, isAssociated(StrEq(psu0), _))
420 .WillOnce(Return(true));
421 EXPECT_CALL(sdbusMock, sd_bus_message_new_method_call(_, _, _, _, _,
422 StrEq("StartUnit")))
423 .Times(0);
424
425 activation->requestedActivation(RequestedStatus::Active);
426 EXPECT_EQ(Status::Active, activation->activation());
427}