1 #include <gtest/gtest.h>
3 #include <boost/filesystem.hpp>
4 #include <boost/process.hpp>
6 #include "config/config.h"
7 #include "http/httpclient.h"
8 #include "package_manager/packagemanagerfactory.h"
9 #include "package_manager/packagemanagerinterface.h"
10 #include "primary/sotauptaneclient.h"
11 #include "storage/invstorage.h"
12 #include "test_utils.h"
13 #include "uptane/fetcher.h"
15 static std::string repo_server =
"http://127.0.0.1:";
16 static std::string treehub_server =
"http://127.0.0.1:";
17 static boost::filesystem::path test_sysroot;
18 static boost::filesystem::path uptane_gen;
20 static void progress_cb(
const Uptane::Target& target,
const std::string& description,
unsigned int progress) {
22 LOG_INFO <<
"progress_cb " << target <<
" " << progress;
25 static std::unique_ptr<boost::process::child> create_repo(
const boost::filesystem::path& repo_path) {
26 std::string port = TestUtils::getFreePort();
28 auto p = std_::make_unique<boost::process::child>(
"src/libaktualizr/package_manager/dockerapp_test_repo.sh",
29 uptane_gen, repo_path, port);
30 TestUtils::waitForServer(repo_server +
"/");
36 config.pacman.type = PACKAGE_MANAGER_OSTREEDOCKERAPP;
37 config.pacman.sysroot = test_sysroot;
39 config.storage.path = dir.Path();
41 std::shared_ptr<INvStorage> storage = INvStorage::newStorage(config.storage);
42 auto pacman = PackageManagerFactory::makePackageManager(config.pacman, config.bootloader, storage,
nullptr);
47 std::string sha = Utils::readFile(test_sysroot /
"ostree/repo/refs/heads/ostree/1/1/0",
true);
48 Json::Value target_json;
49 target_json[
"hashes"][
"sha256"] = sha;
50 target_json[
"custom"][
"targetFormat"] =
"OSTREE";
51 target_json[
"length"] = 0;
52 target_json[
"custom"][
"docker_apps"][
"app1"][
"filename"] =
"foo.dockerapp";
54 target_json[
"custom"][
"docker_apps"][
"app1"][
"uri"] =
"http://foo.com";
58 auto repo = temp_dir.Path();
59 auto repod = create_repo(repo);
61 boost::filesystem::path apps_root = temp_dir /
"docker_apps";
64 config.pacman.type = PACKAGE_MANAGER_OSTREEDOCKERAPP;
65 config.pacman.sysroot = test_sysroot.string();
66 config.pacman.ostree_server = treehub_server;
67 config.pacman.extra[
"docker_apps_root"] = apps_root.string();
68 config.pacman.extra[
"docker_apps"] =
"app1 app2";
69 config.pacman.extra[
"docker_app_bin"] = config.pacman.extra[
"docker_compose_bin"] =
70 "src/libaktualizr/package_manager/docker_fake.sh";
71 config.uptane.repo_server = repo_server +
"/repo/repo";
73 config.storage.path = dir.Path();
77 boost::filesystem::create_directories(apps_root /
"delete-this-app");
80 boost::filesystem::create_directories(apps_root /
"app2");
82 std::shared_ptr<INvStorage> storage = INvStorage::newStorage(config.storage);
83 KeyManager keys(storage, config.keymanagerConfig());
84 auto client = std_::make_unique<SotaUptaneClient>(config, storage);
85 ASSERT_TRUE(client->updateImageMeta());
87 std::string targets = Utils::readFile(repo /
"repo/repo/targets.json");
88 LOG_INFO <<
"Repo targets " << targets;
90 bool result = client->package_manager_->fetchTarget(target, *(client->uptane_fetcher), keys, progress_cb,
nullptr);
93 auto hashes = std::vector<Uptane::Hash>{
94 Uptane::Hash(Uptane::Hash::Type::kSha256,
"dfca385c923400228c8ddd3c2d572919985e48a9409a2d71dab33148017231c3"),
96 "76b183d51f53613a450825afc6f984077b68ae7b321ba041a2b3871f3c25a9a20d964ad0b60352e5fdd09b78fd53879f4e3"
97 "fa3dcc8335b26d3bbf455803d2ecb")};
98 Uptane::Target app_target(
"foo.dockerapp", Uptane::EcuMap{}, hashes, 8);
99 ASSERT_TRUE(storage->checkTargetFile(app_target));
101 client->package_manager_->install(target);
102 std::string content = Utils::readFile(apps_root /
"app1/docker-compose.yml");
103 ASSERT_EQ(
"DOCKER-APP RENDER OUTPUT\nfake contents of a docker app\n", content);
106 ASSERT_FALSE(boost::filesystem::exists(apps_root /
"delete-this-app"));
107 ASSERT_FALSE(boost::filesystem::exists(apps_root /
"app2"));
108 ASSERT_TRUE(boost::filesystem::exists(apps_root /
"docker-compose-down-called"));
110 setenv(
"DOCKER_APP_FAIL",
"1", 1);
111 result = client->package_manager_->fetchTarget(target, *(client->uptane_fetcher), keys, progress_cb,
nullptr);
117 unsetenv(
"DOCKER_APP_FAIL");
118 std::string sha = Utils::readFile(test_sysroot /
"ostree/repo/refs/heads/ostree/1/1/0",
true);
119 Json::Value target_json;
120 target_json[
"hashes"][
"sha256"] = sha;
121 target_json[
"custom"][
"targetFormat"] =
"OSTREE";
122 target_json[
"length"] = 0;
123 target_json[
"custom"][
"docker_apps"][
"app1"][
"uri"] =
"hub.docker.io/user/hello@sha256:deadbeef";
125 target_json[
"custom"][
"docker_apps"][
"app1"][
"filename"] =
"foo.dockerapp";
131 boost::filesystem::path docker =
132 boost::filesystem::system_complete(
"src/libaktualizr/package_manager/docker_fake.sh");
133 ASSERT_EQ(0, symlink(docker.c_str(), (temp_dir.Path() /
"docker").c_str()));
134 std::string path(temp_dir.PathString() +
":" + getenv(
"PATH"));
135 setenv(
"PATH", path.c_str(), 1);
138 boost::filesystem::path apps_root = temp_dir /
"docker_apps";
140 config.pacman.type = PACKAGE_MANAGER_OSTREEDOCKERAPP;
141 config.pacman.sysroot = test_sysroot;
142 config.pacman.extra[
"docker_apps_root"] = apps_root.string();
143 config.pacman.extra[
"docker_apps"] =
"app1 app2";
144 config.pacman.extra[
"docker_compose_bin"] =
"src/libaktualizr/package_manager/docker_fake.sh";
145 config.pacman.ostree_server = treehub_server;
146 config.uptane.repo_server = repo_server +
"/repo/repo";
148 config.storage.path = dir.Path();
155 boost::filesystem::create_directories(apps_root /
"app2");
157 std::shared_ptr<INvStorage> storage = INvStorage::newStorage(config.storage);
158 storage->savePrimaryInstalledVersion(target, InstalledVersionUpdateMode::kCurrent);
159 KeyManager keys(storage, config.keymanagerConfig());
160 auto client = std_::make_unique<SotaUptaneClient>(config, storage);
162 ASSERT_TRUE(client->package_manager_->fetchTarget(target, *(client->uptane_fetcher), keys, progress_cb,
nullptr));
163 std::string content = Utils::readFile(temp_dir /
"docker-app-pull");
164 ASSERT_EQ(
"PULL CALLED app pull hub.docker.io/user/hello@sha256:deadbeef\n", content);
166 client->package_manager_->install(target);
167 content = Utils::readFile(apps_root /
"app1/docker-compose.yml");
168 ASSERT_EQ(
"FAKE CONTENT FOR IMAGE RENDER\nhub.docker.io/user/hello@sha256:deadbeef\n", content);
171 ASSERT_FALSE(boost::filesystem::exists(apps_root /
"delete-this-app"));
172 ASSERT_FALSE(boost::filesystem::exists(apps_root /
"app2"));
173 ASSERT_TRUE(boost::filesystem::exists(apps_root /
"docker-compose-down-called"));
177 int main(
int argc,
char** argv) {
178 ::testing::InitGoogleTest(&argc, argv);
181 std::cerr <<
"Error: " << argv[0]
182 <<
" requires the path to an OSTree sysroot and uptane-generator as an input argument.\n";
185 uptane_gen = argv[2];
187 std::string port = TestUtils::getFreePort();
188 treehub_server += port;
189 boost::process::child server_process(
"tests/fake_http_server/fake_test_server.py", port);
193 int r = system((std::string(
"cp -r ") + argv[1] + std::string(
" ") + temp_dir.PathString()).c_str());
197 test_sysroot = (temp_dir.Path() /
"ostree_repo").
string();
199 TestUtils::waitForServer(treehub_server +
"/");
201 return RUN_ALL_TESTS();