blob: 185c201744550266d1e8e023e497682839bb0787 [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",
80 &decompressed_path, NULL));
81 string compressed_path;
82 ASSERT_TRUE(utils::MakeTempFile("BzipExtentWriterTest-compressed-XXXXXX",
83 &compressed_path, NULL));
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);
93 FillWithData(&decompressed_data);
Gilad Arnolde1d1e982013-07-01 04:25:55 -070094
95 EXPECT_TRUE(WriteFileVector(decompressed_path, decompressed_data));
96
97 EXPECT_EQ(0, System(string("cat ") + decompressed_path + "|bzip2>" +
98 compressed_path));
Andrew de los Reyes80061062010-02-04 14:25:00 -080099
100 vector<char> compressed_data;
Gilad Arnolde1d1e982013-07-01 04:25:55 -0700101 EXPECT_TRUE(utils::ReadFile(compressed_path, &compressed_data));
102
Andrew de los Reyes80061062010-02-04 14:25:00 -0800103 DirectExtentWriter direct_writer;
104 BzipExtentWriter bzip_writer(&direct_writer);
105 EXPECT_TRUE(bzip_writer.Init(fd(), extents, kBlockSize));
106
Darin Petkove0622392013-04-24 12:56:19 +0200107 vector<char> original_compressed_data = compressed_data;
Andrew de los Reyes80061062010-02-04 14:25:00 -0800108 for (vector<char>::size_type i = 0; i < compressed_data.size();
109 i += kChunkSize) {
110 size_t this_chunk_size = min(kChunkSize, compressed_data.size() - i);
111 EXPECT_TRUE(bzip_writer.Write(&compressed_data[i], this_chunk_size));
112 }
113 EXPECT_TRUE(bzip_writer.End());
Darin Petkove0622392013-04-24 12:56:19 +0200114
115 // Check that the const input has not been clobbered.
116 ExpectVectorsEq(original_compressed_data, compressed_data);
Gilad Arnolde1d1e982013-07-01 04:25:55 -0700117
Andrew de los Reyes80061062010-02-04 14:25:00 -0800118 vector<char> output(kDecompressedLength + 1);
119 ssize_t bytes_read = pread(fd(), &output[0], output.size(), 0);
120 EXPECT_EQ(kDecompressedLength, bytes_read);
121 output.resize(kDecompressedLength);
122 ExpectVectorsEq(decompressed_data, output);
Gilad Arnolde1d1e982013-07-01 04:25:55 -0700123
124 unlink(decompressed_path.c_str());
125 unlink(compressed_path.c_str());
Andrew de los Reyes80061062010-02-04 14:25:00 -0800126}
127
128} // namespace chromeos_update_engine