Skip to content
This repository was archived by the owner on May 21, 2024. It is now read-only.

Fix installation of 0-byte files. #1652

Merged
merged 1 commit into from
Apr 22, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 12 additions & 7 deletions src/libaktualizr/package_manager/fetcher_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -230,20 +230,21 @@ class HttpZeroLength : public HttpFake {
HttpZeroLength(const boost::filesystem::path& test_dir_in) : HttpFake(test_dir_in) {}
HttpResponse download(const std::string& url, curl_write_callback write_cb, curl_xferinfo_callback progress_cb,
void* userp, curl_off_t from) override {
(void)write_cb;
(void)progress_cb;
(void)userp;
(void)from;

EXPECT_EQ(url, server + "/targets/fake_file");
const std::string content = "0";
write_cb(const_cast<char*>(&content[0]), 1, 1, userp);
counter++;
return HttpResponse("0", 200, CURLE_OK, "");
return HttpResponse(content, 200, CURLE_OK, "");
}

int counter = 0;
};

/* Don't bother downloading a target with length 0. */
/* Don't bother downloading a target with length 0, but make sure verification
* still succeeds so that installation is possible. */
TEST(Fetcher, DownloadLengthZero) {
TemporaryDirectory temp_dir;
config.storage.path = temp_dir.Path();
Expand All @@ -261,15 +262,17 @@ TEST(Fetcher, DownloadLengthZero) {
empty_target_json["length"] = 0;
Uptane::Target empty_target("empty_file", empty_target_json);
EXPECT_TRUE(pacman->fetchTarget(empty_target, fetcher, keys, progress_cb, nullptr));
EXPECT_EQ(pacman->verifyTarget(empty_target), TargetStatus::kGood);
EXPECT_EQ(http->counter, 0);

// Non-empty target: download succeeds, and http module is called. This is
// done purely to make sure the test is designed correctly.
Json::Value nonempty_target_json;
nonempty_target_json["hashes"]["sha256"] = "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855";
nonempty_target_json["hashes"]["sha256"] = "5feceb66ffc86f38d952786c6d696c79c2dbc239dd4e91b46729d73a27fb57e9";
nonempty_target_json["length"] = 1;
Uptane::Target nonempty_target("fake_file", nonempty_target_json);
EXPECT_TRUE(pacman->fetchTarget(nonempty_target, fetcher, keys, progress_cb, nullptr));
EXPECT_EQ(pacman->verifyTarget(nonempty_target), TargetStatus::kGood);
EXPECT_EQ(http->counter, 1);
}

Expand All @@ -292,21 +295,23 @@ TEST(Fetcher, NotEnoughDiskSpace) {
const uint64_t available_bytes = (stvfsbuf.f_bsize * stvfsbuf.f_bavail);

// Try to fetch a target larger than the available disk space: an exception is
// thrown and the http module is never called.
// thrown and the http module is never called. Note the hash is bogus.
Json::Value empty_target_json;
empty_target_json["hashes"]["sha256"] = "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855";
empty_target_json["length"] = available_bytes * 2;
Uptane::Target empty_target("empty_file", empty_target_json);
EXPECT_FALSE(pacman->fetchTarget(empty_target, fetcher, keys, progress_cb, nullptr));
EXPECT_NE(pacman->verifyTarget(empty_target), TargetStatus::kGood);
EXPECT_EQ(http->counter, 0);

// Try to fetch a 1-byte target: download succeeds, and http module is called.
// This is done purely to make sure the test is designed correctly.
Json::Value nonempty_target_json;
nonempty_target_json["hashes"]["sha256"] = "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855";
nonempty_target_json["hashes"]["sha256"] = "5feceb66ffc86f38d952786c6d696c79c2dbc239dd4e91b46729d73a27fb57e9";
nonempty_target_json["length"] = 1;
Uptane::Target nonempty_target("fake_file", nonempty_target_json);
EXPECT_TRUE(pacman->fetchTarget(nonempty_target, fetcher, keys, progress_cb, nullptr));
EXPECT_EQ(pacman->verifyTarget(nonempty_target), TargetStatus::kGood);
EXPECT_EQ(http->counter, 1);
}

Expand Down
5 changes: 3 additions & 2 deletions src/libaktualizr/package_manager/packagemanagerinterface.cc
Original file line number Diff line number Diff line change
Expand Up @@ -92,11 +92,12 @@ bool PackageManagerInterface::fetchTarget(const Uptane::Target& target, Uptane::
LOG_INFO << "Image already downloaded; skipping download";
return true;
}
std::unique_ptr<DownloadMetaStruct> ds = std_::make_unique<DownloadMetaStruct>(target, progress_cb, token);
if (target.length() == 0) {
LOG_WARNING << "Skipping download of target with length 0";
LOG_INFO << "Skipping download of target with length 0";
ds->fhandle = storage_->allocateTargetFile(target);
return true;
}
std::unique_ptr<DownloadMetaStruct> ds = std_::make_unique<DownloadMetaStruct>(target, progress_cb, token);
if (exists == TargetStatus::kIncomplete) {
LOG_INFO << "Continuing incomplete download of file " << target.filename();
auto target_check = storage_->checkTargetFile(target);
Expand Down
2 changes: 1 addition & 1 deletion tests/httpfake.h
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ class HttpFake : public HttpInterface {
auto resp_future = resp_promise.get_future();
std::thread(
[path, write_cb, progress_cb, userp, url](std::promise<HttpResponse> promise) {
std::string content = Utils::readFile(path.string());
const std::string content = Utils::readFile(path.string());
for (unsigned int i = 0; i < content.size(); ++i) {
write_cb(const_cast<char *>(&content[i]), 1, 1, userp);
progress_cb(userp, 0, 0, 0, 0);
Expand Down