OLD | NEW |
---|---|
(Empty) | |
1 // 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/extent_writer.h" | |
13 #include "update_engine/test_utils.h" | |
14 #include "update_engine/utils.h" | |
15 | |
16 using std::min; | |
17 using std::string; | |
18 using std::vector; | |
19 | |
20 namespace chromeos_update_engine { | |
21 | |
22 COMPILE_ASSERT(sizeof(off_t) == 8, off_t_not_64_bit); | |
23 | |
24 namespace { | |
25 const char kPathTemplate[] = "./ExtentWriterTest-file.XXXXXX"; | |
26 const size_t kBlockSize = 4096; | |
27 } | |
28 | |
29 class ExtentWriterTest : public ::testing::Test { | |
30 protected: | |
31 virtual void SetUp() { | |
32 memcpy(path_, kPathTemplate, sizeof(kPathTemplate)); | |
33 fd_ = mkstemp(path_); | |
34 ASSERT_GE(fd_, 0); | |
35 } | |
36 virtual void TearDown() { | |
37 close(fd_); | |
38 unlink(path_); | |
39 } | |
40 int fd() { return fd_; } | |
41 const char* path() { return path_; } | |
42 void WriteAlignedExtents(size_t chunk_size, size_t first_chunk_size); | |
Daniel Erat
2010/02/03 02:12:24
add brief comments describing what these methods d
adlr
2010/02/04 22:25:37
Done.
| |
43 void TestZeroPad(bool aligned_size); | |
44 private: | |
45 int fd_; | |
46 char path_[sizeof(kPathTemplate)]; | |
47 }; | |
48 | |
49 TEST_F(ExtentWriterTest, SimpleTest) { | |
50 vector<Extent> extents; | |
51 Extent extent; | |
52 extent.set_start_block(1); | |
53 extent.set_num_blocks(1); | |
54 extents.push_back(extent); | |
55 | |
56 const string bytes = "1234"; | |
57 | |
58 DirectExtentWriter direct_writer; | |
59 EXPECT_TRUE(direct_writer.Init(fd(), extents, kBlockSize)); | |
60 EXPECT_TRUE(direct_writer.Write(bytes.data(), bytes.size())); | |
61 EXPECT_TRUE(direct_writer.End()); | |
62 | |
63 struct stat stbuf; | |
64 EXPECT_EQ(0, fstat(fd(), &stbuf)); | |
65 EXPECT_EQ(kBlockSize + bytes.size(), stbuf.st_size); | |
66 | |
67 vector<char> result_file; | |
68 EXPECT_TRUE(utils::ReadFile(path(), &result_file)); | |
69 | |
70 vector<char> expected_file(kBlockSize); | |
71 expected_file.insert(expected_file.end(), | |
72 bytes.data(), bytes.data() + bytes.size()); | |
73 ExpectVectorsEq(expected_file, result_file); | |
74 } | |
75 | |
76 TEST_F(ExtentWriterTest, ZeroLengthTest) { | |
77 vector<Extent> extents; | |
78 Extent extent; | |
79 extent.set_start_block(1); | |
80 extent.set_num_blocks(1); | |
81 extents.push_back(extent); | |
82 | |
83 DirectExtentWriter direct_writer; | |
84 EXPECT_TRUE(direct_writer.Init(fd(), extents, kBlockSize)); | |
85 EXPECT_TRUE(direct_writer.Write(NULL, 0)); | |
86 EXPECT_TRUE(direct_writer.End()); | |
87 } | |
88 | |
89 TEST_F(ExtentWriterTest, OverflowExtentTest) { | |
90 WriteAlignedExtents(kBlockSize * 3, kBlockSize * 3); | |
91 } | |
92 | |
93 TEST_F(ExtentWriterTest, UnalignedWriteTest) { | |
94 WriteAlignedExtents(7, 7); | |
95 } | |
96 | |
97 TEST_F(ExtentWriterTest, LargeUnalignedWriteTest) { | |
98 WriteAlignedExtents(kBlockSize * 2, kBlockSize / 2); | |
99 } | |
100 | |
101 void ExtentWriterTest::WriteAlignedExtents(size_t chunk_size, | |
102 size_t first_chunk_size) { | |
103 vector<Extent> extents; | |
104 Extent extent; | |
105 extent.set_start_block(1); | |
106 extent.set_num_blocks(1); | |
107 extents.push_back(extent); | |
108 extent.set_start_block(0); | |
109 extent.set_num_blocks(1); | |
110 extents.push_back(extent); | |
111 extent.set_start_block(2); | |
112 extent.set_num_blocks(1); | |
113 extents.push_back(extent); | |
114 | |
115 vector<char> data(kBlockSize * 3); | |
116 FillWithData(&data); | |
117 | |
118 DirectExtentWriter direct_writer; | |
119 EXPECT_TRUE(direct_writer.Init(fd(), extents, kBlockSize)); | |
120 | |
121 size_t bytes_written = 0; | |
122 while (bytes_written < data.size()) { | |
123 size_t bytes_to_write = min(data.size() - bytes_written, chunk_size); | |
124 if (bytes_written == 0) { | |
125 bytes_to_write = min(data.size() - bytes_written, first_chunk_size); | |
126 } | |
127 EXPECT_TRUE(direct_writer.Write(&data[bytes_written], bytes_to_write)); | |
128 bytes_written += bytes_to_write; | |
129 } | |
130 EXPECT_TRUE(direct_writer.End()); | |
131 | |
132 struct stat stbuf; | |
133 EXPECT_EQ(0, fstat(fd(), &stbuf)); | |
134 EXPECT_EQ(data.size(), stbuf.st_size); | |
135 | |
136 vector<char> result_file; | |
137 EXPECT_TRUE(utils::ReadFile(path(), &result_file)); | |
138 | |
139 vector<char> expected_file; | |
140 expected_file.insert(expected_file.end(), | |
141 data.begin() + kBlockSize, | |
142 data.begin() + kBlockSize * 2); | |
143 expected_file.insert(expected_file.end(), | |
144 data.begin(), data.begin() + kBlockSize); | |
145 expected_file.insert(expected_file.end(), | |
146 data.begin() + kBlockSize * 2, data.end()); | |
147 ExpectVectorsEq(expected_file, result_file); | |
148 } | |
149 | |
150 TEST_F(ExtentWriterTest, ZeroPadNullTest) { | |
151 TestZeroPad(true); | |
152 } | |
153 | |
154 TEST_F(ExtentWriterTest, ZeroPadFillTest) { | |
155 TestZeroPad(false); | |
156 } | |
157 | |
158 void ExtentWriterTest::TestZeroPad(bool aligned_size) { | |
159 vector<Extent> extents; | |
160 Extent extent; | |
161 extent.set_start_block(1); | |
162 extent.set_num_blocks(1); | |
163 extents.push_back(extent); | |
164 extent.set_start_block(0); | |
165 extent.set_num_blocks(1); | |
166 extents.push_back(extent); | |
167 | |
168 vector<char> data(kBlockSize * 2); | |
169 FillWithData(&data); | |
170 | |
171 DirectExtentWriter direct_writer; | |
172 ZeroPadExtentWriter zero_pad_writer(&direct_writer); | |
173 | |
174 EXPECT_TRUE(zero_pad_writer.Init(fd(), extents, kBlockSize)); | |
175 size_t bytes_to_write = data.size(); | |
176 const size_t missing_bytes = (aligned_size ? 0 : 9); | |
177 bytes_to_write -= missing_bytes; | |
178 lseek64(fd(), kBlockSize - missing_bytes, SEEK_SET); | |
179 EXPECT_EQ(3, write(fd(), "xxx", 3)); | |
180 ASSERT_TRUE(zero_pad_writer.Write(&data[0], bytes_to_write)); | |
181 EXPECT_TRUE(zero_pad_writer.End()); | |
182 | |
183 struct stat stbuf; | |
184 EXPECT_EQ(0, fstat(fd(), &stbuf)); | |
185 EXPECT_EQ(data.size(), stbuf.st_size); | |
186 | |
187 vector<char> result_file; | |
188 EXPECT_TRUE(utils::ReadFile(path(), &result_file)); | |
189 | |
190 vector<char> expected_file; | |
191 expected_file.insert(expected_file.end(), | |
192 data.begin() + kBlockSize, | |
193 data.begin() + kBlockSize * 2); | |
194 expected_file.insert(expected_file.end(), | |
195 data.begin(), data.begin() + kBlockSize); | |
196 if (missing_bytes) { | |
197 memset(&expected_file[kBlockSize - missing_bytes], 0, missing_bytes); | |
198 } | |
199 | |
200 ExpectVectorsEq(expected_file, result_file); | |
201 } | |
202 | |
203 TEST_F(ExtentWriterTest, SparseFileTest) { | |
204 vector<Extent> extents; | |
205 Extent extent; | |
206 extent.set_start_block(1); | |
207 extent.set_num_blocks(1); | |
208 extents.push_back(extent); | |
209 extent.set_start_block(kSparseHole); | |
210 extent.set_num_blocks(2); | |
211 extents.push_back(extent); | |
212 extent.set_start_block(0); | |
213 extent.set_num_blocks(1); | |
214 extents.push_back(extent); | |
215 const int block_count = 4; | |
216 const int on_disk_count = 2; | |
217 | |
218 vector<char> data(17); | |
219 FillWithData(&data); | |
220 | |
221 DirectExtentWriter direct_writer; | |
222 EXPECT_TRUE(direct_writer.Init(fd(), extents, kBlockSize)); | |
223 | |
224 size_t bytes_written = 0; | |
225 while (bytes_written < (block_count * kBlockSize)) { | |
226 size_t bytes_to_write = min(block_count * kBlockSize - bytes_written, | |
227 data.size()); | |
228 EXPECT_TRUE(direct_writer.Write(&data[0], bytes_to_write)); | |
229 bytes_written += bytes_to_write; | |
230 } | |
231 EXPECT_TRUE(direct_writer.End()); | |
232 | |
233 // check file size, then data inside | |
234 ASSERT_EQ(2 * kBlockSize, FileSize(path())); | |
235 | |
236 vector<char> resultant_data; | |
237 EXPECT_TRUE(utils::ReadFile(path(), &resultant_data)); | |
238 | |
239 // Create expected data | |
240 vector<char> expected_data(on_disk_count * kBlockSize); | |
241 vector<char> big(block_count * kBlockSize); | |
242 for (vector<char>::size_type i = 0; i < big.size(); i++) { | |
243 big[i] = data[i % data.size()]; | |
244 } | |
245 memcpy(&expected_data[kBlockSize], &big[0], kBlockSize); | |
246 memcpy(&expected_data[0], &big[3 * kBlockSize], kBlockSize); | |
247 //EXPECT_EQ(expected_data[0], resultant_data[0]); | |
Daniel Erat
2010/02/03 02:12:24
why are these commented out?
adlr
2010/02/04 22:25:37
Oops. they were helpful when the test was failing,
| |
248 //EXPECT_EQ(expected_data[kBlockSize], resultant_data[kBlockSize]); | |
249 ExpectVectorsEq(expected_data, resultant_data); | |
250 } | |
251 | |
252 } // namespace chromeos_update_engine | |
OLD | NEW |