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/file_util.h> |
13 #include <base/scoped_ptr.h> | 13 #include <base/scoped_ptr.h> |
14 #include <base/string_util.h> | 14 #include <base/string_util.h> |
15 #include <google/protobuf/repeated_field.h> | 15 #include <google/protobuf/repeated_field.h> |
16 #include <gtest/gtest.h> | 16 #include <gtest/gtest.h> |
17 | 17 |
18 #include "update_engine/delta_diff_generator.h" | 18 #include "update_engine/delta_diff_generator.h" |
19 #include "update_engine/delta_performer.h" | 19 #include "update_engine/delta_performer.h" |
20 #include "update_engine/extent_ranges.h" | 20 #include "update_engine/extent_ranges.h" |
| 21 #include "update_engine/full_update_generator.h" |
21 #include "update_engine/graph_types.h" | 22 #include "update_engine/graph_types.h" |
22 #include "update_engine/payload_signer.h" | 23 #include "update_engine/payload_signer.h" |
23 #include "update_engine/prefs_mock.h" | 24 #include "update_engine/prefs_mock.h" |
24 #include "update_engine/test_utils.h" | 25 #include "update_engine/test_utils.h" |
25 #include "update_engine/update_metadata.pb.h" | 26 #include "update_engine/update_metadata.pb.h" |
26 #include "update_engine/utils.h" | 27 #include "update_engine/utils.h" |
27 | 28 |
28 namespace chromeos_update_engine { | 29 namespace chromeos_update_engine { |
29 | 30 |
30 using std::min; | 31 using std::min; |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
106 int fd = open(path.c_str(), O_CREAT | O_TRUNC | O_WRONLY, 0644); | 107 int fd = open(path.c_str(), O_CREAT | O_TRUNC | O_WRONLY, 0644); |
107 TEST_AND_RETURN_FALSE_ERRNO(fd >= 0); | 108 TEST_AND_RETURN_FALSE_ERRNO(fd >= 0); |
108 ScopedFdCloser fd_closer(&fd); | 109 ScopedFdCloser fd_closer(&fd); |
109 off_t rc = lseek(fd, size + 1, SEEK_SET); | 110 off_t rc = lseek(fd, size + 1, SEEK_SET); |
110 TEST_AND_RETURN_FALSE_ERRNO(rc != static_cast<off_t>(-1)); | 111 TEST_AND_RETURN_FALSE_ERRNO(rc != static_cast<off_t>(-1)); |
111 int return_code = ftruncate(fd, size); | 112 int return_code = ftruncate(fd, size); |
112 TEST_AND_RETURN_FALSE_ERRNO(return_code == 0); | 113 TEST_AND_RETURN_FALSE_ERRNO(return_code == 0); |
113 return true; | 114 return true; |
114 } | 115 } |
115 | 116 |
116 void DoSmallImageTest(bool full_kernel, bool noop) { | 117 void DoSmallImageTest(bool full_kernel, bool full_rootfs, bool noop) { |
117 string a_img, b_img; | 118 string a_img, b_img; |
118 EXPECT_TRUE(utils::MakeTempFile("/tmp/a_img.XXXXXX", &a_img, NULL)); | 119 EXPECT_TRUE(utils::MakeTempFile("/tmp/a_img.XXXXXX", &a_img, NULL)); |
119 ScopedPathUnlinker a_img_unlinker(a_img); | 120 ScopedPathUnlinker a_img_unlinker(a_img); |
120 EXPECT_TRUE(utils::MakeTempFile("/tmp/b_img.XXXXXX", &b_img, NULL)); | 121 EXPECT_TRUE(utils::MakeTempFile("/tmp/b_img.XXXXXX", &b_img, NULL)); |
121 ScopedPathUnlinker b_img_unlinker(b_img); | 122 ScopedPathUnlinker b_img_unlinker(b_img); |
122 | 123 |
123 CreateExtImageAtPath(a_img, NULL); | 124 CreateExtImageAtPath(a_img, NULL); |
124 | 125 |
125 int image_size = static_cast<int>(utils::FileSize(a_img)); | 126 int image_size = static_cast<int>(utils::FileSize(a_img)); |
126 | 127 |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
214 EXPECT_TRUE(utils::MakeTempFile("/tmp/delta.XXXXXX", &delta_path, NULL)); | 215 EXPECT_TRUE(utils::MakeTempFile("/tmp/delta.XXXXXX", &delta_path, NULL)); |
215 LOG(INFO) << "delta path: " << delta_path; | 216 LOG(INFO) << "delta path: " << delta_path; |
216 ScopedPathUnlinker delta_path_unlinker(delta_path); | 217 ScopedPathUnlinker delta_path_unlinker(delta_path); |
217 { | 218 { |
218 string a_mnt, b_mnt; | 219 string a_mnt, b_mnt; |
219 ScopedLoopMounter a_mounter(a_img, &a_mnt, MS_RDONLY); | 220 ScopedLoopMounter a_mounter(a_img, &a_mnt, MS_RDONLY); |
220 ScopedLoopMounter b_mounter(b_img, &b_mnt, MS_RDONLY); | 221 ScopedLoopMounter b_mounter(b_img, &b_mnt, MS_RDONLY); |
221 | 222 |
222 EXPECT_TRUE( | 223 EXPECT_TRUE( |
223 DeltaDiffGenerator::GenerateDeltaUpdateFile( | 224 DeltaDiffGenerator::GenerateDeltaUpdateFile( |
224 a_mnt, | 225 full_rootfs ? "" : a_mnt, |
225 a_img, | 226 full_rootfs ? "" : a_img, |
226 b_mnt, | 227 b_mnt, |
227 b_img, | 228 b_img, |
228 full_kernel ? "" : old_kernel, | 229 full_kernel ? "" : old_kernel, |
229 new_kernel, | 230 new_kernel, |
230 delta_path, | 231 delta_path, |
231 kUnittestPrivateKeyPath)); | 232 kUnittestPrivateKeyPath)); |
232 } | 233 } |
233 | 234 |
234 // Read delta into memory. | 235 // Read delta into memory. |
235 vector<char> delta; | 236 vector<char> delta; |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
271 EXPECT_EQ(1, manifest.kernel_install_operations_size()); | 272 EXPECT_EQ(1, manifest.kernel_install_operations_size()); |
272 } | 273 } |
273 | 274 |
274 if (full_kernel) { | 275 if (full_kernel) { |
275 EXPECT_FALSE(manifest.has_old_kernel_info()); | 276 EXPECT_FALSE(manifest.has_old_kernel_info()); |
276 } else { | 277 } else { |
277 EXPECT_EQ(old_kernel_data.size(), manifest.old_kernel_info().size()); | 278 EXPECT_EQ(old_kernel_data.size(), manifest.old_kernel_info().size()); |
278 EXPECT_FALSE(manifest.old_kernel_info().hash().empty()); | 279 EXPECT_FALSE(manifest.old_kernel_info().hash().empty()); |
279 } | 280 } |
280 | 281 |
| 282 if (full_rootfs) { |
| 283 EXPECT_FALSE(manifest.has_old_rootfs_info()); |
| 284 } else { |
| 285 EXPECT_EQ(image_size, manifest.old_rootfs_info().size()); |
| 286 EXPECT_FALSE(manifest.old_rootfs_info().hash().empty()); |
| 287 } |
| 288 |
281 EXPECT_EQ(new_kernel_data.size(), manifest.new_kernel_info().size()); | 289 EXPECT_EQ(new_kernel_data.size(), manifest.new_kernel_info().size()); |
282 EXPECT_EQ(image_size, manifest.old_rootfs_info().size()); | |
283 EXPECT_EQ(image_size, manifest.new_rootfs_info().size()); | 290 EXPECT_EQ(image_size, manifest.new_rootfs_info().size()); |
284 | 291 |
285 EXPECT_FALSE(manifest.new_kernel_info().hash().empty()); | 292 EXPECT_FALSE(manifest.new_kernel_info().hash().empty()); |
286 EXPECT_FALSE(manifest.old_rootfs_info().hash().empty()); | |
287 EXPECT_FALSE(manifest.new_rootfs_info().hash().empty()); | 293 EXPECT_FALSE(manifest.new_rootfs_info().hash().empty()); |
288 } | 294 } |
289 | 295 |
290 PrefsMock prefs; | 296 PrefsMock prefs; |
291 EXPECT_CALL(prefs, SetInt64(kPrefsManifestMetadataSize, | 297 EXPECT_CALL(prefs, SetInt64(kPrefsManifestMetadataSize, |
292 manifest_metadata_size)).WillOnce(Return(true)); | 298 manifest_metadata_size)).WillOnce(Return(true)); |
293 EXPECT_CALL(prefs, SetInt64(kPrefsUpdateStateNextOperation, _)) | 299 EXPECT_CALL(prefs, SetInt64(kPrefsUpdateStateNextOperation, _)) |
294 .WillRepeatedly(Return(true)); | 300 .WillRepeatedly(Return(true)); |
295 EXPECT_CALL(prefs, GetInt64(kPrefsUpdateStateNextOperation, _)) | 301 EXPECT_CALL(prefs, GetInt64(kPrefsUpdateStateNextOperation, _)) |
296 .WillOnce(Return(false)); | 302 .WillOnce(Return(false)); |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
339 EXPECT_TRUE(utils::FileExists(kUnittestPublicKeyPath)); | 345 EXPECT_TRUE(utils::FileExists(kUnittestPublicKeyPath)); |
340 EXPECT_TRUE(performer.VerifyPayload( | 346 EXPECT_TRUE(performer.VerifyPayload( |
341 kUnittestPublicKeyPath, | 347 kUnittestPublicKeyPath, |
342 OmahaHashCalculator::OmahaHashOfData(delta), | 348 OmahaHashCalculator::OmahaHashOfData(delta), |
343 delta.size())); | 349 delta.size())); |
344 EXPECT_TRUE(performer.VerifyAppliedUpdate(a_img, old_kernel)); | 350 EXPECT_TRUE(performer.VerifyAppliedUpdate(a_img, old_kernel)); |
345 } | 351 } |
346 } | 352 } |
347 | 353 |
348 TEST(DeltaPerformerTest, RunAsRootSmallImageTest) { | 354 TEST(DeltaPerformerTest, RunAsRootSmallImageTest) { |
349 DoSmallImageTest(false, false); | 355 DoSmallImageTest(false, false, false); |
350 } | 356 } |
351 | 357 |
352 TEST(DeltaPerformerTest, RunAsRootFullKernelSmallImageTest) { | 358 TEST(DeltaPerformerTest, RunAsRootFullKernelSmallImageTest) { |
353 DoSmallImageTest(true, false); | 359 DoSmallImageTest(true, false, false); |
| 360 } |
| 361 |
| 362 TEST(DeltaPerformerTest, RunAsRootFullSmallImageTest) { |
| 363 DoSmallImageTest(true, true, false); |
354 } | 364 } |
355 | 365 |
356 TEST(DeltaPerformerTest, RunAsRootNoopSmallImageTest) { | 366 TEST(DeltaPerformerTest, RunAsRootNoopSmallImageTest) { |
357 DoSmallImageTest(false, true); | 367 DoSmallImageTest(false, false, true); |
358 } | |
359 | |
360 TEST(DeltaPerformerTest, NewFullUpdateTest) { | |
361 vector<char> new_root(20 * 1024 * 1024); | |
362 vector<char> new_kern(16 * 1024 * 1024); | |
363 const off_t kChunkSize = 128 * 1024; | |
364 FillWithData(&new_root); | |
365 FillWithData(&new_kern); | |
366 // Assume hashes take 2 MiB beyond the rootfs. | |
367 off_t new_rootfs_size = new_root.size() - 2 * 1024 * 1024; | |
368 | |
369 string new_root_path; | |
370 EXPECT_TRUE(utils::MakeTempFile("/tmp/NewFullUpdateTest_R.XXXXXX", | |
371 &new_root_path, | |
372 NULL)); | |
373 ScopedPathUnlinker new_root_path_unlinker(new_root_path); | |
374 EXPECT_TRUE(WriteFileVector(new_root_path, new_root)); | |
375 | |
376 string new_kern_path; | |
377 EXPECT_TRUE(utils::MakeTempFile("/tmp/NewFullUpdateTest_K.XXXXXX", | |
378 &new_kern_path, | |
379 NULL)); | |
380 ScopedPathUnlinker new_kern_path_unlinker(new_kern_path); | |
381 EXPECT_TRUE(WriteFileVector(new_kern_path, new_kern)); | |
382 | |
383 string out_blobs_path; | |
384 int out_blobs_fd; | |
385 EXPECT_TRUE(utils::MakeTempFile("/tmp/NewFullUpdateTest_D.XXXXXX", | |
386 &out_blobs_path, | |
387 &out_blobs_fd)); | |
388 ScopedPathUnlinker out_blobs_path_unlinker(out_blobs_path); | |
389 ScopedFdCloser out_blobs_fd_closer(&out_blobs_fd); | |
390 | |
391 off_t out_blobs_length = 0; | |
392 | |
393 Graph graph; | |
394 vector<DeltaArchiveManifest_InstallOperation> kernel_ops; | |
395 vector<Vertex::Index> final_order; | |
396 | |
397 EXPECT_TRUE(DeltaDiffGenerator::ReadFullUpdateFromDisk(&graph, | |
398 new_kern_path, | |
399 new_root_path, | |
400 new_rootfs_size, | |
401 out_blobs_fd, | |
402 &out_blobs_length, | |
403 kChunkSize, | |
404 &kernel_ops, | |
405 &final_order)); | |
406 EXPECT_EQ(new_rootfs_size / kChunkSize, graph.size()); | |
407 EXPECT_EQ(new_rootfs_size / kChunkSize, final_order.size()); | |
408 EXPECT_EQ(new_kern.size() / kChunkSize, kernel_ops.size()); | |
409 for (off_t i = 0; i < (new_rootfs_size / kChunkSize); ++i) { | |
410 EXPECT_EQ(i, final_order[i]); | |
411 EXPECT_EQ(1, graph[i].op.dst_extents_size()); | |
412 EXPECT_EQ(i * kChunkSize / kBlockSize, | |
413 graph[i].op.dst_extents(0).start_block()) << "i = " << i; | |
414 EXPECT_EQ(kChunkSize / kBlockSize, | |
415 graph[i].op.dst_extents(0).num_blocks()); | |
416 if (graph[i].op.type() != | |
417 DeltaArchiveManifest_InstallOperation_Type_REPLACE) { | |
418 EXPECT_EQ(DeltaArchiveManifest_InstallOperation_Type_REPLACE_BZ, | |
419 graph[i].op.type()); | |
420 } | |
421 } | |
422 } | 368 } |
423 | 369 |
424 TEST(DeltaPerformerTest, IsIdempotentOperationTest) { | 370 TEST(DeltaPerformerTest, IsIdempotentOperationTest) { |
425 DeltaArchiveManifest_InstallOperation op; | 371 DeltaArchiveManifest_InstallOperation op; |
426 EXPECT_TRUE(DeltaPerformer::IsIdempotentOperation(op)); | 372 EXPECT_TRUE(DeltaPerformer::IsIdempotentOperation(op)); |
427 *(op.add_dst_extents()) = ExtentForRange(0, 5); | 373 *(op.add_dst_extents()) = ExtentForRange(0, 5); |
428 EXPECT_TRUE(DeltaPerformer::IsIdempotentOperation(op)); | 374 EXPECT_TRUE(DeltaPerformer::IsIdempotentOperation(op)); |
429 *(op.add_src_extents()) = ExtentForRange(4, 1); | 375 *(op.add_src_extents()) = ExtentForRange(4, 1); |
430 EXPECT_FALSE(DeltaPerformer::IsIdempotentOperation(op)); | 376 EXPECT_FALSE(DeltaPerformer::IsIdempotentOperation(op)); |
431 op.clear_src_extents(); | 377 op.clear_src_extents(); |
432 *(op.add_src_extents()) = ExtentForRange(5, 3); | 378 *(op.add_src_extents()) = ExtentForRange(5, 3); |
433 EXPECT_TRUE(DeltaPerformer::IsIdempotentOperation(op)); | 379 EXPECT_TRUE(DeltaPerformer::IsIdempotentOperation(op)); |
434 *(op.add_dst_extents()) = ExtentForRange(20, 6); | 380 *(op.add_dst_extents()) = ExtentForRange(20, 6); |
435 EXPECT_TRUE(DeltaPerformer::IsIdempotentOperation(op)); | 381 EXPECT_TRUE(DeltaPerformer::IsIdempotentOperation(op)); |
436 *(op.add_src_extents()) = ExtentForRange(19, 2); | 382 *(op.add_src_extents()) = ExtentForRange(19, 2); |
437 EXPECT_FALSE(DeltaPerformer::IsIdempotentOperation(op)); | 383 EXPECT_FALSE(DeltaPerformer::IsIdempotentOperation(op)); |
438 } | 384 } |
439 | 385 |
440 } // namespace chromeos_update_engine | 386 } // namespace chromeos_update_engine |
OLD | NEW |