You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
178 lines
5.5 KiB
178 lines
5.5 KiB
//
|
|
// Copyright (C) 2011 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 agreed 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 <string.h>
|
|
#include <unistd.h>
|
|
|
|
#include <memory>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
#include <gtest/gtest.h>
|
|
|
|
#include "update_engine/common/test_utils.h"
|
|
#include "update_engine/payload_consumer/bzip_extent_writer.h"
|
|
#include "update_engine/payload_consumer/extent_writer.h"
|
|
#include "update_engine/payload_consumer/xz_extent_writer.h"
|
|
#include "update_engine/payload_generator/bzip.h"
|
|
#include "update_engine/payload_generator/xz.h"
|
|
|
|
using chromeos_update_engine::test_utils::kRandomString;
|
|
using google::protobuf::RepeatedPtrField;
|
|
using std::string;
|
|
|
|
namespace chromeos_update_engine {
|
|
|
|
namespace {
|
|
|
|
// ExtentWriter class that writes to memory, used to test the decompression
|
|
// step with the corresponding extent writer.
|
|
class MemoryExtentWriter : public ExtentWriter {
|
|
public:
|
|
// Creates the ExtentWriter that will write all the bytes to the passed |data|
|
|
// blob.
|
|
explicit MemoryExtentWriter(brillo::Blob* data) : data_(data) {
|
|
data_->clear();
|
|
}
|
|
~MemoryExtentWriter() override = default;
|
|
|
|
bool Init(const RepeatedPtrField<Extent>& extents,
|
|
uint32_t block_size) override {
|
|
return true;
|
|
}
|
|
bool Write(const void* bytes, size_t count) override {
|
|
data_->reserve(data_->size() + count);
|
|
data_->insert(data_->end(),
|
|
static_cast<const uint8_t*>(bytes),
|
|
static_cast<const uint8_t*>(bytes) + count);
|
|
return true;
|
|
}
|
|
|
|
private:
|
|
brillo::Blob* data_;
|
|
};
|
|
|
|
template <typename W>
|
|
bool DecompressWithWriter(const brillo::Blob& in, brillo::Blob* out) {
|
|
std::unique_ptr<ExtentWriter> writer(
|
|
new W(std::make_unique<MemoryExtentWriter>(out)));
|
|
// Init() parameters are ignored by the testing MemoryExtentWriter.
|
|
bool ok = writer->Init({}, 1);
|
|
ok = writer->Write(in.data(), in.size()) && ok;
|
|
return ok;
|
|
}
|
|
|
|
} // namespace
|
|
|
|
template <typename T>
|
|
class ZipTest : public ::testing::Test {
|
|
public:
|
|
bool ZipCompress(const brillo::Blob& in, brillo::Blob* out) const = 0;
|
|
bool ZipDecompress(const brillo::Blob& in, brillo::Blob* out) const = 0;
|
|
};
|
|
|
|
class BzipTest {};
|
|
|
|
template <>
|
|
class ZipTest<BzipTest> : public ::testing::Test {
|
|
public:
|
|
bool ZipCompress(const brillo::Blob& in, brillo::Blob* out) const {
|
|
return BzipCompress(in, out);
|
|
}
|
|
bool ZipDecompress(const brillo::Blob& in, brillo::Blob* out) const {
|
|
return DecompressWithWriter<BzipExtentWriter>(in, out);
|
|
}
|
|
};
|
|
|
|
class XzTest {};
|
|
|
|
template <>
|
|
class ZipTest<XzTest> : public ::testing::Test {
|
|
public:
|
|
bool ZipCompress(const brillo::Blob& in, brillo::Blob* out) const {
|
|
return XzCompress(in, out);
|
|
}
|
|
bool ZipDecompress(const brillo::Blob& in, brillo::Blob* out) const {
|
|
return DecompressWithWriter<XzExtentWriter>(in, out);
|
|
}
|
|
};
|
|
|
|
typedef ::testing::Types<BzipTest, XzTest> ZipTestTypes;
|
|
|
|
TYPED_TEST_CASE(ZipTest, ZipTestTypes);
|
|
|
|
TYPED_TEST(ZipTest, SimpleTest) {
|
|
string in_str(
|
|
"this should compress well xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
|
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
|
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
|
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
|
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
|
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
|
|
brillo::Blob in(in_str.begin(), in_str.end());
|
|
brillo::Blob out;
|
|
EXPECT_TRUE(this->ZipCompress(in, &out));
|
|
EXPECT_LT(out.size(), in.size());
|
|
EXPECT_GT(out.size(), 0U);
|
|
brillo::Blob decompressed;
|
|
EXPECT_TRUE(this->ZipDecompress(out, &decompressed));
|
|
EXPECT_EQ(in.size(), decompressed.size());
|
|
EXPECT_EQ(0, memcmp(in.data(), decompressed.data(), in.size()));
|
|
}
|
|
|
|
TYPED_TEST(ZipTest, PoorCompressionTest) {
|
|
brillo::Blob in(std::begin(kRandomString), std::end(kRandomString));
|
|
brillo::Blob out;
|
|
EXPECT_TRUE(this->ZipCompress(in, &out));
|
|
EXPECT_GT(out.size(), in.size());
|
|
brillo::Blob decompressed;
|
|
EXPECT_TRUE(this->ZipDecompress(out, &decompressed));
|
|
EXPECT_EQ(in.size(), decompressed.size());
|
|
EXPECT_EQ(in, decompressed);
|
|
}
|
|
|
|
TYPED_TEST(ZipTest, MalformedZipTest) {
|
|
brillo::Blob in(std::begin(kRandomString), std::end(kRandomString));
|
|
brillo::Blob out;
|
|
EXPECT_FALSE(this->ZipDecompress(in, &out));
|
|
}
|
|
|
|
TYPED_TEST(ZipTest, EmptyInputsTest) {
|
|
brillo::Blob in;
|
|
brillo::Blob out;
|
|
EXPECT_TRUE(this->ZipDecompress(in, &out));
|
|
EXPECT_EQ(0U, out.size());
|
|
|
|
EXPECT_TRUE(this->ZipCompress(in, &out));
|
|
EXPECT_EQ(0U, out.size());
|
|
}
|
|
|
|
TYPED_TEST(ZipTest, CompressELFTest) {
|
|
string path = test_utils::GetBuildArtifactsPath("delta_generator");
|
|
brillo::Blob in;
|
|
utils::ReadFile(path, &in);
|
|
brillo::Blob out;
|
|
EXPECT_TRUE(this->ZipCompress(in, &out));
|
|
EXPECT_LT(out.size(), in.size());
|
|
EXPECT_GT(out.size(), 0U);
|
|
brillo::Blob decompressed;
|
|
EXPECT_TRUE(this->ZipDecompress(out, &decompressed));
|
|
EXPECT_EQ(in.size(), decompressed.size());
|
|
EXPECT_EQ(0, memcmp(in.data(), decompressed.data(), in.size()));
|
|
}
|
|
|
|
} // namespace chromeos_update_engine
|