blob: 96121d4c8c505f449c10138ce1e435d24f08fbaf [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
5#include <sys/stat.h>
6#include <sys/types.h>
7#include <unistd.h>
8#include <algorithm>
9#include <string>
10#include <vector>
11#include <gtest/gtest.h>
12#include "update_engine/bzip_extent_writer.h"
13#include "update_engine/test_utils.h"
14#include "update_engine/utils.h"
15
16using std::min;
17using std::string;
18using std::vector;
19
20namespace chromeos_update_engine {
21
22namespace {
23const char kPathTemplate[] = "./BzipExtentWriterTest-file.XXXXXX";
Andrew de los Reyes09e56d62010-04-23 13:45:53 -070024const uint32_t kBlockSize = 4096;
Andrew de los Reyes80061062010-02-04 14:25:00 -080025}
26
27class BzipExtentWriterTest : public ::testing::Test {
28 protected:
29 virtual void SetUp() {
30 memcpy(path_, kPathTemplate, sizeof(kPathTemplate));
31 fd_ = mkstemp(path_);
32 ASSERT_GE(fd_, 0);
33 }
34 virtual void TearDown() {
35 close(fd_);
Andrew de los Reyes80061062010-02-04 14:25:00 -080036 unlink(path_);
37 }
38 int fd() { return fd_; }
39 const char* path() { return path_; }
40 void WriteAlignedExtents(size_t chunk_size, size_t first_chunk_size);
41 void TestZeroPad(bool aligned_size);
42 private:
43 int fd_;
44 char path_[sizeof(kPathTemplate)];
45};
46
47TEST_F(BzipExtentWriterTest, SimpleTest) {
48 vector<Extent> extents;
49 Extent extent;
50 extent.set_start_block(0);
51 extent.set_num_blocks(1);
52 extents.push_back(extent);
53
54 // 'echo test | bzip2 | hexdump' yields:
Darin Petkove0622392013-04-24 12:56:19 +020055 static const char test_uncompressed[] = "test\n";
56 static const unsigned char test[] = {
Andrew de los Reyes80061062010-02-04 14:25:00 -080057 0x42, 0x5a, 0x68, 0x39, 0x31, 0x41, 0x59, 0x26, 0x53, 0x59, 0xcc, 0xc3,
58 0x71, 0xd4, 0x00, 0x00, 0x02, 0x41, 0x80, 0x00, 0x10, 0x02, 0x00, 0x0c,
59 0x00, 0x20, 0x00, 0x21, 0x9a, 0x68, 0x33, 0x4d, 0x19, 0x97, 0x8b, 0xb9,
Gilad Arnolde1d1e982013-07-01 04:25:55 -070060 0x22, 0x9c, 0x28, 0x48, 0x66, 0x61, 0xb8, 0xea, 0x00,
Andrew de los Reyes80061062010-02-04 14:25:00 -080061 };
Gilad Arnolde1d1e982013-07-01 04:25:55 -070062
Andrew de los Reyes80061062010-02-04 14:25:00 -080063 DirectExtentWriter direct_writer;
64 BzipExtentWriter bzip_writer(&direct_writer);
65 EXPECT_TRUE(bzip_writer.Init(fd(), extents, kBlockSize));
66 EXPECT_TRUE(bzip_writer.Write(test, sizeof(test)));
67 EXPECT_TRUE(bzip_writer.End());
Gilad Arnolde1d1e982013-07-01 04:25:55 -070068
Andrew de los Reyes80061062010-02-04 14:25:00 -080069 char buf[sizeof(test_uncompressed) + 1];
70 memset(buf, 0, sizeof(buf));
71 ssize_t bytes_read = pread(fd(), buf, sizeof(buf) - 1, 0);
72 EXPECT_EQ(strlen(test_uncompressed), bytes_read);
73 EXPECT_EQ(string(buf), string(test_uncompressed));
74}
75
76TEST_F(BzipExtentWriterTest, ChunkedTest) {
77 const vector<char>::size_type kDecompressedLength = 2048 * 1024; // 2 MiB
Gilad Arnolde1d1e982013-07-01 04:25:55 -070078 string decompressed_path;
79 ASSERT_TRUE(utils::MakeTempFile("BzipExtentWriterTest-decompressed-XXXXXX",
Alex Vakulenko88b591f2014-08-28 16:48:57 -070080 &decompressed_path, nullptr));
Gilad Arnolde1d1e982013-07-01 04:25:55 -070081 string compressed_path;
82 ASSERT_TRUE(utils::MakeTempFile("BzipExtentWriterTest-compressed-XXXXXX",
Alex Vakulenko88b591f2014-08-28 16:48:57 -070083 &compressed_path, nullptr));
Andrew de los Reyes80061062010-02-04 14:25:00 -080084 const size_t kChunkSize = 3;
Gilad Arnolde1d1e982013-07-01 04:25:55 -070085
Andrew de los Reyes80061062010-02-04 14:25:00 -080086 vector<Extent> extents;
87 Extent extent;
88 extent.set_start_block(0);
89 extent.set_num_blocks(kDecompressedLength / kBlockSize + 1);
90 extents.push_back(extent);
91
92 vector<char> decompressed_data(kDecompressedLength);
Alex Deymo10875d92014-11-10 21:52:57 -080093 test_utils::FillWithData(&decompressed_data);
Gilad Arnolde1d1e982013-07-01 04:25:55 -070094
Alex Deymo10875d92014-11-10 21:52:57 -080095 EXPECT_TRUE(test_utils::WriteFileVector(
96 decompressed_path, decompressed_data));
Gilad Arnolde1d1e982013-07-01 04:25:55 -070097
Alex Deymo10875d92014-11-10 21:52:57 -080098 EXPECT_EQ(0, test_utils::System(
99 string("cat ") + decompressed_path + "|bzip2>" + compressed_path));
Andrew de los Reyes80061062010-02-04 14:25:00 -0800100
101 vector<char> compressed_data;
Gilad Arnolde1d1e982013-07-01 04:25:55 -0700102 EXPECT_TRUE(utils::ReadFile(compressed_path, &compressed_data));
103
Andrew de los Reyes80061062010-02-04 14:25:00 -0800104 DirectExtentWriter direct_writer;
105 BzipExtentWriter bzip_writer(&direct_writer);
106 EXPECT_TRUE(bzip_writer.Init(fd(), extents, kBlockSize));
107
Darin Petkove0622392013-04-24 12:56:19 +0200108 vector<char> original_compressed_data = compressed_data;
Andrew de los Reyes80061062010-02-04 14:25:00 -0800109 for (vector<char>::size_type i = 0; i < compressed_data.size();
110 i += kChunkSize) {
111 size_t this_chunk_size = min(kChunkSize, compressed_data.size() - i);
112 EXPECT_TRUE(bzip_writer.Write(&compressed_data[i], this_chunk_size));
113 }
114 EXPECT_TRUE(bzip_writer.End());
Darin Petkove0622392013-04-24 12:56:19 +0200115
116 // Check that the const input has not been clobbered.
Alex Deymo10875d92014-11-10 21:52:57 -0800117 test_utils::ExpectVectorsEq(original_compressed_data, compressed_data);
Gilad Arnolde1d1e982013-07-01 04:25:55 -0700118
Andrew de los Reyes80061062010-02-04 14:25:00 -0800119 vector<char> output(kDecompressedLength + 1);
120 ssize_t bytes_read = pread(fd(), &output[0], output.size(), 0);
121 EXPECT_EQ(kDecompressedLength, bytes_read);
122 output.resize(kDecompressedLength);
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