blob: 125e1e5e2a3cbab5860842bbfc00a75bddaae3a5 [file] [log] [blame]
Alex Deymoaea4c1c2015-08-19 20:24:43 -07001//
2// Copyright (C) 2009 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 Reyes80061062010-02-04 14:25:00 -080016
Alex Deymo39910dc2015-11-09 17:04:30 -080017#include "update_engine/payload_consumer/bzip_extent_writer.h"
Alex Deymoaab50e32014-11-10 19:55:35 -080018
Xiyuan Xia4eccae22016-02-26 14:30:02 -080019#include <fcntl.h>
20
Andrew de los Reyes80061062010-02-04 14:25:00 -080021#include <algorithm>
Ben Chanab5a0af2017-10-12 14:57:50 -070022#include <memory>
Andrew de los Reyes80061062010-02-04 14:25:00 -080023#include <string>
24#include <vector>
Alex Deymo05322872015-09-30 09:50:24 -070025
Andrew de los Reyes80061062010-02-04 14:25:00 -080026#include <gtest/gtest.h>
Alex Deymo05322872015-09-30 09:50:24 -070027
Alex Deymo39910dc2015-11-09 17:04:30 -080028#include "update_engine/common/test_utils.h"
29#include "update_engine/common/utils.h"
Amin Hassanicd7edbe2017-09-18 17:05:02 -070030#include "update_engine/payload_generator/extent_ranges.h"
Andrew de los Reyes80061062010-02-04 14:25:00 -080031
Amin Hassanicd7edbe2017-09-18 17:05:02 -070032using google::protobuf::RepeatedPtrField;
Andrew de los Reyes80061062010-02-04 14:25:00 -080033using std::min;
34using std::string;
35using std::vector;
36
37namespace chromeos_update_engine {
38
39namespace {
Andrew de los Reyes09e56d62010-04-23 13:45:53 -070040const uint32_t kBlockSize = 4096;
Andrew de los Reyes80061062010-02-04 14:25:00 -080041}
42
43class BzipExtentWriterTest : public ::testing::Test {
44 protected:
Alex Deymo610277e2014-11-11 21:18:11 -080045 void SetUp() override {
Nam T. Nguyenf1d582e2014-12-08 15:07:17 -080046 fd_.reset(new EintrSafeFileDescriptor);
Alex Deymobffa0602016-02-12 17:16:29 -080047 ASSERT_TRUE(fd_->Open(temp_file_.path().c_str(), O_RDWR, 0600));
Andrew de los Reyes80061062010-02-04 14:25:00 -080048 }
Amin Hassani008c4582019-01-13 16:22:47 -080049 void TearDown() override { fd_->Close(); }
Nam T. Nguyenf1d582e2014-12-08 15:07:17 -080050
51 FileDescriptorPtr fd_;
Alex Deymobffa0602016-02-12 17:16:29 -080052 test_utils::ScopedTempFile temp_file_{"BzipExtentWriterTest-file.XXXXXX"};
Andrew de los Reyes80061062010-02-04 14:25:00 -080053};
54
55TEST_F(BzipExtentWriterTest, SimpleTest) {
Amin Hassanicd7edbe2017-09-18 17:05:02 -070056 vector<Extent> extents = {ExtentForRange(0, 1)};
Andrew de los Reyes80061062010-02-04 14:25:00 -080057
58 // 'echo test | bzip2 | hexdump' yields:
Darin Petkove0622392013-04-24 12:56:19 +020059 static const char test_uncompressed[] = "test\n";
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -080060 static const uint8_t test[] = {
Amin Hassani008c4582019-01-13 16:22:47 -080061 0x42, 0x5a, 0x68, 0x39, 0x31, 0x41, 0x59, 0x26, 0x53, 0x59, 0xcc, 0xc3,
62 0x71, 0xd4, 0x00, 0x00, 0x02, 0x41, 0x80, 0x00, 0x10, 0x02, 0x00, 0x0c,
63 0x00, 0x20, 0x00, 0x21, 0x9a, 0x68, 0x33, 0x4d, 0x19, 0x97, 0x8b, 0xb9,
64 0x22, 0x9c, 0x28, 0x48, 0x66, 0x61, 0xb8, 0xea, 0x00,
Andrew de los Reyes80061062010-02-04 14:25:00 -080065 };
Gilad Arnolde1d1e982013-07-01 04:25:55 -070066
Ben Chanab5a0af2017-10-12 14:57:50 -070067 BzipExtentWriter bzip_writer(std::make_unique<DirectExtentWriter>());
Amin Hassanicd7edbe2017-09-18 17:05:02 -070068 EXPECT_TRUE(
69 bzip_writer.Init(fd_, {extents.begin(), extents.end()}, kBlockSize));
Andrew de los Reyes80061062010-02-04 14:25:00 -080070 EXPECT_TRUE(bzip_writer.Write(test, sizeof(test)));
Gilad Arnolde1d1e982013-07-01 04:25:55 -070071
Alex Vakulenko3f39d5c2015-10-13 09:27:13 -070072 brillo::Blob buf;
Alex Deymobffa0602016-02-12 17:16:29 -080073 EXPECT_TRUE(utils::ReadFile(temp_file_.path(), &buf));
Nam T. Nguyenf1d582e2014-12-08 15:07:17 -080074 EXPECT_EQ(strlen(test_uncompressed), buf.size());
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -080075 EXPECT_EQ(string(buf.begin(), buf.end()), string(test_uncompressed));
Andrew de los Reyes80061062010-02-04 14:25:00 -080076}
77
78TEST_F(BzipExtentWriterTest, ChunkedTest) {
Alex Deymobffa0602016-02-12 17:16:29 -080079 // Generated with:
Xiyuan Xia4eccae22016-02-26 14:30:02 -080080 // yes "ABC" | head -c 819200 | bzip2 -9 |
81 // hexdump -v -e '" " 11/1 "0x%02x, " "\n"'
Alex Deymobffa0602016-02-12 17:16:29 -080082 static const uint8_t kCompressedData[] = {
83 0x42, 0x5a, 0x68, 0x39, 0x31, 0x41, 0x59, 0x26, 0x53, 0x59, 0xbe,
84 0x1c, 0xda, 0xee, 0x03, 0x1f, 0xff, 0xc4, 0x00, 0x00, 0x10, 0x38,
85 0x00, 0x20, 0x00, 0x50, 0x66, 0x9a, 0x05, 0x28, 0x38, 0x00, 0x11,
86 0x60, 0x00, 0x22, 0xd0, 0x00, 0x45, 0xc0, 0x00, 0x8b, 0xc5, 0xdc,
87 0x91, 0x4e, 0x14, 0x24, 0x2f, 0x87, 0x36, 0xbb, 0x80};
88 brillo::Blob compressed_data(std::begin(kCompressedData),
89 std::end(kCompressedData));
90
91 const brillo::Blob::size_type kDecompressedLength = 800 * 1024; // 800 KiB
Andrew de los Reyes80061062010-02-04 14:25:00 -080092 const size_t kChunkSize = 3;
Gilad Arnolde1d1e982013-07-01 04:25:55 -070093
Alex Deymobffa0602016-02-12 17:16:29 -080094 brillo::Blob decompressed_data(kDecompressedLength);
95 for (size_t i = 0; i < decompressed_data.size(); ++i)
96 decompressed_data[i] = static_cast<uint8_t>("ABC\n"[i % 4]);
97
Sen Jiang0a582fb2018-06-26 19:27:21 -070098 vector<Extent> extents = {ExtentForBytes(kBlockSize, 0, kDecompressedLength)};
Andrew de los Reyes80061062010-02-04 14:25:00 -080099
Ben Chanab5a0af2017-10-12 14:57:50 -0700100 BzipExtentWriter bzip_writer(std::make_unique<DirectExtentWriter>());
Amin Hassanicd7edbe2017-09-18 17:05:02 -0700101 EXPECT_TRUE(
102 bzip_writer.Init(fd_, {extents.begin(), extents.end()}, kBlockSize));
Andrew de los Reyes80061062010-02-04 14:25:00 -0800103
Alex Vakulenko3f39d5c2015-10-13 09:27:13 -0700104 brillo::Blob original_compressed_data = compressed_data;
105 for (brillo::Blob::size_type i = 0; i < compressed_data.size();
Andrew de los Reyes80061062010-02-04 14:25:00 -0800106 i += kChunkSize) {
107 size_t this_chunk_size = min(kChunkSize, compressed_data.size() - i);
108 EXPECT_TRUE(bzip_writer.Write(&compressed_data[i], this_chunk_size));
109 }
Darin Petkove0622392013-04-24 12:56:19 +0200110
111 // Check that the const input has not been clobbered.
Alex Deymo10875d92014-11-10 21:52:57 -0800112 test_utils::ExpectVectorsEq(original_compressed_data, compressed_data);
Gilad Arnolde1d1e982013-07-01 04:25:55 -0700113
Alex Vakulenko3f39d5c2015-10-13 09:27:13 -0700114 brillo::Blob output;
Alex Deymobffa0602016-02-12 17:16:29 -0800115 EXPECT_TRUE(utils::ReadFile(temp_file_.path(), &output));
Nam T. Nguyenf1d582e2014-12-08 15:07:17 -0800116 EXPECT_EQ(kDecompressedLength, output.size());
Alex Deymo10875d92014-11-10 21:52:57 -0800117 test_utils::ExpectVectorsEq(decompressed_data, output);
Andrew de los Reyes80061062010-02-04 14:25:00 -0800118}
119
120} // namespace chromeos_update_engine