OLD | NEW |
1 // Copyright (c) 2009 The Chromium OS Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <sys/mount.h> | 5 #include <sys/mount.h> |
6 #include <inttypes.h> | 6 #include <inttypes.h> |
7 | 7 |
8 #include <algorithm> | 8 #include <algorithm> |
9 #include <string> | 9 #include <string> |
10 #include <vector> | 10 #include <vector> |
11 | 11 |
| 12 #include <base/file_util.h> |
12 #include <base/scoped_ptr.h> | 13 #include <base/scoped_ptr.h> |
13 #include <base/string_util.h> | 14 #include <base/string_util.h> |
14 #include <google/protobuf/repeated_field.h> | 15 #include <google/protobuf/repeated_field.h> |
15 #include <gtest/gtest.h> | 16 #include <gtest/gtest.h> |
16 | 17 |
17 #include "update_engine/delta_diff_generator.h" | 18 #include "update_engine/delta_diff_generator.h" |
18 #include "update_engine/delta_performer.h" | 19 #include "update_engine/delta_performer.h" |
19 #include "update_engine/extent_ranges.h" | 20 #include "update_engine/extent_ranges.h" |
20 #include "update_engine/graph_types.h" | 21 #include "update_engine/graph_types.h" |
21 #include "update_engine/payload_signer.h" | 22 #include "update_engine/payload_signer.h" |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
105 int fd = open(path.c_str(), O_CREAT | O_TRUNC | O_WRONLY, 0644); | 106 int fd = open(path.c_str(), O_CREAT | O_TRUNC | O_WRONLY, 0644); |
106 TEST_AND_RETURN_FALSE_ERRNO(fd >= 0); | 107 TEST_AND_RETURN_FALSE_ERRNO(fd >= 0); |
107 ScopedFdCloser fd_closer(&fd); | 108 ScopedFdCloser fd_closer(&fd); |
108 off_t rc = lseek(fd, size + 1, SEEK_SET); | 109 off_t rc = lseek(fd, size + 1, SEEK_SET); |
109 TEST_AND_RETURN_FALSE_ERRNO(rc != static_cast<off_t>(-1)); | 110 TEST_AND_RETURN_FALSE_ERRNO(rc != static_cast<off_t>(-1)); |
110 int return_code = ftruncate(fd, size); | 111 int return_code = ftruncate(fd, size); |
111 TEST_AND_RETURN_FALSE_ERRNO(return_code == 0); | 112 TEST_AND_RETURN_FALSE_ERRNO(return_code == 0); |
112 return true; | 113 return true; |
113 } | 114 } |
114 | 115 |
115 void DoSmallImageTest(bool full_kernel) { | 116 void DoSmallImageTest(bool full_kernel, bool noop) { |
116 string a_img, b_img; | 117 string a_img, b_img; |
117 EXPECT_TRUE(utils::MakeTempFile("/tmp/a_img.XXXXXX", &a_img, NULL)); | 118 EXPECT_TRUE(utils::MakeTempFile("/tmp/a_img.XXXXXX", &a_img, NULL)); |
118 ScopedPathUnlinker a_img_unlinker(a_img); | 119 ScopedPathUnlinker a_img_unlinker(a_img); |
119 EXPECT_TRUE(utils::MakeTempFile("/tmp/b_img.XXXXXX", &b_img, NULL)); | 120 EXPECT_TRUE(utils::MakeTempFile("/tmp/b_img.XXXXXX", &b_img, NULL)); |
120 ScopedPathUnlinker b_img_unlinker(b_img); | 121 ScopedPathUnlinker b_img_unlinker(b_img); |
121 | 122 |
122 CreateExtImageAtPath(a_img, NULL); | 123 CreateExtImageAtPath(a_img, NULL); |
123 CreateExtImageAtPath(b_img, NULL); | |
124 | 124 |
125 int image_size = static_cast<int>(utils::FileSize(a_img)); | 125 int image_size = static_cast<int>(utils::FileSize(a_img)); |
126 | 126 |
127 // Extend the "partitions" holding the file system a bit. | 127 // Extend the "partitions" holding the file system a bit. |
128 EXPECT_EQ(0, System(base::StringPrintf( | 128 EXPECT_EQ(0, System(base::StringPrintf( |
129 "dd if=/dev/zero of=%s seek=%d bs=1 count=1", | 129 "dd if=/dev/zero of=%s seek=%d bs=1 count=1", |
130 a_img.c_str(), | 130 a_img.c_str(), |
131 image_size + 1024 * 1024 - 1))); | 131 image_size + 1024 * 1024 - 1))); |
132 EXPECT_EQ(0, System(base::StringPrintf( | |
133 "dd if=/dev/zero of=%s seek=%d bs=1 count=1", | |
134 b_img.c_str(), | |
135 image_size + 1024 * 1024 - 1))); | |
136 EXPECT_EQ(image_size + 1024 * 1024, utils::FileSize(a_img)); | 132 EXPECT_EQ(image_size + 1024 * 1024, utils::FileSize(a_img)); |
137 EXPECT_EQ(image_size + 1024 * 1024, utils::FileSize(b_img)); | |
138 | 133 |
139 // Make some changes to the A image. | 134 // Make some changes to the A image. |
140 { | 135 { |
141 string a_mnt; | 136 string a_mnt; |
142 ScopedLoopMounter b_mounter(a_img, &a_mnt, 0); | 137 ScopedLoopMounter b_mounter(a_img, &a_mnt, 0); |
143 | 138 |
144 EXPECT_TRUE(utils::WriteFile(StringPrintf("%s/hardtocompress", | 139 EXPECT_TRUE(utils::WriteFile(StringPrintf("%s/hardtocompress", |
145 a_mnt.c_str()).c_str(), | 140 a_mnt.c_str()).c_str(), |
146 reinterpret_cast<const char*>(kRandomString), | 141 reinterpret_cast<const char*>(kRandomString), |
147 sizeof(kRandomString) - 1)); | 142 sizeof(kRandomString) - 1)); |
148 // Write 1 MiB of 0xff to try to catch the case where writing a bsdiff | 143 // Write 1 MiB of 0xff to try to catch the case where writing a bsdiff |
149 // patch fails to zero out the final block. | 144 // patch fails to zero out the final block. |
150 vector<char> ones(1024 * 1024, 0xff); | 145 vector<char> ones(1024 * 1024, 0xff); |
151 EXPECT_TRUE(utils::WriteFile(StringPrintf("%s/ones", | 146 EXPECT_TRUE(utils::WriteFile(StringPrintf("%s/ones", |
152 a_mnt.c_str()).c_str(), | 147 a_mnt.c_str()).c_str(), |
153 &ones[0], | 148 &ones[0], |
154 ones.size())); | 149 ones.size())); |
155 } | 150 } |
156 | 151 |
157 // Make some changes to the B image. | 152 if (noop) { |
158 { | 153 EXPECT_TRUE(file_util::CopyFile(FilePath(a_img), FilePath(b_img))); |
| 154 } else { |
| 155 CreateExtImageAtPath(b_img, NULL); |
| 156 EXPECT_EQ(0, System(base::StringPrintf( |
| 157 "dd if=/dev/zero of=%s seek=%d bs=1 count=1", |
| 158 b_img.c_str(), |
| 159 image_size + 1024 * 1024 - 1))); |
| 160 EXPECT_EQ(image_size + 1024 * 1024, utils::FileSize(b_img)); |
| 161 |
| 162 // Make some changes to the B image. |
159 string b_mnt; | 163 string b_mnt; |
160 ScopedLoopMounter b_mounter(b_img, &b_mnt, 0); | 164 ScopedLoopMounter b_mounter(b_img, &b_mnt, 0); |
161 | 165 |
162 EXPECT_EQ(0, system(StringPrintf("cp %s/hello %s/hello2", b_mnt.c_str(), | 166 EXPECT_EQ(0, system(StringPrintf("cp %s/hello %s/hello2", b_mnt.c_str(), |
163 b_mnt.c_str()).c_str())); | 167 b_mnt.c_str()).c_str())); |
164 EXPECT_EQ(0, system(StringPrintf("rm %s/hello", b_mnt.c_str()).c_str())); | 168 EXPECT_EQ(0, system(StringPrintf("rm %s/hello", b_mnt.c_str()).c_str())); |
165 EXPECT_EQ(0, system(StringPrintf("mv %s/hello2 %s/hello", b_mnt.c_str(), | 169 EXPECT_EQ(0, system(StringPrintf("mv %s/hello2 %s/hello", b_mnt.c_str(), |
166 b_mnt.c_str()).c_str())); | 170 b_mnt.c_str()).c_str())); |
167 EXPECT_EQ(0, system(StringPrintf("echo foo > %s/foo", | 171 EXPECT_EQ(0, system(StringPrintf("echo foo > %s/foo", |
168 b_mnt.c_str()).c_str())); | 172 b_mnt.c_str()).c_str())); |
(...skipping 20 matching lines...) Expand all Loading... |
189 | 193 |
190 vector<char> old_kernel_data(4096); // Something small for a test | 194 vector<char> old_kernel_data(4096); // Something small for a test |
191 vector<char> new_kernel_data(old_kernel_data.size()); | 195 vector<char> new_kernel_data(old_kernel_data.size()); |
192 FillWithData(&old_kernel_data); | 196 FillWithData(&old_kernel_data); |
193 FillWithData(&new_kernel_data); | 197 FillWithData(&new_kernel_data); |
194 | 198 |
195 // change the new kernel data | 199 // change the new kernel data |
196 const char* new_data_string = "This is new data."; | 200 const char* new_data_string = "This is new data."; |
197 strcpy(&new_kernel_data[0], new_data_string); | 201 strcpy(&new_kernel_data[0], new_data_string); |
198 | 202 |
| 203 if (noop) { |
| 204 old_kernel_data = new_kernel_data; |
| 205 } |
| 206 |
199 // Write kernels to disk | 207 // Write kernels to disk |
200 EXPECT_TRUE(utils::WriteFile( | 208 EXPECT_TRUE(utils::WriteFile( |
201 old_kernel.c_str(), &old_kernel_data[0], old_kernel_data.size())); | 209 old_kernel.c_str(), &old_kernel_data[0], old_kernel_data.size())); |
202 EXPECT_TRUE(utils::WriteFile( | 210 EXPECT_TRUE(utils::WriteFile( |
203 new_kernel.c_str(), &new_kernel_data[0], new_kernel_data.size())); | 211 new_kernel.c_str(), &new_kernel_data[0], new_kernel_data.size())); |
204 | 212 |
205 string delta_path; | 213 string delta_path; |
206 EXPECT_TRUE(utils::MakeTempFile("/tmp/delta.XXXXXX", &delta_path, NULL)); | 214 EXPECT_TRUE(utils::MakeTempFile("/tmp/delta.XXXXXX", &delta_path, NULL)); |
207 LOG(INFO) << "delta path: " << delta_path; | 215 LOG(INFO) << "delta path: " << delta_path; |
208 ScopedPathUnlinker delta_path_unlinker(delta_path); | 216 ScopedPathUnlinker delta_path_unlinker(delta_path); |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
251 EXPECT_EQ(1, sigs_message.signatures_size()); | 259 EXPECT_EQ(1, sigs_message.signatures_size()); |
252 const Signatures_Signature& signature = sigs_message.signatures(0); | 260 const Signatures_Signature& signature = sigs_message.signatures(0); |
253 EXPECT_EQ(1, signature.version()); | 261 EXPECT_EQ(1, signature.version()); |
254 | 262 |
255 uint64_t expected_sig_data_length = 0; | 263 uint64_t expected_sig_data_length = 0; |
256 EXPECT_TRUE(PayloadSigner::SignatureBlobLength(kUnittestPrivateKeyPath, | 264 EXPECT_TRUE(PayloadSigner::SignatureBlobLength(kUnittestPrivateKeyPath, |
257 &expected_sig_data_length)); | 265 &expected_sig_data_length)); |
258 EXPECT_EQ(expected_sig_data_length, manifest.signatures_size()); | 266 EXPECT_EQ(expected_sig_data_length, manifest.signatures_size()); |
259 EXPECT_FALSE(signature.data().empty()); | 267 EXPECT_FALSE(signature.data().empty()); |
260 | 268 |
| 269 if (noop) { |
| 270 EXPECT_EQ(1, manifest.install_operations_size()); |
| 271 EXPECT_EQ(1, manifest.kernel_install_operations_size()); |
| 272 } |
| 273 |
261 if (full_kernel) { | 274 if (full_kernel) { |
262 EXPECT_FALSE(manifest.has_old_kernel_info()); | 275 EXPECT_FALSE(manifest.has_old_kernel_info()); |
263 } else { | 276 } else { |
264 EXPECT_EQ(old_kernel_data.size(), manifest.old_kernel_info().size()); | 277 EXPECT_EQ(old_kernel_data.size(), manifest.old_kernel_info().size()); |
265 EXPECT_FALSE(manifest.old_kernel_info().hash().empty()); | 278 EXPECT_FALSE(manifest.old_kernel_info().hash().empty()); |
266 } | 279 } |
267 | 280 |
268 EXPECT_EQ(new_kernel_data.size(), manifest.new_kernel_info().size()); | 281 EXPECT_EQ(new_kernel_data.size(), manifest.new_kernel_info().size()); |
269 EXPECT_EQ(image_size, manifest.old_rootfs_info().size()); | 282 EXPECT_EQ(image_size, manifest.old_rootfs_info().size()); |
270 EXPECT_EQ(image_size, manifest.new_rootfs_info().size()); | 283 EXPECT_EQ(image_size, manifest.new_rootfs_info().size()); |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
326 EXPECT_TRUE(utils::FileExists(kUnittestPublicKeyPath)); | 339 EXPECT_TRUE(utils::FileExists(kUnittestPublicKeyPath)); |
327 EXPECT_TRUE(performer.VerifyPayload( | 340 EXPECT_TRUE(performer.VerifyPayload( |
328 kUnittestPublicKeyPath, | 341 kUnittestPublicKeyPath, |
329 OmahaHashCalculator::OmahaHashOfData(delta), | 342 OmahaHashCalculator::OmahaHashOfData(delta), |
330 delta.size())); | 343 delta.size())); |
331 EXPECT_TRUE(performer.VerifyAppliedUpdate(a_img, old_kernel)); | 344 EXPECT_TRUE(performer.VerifyAppliedUpdate(a_img, old_kernel)); |
332 } | 345 } |
333 } | 346 } |
334 | 347 |
335 TEST(DeltaPerformerTest, RunAsRootSmallImageTest) { | 348 TEST(DeltaPerformerTest, RunAsRootSmallImageTest) { |
336 DoSmallImageTest(false); | 349 DoSmallImageTest(false, false); |
337 } | 350 } |
338 | 351 |
339 TEST(DeltaPerformerTest, RunAsRootFullKernelSmallImageTest) { | 352 TEST(DeltaPerformerTest, RunAsRootFullKernelSmallImageTest) { |
340 DoSmallImageTest(true); | 353 DoSmallImageTest(true, false); |
| 354 } |
| 355 |
| 356 TEST(DeltaPerformerTest, RunAsRootNoopSmallImageTest) { |
| 357 DoSmallImageTest(false, true); |
341 } | 358 } |
342 | 359 |
343 TEST(DeltaPerformerTest, NewFullUpdateTest) { | 360 TEST(DeltaPerformerTest, NewFullUpdateTest) { |
344 vector<char> new_root(20 * 1024 * 1024); | 361 vector<char> new_root(20 * 1024 * 1024); |
345 vector<char> new_kern(16 * 1024 * 1024); | 362 vector<char> new_kern(16 * 1024 * 1024); |
346 const off_t kChunkSize = 128 * 1024; | 363 const off_t kChunkSize = 128 * 1024; |
347 FillWithData(&new_root); | 364 FillWithData(&new_root); |
348 FillWithData(&new_kern); | 365 FillWithData(&new_kern); |
349 // Assume hashes take 2 MiB beyond the rootfs. | 366 // Assume hashes take 2 MiB beyond the rootfs. |
350 off_t new_rootfs_size = new_root.size() - 2 * 1024 * 1024; | 367 off_t new_rootfs_size = new_root.size() - 2 * 1024 * 1024; |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
414 op.clear_src_extents(); | 431 op.clear_src_extents(); |
415 *(op.add_src_extents()) = ExtentForRange(5, 3); | 432 *(op.add_src_extents()) = ExtentForRange(5, 3); |
416 EXPECT_TRUE(DeltaPerformer::IsIdempotentOperation(op)); | 433 EXPECT_TRUE(DeltaPerformer::IsIdempotentOperation(op)); |
417 *(op.add_dst_extents()) = ExtentForRange(20, 6); | 434 *(op.add_dst_extents()) = ExtentForRange(20, 6); |
418 EXPECT_TRUE(DeltaPerformer::IsIdempotentOperation(op)); | 435 EXPECT_TRUE(DeltaPerformer::IsIdempotentOperation(op)); |
419 *(op.add_src_extents()) = ExtentForRange(19, 2); | 436 *(op.add_src_extents()) = ExtentForRange(19, 2); |
420 EXPECT_FALSE(DeltaPerformer::IsIdempotentOperation(op)); | 437 EXPECT_FALSE(DeltaPerformer::IsIdempotentOperation(op)); |
421 } | 438 } |
422 | 439 |
423 } // namespace chromeos_update_engine | 440 } // namespace chromeos_update_engine |
OLD | NEW |