blob: 4cf971b03bd3770d16d8846c8473b62e74eeb1b3 [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
Andrew de los Reyes80061062010-02-04 14:25:00 -08007#include <sys/stat.h>
8#include <sys/types.h>
9#include <unistd.h>
10#include <algorithm>
11#include <string>
12#include <vector>
13#include <gtest/gtest.h>
Andrew de los Reyes80061062010-02-04 14:25:00 -080014#include "update_engine/test_utils.h"
15#include "update_engine/utils.h"
16
17using std::min;
18using std::string;
19using std::vector;
20
21namespace chromeos_update_engine {
22
23namespace {
24const char kPathTemplate[] = "./BzipExtentWriterTest-file.XXXXXX";
Andrew de los Reyes09e56d62010-04-23 13:45:53 -070025const uint32_t kBlockSize = 4096;
Andrew de los Reyes80061062010-02-04 14:25:00 -080026}
27
28class BzipExtentWriterTest : public ::testing::Test {
29 protected:
Alex Deymo610277e2014-11-11 21:18:11 -080030 void SetUp() override {
Andrew de los Reyes80061062010-02-04 14:25:00 -080031 memcpy(path_, kPathTemplate, sizeof(kPathTemplate));
32 fd_ = mkstemp(path_);
33 ASSERT_GE(fd_, 0);
34 }
Alex Deymo610277e2014-11-11 21:18:11 -080035 void TearDown() override {
Andrew de los Reyes80061062010-02-04 14:25:00 -080036 close(fd_);
Andrew de los Reyes80061062010-02-04 14:25:00 -080037 unlink(path_);
38 }
39 int fd() { return fd_; }
40 const char* path() { return path_; }
41 void WriteAlignedExtents(size_t chunk_size, size_t first_chunk_size);
42 void TestZeroPad(bool aligned_size);
43 private:
44 int fd_;
45 char path_[sizeof(kPathTemplate)];
46};
47
48TEST_F(BzipExtentWriterTest, SimpleTest) {
49 vector<Extent> extents;
50 Extent extent;
51 extent.set_start_block(0);
52 extent.set_num_blocks(1);
53 extents.push_back(extent);
54
55 // 'echo test | bzip2 | hexdump' yields:
Darin Petkove0622392013-04-24 12:56:19 +020056 static const char test_uncompressed[] = "test\n";
57 static const unsigned char test[] = {
Andrew de los Reyes80061062010-02-04 14:25:00 -080058 0x42, 0x5a, 0x68, 0x39, 0x31, 0x41, 0x59, 0x26, 0x53, 0x59, 0xcc, 0xc3,
59 0x71, 0xd4, 0x00, 0x00, 0x02, 0x41, 0x80, 0x00, 0x10, 0x02, 0x00, 0x0c,
60 0x00, 0x20, 0x00, 0x21, 0x9a, 0x68, 0x33, 0x4d, 0x19, 0x97, 0x8b, 0xb9,
Gilad Arnolde1d1e982013-07-01 04:25:55 -070061 0x22, 0x9c, 0x28, 0x48, 0x66, 0x61, 0xb8, 0xea, 0x00,
Andrew de los Reyes80061062010-02-04 14:25:00 -080062 };
Gilad Arnolde1d1e982013-07-01 04:25:55 -070063
Andrew de los Reyes80061062010-02-04 14:25:00 -080064 DirectExtentWriter direct_writer;
65 BzipExtentWriter bzip_writer(&direct_writer);
66 EXPECT_TRUE(bzip_writer.Init(fd(), extents, kBlockSize));
67 EXPECT_TRUE(bzip_writer.Write(test, sizeof(test)));
68 EXPECT_TRUE(bzip_writer.End());
Gilad Arnolde1d1e982013-07-01 04:25:55 -070069
Andrew de los Reyes80061062010-02-04 14:25:00 -080070 char buf[sizeof(test_uncompressed) + 1];
71 memset(buf, 0, sizeof(buf));
72 ssize_t bytes_read = pread(fd(), buf, sizeof(buf) - 1, 0);
73 EXPECT_EQ(strlen(test_uncompressed), bytes_read);
74 EXPECT_EQ(string(buf), string(test_uncompressed));
75}
76
77TEST_F(BzipExtentWriterTest, ChunkedTest) {
78 const vector<char>::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
93 vector<char> 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
102 vector<char> 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);
107 EXPECT_TRUE(bzip_writer.Init(fd(), extents, kBlockSize));
108
Darin Petkove0622392013-04-24 12:56:19 +0200109 vector<char> original_compressed_data = compressed_data;
Andrew de los Reyes80061062010-02-04 14:25:00 -0800110 for (vector<char>::size_type i = 0; i < compressed_data.size();
111 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
Andrew de los Reyes80061062010-02-04 14:25:00 -0800120 vector<char> output(kDecompressedLength + 1);
121 ssize_t bytes_read = pread(fd(), &output[0], output.size(), 0);
122 EXPECT_EQ(kDecompressedLength, bytes_read);
123 output.resize(kDecompressedLength);
Alex Deymo10875d92014-11-10 21:52:57 -0800124 test_utils::ExpectVectorsEq(decompressed_data, output);
Gilad Arnolde1d1e982013-07-01 04:25:55 -0700125
126 unlink(decompressed_path.c_str());
127 unlink(compressed_path.c_str());
Andrew de los Reyes80061062010-02-04 14:25:00 -0800128}
129
130} // namespace chromeos_update_engine