full_update_generator_unittest.cc revision 6c396a9b3020df9b0b58886fd6f36523bec29d3a
1// Copyright (c) 2010 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 "update_engine/payload_generator/full_update_generator.h" 6 7#include <string> 8#include <vector> 9 10#include <gtest/gtest.h> 11 12#include "update_engine/delta_performer.h" 13#include "update_engine/payload_generator/extent_utils.h" 14#include "update_engine/test_utils.h" 15 16using chromeos_update_engine::test_utils::FillWithData; 17using std::string; 18using std::vector; 19 20namespace chromeos_update_engine { 21 22class FullUpdateGeneratorTest : public ::testing::Test { 23 protected: 24 void SetUp() override { 25 config_.is_delta = false; 26 config_.minor_version = DeltaPerformer::kFullPayloadMinorVersion; 27 config_.chunk_size = 128 * 1024; 28 config_.block_size = 4096; 29 30 EXPECT_TRUE(utils::MakeTempFile("FullUpdateTest_rootfs.XXXXXX", 31 &config_.target.rootfs.path, 32 nullptr)); 33 EXPECT_TRUE(utils::MakeTempFile("FullUpdateTest_kernel.XXXXXX", 34 &config_.target.kernel.path, 35 nullptr)); 36 EXPECT_TRUE(utils::MakeTempFile("FullUpdateTest_blobs.XXXXXX", 37 &out_blobs_path_, 38 &out_blobs_fd_)); 39 40 rootfs_part_unlinker_.reset( 41 new ScopedPathUnlinker(config_.target.rootfs.path)); 42 kernel_part_unlinker_.reset( 43 new ScopedPathUnlinker(config_.target.kernel.path)); 44 out_blobs_unlinker_.reset(new ScopedPathUnlinker(out_blobs_path_)); 45 } 46 47 PayloadGenerationConfig config_; 48 49 // Output file holding the payload blobs. 50 string out_blobs_path_; 51 int out_blobs_fd_{-1}; 52 ScopedFdCloser out_blobs_fd_closer_{&out_blobs_fd_}; 53 54 std::unique_ptr<ScopedPathUnlinker> rootfs_part_unlinker_; 55 std::unique_ptr<ScopedPathUnlinker> kernel_part_unlinker_; 56 std::unique_ptr<ScopedPathUnlinker> out_blobs_unlinker_; 57 58 // FullUpdateGenerator under test. 59 FullUpdateGenerator generator_; 60}; 61 62TEST_F(FullUpdateGeneratorTest, RunTest) { 63 chromeos::Blob new_root(9 * 1024 * 1024); 64 chromeos::Blob new_kern(3 * 1024 * 1024); 65 FillWithData(&new_root); 66 FillWithData(&new_kern); 67 68 // Assume hashes take 2 MiB beyond the rootfs. 69 config_.rootfs_partition_size = new_root.size(); 70 config_.target.rootfs.size = new_root.size() - 2 * 1024 * 1024; 71 config_.target.kernel.size = new_kern.size(); 72 73 EXPECT_TRUE(test_utils::WriteFileVector(config_.target.rootfs.path, 74 new_root)); 75 EXPECT_TRUE(test_utils::WriteFileVector(config_.target.kernel.path, 76 new_kern)); 77 78 off_t out_blobs_length = 0; 79 vector<AnnotatedOperation> rootfs_ops; 80 vector<AnnotatedOperation> kernel_ops; 81 82 EXPECT_TRUE(generator_.GenerateOperations(config_, 83 out_blobs_fd_, 84 &out_blobs_length, 85 &rootfs_ops, 86 &kernel_ops)); 87 int64_t target_rootfs_chunks = 88 config_.target.rootfs.size / config_.chunk_size; 89 EXPECT_EQ(target_rootfs_chunks, rootfs_ops.size()); 90 EXPECT_EQ(new_kern.size() / config_.chunk_size, kernel_ops.size()); 91 for (off_t i = 0; i < target_rootfs_chunks; ++i) { 92 EXPECT_EQ(1, rootfs_ops[i].op.dst_extents_size()); 93 EXPECT_EQ(i * config_.chunk_size / config_.block_size, 94 rootfs_ops[i].op.dst_extents(0).start_block()) << "i = " << i; 95 EXPECT_EQ(config_.chunk_size / config_.block_size, 96 rootfs_ops[i].op.dst_extents(0).num_blocks()); 97 if (rootfs_ops[i].op.type() != 98 DeltaArchiveManifest_InstallOperation_Type_REPLACE) { 99 EXPECT_EQ(DeltaArchiveManifest_InstallOperation_Type_REPLACE_BZ, 100 rootfs_ops[i].op.type()); 101 } 102 } 103} 104 105// Test that if the chunk size is not a divisor of the image size, it handles 106// correctly the last chunk of each partition. 107TEST_F(FullUpdateGeneratorTest, ChunkSizeTooBig) { 108 config_.chunk_size = 1024 * 1024; 109 chromeos::Blob new_root(1536 * 1024); // 1.5 MiB 110 chromeos::Blob new_kern(128 * 1024); 111 config_.rootfs_partition_size = new_root.size(); 112 config_.target.rootfs.size = new_root.size(); 113 config_.target.kernel.size = new_kern.size(); 114 115 EXPECT_TRUE(test_utils::WriteFileVector(config_.target.rootfs.path, 116 new_root)); 117 EXPECT_TRUE(test_utils::WriteFileVector(config_.target.kernel.path, 118 new_kern)); 119 120 off_t out_blobs_length = 0; 121 vector<AnnotatedOperation> rootfs_ops; 122 vector<AnnotatedOperation> kernel_ops; 123 124 EXPECT_TRUE(generator_.GenerateOperations(config_, 125 out_blobs_fd_, 126 &out_blobs_length, 127 &rootfs_ops, 128 &kernel_ops)); 129 // rootfs has one chunk and a half. 130 EXPECT_EQ(2, rootfs_ops.size()); 131 EXPECT_EQ(config_.chunk_size / config_.block_size, 132 BlocksInExtents(rootfs_ops[0].op.dst_extents())); 133 EXPECT_EQ((new_root.size() - config_.chunk_size) / config_.block_size, 134 BlocksInExtents(rootfs_ops[1].op.dst_extents())); 135 136 // kernel has less than one chunk. 137 EXPECT_EQ(1, kernel_ops.size()); 138 EXPECT_EQ(new_kern.size() / config_.block_size, 139 BlocksInExtents(kernel_ops[0].op.dst_extents())); 140} 141 142} // namespace chromeos_update_engine 143