blob: 29f16d3c2683f471f6222cf451fb37726bf1c8aa [file] [log] [blame]
Alex Deymoaea4c1c2015-08-19 20:24:43 -07001//
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//
Andrew de los Reyesd2135f32010-03-11 16:00:28 -080016
17#include <string.h>
18#include <unistd.h>
Darin Petkov7ed561b2011-10-04 02:59:03 -070019
Ben Chanab5a0af2017-10-12 14:57:50 -070020#include <memory>
Andrew de los Reyesd2135f32010-03-11 16:00:28 -080021#include <string>
22#include <vector>
Darin Petkov7ed561b2011-10-04 02:59:03 -070023
Andrew de los Reyesd2135f32010-03-11 16:00:28 -080024#include <gtest/gtest.h>
Darin Petkov7ed561b2011-10-04 02:59:03 -070025
Alex Deymo39910dc2015-11-09 17:04:30 -080026#include "update_engine/common/test_utils.h"
Alex Deymo246bf212016-03-22 19:27:33 -070027#include "update_engine/payload_consumer/bzip_extent_writer.h"
28#include "update_engine/payload_consumer/extent_writer.h"
29#include "update_engine/payload_consumer/xz_extent_writer.h"
Alex Deymo0bc26112015-10-19 20:54:57 -070030#include "update_engine/payload_generator/bzip.h"
Alex Deymo246bf212016-03-22 19:27:33 -070031#include "update_engine/payload_generator/xz.h"
Andrew de los Reyesd2135f32010-03-11 16:00:28 -080032
Alex Deymo10875d92014-11-10 21:52:57 -080033using chromeos_update_engine::test_utils::kRandomString;
Amin Hassanicd7edbe2017-09-18 17:05:02 -070034using google::protobuf::RepeatedPtrField;
Andrew de los Reyesd2135f32010-03-11 16:00:28 -080035using std::string;
36using std::vector;
37
38namespace chromeos_update_engine {
39
Alex Deymo246bf212016-03-22 19:27:33 -070040namespace {
41
42// ExtentWriter class that writes to memory, used to test the decompression
43// step with the corresponding extent writer.
44class MemoryExtentWriter : public ExtentWriter {
45 public:
46 // Creates the ExtentWriter that will write all the bytes to the passed |data|
47 // blob.
48 explicit MemoryExtentWriter(brillo::Blob* data) : data_(data) {
49 data_->clear();
50 }
51 ~MemoryExtentWriter() override = default;
52
53 bool Init(FileDescriptorPtr fd,
Amin Hassanicd7edbe2017-09-18 17:05:02 -070054 const RepeatedPtrField<Extent>& extents,
Alex Deymo246bf212016-03-22 19:27:33 -070055 uint32_t block_size) override {
56 return true;
57 }
58 bool Write(const void* bytes, size_t count) override {
59 data_->reserve(data_->size() + count);
60 data_->insert(data_->end(),
61 static_cast<const uint8_t*>(bytes),
62 static_cast<const uint8_t*>(bytes) + count);
63 return true;
64 }
65 bool EndImpl() override { return true; }
66
67 private:
68 brillo::Blob* data_;
69};
70
71template <typename W>
72bool DecompressWithWriter(const brillo::Blob& in, brillo::Blob* out) {
73 std::unique_ptr<ExtentWriter> writer(
Ben Chanab5a0af2017-10-12 14:57:50 -070074 new W(std::make_unique<MemoryExtentWriter>(out)));
Alex Deymo246bf212016-03-22 19:27:33 -070075 // Init() parameters are ignored by the testing MemoryExtentWriter.
Alex Deymod3251ef2016-03-29 21:01:54 -070076 bool ok = writer->Init(nullptr, {}, 1);
77 ok = writer->Write(in.data(), in.size()) && ok;
78 // Call End() even if the Write failed.
79 ok = writer->End() && ok;
80 return ok;
Alex Deymo246bf212016-03-22 19:27:33 -070081}
82
83} // namespace
84
Andrew de los Reyesd2135f32010-03-11 16:00:28 -080085template <typename T>
86class ZipTest : public ::testing::Test {
87 public:
Alex Deymo0bc26112015-10-19 20:54:57 -070088 bool ZipCompress(const brillo::Blob& in, brillo::Blob* out) const = 0;
Alex Deymo246bf212016-03-22 19:27:33 -070089 bool ZipDecompress(const brillo::Blob& in, brillo::Blob* out) const = 0;
Andrew de los Reyesd2135f32010-03-11 16:00:28 -080090};
91
Andrew de los Reyesd2135f32010-03-11 16:00:28 -080092class BzipTest {};
93
94template <>
95class ZipTest<BzipTest> : public ::testing::Test {
96 public:
Alex Deymo0bc26112015-10-19 20:54:57 -070097 bool ZipCompress(const brillo::Blob& in, brillo::Blob* out) const {
Andrew de los Reyesd2135f32010-03-11 16:00:28 -080098 return BzipCompress(in, out);
99 }
Alex Deymo246bf212016-03-22 19:27:33 -0700100 bool ZipDecompress(const brillo::Blob& in, brillo::Blob* out) const {
101 return DecompressWithWriter<BzipExtentWriter>(in, out);
Andrew de los Reyesd2135f32010-03-11 16:00:28 -0800102 }
103};
104
Alex Deymo246bf212016-03-22 19:27:33 -0700105class XzTest {};
106
107template <>
108class ZipTest<XzTest> : public ::testing::Test {
109 public:
110 bool ZipCompress(const brillo::Blob& in, brillo::Blob* out) const {
111 return XzCompress(in, out);
112 }
113 bool ZipDecompress(const brillo::Blob& in, brillo::Blob* out) const {
114 return DecompressWithWriter<XzExtentWriter>(in, out);
115 }
116};
117
Alex Deymo246bf212016-03-22 19:27:33 -0700118typedef ::testing::Types<BzipTest, XzTest> ZipTestTypes;
Alex Deymo246bf212016-03-22 19:27:33 -0700119
Andrew de los Reyesd2135f32010-03-11 16:00:28 -0800120TYPED_TEST_CASE(ZipTest, ZipTestTypes);
121
Andrew de los Reyesd2135f32010-03-11 16:00:28 -0800122TYPED_TEST(ZipTest, SimpleTest) {
Alex Deymo246bf212016-03-22 19:27:33 -0700123 string in_str(
124 "this should compress well xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
125 "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
126 "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
127 "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
128 "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
129 "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
130 brillo::Blob in(in_str.begin(), in_str.end());
Alex Vakulenko3f39d5c2015-10-13 09:27:13 -0700131 brillo::Blob out;
Alex Deymo246bf212016-03-22 19:27:33 -0700132 EXPECT_TRUE(this->ZipCompress(in, &out));
Andrew de los Reyesd2135f32010-03-11 16:00:28 -0800133 EXPECT_LT(out.size(), in.size());
Alex Deymo80f70ff2016-02-10 16:08:11 -0800134 EXPECT_GT(out.size(), 0U);
Alex Vakulenko3f39d5c2015-10-13 09:27:13 -0700135 brillo::Blob decompressed;
Andrew de los Reyesd2135f32010-03-11 16:00:28 -0800136 EXPECT_TRUE(this->ZipDecompress(out, &decompressed));
137 EXPECT_EQ(in.size(), decompressed.size());
Sen Jiang5288bd12018-05-03 11:39:04 -0700138 EXPECT_EQ(0, memcmp(in.data(), decompressed.data(), in.size()));
Andrew de los Reyesd2135f32010-03-11 16:00:28 -0800139}
140
141TYPED_TEST(ZipTest, PoorCompressionTest) {
Alex Deymo246bf212016-03-22 19:27:33 -0700142 brillo::Blob in(std::begin(kRandomString), std::end(kRandomString));
Alex Vakulenko3f39d5c2015-10-13 09:27:13 -0700143 brillo::Blob out;
Alex Deymo246bf212016-03-22 19:27:33 -0700144 EXPECT_TRUE(this->ZipCompress(in, &out));
Andrew de los Reyesd2135f32010-03-11 16:00:28 -0800145 EXPECT_GT(out.size(), in.size());
Alex Vakulenko3f39d5c2015-10-13 09:27:13 -0700146 brillo::Blob decompressed;
Alex Deymo246bf212016-03-22 19:27:33 -0700147 EXPECT_TRUE(this->ZipDecompress(out, &decompressed));
Andrew de los Reyesd2135f32010-03-11 16:00:28 -0800148 EXPECT_EQ(in.size(), decompressed.size());
Alex Deymo246bf212016-03-22 19:27:33 -0700149 EXPECT_EQ(in, decompressed);
Andrew de los Reyesd2135f32010-03-11 16:00:28 -0800150}
151
152TYPED_TEST(ZipTest, MalformedZipTest) {
Alex Deymo246bf212016-03-22 19:27:33 -0700153 brillo::Blob in(std::begin(kRandomString), std::end(kRandomString));
Alex Vakulenko3f39d5c2015-10-13 09:27:13 -0700154 brillo::Blob out;
Alex Deymo246bf212016-03-22 19:27:33 -0700155 EXPECT_FALSE(this->ZipDecompress(in, &out));
Andrew de los Reyesd2135f32010-03-11 16:00:28 -0800156}
157
158TYPED_TEST(ZipTest, EmptyInputsTest) {
Alex Deymo246bf212016-03-22 19:27:33 -0700159 brillo::Blob in;
Alex Vakulenko3f39d5c2015-10-13 09:27:13 -0700160 brillo::Blob out;
Alex Deymo246bf212016-03-22 19:27:33 -0700161 EXPECT_TRUE(this->ZipDecompress(in, &out));
Alex Deymo80f70ff2016-02-10 16:08:11 -0800162 EXPECT_EQ(0U, out.size());
Andrew de los Reyesd2135f32010-03-11 16:00:28 -0800163
Alex Deymo246bf212016-03-22 19:27:33 -0700164 EXPECT_TRUE(this->ZipCompress(in, &out));
Alex Deymo80f70ff2016-02-10 16:08:11 -0800165 EXPECT_EQ(0U, out.size());
Andrew de los Reyesd2135f32010-03-11 16:00:28 -0800166}
167
Sen Jiang5288bd12018-05-03 11:39:04 -0700168TYPED_TEST(ZipTest, CompressELFTest) {
169 string path = test_utils::GetBuildArtifactsPath("delta_generator");
170 brillo::Blob in;
171 utils::ReadFile(path, &in);
172 brillo::Blob out;
173 EXPECT_TRUE(this->ZipCompress(in, &out));
174 EXPECT_LT(out.size(), in.size());
175 EXPECT_GT(out.size(), 0U);
176 brillo::Blob decompressed;
177 EXPECT_TRUE(this->ZipDecompress(out, &decompressed));
178 EXPECT_EQ(in.size(), decompressed.size());
179 EXPECT_EQ(0, memcmp(in.data(), decompressed.data(), in.size()));
180}
181
Andrew de los Reyesd2135f32010-03-11 16:00:28 -0800182} // namespace chromeos_update_engine