blob: 54adfcbe07764c1cd1c2bbcb95f590c7cc88f07e [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
Andrew de los Reyesd2135f32010-03-11 16:00:28 -080020#include <string>
21#include <vector>
Darin Petkov7ed561b2011-10-04 02:59:03 -070022
Alex Deymo246bf212016-03-22 19:27:33 -070023#include <brillo/make_unique_ptr.h>
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;
Andrew de los Reyesd2135f32010-03-11 16:00:28 -080034using std::string;
35using std::vector;
36
37namespace chromeos_update_engine {
38
Alex Deymo246bf212016-03-22 19:27:33 -070039namespace {
40
41// ExtentWriter class that writes to memory, used to test the decompression
42// step with the corresponding extent writer.
43class MemoryExtentWriter : public ExtentWriter {
44 public:
45 // Creates the ExtentWriter that will write all the bytes to the passed |data|
46 // blob.
47 explicit MemoryExtentWriter(brillo::Blob* data) : data_(data) {
48 data_->clear();
49 }
50 ~MemoryExtentWriter() override = default;
51
52 bool Init(FileDescriptorPtr fd,
53 const vector<Extent>& extents,
54 uint32_t block_size) override {
55 return true;
56 }
57 bool Write(const void* bytes, size_t count) override {
58 data_->reserve(data_->size() + count);
59 data_->insert(data_->end(),
60 static_cast<const uint8_t*>(bytes),
61 static_cast<const uint8_t*>(bytes) + count);
62 return true;
63 }
64 bool EndImpl() override { return true; }
65
66 private:
67 brillo::Blob* data_;
68};
69
70template <typename W>
71bool DecompressWithWriter(const brillo::Blob& in, brillo::Blob* out) {
72 std::unique_ptr<ExtentWriter> writer(
73 new W(brillo::make_unique_ptr(new MemoryExtentWriter(out))));
74 // Init() parameters are ignored by the testing MemoryExtentWriter.
Alex Deymod3251ef2016-03-29 21:01:54 -070075 bool ok = writer->Init(nullptr, {}, 1);
76 ok = writer->Write(in.data(), in.size()) && ok;
77 // Call End() even if the Write failed.
78 ok = writer->End() && ok;
79 return ok;
Alex Deymo246bf212016-03-22 19:27:33 -070080}
81
82} // namespace
83
Andrew de los Reyesd2135f32010-03-11 16:00:28 -080084template <typename T>
85class ZipTest : public ::testing::Test {
86 public:
Alex Deymo0bc26112015-10-19 20:54:57 -070087 bool ZipCompress(const brillo::Blob& in, brillo::Blob* out) const = 0;
Alex Deymo246bf212016-03-22 19:27:33 -070088 bool ZipDecompress(const brillo::Blob& in, brillo::Blob* out) const = 0;
Andrew de los Reyesd2135f32010-03-11 16:00:28 -080089};
90
Andrew de los Reyesd2135f32010-03-11 16:00:28 -080091class BzipTest {};
92
93template <>
94class ZipTest<BzipTest> : public ::testing::Test {
95 public:
Alex Deymo0bc26112015-10-19 20:54:57 -070096 bool ZipCompress(const brillo::Blob& in, brillo::Blob* out) const {
Andrew de los Reyesd2135f32010-03-11 16:00:28 -080097 return BzipCompress(in, out);
98 }
Alex Deymo246bf212016-03-22 19:27:33 -070099 bool ZipDecompress(const brillo::Blob& in, brillo::Blob* out) const {
100 return DecompressWithWriter<BzipExtentWriter>(in, out);
Andrew de los Reyesd2135f32010-03-11 16:00:28 -0800101 }
102};
103
Alex Deymo246bf212016-03-22 19:27:33 -0700104class XzTest {};
105
106template <>
107class ZipTest<XzTest> : public ::testing::Test {
108 public:
109 bool ZipCompress(const brillo::Blob& in, brillo::Blob* out) const {
110 return XzCompress(in, out);
111 }
112 bool ZipDecompress(const brillo::Blob& in, brillo::Blob* out) const {
113 return DecompressWithWriter<XzExtentWriter>(in, out);
114 }
115};
116
117#ifdef __ANDROID__
118typedef ::testing::Types<BzipTest, XzTest> ZipTestTypes;
119#else
120// Chrome OS implementation of Xz compressor just returns false.
Darin Petkov7ed561b2011-10-04 02:59:03 -0700121typedef ::testing::Types<BzipTest> ZipTestTypes;
Alex Deymo246bf212016-03-22 19:27:33 -0700122#endif // __ANDROID__
123
Andrew de los Reyesd2135f32010-03-11 16:00:28 -0800124TYPED_TEST_CASE(ZipTest, ZipTestTypes);
125
Andrew de los Reyesd2135f32010-03-11 16:00:28 -0800126TYPED_TEST(ZipTest, SimpleTest) {
Alex Deymo246bf212016-03-22 19:27:33 -0700127 string in_str(
128 "this should compress well xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
129 "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
130 "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
131 "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
132 "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
133 "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
134 brillo::Blob in(in_str.begin(), in_str.end());
Alex Vakulenko3f39d5c2015-10-13 09:27:13 -0700135 brillo::Blob out;
Alex Deymo246bf212016-03-22 19:27:33 -0700136 EXPECT_TRUE(this->ZipCompress(in, &out));
Andrew de los Reyesd2135f32010-03-11 16:00:28 -0800137 EXPECT_LT(out.size(), in.size());
Alex Deymo80f70ff2016-02-10 16:08:11 -0800138 EXPECT_GT(out.size(), 0U);
Alex Vakulenko3f39d5c2015-10-13 09:27:13 -0700139 brillo::Blob decompressed;
Andrew de los Reyesd2135f32010-03-11 16:00:28 -0800140 EXPECT_TRUE(this->ZipDecompress(out, &decompressed));
141 EXPECT_EQ(in.size(), decompressed.size());
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -0800142 EXPECT_TRUE(!memcmp(in.data(), decompressed.data(), in.size()));
Andrew de los Reyesd2135f32010-03-11 16:00:28 -0800143}
144
145TYPED_TEST(ZipTest, PoorCompressionTest) {
Alex Deymo246bf212016-03-22 19:27:33 -0700146 brillo::Blob in(std::begin(kRandomString), std::end(kRandomString));
Alex Vakulenko3f39d5c2015-10-13 09:27:13 -0700147 brillo::Blob out;
Alex Deymo246bf212016-03-22 19:27:33 -0700148 EXPECT_TRUE(this->ZipCompress(in, &out));
Andrew de los Reyesd2135f32010-03-11 16:00:28 -0800149 EXPECT_GT(out.size(), in.size());
Alex Vakulenko3f39d5c2015-10-13 09:27:13 -0700150 brillo::Blob decompressed;
Alex Deymo246bf212016-03-22 19:27:33 -0700151 EXPECT_TRUE(this->ZipDecompress(out, &decompressed));
Andrew de los Reyesd2135f32010-03-11 16:00:28 -0800152 EXPECT_EQ(in.size(), decompressed.size());
Alex Deymo246bf212016-03-22 19:27:33 -0700153 EXPECT_EQ(in, decompressed);
Andrew de los Reyesd2135f32010-03-11 16:00:28 -0800154}
155
156TYPED_TEST(ZipTest, MalformedZipTest) {
Alex Deymo246bf212016-03-22 19:27:33 -0700157 brillo::Blob in(std::begin(kRandomString), std::end(kRandomString));
Alex Vakulenko3f39d5c2015-10-13 09:27:13 -0700158 brillo::Blob out;
Alex Deymo246bf212016-03-22 19:27:33 -0700159 EXPECT_FALSE(this->ZipDecompress(in, &out));
Andrew de los Reyesd2135f32010-03-11 16:00:28 -0800160}
161
162TYPED_TEST(ZipTest, EmptyInputsTest) {
Alex Deymo246bf212016-03-22 19:27:33 -0700163 brillo::Blob in;
Alex Vakulenko3f39d5c2015-10-13 09:27:13 -0700164 brillo::Blob out;
Alex Deymo246bf212016-03-22 19:27:33 -0700165 EXPECT_TRUE(this->ZipDecompress(in, &out));
Alex Deymo80f70ff2016-02-10 16:08:11 -0800166 EXPECT_EQ(0U, out.size());
Andrew de los Reyesd2135f32010-03-11 16:00:28 -0800167
Alex Deymo246bf212016-03-22 19:27:33 -0700168 EXPECT_TRUE(this->ZipCompress(in, &out));
Alex Deymo80f70ff2016-02-10 16:08:11 -0800169 EXPECT_EQ(0U, out.size());
Andrew de los Reyesd2135f32010-03-11 16:00:28 -0800170}
171
172} // namespace chromeos_update_engine