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/dockerappmanager.h"
9 #include "package_manager/packagemanagerfactory.h"
10 #include "package_manager/packagemanagerinterface.h"
11 #include "primary/sotauptaneclient.h"
12 #include "storage/invstorage.h"
13 #include "test_utils.h"
14 #include "uptane/fetcher.h"
16 static std::string repo_server =
"http://127.0.0.1:";
17 static std::string treehub_server =
"http://127.0.0.1:";
18 static boost::filesystem::path test_sysroot;
19 static boost::filesystem::path uptane_gen;
21 static void progress_cb(
const Uptane::Target& target,
const std::string& description,
unsigned int progress) {
23 LOG_INFO <<
"progress_cb " << target <<
" " << progress;
26 static std::unique_ptr<boost::process::child> create_repo(
const boost::filesystem::path& repo_path) {
27 std::string port = TestUtils::getFreePort();
29 auto p = std_::make_unique<boost::process::child>(
"src/libaktualizr/package_manager/dockerapp_test_repo.sh",
30 uptane_gen, repo_path, port);
31 TestUtils::waitForServer(repo_server +
"/");
37 config.pacman.type = PACKAGE_MANAGER_OSTREEDOCKERAPP;
38 config.pacman.sysroot = test_sysroot;
40 config.storage.path = dir.Path();
42 std::shared_ptr<INvStorage> storage = INvStorage::newStorage(config.storage);
43 auto pacman = PackageManagerFactory::makePackageManager(config.pacman, config.bootloader, storage,
nullptr);
49 config.pacman.type = PACKAGE_MANAGER_OSTREEDOCKERAPP;
50 config.pacman.sysroot = test_sysroot.string();
51 config.pacman.ostree_server = treehub_server;
52 config.pacman.extra[
"docker_apps_root"] =
"apps-root";
53 config.pacman.extra[
"docker_apps"] =
"app1 app2";
54 config.pacman.extra[
"docker_app_bin"] =
"dab";
55 config.pacman.extra[
"docker_compose_bin"] =
"compose";
58 ASSERT_TRUE(dacfg.docker_prune);
59 ASSERT_EQ(2, dacfg.docker_apps.size());
60 ASSERT_EQ(
"app1", dacfg.docker_apps[0]);
61 ASSERT_EQ(
"app2", dacfg.docker_apps[1]);
62 ASSERT_EQ(
"apps-root", dacfg.docker_apps_root);
63 ASSERT_EQ(
"dab", dacfg.docker_app_bin);
64 ASSERT_EQ(
"compose", dacfg.docker_compose_bin);
66 config.pacman.extra[
"docker_prune"] =
"0";
68 ASSERT_FALSE(dacfg.docker_prune);
70 config.pacman.extra[
"docker_prune"] =
"FALSE";
72 ASSERT_FALSE(dacfg.docker_prune);
76 std::string sha = Utils::readFile(test_sysroot /
"ostree/repo/refs/heads/ostree/1/1/0",
true);
77 Json::Value target_json;
78 target_json[
"hashes"][
"sha256"] = sha;
79 target_json[
"custom"][
"targetFormat"] =
"OSTREE";
80 target_json[
"length"] = 0;
81 target_json[
"custom"][
"docker_apps"][
"app1"][
"filename"] =
"foo.dockerapp";
83 target_json[
"custom"][
"docker_apps"][
"app1"][
"uri"] =
"http://foo.com";
87 auto repo = temp_dir.Path();
88 auto repod = create_repo(repo);
90 boost::filesystem::path apps_root = temp_dir /
"docker_apps";
93 config.pacman.type = PACKAGE_MANAGER_OSTREEDOCKERAPP;
94 config.pacman.sysroot = test_sysroot.string();
95 config.pacman.ostree_server = treehub_server;
96 config.pacman.extra[
"docker_apps_root"] = apps_root.string();
97 config.pacman.extra[
"docker_apps"] =
"app1 app2";
98 config.pacman.extra[
"docker_app_bin"] = config.pacman.extra[
"docker_compose_bin"] =
99 "src/libaktualizr/package_manager/docker_fake.sh";
100 config.uptane.repo_server = repo_server +
"/repo/repo";
102 config.storage.path = dir.Path();
106 boost::filesystem::create_directories(apps_root /
"delete-this-app");
109 boost::filesystem::create_directories(apps_root /
"app2");
111 std::shared_ptr<INvStorage> storage = INvStorage::newStorage(config.storage);
112 KeyManager keys(storage, config.keymanagerConfig());
113 auto client = std_::make_unique<SotaUptaneClient>(config, storage);
114 ASSERT_NO_THROW(client->updateImageMeta());
116 std::string targets = Utils::readFile(repo /
"repo/repo/targets.json");
117 LOG_INFO <<
"Repo targets " << targets;
119 bool result = client->package_manager_->fetchTarget(target, *(client->uptane_fetcher), keys, progress_cb,
nullptr);
122 auto hashes = std::vector<Hash>{
123 Hash(Hash::Type::kSha256,
"dfca385c923400228c8ddd3c2d572919985e48a9409a2d71dab33148017231c3"),
124 Hash(Hash::Type::kSha512,
125 "76b183d51f53613a450825afc6f984077b68ae7b321ba041a2b3871f3c25a9a20d964ad0b60352e5fdd09b78fd53879f4e3"
126 "fa3dcc8335b26d3bbf455803d2ecb")};
127 Uptane::Target app_target(
"foo.dockerapp", Uptane::EcuMap{}, hashes, 8);
128 ASSERT_TRUE(storage->checkTargetFile(app_target));
130 client->package_manager_->install(target);
131 std::string content = Utils::readFile(apps_root /
"app1/docker-compose.yml");
132 ASSERT_EQ(
"DOCKER-APP RENDER OUTPUT\nfake contents of a docker app\n", content);
135 ASSERT_FALSE(boost::filesystem::exists(apps_root /
"delete-this-app"));
136 ASSERT_FALSE(boost::filesystem::exists(apps_root /
"app2"));
137 ASSERT_TRUE(boost::filesystem::exists(apps_root /
"docker-compose-down-called"));
139 setenv(
"DOCKER_APP_FAIL",
"1", 1);
140 result = client->package_manager_->fetchTarget(target, *(client->uptane_fetcher), keys, progress_cb,
nullptr);
146 unsetenv(
"DOCKER_APP_FAIL");
147 std::string sha = Utils::readFile(test_sysroot /
"ostree/repo/refs/heads/ostree/1/1/0",
true);
148 Json::Value target_json;
149 target_json[
"hashes"][
"sha256"] = sha;
150 target_json[
"custom"][
"targetFormat"] =
"OSTREE";
151 target_json[
"length"] = 0;
152 target_json[
"custom"][
"docker_apps"][
"app1"][
"uri"] =
"hub.docker.io/user/hello@sha256:deadbeef";
154 target_json[
"custom"][
"docker_apps"][
"app1"][
"filename"] =
"foo.dockerapp";
160 boost::filesystem::path docker =
161 boost::filesystem::system_complete(
"src/libaktualizr/package_manager/docker_fake.sh");
162 ASSERT_EQ(0, symlink(docker.c_str(), (temp_dir.Path() /
"docker").c_str()));
163 std::string path(temp_dir.PathString() +
":" + getenv(
"PATH"));
164 setenv(
"PATH", path.c_str(), 1);
167 boost::filesystem::path apps_root = temp_dir /
"docker_apps";
169 config.pacman.type = PACKAGE_MANAGER_OSTREEDOCKERAPP;
170 config.pacman.sysroot = test_sysroot;
171 config.pacman.extra[
"docker_apps_root"] = apps_root.string();
172 config.pacman.extra[
"docker_apps"] =
"app1 app2";
173 config.pacman.extra[
"docker_compose_bin"] =
"src/libaktualizr/package_manager/docker_fake.sh";
174 config.pacman.ostree_server = treehub_server;
175 config.uptane.repo_server = repo_server +
"/repo/repo";
177 config.storage.path = dir.Path();
184 boost::filesystem::create_directories(apps_root /
"app2");
186 std::shared_ptr<INvStorage> storage = INvStorage::newStorage(config.storage);
187 storage->savePrimaryInstalledVersion(target, InstalledVersionUpdateMode::kCurrent);
188 KeyManager keys(storage, config.keymanagerConfig());
189 auto client = std_::make_unique<SotaUptaneClient>(config, storage);
191 ASSERT_TRUE(client->package_manager_->fetchTarget(target, *(client->uptane_fetcher), keys, progress_cb,
nullptr));
192 std::string content = Utils::readFile(temp_dir /
"docker-app-pull");
193 ASSERT_EQ(
"PULL CALLED app pull hub.docker.io/user/hello@sha256:deadbeef\n", content);
195 client->package_manager_->install(target);
196 content = Utils::readFile(apps_root /
"app1/docker-compose.yml");
197 ASSERT_EQ(
"FAKE CONTENT FOR IMAGE RENDER\nhub.docker.io/user/hello@sha256:deadbeef\n", content);
200 ASSERT_FALSE(boost::filesystem::exists(apps_root /
"delete-this-app"));
201 ASSERT_FALSE(boost::filesystem::exists(apps_root /
"app2"));
202 ASSERT_TRUE(boost::filesystem::exists(apps_root /
"docker-compose-down-called"));
206 int main(
int argc,
char** argv) {
207 ::testing::InitGoogleTest(&argc, argv);
210 std::cerr <<
"Error: " << argv[0]
211 <<
" requires the path to an OSTree sysroot and uptane-generator as an input argument.\n";
214 uptane_gen = argv[2];
216 std::string port = TestUtils::getFreePort();
217 treehub_server += port;
218 boost::process::child server_process(
"tests/fake_http_server/fake_test_server.py", port);
222 int r = system((std::string(
"cp -r ") + argv[1] + std::string(
" ") + temp_dir.PathString()).c_str());
226 test_sysroot = (temp_dir.Path() /
"ostree_repo").
string();
228 TestUtils::waitForServer(treehub_server +
"/");
230 return RUN_ALL_TESTS();