1 #include <gmock/gmock.h>
2 #include <gtest/gtest.h>
4 #include <boost/process.hpp>
6 #include "aktualizr_secondary.h"
7 #include "aktualizr_secondary_factory.h"
8 #include "crypto/keymanager.h"
9 #include "test_utils.h"
10 #include "update_agent.h"
11 #include "update_agent_file.h"
12 #include "uptane_repo.h"
14 using ::testing::NiceMock;
18 UpdateAgentMock(boost::filesystem::path target_filepath, std::string target_name)
20 ON_CALL(*
this, download).WillByDefault([
this](
const Uptane::Target& target,
const std::string&
data) {
21 return FileUpdateAgent::download(target,
data);
23 ON_CALL(*
this, install).WillByDefault([
this](
const Uptane::Target& target) {
24 return FileUpdateAgent::install(target);
36 config.pacman.type = PACKAGE_MANAGER_NONE;
38 config.storage.path = storage_dir_.Path();
39 config.storage.type = StorageType::kSqlite;
41 storage_ = INvStorage::newStorage(config.storage);
42 auto key_mngr = std::make_shared<KeyManager>(storage_, config.keymanagerConfig());
43 update_agent = std::make_shared<NiceMock<UpdateAgentMock>>(config.storage.path /
"firmware.txt",
"");
45 secondary_ = std::make_shared<AktualizrSecondary>(config, storage_, key_mngr, update_agent);
48 std::shared_ptr<AktualizrSecondary>& operator->() {
return secondary_; }
51 boost::optional<Uptane::Target> pending_target;
53 storage_->loadInstalledVersions(secondary_->getSerial().ToString(),
nullptr, &pending_target);
54 return *pending_target;
57 std::string hardwareID()
const {
return secondary_->getHwId().ToString(); }
59 std::string serial()
const {
return secondary_->getSerial().ToString(); }
61 boost::filesystem::path targetFilepath()
const {
62 return storage_dir_.Path() / AktualizrSecondaryFactory::BinaryUpdateDefaultFile;
65 std::shared_ptr<NiceMock<UpdateAgentMock>> update_agent;
69 AktualizrSecondary::Ptr secondary_;
70 std::shared_ptr<INvStorage> storage_;
77 Metadata addImageFile(
const std::string& targetname,
const std::string& hardware_id,
const std::string& serial,
78 bool add_and_sign_target =
true) {
79 const auto image_file_path = root_dir_ / targetname;
80 boost::filesystem::ofstream(image_file_path) <<
"some data";
82 uptane_repo_.addImage(image_file_path, targetname, hardware_id,
"",
Delegation());
83 if (add_and_sign_target) {
84 uptane_repo_.addTarget(targetname, hardware_id, serial,
"");
85 uptane_repo_.signTargets();
88 return getCurrentMetadata();
94 boost::filesystem::load_string_file(director_dir_ /
"root.json", metadata.director_root);
95 boost::filesystem::load_string_file(director_dir_ /
"targets.json", metadata.director_targets);
97 boost::filesystem::load_string_file(imagerepo_dir_ /
"root.json", metadata.image_root);
98 boost::filesystem::load_string_file(imagerepo_dir_ /
"timestamp.json", metadata.image_timestamp);
99 boost::filesystem::load_string_file(imagerepo_dir_ /
"snapshot.json", metadata.image_snapshot);
100 boost::filesystem::load_string_file(imagerepo_dir_ /
"targets.json", metadata.image_targets);
105 std::string getImageData(
const std::string& targetname)
const {
106 std::string image_data;
107 boost::filesystem::load_string_file(root_dir_ / targetname, image_data);
115 boost::filesystem::path director_dir_{root_dir_ /
"repo/director"};
116 boost::filesystem::path imagerepo_dir_{root_dir_ /
"repo/repo"};
117 UptaneRepo uptane_repo_{root_dir_.Path(),
"",
""};
123 SecondaryTest() : update_agent_(*(secondary_.update_agent)) {
124 uptane_repo_.addImageFile(default_target_, secondary_->getHwId().ToString(), secondary_->getSerial().ToString());
127 std::string getImageData(
const std::string& targetname = default_target_)
const {
128 return uptane_repo_.getImageData(targetname);
131 std::vector<Uptane::Target> getCurrentTargets() {
132 auto targets =
Uptane::Targets(Utils::parseJSON(uptane_repo_.getCurrentMetadata().director_targets));
133 return targets.getTargets(secondary_->getSerial(), secondary_->getHwId());
137 auto targets = getCurrentTargets();
138 EXPECT_GT(targets.size(), 0);
142 Hash getDefaultTargetHash() {
return Hash(Hash::Type::kSha256, getDefaultTarget().sha256Hash()); }
145 static constexpr
const char*
const default_target_{
"default-target"};
148 NiceMock<UpdateAgentMock>& update_agent_;
152 public ::testing::WithParamInterface<std::pair<Uptane::RepositoryType, Uptane::Role>> {
161 :
Metadata(valid_metadata), repo_type_(repo), role_(role) {}
165 Metadata::getRoleMetadata(
result, repo, role, version);
166 if (!(repo_type_ == repo && role_ == role)) {
178 return MetadataInvalidator(uptane_repo_.getCurrentMetadata(), GetParam().first, GetParam().second);
183 NiceMock<UpdateAgentMock>& update_agent_;
193 EXPECT_FALSE(secondary_->putMetadata(currentMetadata()));
195 EXPECT_CALL(update_agent_, download).Times(0);
196 EXPECT_CALL(update_agent_, install).Times(0);
198 EXPECT_FALSE(secondary_->sendFirmware(
"firmware"));
200 EXPECT_NE(secondary_->install(
"target"), data::ResultCode::Numeric::kOk);
208 ::testing::Values(std::make_pair(Uptane::RepositoryType::Director(), Uptane::Role::Root()),
209 std::make_pair(Uptane::RepositoryType::Director(), Uptane::Role::Targets()),
210 std::make_pair(Uptane::RepositoryType::Image(), Uptane::Role::Root()),
211 std::make_pair(Uptane::RepositoryType::Image(), Uptane::Role::Timestamp()),
212 std::make_pair(Uptane::RepositoryType::Image(), Uptane::Role::Snapshot()),
213 std::make_pair(Uptane::RepositoryType::Image(), Uptane::Role::Targets())));
216 EXPECT_CALL(update_agent_, download).Times(1);
217 EXPECT_CALL(update_agent_, install).Times(1);
219 ASSERT_TRUE(secondary_->putMetadata(uptane_repo_.getCurrentMetadata()));
220 ASSERT_TRUE(secondary_->sendFirmware(getImageData()));
221 ASSERT_EQ(secondary_->install(default_target_), data::ResultCode::Numeric::kOk);
224 ASSERT_TRUE(boost::filesystem::exists(secondary_.targetFilepath()));
225 auto target = getDefaultTarget();
228 auto target_hash =
Hash(Hash::Type::kSha256, target.sha256Hash());
229 auto target_file_hash = Hash::generate(Hash::Type::kSha256, Utils::readFile(secondary_.targetFilepath()));
230 EXPECT_EQ(target_hash, target_file_hash);
233 auto manifest = secondary_->getManifest();
234 EXPECT_EQ(manifest.installedImageHash(), target_file_hash);
235 EXPECT_EQ(manifest.filepath(), target.filename());
241 uptane_repo_.addImageFile(
"second_image_00", secondary_->getHwId().ToString(), secondary_->getSerial().ToString(),
243 EXPECT_TRUE(secondary_->putMetadata(uptane_repo_.getCurrentMetadata()));
249 uptane_repo_.addImageFile(
"second_target", secondary_->getHwId().ToString(), secondary_->getSerial().ToString());
251 EXPECT_FALSE(secondary_->putMetadata(uptane_repo_.getCurrentMetadata()));
257 UptaneRepoWrapper().addImageFile(
"mytarget", secondary_->getHwId().ToString(),
"non-existing-serial");
259 EXPECT_FALSE(secondary_->putMetadata(metadata));
265 UptaneRepoWrapper().addImageFile(
"mytarget",
"non-existig-hwid", secondary_->getSerial().ToString());
267 EXPECT_FALSE(secondary_->putMetadata(metadata));
272 uptane_repo_.refreshRoot(Uptane::RepositoryType::Director());
273 EXPECT_TRUE(secondary_->putMetadata(uptane_repo_.getCurrentMetadata()));
277 uptane_repo_.refreshRoot(Uptane::RepositoryType::Image());
278 EXPECT_TRUE(secondary_->putMetadata(uptane_repo_.getCurrentMetadata()));
282 EXPECT_CALL(update_agent_, download).Times(1);
283 EXPECT_CALL(update_agent_, install).Times(0);
285 EXPECT_TRUE(secondary_->putMetadata(uptane_repo_.getCurrentMetadata()));
286 auto image_data = getImageData();
287 image_data.append(
"\n");
288 EXPECT_FALSE(secondary_->sendFirmware(image_data));
289 EXPECT_NE(secondary_->install(default_target_), data::ResultCode::Numeric::kOk);
293 EXPECT_CALL(update_agent_, download).Times(1);
294 EXPECT_CALL(update_agent_, install).Times(0);
296 EXPECT_TRUE(secondary_->putMetadata(uptane_repo_.getCurrentMetadata()));
297 auto image_data = getImageData();
298 image_data.operator[](3) =
'0';
299 EXPECT_FALSE(secondary_->sendFirmware(image_data));
300 EXPECT_NE(secondary_->install(default_target_), data::ResultCode::Numeric::kOk);
303 int main(
int argc,
char** argv) {
304 ::testing::InitGoogleTest(&argc, argv);
307 logger_set_threshold(boost::log::trivial::info);
309 return RUN_ALL_TESTS();