Chromium Code Reviews| 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 |