blob: 38ba117bf0e574d02ca9ce660c248b6a34137fb8 [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_);
36 LOG(INFO) << "unlink: " << path_;
37 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,
61 0x22, 0x9c, 0x28, 0x48, 0x66, 0x61, 0xb8, 0xea, 0x00,
62 };
63
64 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());
69
70 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
79 const string kDecompressedPath = "BzipExtentWriterTest-file-decompressed";
80 const string kCompressedPath = "BzipExtentWriterTest-file-compressed";
81 const size_t kChunkSize = 3;
82
83 vector<Extent> extents;
84 Extent extent;
85 extent.set_start_block(0);
86 extent.set_num_blocks(kDecompressedLength / kBlockSize + 1);
87 extents.push_back(extent);
88
89 vector<char> decompressed_data(kDecompressedLength);
90 FillWithData(&decompressed_data);
91
92 EXPECT_TRUE(WriteFileVector(kDecompressedPath, decompressed_data));
93
94 EXPECT_EQ(0, System(string("cat ") + kDecompressedPath + "|bzip2>" +
95 kCompressedPath));
96
97 vector<char> compressed_data;
98 EXPECT_TRUE(utils::ReadFile(kCompressedPath, &compressed_data));
99
100 DirectExtentWriter direct_writer;
101 BzipExtentWriter bzip_writer(&direct_writer);
102 EXPECT_TRUE(bzip_writer.Init(fd(), extents, kBlockSize));
103
Darin Petkove0622392013-04-24 12:56:19 +0200104 vector<char> original_compressed_data = compressed_data;
Andrew de los Reyes80061062010-02-04 14:25:00 -0800105 for (vector<char>::size_type i = 0; i < compressed_data.size();
106 i += kChunkSize) {
107 size_t this_chunk_size = min(kChunkSize, compressed_data.size() - i);
108 EXPECT_TRUE(bzip_writer.Write(&compressed_data[i], this_chunk_size));
109 }
110 EXPECT_TRUE(bzip_writer.End());
Darin Petkove0622392013-04-24 12:56:19 +0200111
112 // Check that the const input has not been clobbered.
113 ExpectVectorsEq(original_compressed_data, compressed_data);
Andrew de los Reyes80061062010-02-04 14:25:00 -0800114
115 vector<char> output(kDecompressedLength + 1);
116 ssize_t bytes_read = pread(fd(), &output[0], output.size(), 0);
117 EXPECT_EQ(kDecompressedLength, bytes_read);
118 output.resize(kDecompressedLength);
119 ExpectVectorsEq(decompressed_data, output);
120
121 unlink(kDecompressedPath.c_str());
122 unlink(kCompressedPath.c_str());
123}
124
125} // namespace chromeos_update_engine