From 37304f3cc920804c97d52df929b9871c057c55e0 Mon Sep 17 00:00:00 2001 From: xunchang Date: Tue, 12 Mar 2019 12:40:14 -0700 Subject: Implement FilePackage class This is another implementation of the Package class. And we will later need it when reading the package from FUSE. Bug: 127071893 Test: unit tests pass, sideload a file package on sailfish Change-Id: I3de5d5ef60b29c8b73517d6de3498459d7d95975 --- tests/unit/package_test.cpp | 117 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 117 insertions(+) create mode 100644 tests/unit/package_test.cpp (limited to 'tests/unit') diff --git a/tests/unit/package_test.cpp b/tests/unit/package_test.cpp new file mode 100644 index 000000000..fa492d38b --- /dev/null +++ b/tests/unit/package_test.cpp @@ -0,0 +1,117 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agree to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include +#include +#include + +#include +#include +#include +#include + +#include "common/test_constants.h" +#include "package.h" + +class PackageTest : public ::testing::Test { + protected: + void SetUp() override; + + // A list of package classes for test, including MemoryPackage and FilePackage. + std::vector> packages_; + + TemporaryFile temp_file_; // test package file. + std::string file_content_; // actual bytes of the package file. +}; + +void PackageTest::SetUp() { + std::vector entries = { "file1.txt", "file2.txt", "dir1/file3.txt" }; + FILE* file_ptr = fdopen(temp_file_.release(), "wb"); + ZipWriter writer(file_ptr); + for (const auto& entry : entries) { + ASSERT_EQ(0, writer.StartEntry(entry.c_str(), ZipWriter::kCompress)); + ASSERT_EQ(0, writer.WriteBytes(entry.c_str(), entry.size())); + ASSERT_EQ(0, writer.FinishEntry()); + } + writer.Finish(); + ASSERT_EQ(0, fclose(file_ptr)); + + ASSERT_TRUE(android::base::ReadFileToString(temp_file_.path, &file_content_)); + auto memory_package = Package::CreateMemoryPackage(temp_file_.path, nullptr); + ASSERT_TRUE(memory_package); + packages_.emplace_back(std::move(memory_package)); + + auto file_package = Package::CreateFilePackage(temp_file_.path, nullptr); + ASSERT_TRUE(file_package); + packages_.emplace_back(std::move(file_package)); +} + +TEST_F(PackageTest, ReadFullyAtOffset_success) { + for (const auto& package : packages_) { + std::vector buffer(file_content_.size()); + ASSERT_TRUE(package->ReadFullyAtOffset(buffer.data(), file_content_.size(), 0)); + ASSERT_EQ(file_content_, std::string(buffer.begin(), buffer.end())); + + ASSERT_TRUE(package->ReadFullyAtOffset(buffer.data(), file_content_.size() - 10, 10)); + ASSERT_EQ(file_content_.substr(10), std::string(buffer.begin(), buffer.end() - 10)); + } +} + +TEST_F(PackageTest, ReadFullyAtOffset_failure) { + for (const auto& package : packages_) { + std::vector buffer(file_content_.size()); + // Out of bound read. + ASSERT_FALSE(package->ReadFullyAtOffset(buffer.data(), file_content_.size(), 10)); + } +} + +TEST_F(PackageTest, UpdateHashAtOffset_sha1_hash) { + // Check that the hash matches for first half of the file. + uint64_t hash_size = file_content_.size() / 2; + std::vector expected_sha(SHA_DIGEST_LENGTH); + SHA1(reinterpret_cast(file_content_.data()), hash_size, expected_sha.data()); + + for (const auto& package : packages_) { + SHA_CTX ctx; + SHA1_Init(&ctx); + std::vector hashers{ std::bind(&SHA1_Update, &ctx, std::placeholders::_1, + std::placeholders::_2) }; + package->UpdateHashAtOffset(hashers, 0, hash_size); + + std::vector calculated_sha(SHA_DIGEST_LENGTH); + SHA1_Final(calculated_sha.data(), &ctx); + ASSERT_EQ(expected_sha, calculated_sha); + } +} + +TEST_F(PackageTest, GetZipArchiveHandle_extract_entry) { + for (const auto& package : packages_) { + ZipArchiveHandle zip = package->GetZipArchiveHandle(); + ASSERT_TRUE(zip); + + // Check that we can extract one zip entry. + std::string entry_name = "dir1/file3.txt"; + ZipString path(entry_name.c_str()); + ZipEntry entry; + ASSERT_EQ(0, FindEntry(zip, path, &entry)); + + std::vector extracted(entry_name.size()); + ASSERT_EQ(0, ExtractToMemory(zip, &entry, extracted.data(), extracted.size())); + ASSERT_EQ(entry_name, std::string(extracted.begin(), extracted.end())); + } +} -- cgit v1.2.3