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);
143 return Uptane::Hash(Uptane::Hash::Type::kSha256, getDefaultTarget().sha256Hash());
147 static constexpr
const char*
const _default_target{
"default-target"};
150 NiceMock<UpdateAgentMock>& _update_agent;
154 public ::testing::WithParamInterface<std::pair<Uptane::RepositoryType, Uptane::Role>> {
163 :
Metadata(valid_metadata), _repo_type(repo), _role(role) {}
167 auto return_val = Metadata::getRoleMetadata(
result, repo, role, version);
168 if (!(_repo_type == repo && _role == role)) {
181 return MetadataInvalidator(_uptane_repo.getCurrentMetadata(), GetParam().first, GetParam().second);
186 NiceMock<UpdateAgentMock>& _update_agent;
196 EXPECT_FALSE(_secondary->putMetadata(currentMetadata()));
198 EXPECT_CALL(_update_agent, download).Times(0);
199 EXPECT_CALL(_update_agent, install).Times(0);
201 EXPECT_FALSE(_secondary->sendFirmware(
"firmware"));
203 EXPECT_NE(_secondary->install(
"target"), data::ResultCode::Numeric::kOk);
211 ::testing::Values(std::make_pair(Uptane::RepositoryType::Director(), Uptane::Role::Root()),
212 std::make_pair(Uptane::RepositoryType::Director(), Uptane::Role::Targets()),
213 std::make_pair(Uptane::RepositoryType::Image(), Uptane::Role::Root()),
214 std::make_pair(Uptane::RepositoryType::Image(), Uptane::Role::Timestamp()),
215 std::make_pair(Uptane::RepositoryType::Image(), Uptane::Role::Snapshot()),
216 std::make_pair(Uptane::RepositoryType::Image(), Uptane::Role::Targets())));
219 EXPECT_CALL(_update_agent, download).Times(1);
220 EXPECT_CALL(_update_agent, install).Times(1);
222 ASSERT_TRUE(_secondary->putMetadata(_uptane_repo.getCurrentMetadata()));
223 ASSERT_TRUE(_secondary->sendFirmware(getImageData()));
224 ASSERT_EQ(_secondary->install(_default_target), data::ResultCode::Numeric::kOk);
227 ASSERT_TRUE(boost::filesystem::exists(_secondary.targetFilepath()));
228 auto target = getDefaultTarget();
231 auto target_hash =
Uptane::Hash(Uptane::Hash::Type::kSha256, target.sha256Hash());
232 auto target_file_hash =
233 Uptane::Hash::generate(Uptane::Hash::Type::kSha256, Utils::readFile(_secondary.targetFilepath()));
234 EXPECT_EQ(target_hash, target_file_hash);
237 auto manifest = _secondary->getManifest();
238 EXPECT_EQ(manifest.installedImageHash(), target_file_hash);
239 EXPECT_EQ(manifest.filepath(), target.filename());
245 _uptane_repo.addImageFile(
"second_image_00", _secondary->getHwId().ToString(), _secondary->getSerial().ToString(),
247 EXPECT_TRUE(_secondary->putMetadata(_uptane_repo.getCurrentMetadata()));
253 _uptane_repo.addImageFile(
"second_target", _secondary->getHwId().ToString(), _secondary->getSerial().ToString());
255 EXPECT_FALSE(_secondary->putMetadata(_uptane_repo.getCurrentMetadata()));
261 UptaneRepoWrapper().addImageFile(
"mytarget", _secondary->getHwId().ToString(),
"non-existing-serial");
263 EXPECT_FALSE(_secondary->putMetadata(metadata));
269 UptaneRepoWrapper().addImageFile(
"mytarget",
"non-existig-hwid", _secondary->getSerial().ToString());
271 EXPECT_FALSE(_secondary->putMetadata(metadata));
276 _uptane_repo.refreshRoot(Uptane::RepositoryType::Director());
277 EXPECT_TRUE(_secondary->putMetadata(_uptane_repo.getCurrentMetadata()));
281 _uptane_repo.refreshRoot(Uptane::RepositoryType::Image());
282 EXPECT_TRUE(_secondary->putMetadata(_uptane_repo.getCurrentMetadata()));
286 EXPECT_CALL(_update_agent, download).Times(1);
287 EXPECT_CALL(_update_agent, install).Times(0);
289 EXPECT_TRUE(_secondary->putMetadata(_uptane_repo.getCurrentMetadata()));
290 auto image_data = getImageData();
291 image_data.append(
"\n");
292 EXPECT_FALSE(_secondary->sendFirmware(image_data));
293 EXPECT_NE(_secondary->install(_default_target), data::ResultCode::Numeric::kOk);
297 EXPECT_CALL(_update_agent, download).Times(1);
298 EXPECT_CALL(_update_agent, install).Times(0);
300 EXPECT_TRUE(_secondary->putMetadata(_uptane_repo.getCurrentMetadata()));
301 auto image_data = getImageData();
302 image_data.operator[](3) =
'0';
303 EXPECT_FALSE(_secondary->sendFirmware(image_data));
304 EXPECT_NE(_secondary->install(_default_target), data::ResultCode::Numeric::kOk);
307 int main(
int argc,
char** argv) {
308 ::testing::InitGoogleTest(&argc, argv);
311 logger_set_threshold(boost::log::trivial::info);
313 return RUN_ALL_TESTS();