zip_unittest.cc 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. //
  2. // Copyright (C) 2011 The Android Open Source Project
  3. //
  4. // Licensed under the Apache License, Version 2.0 (the "License");
  5. // you may not use this file except in compliance with the License.
  6. // You may obtain a copy of the License at
  7. //
  8. // http://www.apache.org/licenses/LICENSE-2.0
  9. //
  10. // Unless required by applicable law or agreed to in writing, software
  11. // distributed under the License is distributed on an "AS IS" BASIS,
  12. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. // See the License for the specific language governing permissions and
  14. // limitations under the License.
  15. //
  16. #include <string.h>
  17. #include <unistd.h>
  18. #include <memory>
  19. #include <string>
  20. #include <vector>
  21. #include <gtest/gtest.h>
  22. #include "update_engine/common/test_utils.h"
  23. #include "update_engine/payload_consumer/bzip_extent_writer.h"
  24. #include "update_engine/payload_consumer/extent_writer.h"
  25. #include "update_engine/payload_consumer/xz_extent_writer.h"
  26. #include "update_engine/payload_generator/bzip.h"
  27. #include "update_engine/payload_generator/xz.h"
  28. using chromeos_update_engine::test_utils::kRandomString;
  29. using google::protobuf::RepeatedPtrField;
  30. using std::string;
  31. using std::vector;
  32. namespace chromeos_update_engine {
  33. namespace {
  34. // ExtentWriter class that writes to memory, used to test the decompression
  35. // step with the corresponding extent writer.
  36. class MemoryExtentWriter : public ExtentWriter {
  37. public:
  38. // Creates the ExtentWriter that will write all the bytes to the passed |data|
  39. // blob.
  40. explicit MemoryExtentWriter(brillo::Blob* data) : data_(data) {
  41. data_->clear();
  42. }
  43. ~MemoryExtentWriter() override = default;
  44. bool Init(FileDescriptorPtr fd,
  45. const RepeatedPtrField<Extent>& extents,
  46. uint32_t block_size) override {
  47. return true;
  48. }
  49. bool Write(const void* bytes, size_t count) override {
  50. data_->reserve(data_->size() + count);
  51. data_->insert(data_->end(),
  52. static_cast<const uint8_t*>(bytes),
  53. static_cast<const uint8_t*>(bytes) + count);
  54. return true;
  55. }
  56. private:
  57. brillo::Blob* data_;
  58. };
  59. template <typename W>
  60. bool DecompressWithWriter(const brillo::Blob& in, brillo::Blob* out) {
  61. std::unique_ptr<ExtentWriter> writer(
  62. new W(std::make_unique<MemoryExtentWriter>(out)));
  63. // Init() parameters are ignored by the testing MemoryExtentWriter.
  64. bool ok = writer->Init(nullptr, {}, 1);
  65. ok = writer->Write(in.data(), in.size()) && ok;
  66. return ok;
  67. }
  68. } // namespace
  69. template <typename T>
  70. class ZipTest : public ::testing::Test {
  71. public:
  72. bool ZipCompress(const brillo::Blob& in, brillo::Blob* out) const = 0;
  73. bool ZipDecompress(const brillo::Blob& in, brillo::Blob* out) const = 0;
  74. };
  75. class BzipTest {};
  76. template <>
  77. class ZipTest<BzipTest> : public ::testing::Test {
  78. public:
  79. bool ZipCompress(const brillo::Blob& in, brillo::Blob* out) const {
  80. return BzipCompress(in, out);
  81. }
  82. bool ZipDecompress(const brillo::Blob& in, brillo::Blob* out) const {
  83. return DecompressWithWriter<BzipExtentWriter>(in, out);
  84. }
  85. };
  86. class XzTest {};
  87. template <>
  88. class ZipTest<XzTest> : public ::testing::Test {
  89. public:
  90. bool ZipCompress(const brillo::Blob& in, brillo::Blob* out) const {
  91. return XzCompress(in, out);
  92. }
  93. bool ZipDecompress(const brillo::Blob& in, brillo::Blob* out) const {
  94. return DecompressWithWriter<XzExtentWriter>(in, out);
  95. }
  96. };
  97. typedef ::testing::Types<BzipTest, XzTest> ZipTestTypes;
  98. TYPED_TEST_CASE(ZipTest, ZipTestTypes);
  99. TYPED_TEST(ZipTest, SimpleTest) {
  100. string in_str(
  101. "this should compress well xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
  102. "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
  103. "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
  104. "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
  105. "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
  106. "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
  107. brillo::Blob in(in_str.begin(), in_str.end());
  108. brillo::Blob out;
  109. EXPECT_TRUE(this->ZipCompress(in, &out));
  110. EXPECT_LT(out.size(), in.size());
  111. EXPECT_GT(out.size(), 0U);
  112. brillo::Blob decompressed;
  113. EXPECT_TRUE(this->ZipDecompress(out, &decompressed));
  114. EXPECT_EQ(in.size(), decompressed.size());
  115. EXPECT_EQ(0, memcmp(in.data(), decompressed.data(), in.size()));
  116. }
  117. TYPED_TEST(ZipTest, PoorCompressionTest) {
  118. brillo::Blob in(std::begin(kRandomString), std::end(kRandomString));
  119. brillo::Blob out;
  120. EXPECT_TRUE(this->ZipCompress(in, &out));
  121. EXPECT_GT(out.size(), in.size());
  122. brillo::Blob decompressed;
  123. EXPECT_TRUE(this->ZipDecompress(out, &decompressed));
  124. EXPECT_EQ(in.size(), decompressed.size());
  125. EXPECT_EQ(in, decompressed);
  126. }
  127. TYPED_TEST(ZipTest, MalformedZipTest) {
  128. brillo::Blob in(std::begin(kRandomString), std::end(kRandomString));
  129. brillo::Blob out;
  130. EXPECT_FALSE(this->ZipDecompress(in, &out));
  131. }
  132. TYPED_TEST(ZipTest, EmptyInputsTest) {
  133. brillo::Blob in;
  134. brillo::Blob out;
  135. EXPECT_TRUE(this->ZipDecompress(in, &out));
  136. EXPECT_EQ(0U, out.size());
  137. EXPECT_TRUE(this->ZipCompress(in, &out));
  138. EXPECT_EQ(0U, out.size());
  139. }
  140. TYPED_TEST(ZipTest, CompressELFTest) {
  141. string path = test_utils::GetBuildArtifactsPath("delta_generator");
  142. brillo::Blob in;
  143. utils::ReadFile(path, &in);
  144. brillo::Blob out;
  145. EXPECT_TRUE(this->ZipCompress(in, &out));
  146. EXPECT_LT(out.size(), in.size());
  147. EXPECT_GT(out.size(), 0U);
  148. brillo::Blob decompressed;
  149. EXPECT_TRUE(this->ZipDecompress(out, &decompressed));
  150. EXPECT_EQ(in.size(), decompressed.size());
  151. EXPECT_EQ(0, memcmp(in.data(), decompressed.data(), in.size()));
  152. }
  153. } // namespace chromeos_update_engine