blob: 891cdb6c70a8eec8721ac7a77a88a9c76d7abfe7 [file] [log] [blame]
Lei YU12c9f4c2019-09-11 15:08:15 +08001#include "activation.hpp"
Lei YU7f2a2152019-09-16 16:50:18 +08002#include "mocked_association_interface.hpp"
Lei YUff83c2a2019-09-12 13:55:18 +08003#include "mocked_utils.hpp"
Lei YU12c9f4c2019-09-11 15:08:15 +08004
5#include <sdbusplus/test/sdbus_mock.hpp>
6
7#include <gmock/gmock.h>
8#include <gtest/gtest.h>
9
10using namespace phosphor::software::updater;
11
Lei YUff83c2a2019-09-12 13:55:18 +080012using ::testing::_;
13using ::testing::Return;
14
Lei YU12c9f4c2019-09-11 15:08:15 +080015class TestActivation : public ::testing::Test
16{
17 public:
Lei YUff83c2a2019-09-12 13:55:18 +080018 using Status = Activation::Status;
19 using RequestedStatus = Activation::RequestedActivations;
20 TestActivation() :
21 mockedUtils(
22 reinterpret_cast<const utils::MockedUtils&>(utils::getUtils()))
Lei YU12c9f4c2019-09-11 15:08:15 +080023 {
24 }
25 ~TestActivation()
26 {
27 }
Lei YUff83c2a2019-09-12 13:55:18 +080028
29 void onUpdateDone()
30 {
31 activation->onUpdateDone();
32 }
33 void onUpdateFailed()
34 {
35 activation->onUpdateFailed();
36 }
37 int getProgress()
38 {
39 return activation->activationProgress->progress();
40 }
Lei YU12c9f4c2019-09-11 15:08:15 +080041 sdbusplus::SdBusMock sdbusMock;
42 sdbusplus::bus::bus mockedBus = sdbusplus::get_mocked_new(&sdbusMock);
Lei YUff83c2a2019-09-12 13:55:18 +080043 const utils::MockedUtils& mockedUtils;
Lei YU7f2a2152019-09-16 16:50:18 +080044 MockedAssociationInterface mockedAssociationInterface;
Lei YU12c9f4c2019-09-11 15:08:15 +080045 std::unique_ptr<Activation> activation;
46 std::string versionId = "abcdefgh";
47 std::string extVersion = "Some Ext Version";
Lei YU7f2a2152019-09-16 16:50:18 +080048 std::string dBusPath = std::string(SOFTWARE_OBJPATH) + "/" + versionId;
Lei YUff83c2a2019-09-12 13:55:18 +080049 Status status = Status::Ready;
Lei YU12c9f4c2019-09-11 15:08:15 +080050 AssociationList associations;
51};
52
53TEST_F(TestActivation, ctordtor)
54{
55 activation = std::make_unique<Activation>(mockedBus, dBusPath, versionId,
Lei YU7f2a2152019-09-16 16:50:18 +080056 extVersion, status, associations,
57 &mockedAssociationInterface);
Lei YU12c9f4c2019-09-11 15:08:15 +080058}
59
60namespace phosphor::software::updater::internal
61{
62extern std::string getUpdateService(const std::string& psuInventoryPath,
63 const std::string& versionId);
64}
65
66TEST_F(TestActivation, getUpdateService)
67{
68 std::string psuInventoryPath = "/com/example/inventory/powersupply1";
69 std::string versionId = "12345678";
70 std::string toCompare = "psu-update@-com-example-inventory-"
71 "powersupply1\\x20-tmp-images-12345678.service";
72
73 auto service = phosphor::software::updater::internal::getUpdateService(
74 psuInventoryPath, versionId);
75 EXPECT_EQ(toCompare, service);
76}
Lei YUff83c2a2019-09-12 13:55:18 +080077
78TEST_F(TestActivation, doUpdateWhenNoPSU)
79{
80 activation = std::make_unique<Activation>(mockedBus, dBusPath, versionId,
Lei YU7f2a2152019-09-16 16:50:18 +080081 extVersion, status, associations,
82 &mockedAssociationInterface);
Lei YUff83c2a2019-09-12 13:55:18 +080083 ON_CALL(mockedUtils, getPSUInventoryPath(_))
84 .WillByDefault(
85 Return(std::vector<std::string>({}))); // No PSU inventory
86 activation->requestedActivation(RequestedStatus::Active);
87
Lei YU7f2a2152019-09-16 16:50:18 +080088 EXPECT_CALL(mockedAssociationInterface, createActiveAssociation(dBusPath))
89 .Times(0);
90 EXPECT_CALL(mockedAssociationInterface, addFunctionalAssociation(dBusPath))
91 .Times(0);
Lei YUff83c2a2019-09-12 13:55:18 +080092 EXPECT_EQ(Status::Failed, activation->activation());
93}
94
95TEST_F(TestActivation, doUpdateOnePSUOK)
96{
97 constexpr auto psu0 = "/com/example/inventory/psu0";
98 activation = std::make_unique<Activation>(mockedBus, dBusPath, versionId,
Lei YU7f2a2152019-09-16 16:50:18 +080099 extVersion, status, associations,
100 &mockedAssociationInterface);
Lei YUff83c2a2019-09-12 13:55:18 +0800101 ON_CALL(mockedUtils, getPSUInventoryPath(_))
102 .WillByDefault(
103 Return(std::vector<std::string>({psu0}))); // One PSU inventory
104 activation->requestedActivation(RequestedStatus::Active);
105
106 EXPECT_EQ(Status::Activating, activation->activation());
107
Lei YU7f2a2152019-09-16 16:50:18 +0800108 EXPECT_CALL(mockedAssociationInterface, createActiveAssociation(dBusPath))
109 .Times(1);
110 EXPECT_CALL(mockedAssociationInterface, addFunctionalAssociation(dBusPath))
111 .Times(1);
Lei YUff83c2a2019-09-12 13:55:18 +0800112 onUpdateDone();
113 EXPECT_EQ(Status::Active, activation->activation());
114}
115
116TEST_F(TestActivation, doUpdateFourPSUsOK)
117{
118 constexpr auto psu0 = "/com/example/inventory/psu0";
119 constexpr auto psu1 = "/com/example/inventory/psu1";
120 constexpr auto psu2 = "/com/example/inventory/psu2";
121 constexpr auto psu3 = "/com/example/inventory/psu3";
122 activation = std::make_unique<Activation>(mockedBus, dBusPath, versionId,
Lei YU7f2a2152019-09-16 16:50:18 +0800123 extVersion, status, associations,
124 &mockedAssociationInterface);
Lei YUff83c2a2019-09-12 13:55:18 +0800125 ON_CALL(mockedUtils, getPSUInventoryPath(_))
126 .WillByDefault(Return(
127 std::vector<std::string>({psu0, psu1, psu2, psu3}))); // 4 PSUs
128 activation->requestedActivation(RequestedStatus::Active);
129
130 EXPECT_EQ(Status::Activating, activation->activation());
131 EXPECT_EQ(10, getProgress());
132
133 onUpdateDone();
134 EXPECT_EQ(Status::Activating, activation->activation());
135 EXPECT_EQ(30, getProgress());
136
137 onUpdateDone();
138 EXPECT_EQ(Status::Activating, activation->activation());
139 EXPECT_EQ(50, getProgress());
140
141 onUpdateDone();
142 EXPECT_EQ(Status::Activating, activation->activation());
143 EXPECT_EQ(70, getProgress());
144
Lei YU7f2a2152019-09-16 16:50:18 +0800145 EXPECT_CALL(mockedAssociationInterface, createActiveAssociation(dBusPath))
146 .Times(1);
147 EXPECT_CALL(mockedAssociationInterface, addFunctionalAssociation(dBusPath))
148 .Times(1);
149
Lei YUff83c2a2019-09-12 13:55:18 +0800150 onUpdateDone();
151 EXPECT_EQ(Status::Active, activation->activation());
152}
153
154TEST_F(TestActivation, doUpdateFourPSUsFailonSecond)
155{
156 constexpr auto psu0 = "/com/example/inventory/psu0";
157 constexpr auto psu1 = "/com/example/inventory/psu1";
158 constexpr auto psu2 = "/com/example/inventory/psu2";
159 constexpr auto psu3 = "/com/example/inventory/psu3";
160 activation = std::make_unique<Activation>(mockedBus, dBusPath, versionId,
Lei YU7f2a2152019-09-16 16:50:18 +0800161 extVersion, status, associations,
162 &mockedAssociationInterface);
Lei YUff83c2a2019-09-12 13:55:18 +0800163 ON_CALL(mockedUtils, getPSUInventoryPath(_))
164 .WillByDefault(Return(
165 std::vector<std::string>({psu0, psu1, psu2, psu3}))); // 4 PSUs
166 activation->requestedActivation(RequestedStatus::Active);
167
168 EXPECT_EQ(Status::Activating, activation->activation());
169 EXPECT_EQ(10, getProgress());
170
171 onUpdateDone();
172 EXPECT_EQ(Status::Activating, activation->activation());
173 EXPECT_EQ(30, getProgress());
174
Lei YU7f2a2152019-09-16 16:50:18 +0800175 EXPECT_CALL(mockedAssociationInterface, createActiveAssociation(dBusPath))
176 .Times(0);
177 EXPECT_CALL(mockedAssociationInterface, addFunctionalAssociation(dBusPath))
178 .Times(0);
Lei YUff83c2a2019-09-12 13:55:18 +0800179 onUpdateFailed();
180 EXPECT_EQ(Status::Failed, activation->activation());
181}
182
183TEST_F(TestActivation, doUpdateOnExceptionFromDbus)
184{
185 constexpr auto psu0 = "/com/example/inventory/psu0";
186 activation = std::make_unique<Activation>(mockedBus, dBusPath, versionId,
Lei YU7f2a2152019-09-16 16:50:18 +0800187 extVersion, status, associations,
188 &mockedAssociationInterface);
Lei YUff83c2a2019-09-12 13:55:18 +0800189 ON_CALL(mockedUtils, getPSUInventoryPath(_))
190 .WillByDefault(
191 Return(std::vector<std::string>({psu0}))); // One PSU inventory
192 ON_CALL(sdbusMock, sd_bus_call(_, _, _, _, nullptr))
193 .WillByDefault(Return(-1)); // Make sdbus call failure
194 activation->requestedActivation(RequestedStatus::Active);
195
196 EXPECT_EQ(Status::Failed, activation->activation());
197}