blob: d84019acf1dbb134173f7f62dcb6cf947f160050 [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 Deymoaab50e32014-11-10 19:55:35 -080017#include "update_engine/bzip_extent_writer.h"
18
Nam T. Nguyenf1d582e2014-12-08 15:07:17 -080019#include <fcntl.h>
Andrew de los Reyes80061062010-02-04 14:25:00 -080020#include <sys/stat.h>
21#include <sys/types.h>
22#include <unistd.h>
Alex Deymo05322872015-09-30 09:50:24 -070023
Andrew de los Reyes80061062010-02-04 14:25:00 -080024#include <algorithm>
25#include <string>
26#include <vector>
Alex Deymo05322872015-09-30 09:50:24 -070027
Alex Vakulenko3f39d5c2015-10-13 09:27:13 -070028#include <brillo/make_unique_ptr.h>
Andrew de los Reyes80061062010-02-04 14:25:00 -080029#include <gtest/gtest.h>
Alex Deymo05322872015-09-30 09:50:24 -070030
Andrew de los Reyes80061062010-02-04 14:25:00 -080031#include "update_engine/test_utils.h"
32#include "update_engine/utils.h"
33
34using std::min;
35using std::string;
36using std::vector;
37
38namespace chromeos_update_engine {
39
40namespace {
41const char kPathTemplate[] = "./BzipExtentWriterTest-file.XXXXXX";
Andrew de los Reyes09e56d62010-04-23 13:45:53 -070042const uint32_t kBlockSize = 4096;
Andrew de los Reyes80061062010-02-04 14:25:00 -080043}
44
45class BzipExtentWriterTest : public ::testing::Test {
46 protected:
Alex Deymo610277e2014-11-11 21:18:11 -080047 void SetUp() override {
Andrew de los Reyes80061062010-02-04 14:25:00 -080048 memcpy(path_, kPathTemplate, sizeof(kPathTemplate));
Nam T. Nguyenf1d582e2014-12-08 15:07:17 -080049 fd_.reset(new EintrSafeFileDescriptor);
50 int fd = mkstemp(path_);
51 ASSERT_TRUE(fd_->Open(path_, O_RDWR, 0600));
52 close(fd);
Andrew de los Reyes80061062010-02-04 14:25:00 -080053 }
Alex Deymo610277e2014-11-11 21:18:11 -080054 void TearDown() override {
Nam T. Nguyenf1d582e2014-12-08 15:07:17 -080055 fd_->Close();
Andrew de los Reyes80061062010-02-04 14:25:00 -080056 unlink(path_);
57 }
Andrew de los Reyes80061062010-02-04 14:25:00 -080058 void WriteAlignedExtents(size_t chunk_size, size_t first_chunk_size);
59 void TestZeroPad(bool aligned_size);
Nam T. Nguyenf1d582e2014-12-08 15:07:17 -080060
61 FileDescriptorPtr fd_;
Andrew de los Reyes80061062010-02-04 14:25:00 -080062 char path_[sizeof(kPathTemplate)];
63};
64
65TEST_F(BzipExtentWriterTest, SimpleTest) {
66 vector<Extent> extents;
67 Extent extent;
68 extent.set_start_block(0);
69 extent.set_num_blocks(1);
70 extents.push_back(extent);
71
72 // 'echo test | bzip2 | hexdump' yields:
Darin Petkove0622392013-04-24 12:56:19 +020073 static const char test_uncompressed[] = "test\n";
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -080074 static const uint8_t test[] = {
Andrew de los Reyes80061062010-02-04 14:25:00 -080075 0x42, 0x5a, 0x68, 0x39, 0x31, 0x41, 0x59, 0x26, 0x53, 0x59, 0xcc, 0xc3,
76 0x71, 0xd4, 0x00, 0x00, 0x02, 0x41, 0x80, 0x00, 0x10, 0x02, 0x00, 0x0c,
77 0x00, 0x20, 0x00, 0x21, 0x9a, 0x68, 0x33, 0x4d, 0x19, 0x97, 0x8b, 0xb9,
Gilad Arnolde1d1e982013-07-01 04:25:55 -070078 0x22, 0x9c, 0x28, 0x48, 0x66, 0x61, 0xb8, 0xea, 0x00,
Andrew de los Reyes80061062010-02-04 14:25:00 -080079 };
Gilad Arnolde1d1e982013-07-01 04:25:55 -070080
Alex Deymo05322872015-09-30 09:50:24 -070081 BzipExtentWriter bzip_writer(
Alex Vakulenko3f39d5c2015-10-13 09:27:13 -070082 brillo::make_unique_ptr(new DirectExtentWriter()));
Nam T. Nguyenf1d582e2014-12-08 15:07:17 -080083 EXPECT_TRUE(bzip_writer.Init(fd_, extents, kBlockSize));
Andrew de los Reyes80061062010-02-04 14:25:00 -080084 EXPECT_TRUE(bzip_writer.Write(test, sizeof(test)));
85 EXPECT_TRUE(bzip_writer.End());
Gilad Arnolde1d1e982013-07-01 04:25:55 -070086
Alex Vakulenko3f39d5c2015-10-13 09:27:13 -070087 brillo::Blob buf;
Nam T. Nguyenf1d582e2014-12-08 15:07:17 -080088 EXPECT_TRUE(utils::ReadFile(path_, &buf));
89 EXPECT_EQ(strlen(test_uncompressed), buf.size());
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -080090 EXPECT_EQ(string(buf.begin(), buf.end()), string(test_uncompressed));
Andrew de los Reyes80061062010-02-04 14:25:00 -080091}
92
93TEST_F(BzipExtentWriterTest, ChunkedTest) {
Alex Vakulenko3f39d5c2015-10-13 09:27:13 -070094 const brillo::Blob::size_type kDecompressedLength = 2048 * 1024; // 2 MiB
Gilad Arnolde1d1e982013-07-01 04:25:55 -070095 string decompressed_path;
96 ASSERT_TRUE(utils::MakeTempFile("BzipExtentWriterTest-decompressed-XXXXXX",
Alex Vakulenko88b591f2014-08-28 16:48:57 -070097 &decompressed_path, nullptr));
Gilad Arnolde1d1e982013-07-01 04:25:55 -070098 string compressed_path;
99 ASSERT_TRUE(utils::MakeTempFile("BzipExtentWriterTest-compressed-XXXXXX",
Alex Vakulenko88b591f2014-08-28 16:48:57 -0700100 &compressed_path, nullptr));
Andrew de los Reyes80061062010-02-04 14:25:00 -0800101 const size_t kChunkSize = 3;
Gilad Arnolde1d1e982013-07-01 04:25:55 -0700102
Andrew de los Reyes80061062010-02-04 14:25:00 -0800103 vector<Extent> extents;
104 Extent extent;
105 extent.set_start_block(0);
106 extent.set_num_blocks(kDecompressedLength / kBlockSize + 1);
107 extents.push_back(extent);
108
Alex Vakulenko3f39d5c2015-10-13 09:27:13 -0700109 brillo::Blob decompressed_data(kDecompressedLength);
Alex Deymo10875d92014-11-10 21:52:57 -0800110 test_utils::FillWithData(&decompressed_data);
Gilad Arnolde1d1e982013-07-01 04:25:55 -0700111
Alex Deymo10875d92014-11-10 21:52:57 -0800112 EXPECT_TRUE(test_utils::WriteFileVector(
113 decompressed_path, decompressed_data));
Gilad Arnolde1d1e982013-07-01 04:25:55 -0700114
Alex Deymo10875d92014-11-10 21:52:57 -0800115 EXPECT_EQ(0, test_utils::System(
116 string("cat ") + decompressed_path + "|bzip2>" + compressed_path));
Andrew de los Reyes80061062010-02-04 14:25:00 -0800117
Alex Vakulenko3f39d5c2015-10-13 09:27:13 -0700118 brillo::Blob compressed_data;
Gilad Arnolde1d1e982013-07-01 04:25:55 -0700119 EXPECT_TRUE(utils::ReadFile(compressed_path, &compressed_data));
120
Alex Deymo05322872015-09-30 09:50:24 -0700121 BzipExtentWriter bzip_writer(
Alex Vakulenko3f39d5c2015-10-13 09:27:13 -0700122 brillo::make_unique_ptr(new DirectExtentWriter()));
Nam T. Nguyenf1d582e2014-12-08 15:07:17 -0800123 EXPECT_TRUE(bzip_writer.Init(fd_, extents, kBlockSize));
Andrew de los Reyes80061062010-02-04 14:25:00 -0800124
Alex Vakulenko3f39d5c2015-10-13 09:27:13 -0700125 brillo::Blob original_compressed_data = compressed_data;
126 for (brillo::Blob::size_type i = 0; i < compressed_data.size();
Andrew de los Reyes80061062010-02-04 14:25:00 -0800127 i += kChunkSize) {
128 size_t this_chunk_size = min(kChunkSize, compressed_data.size() - i);
129 EXPECT_TRUE(bzip_writer.Write(&compressed_data[i], this_chunk_size));
130 }
131 EXPECT_TRUE(bzip_writer.End());
Darin Petkove0622392013-04-24 12:56:19 +0200132
133 // Check that the const input has not been clobbered.
Alex Deymo10875d92014-11-10 21:52:57 -0800134 test_utils::ExpectVectorsEq(original_compressed_data, compressed_data);
Gilad Arnolde1d1e982013-07-01 04:25:55 -0700135
Alex Vakulenko3f39d5c2015-10-13 09:27:13 -0700136 brillo::Blob output;
Nam T. Nguyenf1d582e2014-12-08 15:07:17 -0800137 EXPECT_TRUE(utils::ReadFile(path_, &output));
138 EXPECT_EQ(kDecompressedLength, output.size());
Alex Deymo10875d92014-11-10 21:52:57 -0800139 test_utils::ExpectVectorsEq(decompressed_data, output);
Gilad Arnolde1d1e982013-07-01 04:25:55 -0700140
141 unlink(decompressed_path.c_str());
142 unlink(compressed_path.c_str());
Andrew de los Reyes80061062010-02-04 14:25:00 -0800143}
144
145} // namespace chromeos_update_engine