blob: 2b98eb1b1cb15314265b664a3b8942cdbae8d424 [file] [log] [blame]
Andrew de los Reyes80061062010-02-04 14:25:00 -08001// Copyright (c) 2009 The Chromium OS Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Alex Deymoaab50e32014-11-10 19:55:35 -08005#include "update_engine/bzip_extent_writer.h"
6
Nam T. Nguyenf1d582e2014-12-08 15:07:17 -08007#include <fcntl.h>
Andrew de los Reyes80061062010-02-04 14:25:00 -08008#include <sys/stat.h>
9#include <sys/types.h>
10#include <unistd.h>
11#include <algorithm>
12#include <string>
13#include <vector>
14#include <gtest/gtest.h>
Andrew de los Reyes80061062010-02-04 14:25:00 -080015#include "update_engine/test_utils.h"
16#include "update_engine/utils.h"
17
18using std::min;
19using std::string;
20using std::vector;
21
22namespace chromeos_update_engine {
23
24namespace {
25const char kPathTemplate[] = "./BzipExtentWriterTest-file.XXXXXX";
Andrew de los Reyes09e56d62010-04-23 13:45:53 -070026const uint32_t kBlockSize = 4096;
Andrew de los Reyes80061062010-02-04 14:25:00 -080027}
28
29class BzipExtentWriterTest : public ::testing::Test {
30 protected:
Alex Deymo610277e2014-11-11 21:18:11 -080031 void SetUp() override {
Andrew de los Reyes80061062010-02-04 14:25:00 -080032 memcpy(path_, kPathTemplate, sizeof(kPathTemplate));
Nam T. Nguyenf1d582e2014-12-08 15:07:17 -080033 fd_.reset(new EintrSafeFileDescriptor);
34 int fd = mkstemp(path_);
35 ASSERT_TRUE(fd_->Open(path_, O_RDWR, 0600));
36 close(fd);
Andrew de los Reyes80061062010-02-04 14:25:00 -080037 }
Alex Deymo610277e2014-11-11 21:18:11 -080038 void TearDown() override {
Nam T. Nguyenf1d582e2014-12-08 15:07:17 -080039 fd_->Close();
Andrew de los Reyes80061062010-02-04 14:25:00 -080040 unlink(path_);
41 }
Andrew de los Reyes80061062010-02-04 14:25:00 -080042 void WriteAlignedExtents(size_t chunk_size, size_t first_chunk_size);
43 void TestZeroPad(bool aligned_size);
Nam T. Nguyenf1d582e2014-12-08 15:07:17 -080044
45 FileDescriptorPtr fd_;
Andrew de los Reyes80061062010-02-04 14:25:00 -080046 char path_[sizeof(kPathTemplate)];
47};
48
49TEST_F(BzipExtentWriterTest, SimpleTest) {
50 vector<Extent> extents;
51 Extent extent;
52 extent.set_start_block(0);
53 extent.set_num_blocks(1);
54 extents.push_back(extent);
55
56 // 'echo test | bzip2 | hexdump' yields:
Darin Petkove0622392013-04-24 12:56:19 +020057 static const char test_uncompressed[] = "test\n";
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -080058 static const uint8_t test[] = {
Andrew de los Reyes80061062010-02-04 14:25:00 -080059 0x42, 0x5a, 0x68, 0x39, 0x31, 0x41, 0x59, 0x26, 0x53, 0x59, 0xcc, 0xc3,
60 0x71, 0xd4, 0x00, 0x00, 0x02, 0x41, 0x80, 0x00, 0x10, 0x02, 0x00, 0x0c,
61 0x00, 0x20, 0x00, 0x21, 0x9a, 0x68, 0x33, 0x4d, 0x19, 0x97, 0x8b, 0xb9,
Gilad Arnolde1d1e982013-07-01 04:25:55 -070062 0x22, 0x9c, 0x28, 0x48, 0x66, 0x61, 0xb8, 0xea, 0x00,
Andrew de los Reyes80061062010-02-04 14:25:00 -080063 };
Gilad Arnolde1d1e982013-07-01 04:25:55 -070064
Andrew de los Reyes80061062010-02-04 14:25:00 -080065 DirectExtentWriter direct_writer;
66 BzipExtentWriter bzip_writer(&direct_writer);
Nam T. Nguyenf1d582e2014-12-08 15:07:17 -080067 EXPECT_TRUE(bzip_writer.Init(fd_, extents, kBlockSize));
Andrew de los Reyes80061062010-02-04 14:25:00 -080068 EXPECT_TRUE(bzip_writer.Write(test, sizeof(test)));
69 EXPECT_TRUE(bzip_writer.End());
Gilad Arnolde1d1e982013-07-01 04:25:55 -070070
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -080071 chromeos::Blob buf;
Nam T. Nguyenf1d582e2014-12-08 15:07:17 -080072 EXPECT_TRUE(utils::ReadFile(path_, &buf));
73 EXPECT_EQ(strlen(test_uncompressed), buf.size());
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -080074 EXPECT_EQ(string(buf.begin(), buf.end()), string(test_uncompressed));
Andrew de los Reyes80061062010-02-04 14:25:00 -080075}
76
77TEST_F(BzipExtentWriterTest, ChunkedTest) {
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -080078 const chromeos::Blob::size_type kDecompressedLength = 2048 * 1024; // 2 MiB
Gilad Arnolde1d1e982013-07-01 04:25:55 -070079 string decompressed_path;
80 ASSERT_TRUE(utils::MakeTempFile("BzipExtentWriterTest-decompressed-XXXXXX",
Alex Vakulenko88b591f2014-08-28 16:48:57 -070081 &decompressed_path, nullptr));
Gilad Arnolde1d1e982013-07-01 04:25:55 -070082 string compressed_path;
83 ASSERT_TRUE(utils::MakeTempFile("BzipExtentWriterTest-compressed-XXXXXX",
Alex Vakulenko88b591f2014-08-28 16:48:57 -070084 &compressed_path, nullptr));
Andrew de los Reyes80061062010-02-04 14:25:00 -080085 const size_t kChunkSize = 3;
Gilad Arnolde1d1e982013-07-01 04:25:55 -070086
Andrew de los Reyes80061062010-02-04 14:25:00 -080087 vector<Extent> extents;
88 Extent extent;
89 extent.set_start_block(0);
90 extent.set_num_blocks(kDecompressedLength / kBlockSize + 1);
91 extents.push_back(extent);
92
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -080093 chromeos::Blob decompressed_data(kDecompressedLength);
Alex Deymo10875d92014-11-10 21:52:57 -080094 test_utils::FillWithData(&decompressed_data);
Gilad Arnolde1d1e982013-07-01 04:25:55 -070095
Alex Deymo10875d92014-11-10 21:52:57 -080096 EXPECT_TRUE(test_utils::WriteFileVector(
97 decompressed_path, decompressed_data));
Gilad Arnolde1d1e982013-07-01 04:25:55 -070098
Alex Deymo10875d92014-11-10 21:52:57 -080099 EXPECT_EQ(0, test_utils::System(
100 string("cat ") + decompressed_path + "|bzip2>" + compressed_path));
Andrew de los Reyes80061062010-02-04 14:25:00 -0800101
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -0800102 chromeos::Blob compressed_data;
Gilad Arnolde1d1e982013-07-01 04:25:55 -0700103 EXPECT_TRUE(utils::ReadFile(compressed_path, &compressed_data));
104
Andrew de los Reyes80061062010-02-04 14:25:00 -0800105 DirectExtentWriter direct_writer;
106 BzipExtentWriter bzip_writer(&direct_writer);
Nam T. Nguyenf1d582e2014-12-08 15:07:17 -0800107 EXPECT_TRUE(bzip_writer.Init(fd_, extents, kBlockSize));
Andrew de los Reyes80061062010-02-04 14:25:00 -0800108
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -0800109 chromeos::Blob original_compressed_data = compressed_data;
110 for (chromeos::Blob::size_type i = 0; i < compressed_data.size();
Andrew de los Reyes80061062010-02-04 14:25:00 -0800111 i += kChunkSize) {
112 size_t this_chunk_size = min(kChunkSize, compressed_data.size() - i);
113 EXPECT_TRUE(bzip_writer.Write(&compressed_data[i], this_chunk_size));
114 }
115 EXPECT_TRUE(bzip_writer.End());
Darin Petkove0622392013-04-24 12:56:19 +0200116
117 // Check that the const input has not been clobbered.
Alex Deymo10875d92014-11-10 21:52:57 -0800118 test_utils::ExpectVectorsEq(original_compressed_data, compressed_data);
Gilad Arnolde1d1e982013-07-01 04:25:55 -0700119
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -0800120 chromeos::Blob output;
Nam T. Nguyenf1d582e2014-12-08 15:07:17 -0800121 EXPECT_TRUE(utils::ReadFile(path_, &output));
122 EXPECT_EQ(kDecompressedLength, output.size());
Alex Deymo10875d92014-11-10 21:52:57 -0800123 test_utils::ExpectVectorsEq(decompressed_data, output);
Gilad Arnolde1d1e982013-07-01 04:25:55 -0700124
125 unlink(decompressed_path.c_str());
126 unlink(compressed_path.c_str());
Andrew de los Reyes80061062010-02-04 14:25:00 -0800127}
128
129} // namespace chromeos_update_engine