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.
172 lines
5.3 KiB
172 lines
5.3 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 <string> |
|
#include <vector> |
|
|
|
#include <brillo/make_unique_ptr.h> |
|
#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 std::string; |
|
using std::vector; |
|
|
|
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(FileDescriptorPtr fd, |
|
const vector<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; |
|
} |
|
bool EndImpl() override { 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(brillo::make_unique_ptr(new MemoryExtentWriter(out)))); |
|
// Init() parameters are ignored by the testing MemoryExtentWriter. |
|
bool ok = writer->Init(nullptr, {}, 1); |
|
ok = writer->Write(in.data(), in.size()) && ok; |
|
// Call End() even if the Write failed. |
|
ok = writer->End() && 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); |
|
} |
|
}; |
|
|
|
#ifdef __ANDROID__ |
|
typedef ::testing::Types<BzipTest, XzTest> ZipTestTypes; |
|
#else |
|
// Chrome OS implementation of Xz compressor just returns false. |
|
typedef ::testing::Types<BzipTest> ZipTestTypes; |
|
#endif // __ANDROID__ |
|
|
|
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_TRUE(!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()); |
|
} |
|
|
|
} // namespace chromeos_update_engine
|
|
|