blob: 14e821a753031aa2964f90aac27c5d84a9948828 [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>
23#include <algorithm>
24#include <string>
25#include <vector>
26#include <gtest/gtest.h>
Andrew de los Reyes80061062010-02-04 14:25:00 -080027#include "update_engine/test_utils.h"
28#include "update_engine/utils.h"
29
30using std::min;
31using std::string;
32using std::vector;
33
34namespace chromeos_update_engine {
35
36namespace {
37const char kPathTemplate[] = "./BzipExtentWriterTest-file.XXXXXX";
Andrew de los Reyes09e56d62010-04-23 13:45:53 -070038const uint32_t kBlockSize = 4096;
Andrew de los Reyes80061062010-02-04 14:25:00 -080039}
40
41class BzipExtentWriterTest : public ::testing::Test {
42 protected:
Alex Deymo610277e2014-11-11 21:18:11 -080043 void SetUp() override {
Andrew de los Reyes80061062010-02-04 14:25:00 -080044 memcpy(path_, kPathTemplate, sizeof(kPathTemplate));
Nam T. Nguyenf1d582e2014-12-08 15:07:17 -080045 fd_.reset(new EintrSafeFileDescriptor);
46 int fd = mkstemp(path_);
47 ASSERT_TRUE(fd_->Open(path_, O_RDWR, 0600));
48 close(fd);
Andrew de los Reyes80061062010-02-04 14:25:00 -080049 }
Alex Deymo610277e2014-11-11 21:18:11 -080050 void TearDown() override {
Nam T. Nguyenf1d582e2014-12-08 15:07:17 -080051 fd_->Close();
Andrew de los Reyes80061062010-02-04 14:25:00 -080052 unlink(path_);
53 }
Andrew de los Reyes80061062010-02-04 14:25:00 -080054 void WriteAlignedExtents(size_t chunk_size, size_t first_chunk_size);
55 void TestZeroPad(bool aligned_size);
Nam T. Nguyenf1d582e2014-12-08 15:07:17 -080056
57 FileDescriptorPtr fd_;
Andrew de los Reyes80061062010-02-04 14:25:00 -080058 char path_[sizeof(kPathTemplate)];
59};
60
61TEST_F(BzipExtentWriterTest, SimpleTest) {
62 vector<Extent> extents;
63 Extent extent;
64 extent.set_start_block(0);
65 extent.set_num_blocks(1);
66 extents.push_back(extent);
67
68 // 'echo test | bzip2 | hexdump' yields:
Darin Petkove0622392013-04-24 12:56:19 +020069 static const char test_uncompressed[] = "test\n";
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -080070 static const uint8_t test[] = {
Andrew de los Reyes80061062010-02-04 14:25:00 -080071 0x42, 0x5a, 0x68, 0x39, 0x31, 0x41, 0x59, 0x26, 0x53, 0x59, 0xcc, 0xc3,
72 0x71, 0xd4, 0x00, 0x00, 0x02, 0x41, 0x80, 0x00, 0x10, 0x02, 0x00, 0x0c,
73 0x00, 0x20, 0x00, 0x21, 0x9a, 0x68, 0x33, 0x4d, 0x19, 0x97, 0x8b, 0xb9,
Gilad Arnolde1d1e982013-07-01 04:25:55 -070074 0x22, 0x9c, 0x28, 0x48, 0x66, 0x61, 0xb8, 0xea, 0x00,
Andrew de los Reyes80061062010-02-04 14:25:00 -080075 };
Gilad Arnolde1d1e982013-07-01 04:25:55 -070076
Andrew de los Reyes80061062010-02-04 14:25:00 -080077 DirectExtentWriter direct_writer;
78 BzipExtentWriter bzip_writer(&direct_writer);
Nam T. Nguyenf1d582e2014-12-08 15:07:17 -080079 EXPECT_TRUE(bzip_writer.Init(fd_, extents, kBlockSize));
Andrew de los Reyes80061062010-02-04 14:25:00 -080080 EXPECT_TRUE(bzip_writer.Write(test, sizeof(test)));
81 EXPECT_TRUE(bzip_writer.End());
Gilad Arnolde1d1e982013-07-01 04:25:55 -070082
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -080083 chromeos::Blob buf;
Nam T. Nguyenf1d582e2014-12-08 15:07:17 -080084 EXPECT_TRUE(utils::ReadFile(path_, &buf));
85 EXPECT_EQ(strlen(test_uncompressed), buf.size());
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -080086 EXPECT_EQ(string(buf.begin(), buf.end()), string(test_uncompressed));
Andrew de los Reyes80061062010-02-04 14:25:00 -080087}
88
89TEST_F(BzipExtentWriterTest, ChunkedTest) {
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -080090 const chromeos::Blob::size_type kDecompressedLength = 2048 * 1024; // 2 MiB
Gilad Arnolde1d1e982013-07-01 04:25:55 -070091 string decompressed_path;
92 ASSERT_TRUE(utils::MakeTempFile("BzipExtentWriterTest-decompressed-XXXXXX",
Alex Vakulenko88b591f2014-08-28 16:48:57 -070093 &decompressed_path, nullptr));
Gilad Arnolde1d1e982013-07-01 04:25:55 -070094 string compressed_path;
95 ASSERT_TRUE(utils::MakeTempFile("BzipExtentWriterTest-compressed-XXXXXX",
Alex Vakulenko88b591f2014-08-28 16:48:57 -070096 &compressed_path, nullptr));
Andrew de los Reyes80061062010-02-04 14:25:00 -080097 const size_t kChunkSize = 3;
Gilad Arnolde1d1e982013-07-01 04:25:55 -070098
Andrew de los Reyes80061062010-02-04 14:25:00 -080099 vector<Extent> extents;
100 Extent extent;
101 extent.set_start_block(0);
102 extent.set_num_blocks(kDecompressedLength / kBlockSize + 1);
103 extents.push_back(extent);
104
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -0800105 chromeos::Blob decompressed_data(kDecompressedLength);
Alex Deymo10875d92014-11-10 21:52:57 -0800106 test_utils::FillWithData(&decompressed_data);
Gilad Arnolde1d1e982013-07-01 04:25:55 -0700107
Alex Deymo10875d92014-11-10 21:52:57 -0800108 EXPECT_TRUE(test_utils::WriteFileVector(
109 decompressed_path, decompressed_data));
Gilad Arnolde1d1e982013-07-01 04:25:55 -0700110
Alex Deymo10875d92014-11-10 21:52:57 -0800111 EXPECT_EQ(0, test_utils::System(
112 string("cat ") + decompressed_path + "|bzip2>" + compressed_path));
Andrew de los Reyes80061062010-02-04 14:25:00 -0800113
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -0800114 chromeos::Blob compressed_data;
Gilad Arnolde1d1e982013-07-01 04:25:55 -0700115 EXPECT_TRUE(utils::ReadFile(compressed_path, &compressed_data));
116
Andrew de los Reyes80061062010-02-04 14:25:00 -0800117 DirectExtentWriter direct_writer;
118 BzipExtentWriter bzip_writer(&direct_writer);
Nam T. Nguyenf1d582e2014-12-08 15:07:17 -0800119 EXPECT_TRUE(bzip_writer.Init(fd_, extents, kBlockSize));
Andrew de los Reyes80061062010-02-04 14:25:00 -0800120
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -0800121 chromeos::Blob original_compressed_data = compressed_data;
122 for (chromeos::Blob::size_type i = 0; i < compressed_data.size();
Andrew de los Reyes80061062010-02-04 14:25:00 -0800123 i += kChunkSize) {
124 size_t this_chunk_size = min(kChunkSize, compressed_data.size() - i);
125 EXPECT_TRUE(bzip_writer.Write(&compressed_data[i], this_chunk_size));
126 }
127 EXPECT_TRUE(bzip_writer.End());
Darin Petkove0622392013-04-24 12:56:19 +0200128
129 // Check that the const input has not been clobbered.
Alex Deymo10875d92014-11-10 21:52:57 -0800130 test_utils::ExpectVectorsEq(original_compressed_data, compressed_data);
Gilad Arnolde1d1e982013-07-01 04:25:55 -0700131
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -0800132 chromeos::Blob output;
Nam T. Nguyenf1d582e2014-12-08 15:07:17 -0800133 EXPECT_TRUE(utils::ReadFile(path_, &output));
134 EXPECT_EQ(kDecompressedLength, output.size());
Alex Deymo10875d92014-11-10 21:52:57 -0800135 test_utils::ExpectVectorsEq(decompressed_data, output);
Gilad Arnolde1d1e982013-07-01 04:25:55 -0700136
137 unlink(decompressed_path.c_str());
138 unlink(compressed_path.c_str());
Andrew de los Reyes80061062010-02-04 14:25:00 -0800139}
140
141} // namespace chromeos_update_engine