Home | History | Annotate | Download | only in payload_consumer
      1 //
      2 // Copyright (C) 2012 The Android Open Source Project
      3 //
      4 // Licensed under the Apache License, Version 2.0 (the "License");
      5 // you may not use this file except in compliance with the License.
      6 // You may obtain a copy of the License at
      7 //
      8 //      http://www.apache.org/licenses/LICENSE-2.0
      9 //
     10 // Unless required by applicable law or agreed to in writing, software
     11 // distributed under the License is distributed on an "AS IS" BASIS,
     12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13 // See the License for the specific language governing permissions and
     14 // limitations under the License.
     15 //
     16 
     17 #include "update_engine/payload_consumer/delta_performer.h"
     18 
     19 #include <inttypes.h>
     20 #include <sys/mount.h>
     21 
     22 #include <algorithm>
     23 #include <string>
     24 #include <vector>
     25 
     26 #include <base/files/file_path.h>
     27 #include <base/files/file_util.h>
     28 #include <base/strings/string_util.h>
     29 #include <base/strings/stringprintf.h>
     30 #include <google/protobuf/repeated_field.h>
     31 #include <gtest/gtest.h>
     32 #include <openssl/pem.h>
     33 
     34 #include "update_engine/common/constants.h"
     35 #include "update_engine/common/fake_boot_control.h"
     36 #include "update_engine/common/fake_hardware.h"
     37 #include "update_engine/common/mock_prefs.h"
     38 #include "update_engine/common/test_utils.h"
     39 #include "update_engine/common/utils.h"
     40 #include "update_engine/payload_consumer/mock_download_action.h"
     41 #include "update_engine/payload_consumer/payload_constants.h"
     42 #include "update_engine/payload_consumer/payload_verifier.h"
     43 #include "update_engine/payload_generator/delta_diff_generator.h"
     44 #include "update_engine/payload_generator/payload_signer.h"
     45 #include "update_engine/update_metadata.pb.h"
     46 
     47 namespace chromeos_update_engine {
     48 
     49 using std::string;
     50 using std::vector;
     51 using test_utils::GetBuildArtifactsPath;
     52 using test_utils::ScopedLoopMounter;
     53 using test_utils::System;
     54 using test_utils::kRandomString;
     55 using testing::Return;
     56 using testing::_;
     57 
     58 extern const char* kUnittestPrivateKeyPath;
     59 extern const char* kUnittestPublicKeyPath;
     60 extern const char* kUnittestPrivateKey2Path;
     61 extern const char* kUnittestPublicKey2Path;
     62 
     63 static const uint32_t kDefaultKernelSize = 4096;  // Something small for a test
     64 static const uint8_t kNewData[] = {'T', 'h', 'i', 's', ' ', 'i', 's', ' ',
     65                                    'n', 'e', 'w', ' ', 'd', 'a', 't', 'a', '.'};
     66 
     67 namespace {
     68 struct DeltaState {
     69   string a_img;
     70   string b_img;
     71   string result_img;
     72   size_t image_size;
     73 
     74   string delta_path;
     75   uint64_t metadata_size;
     76 
     77   string old_kernel;
     78   brillo::Blob old_kernel_data;
     79 
     80   string new_kernel;
     81   brillo::Blob new_kernel_data;
     82 
     83   string result_kernel;
     84   brillo::Blob result_kernel_data;
     85   size_t kernel_size;
     86 
     87   // The InstallPlan referenced by the DeltaPerformer. This needs to outlive
     88   // the DeltaPerformer.
     89   InstallPlan install_plan;
     90 
     91   // The in-memory copy of delta file.
     92   brillo::Blob delta;
     93 
     94   // Mock and fake instances used by the delta performer.
     95   FakeBootControl fake_boot_control_;
     96   FakeHardware fake_hardware_;
     97   MockDownloadActionDelegate mock_delegate_;
     98 };
     99 
    100 enum SignatureTest {
    101   kSignatureNone,  // No payload signing.
    102   kSignatureGenerator,  // Sign the payload at generation time.
    103   kSignatureGenerated,  // Sign the payload after it's generated.
    104   kSignatureGeneratedPlaceholder,  // Insert placeholder signatures, then real.
    105   kSignatureGeneratedPlaceholderMismatch,  // Insert a wrong sized placeholder.
    106   kSignatureGeneratedShell,  // Sign the generated payload through shell cmds.
    107   kSignatureGeneratedShellBadKey,  // Sign with a bad key through shell cmds.
    108   kSignatureGeneratedShellRotateCl1,  // Rotate key, test client v1
    109   kSignatureGeneratedShellRotateCl2,  // Rotate key, test client v2
    110 };
    111 
    112 enum OperationHashTest {
    113   kInvalidOperationData,
    114   kValidOperationData,
    115 };
    116 
    117 }  // namespace
    118 
    119 class DeltaPerformerIntegrationTest : public ::testing::Test {
    120  public:
    121   static void SetSupportedVersion(DeltaPerformer* performer,
    122                                   uint64_t minor_version) {
    123     performer->supported_minor_version_ = minor_version;
    124   }
    125 };
    126 
    127 static void CompareFilesByBlock(const string& a_file, const string& b_file,
    128                                 size_t image_size) {
    129   EXPECT_EQ(0U, image_size % kBlockSize);
    130 
    131   brillo::Blob a_data, b_data;
    132   EXPECT_TRUE(utils::ReadFile(a_file, &a_data)) << "file failed: " << a_file;
    133   EXPECT_TRUE(utils::ReadFile(b_file, &b_data)) << "file failed: " << b_file;
    134 
    135   EXPECT_GE(a_data.size(), image_size);
    136   EXPECT_GE(b_data.size(), image_size);
    137   for (size_t i = 0; i < image_size; i += kBlockSize) {
    138     EXPECT_EQ(0U, i % kBlockSize);
    139     brillo::Blob a_sub(&a_data[i], &a_data[i + kBlockSize]);
    140     brillo::Blob b_sub(&b_data[i], &b_data[i + kBlockSize]);
    141     EXPECT_TRUE(a_sub == b_sub) << "Block " << (i/kBlockSize) << " differs";
    142   }
    143   if (::testing::Test::HasNonfatalFailure()) {
    144     LOG(INFO) << "Compared filesystems with size " << image_size
    145               << ", partition A " << a_file << " size: " << a_data.size()
    146               << ", partition B " << b_file << " size: " << b_data.size();
    147   }
    148 }
    149 
    150 static bool WriteSparseFile(const string& path, off_t size) {
    151   int fd = open(path.c_str(), O_CREAT | O_TRUNC | O_WRONLY, 0644);
    152   TEST_AND_RETURN_FALSE_ERRNO(fd >= 0);
    153   ScopedFdCloser fd_closer(&fd);
    154   off_t rc = lseek(fd, size + 1, SEEK_SET);
    155   TEST_AND_RETURN_FALSE_ERRNO(rc != static_cast<off_t>(-1));
    156   int return_code = ftruncate(fd, size);
    157   TEST_AND_RETURN_FALSE_ERRNO(return_code == 0);
    158   return true;
    159 }
    160 
    161 static bool WriteByteAtOffset(const string& path, off_t offset) {
    162   int fd = open(path.c_str(), O_CREAT | O_WRONLY, 0644);
    163   TEST_AND_RETURN_FALSE_ERRNO(fd >= 0);
    164   ScopedFdCloser fd_closer(&fd);
    165   EXPECT_TRUE(utils::PWriteAll(fd, "\0", 1, offset));
    166   return true;
    167 }
    168 
    169 static size_t GetSignatureSize(const string& private_key_path) {
    170   const brillo::Blob data(1, 'x');
    171   brillo::Blob hash;
    172   EXPECT_TRUE(HashCalculator::RawHashOfData(data, &hash));
    173   brillo::Blob signature;
    174   EXPECT_TRUE(PayloadSigner::SignHash(hash,
    175                                       private_key_path,
    176                                       &signature));
    177   return signature.size();
    178 }
    179 
    180 static bool InsertSignaturePlaceholder(int signature_size,
    181                                        const string& payload_path,
    182                                        uint64_t* out_metadata_size) {
    183   vector<brillo::Blob> signatures;
    184   signatures.push_back(brillo::Blob(signature_size, 0));
    185 
    186   return PayloadSigner::AddSignatureToPayload(
    187       payload_path,
    188       signatures,
    189       {},
    190       payload_path,
    191       out_metadata_size);
    192 }
    193 
    194 static void SignGeneratedPayload(const string& payload_path,
    195                                  uint64_t* out_metadata_size) {
    196   string private_key_path = GetBuildArtifactsPath(kUnittestPrivateKeyPath);
    197   int signature_size = GetSignatureSize(private_key_path);
    198   brillo::Blob hash;
    199   ASSERT_TRUE(PayloadSigner::HashPayloadForSigning(
    200       payload_path, {signature_size}, &hash, nullptr));
    201   brillo::Blob signature;
    202   ASSERT_TRUE(PayloadSigner::SignHash(hash, private_key_path, &signature));
    203   ASSERT_TRUE(PayloadSigner::AddSignatureToPayload(
    204       payload_path, {signature}, {}, payload_path, out_metadata_size));
    205   EXPECT_TRUE(PayloadSigner::VerifySignedPayload(
    206       payload_path, GetBuildArtifactsPath(kUnittestPublicKeyPath)));
    207 }
    208 
    209 static void SignGeneratedShellPayload(SignatureTest signature_test,
    210                                       const string& payload_path) {
    211   string private_key_path = GetBuildArtifactsPath(kUnittestPrivateKeyPath);
    212   if (signature_test == kSignatureGeneratedShellBadKey) {
    213     ASSERT_TRUE(utils::MakeTempFile("key.XXXXXX",
    214                                     &private_key_path,
    215                                     nullptr));
    216   } else {
    217     ASSERT_TRUE(signature_test == kSignatureGeneratedShell ||
    218                 signature_test == kSignatureGeneratedShellRotateCl1 ||
    219                 signature_test == kSignatureGeneratedShellRotateCl2);
    220   }
    221   ScopedPathUnlinker key_unlinker(private_key_path);
    222   key_unlinker.set_should_remove(signature_test ==
    223                                  kSignatureGeneratedShellBadKey);
    224   // Generates a new private key that will not match the public key.
    225   if (signature_test == kSignatureGeneratedShellBadKey) {
    226     LOG(INFO) << "Generating a mismatched private key.";
    227     // The code below executes the equivalent of:
    228     // openssl genrsa -out <private_key_path> 2048
    229     RSA* rsa = RSA_new();
    230     BIGNUM* e = BN_new();
    231     EXPECT_EQ(1, BN_set_word(e, RSA_F4));
    232     EXPECT_EQ(1, RSA_generate_key_ex(rsa, 2048, e, nullptr));
    233     BN_free(e);
    234     FILE* fprikey = fopen(private_key_path.c_str(), "w");
    235     EXPECT_NE(nullptr, fprikey);
    236     EXPECT_EQ(1,
    237               PEM_write_RSAPrivateKey(
    238                   fprikey, rsa, nullptr, nullptr, 0, nullptr, nullptr));
    239     fclose(fprikey);
    240     RSA_free(rsa);
    241   }
    242   int signature_size = GetSignatureSize(private_key_path);
    243   string hash_file;
    244   ASSERT_TRUE(utils::MakeTempFile("hash.XXXXXX", &hash_file, nullptr));
    245   ScopedPathUnlinker hash_unlinker(hash_file);
    246   string signature_size_string;
    247   if (signature_test == kSignatureGeneratedShellRotateCl1 ||
    248       signature_test == kSignatureGeneratedShellRotateCl2)
    249     signature_size_string = base::StringPrintf("%d:%d",
    250                                                signature_size, signature_size);
    251   else
    252     signature_size_string = base::StringPrintf("%d", signature_size);
    253   string delta_generator_path = GetBuildArtifactsPath("delta_generator");
    254   ASSERT_EQ(0,
    255             System(base::StringPrintf(
    256                 "%s -in_file=%s -signature_size=%s -out_hash_file=%s",
    257                 delta_generator_path.c_str(),
    258                 payload_path.c_str(),
    259                 signature_size_string.c_str(),
    260                 hash_file.c_str())));
    261 
    262   // Sign the hash
    263   brillo::Blob hash, signature;
    264   ASSERT_TRUE(utils::ReadFile(hash_file, &hash));
    265   ASSERT_TRUE(PayloadSigner::SignHash(hash, private_key_path, &signature));
    266 
    267   string sig_file;
    268   ASSERT_TRUE(utils::MakeTempFile("signature.XXXXXX", &sig_file, nullptr));
    269   ScopedPathUnlinker sig_unlinker(sig_file);
    270   ASSERT_TRUE(test_utils::WriteFileVector(sig_file, signature));
    271 
    272   string sig_file2;
    273   ASSERT_TRUE(utils::MakeTempFile("signature.XXXXXX", &sig_file2, nullptr));
    274   ScopedPathUnlinker sig2_unlinker(sig_file2);
    275   if (signature_test == kSignatureGeneratedShellRotateCl1 ||
    276       signature_test == kSignatureGeneratedShellRotateCl2) {
    277     ASSERT_TRUE(PayloadSigner::SignHash(
    278         hash, GetBuildArtifactsPath(kUnittestPrivateKey2Path), &signature));
    279     ASSERT_TRUE(test_utils::WriteFileVector(sig_file2, signature));
    280     // Append second sig file to first path
    281     sig_file += ":" + sig_file2;
    282   }
    283 
    284   ASSERT_EQ(0,
    285             System(base::StringPrintf(
    286                 "%s -in_file=%s -signature_file=%s -out_file=%s",
    287                 delta_generator_path.c_str(),
    288                 payload_path.c_str(),
    289                 sig_file.c_str(),
    290                 payload_path.c_str())));
    291   int verify_result = System(base::StringPrintf(
    292       "%s -in_file=%s -public_key=%s -public_key_version=%d",
    293       delta_generator_path.c_str(),
    294       payload_path.c_str(),
    295       (signature_test == kSignatureGeneratedShellRotateCl2
    296            ? GetBuildArtifactsPath(kUnittestPublicKey2Path)
    297            : GetBuildArtifactsPath(kUnittestPublicKeyPath))
    298           .c_str(),
    299       signature_test == kSignatureGeneratedShellRotateCl2 ? 2 : 1));
    300   if (signature_test == kSignatureGeneratedShellBadKey) {
    301     ASSERT_NE(0, verify_result);
    302   } else {
    303     ASSERT_EQ(0, verify_result);
    304   }
    305 }
    306 
    307 static void GenerateDeltaFile(bool full_kernel,
    308                               bool full_rootfs,
    309                               bool noop,
    310                               ssize_t chunk_size,
    311                               SignatureTest signature_test,
    312                               DeltaState *state,
    313                               uint32_t minor_version) {
    314   EXPECT_TRUE(utils::MakeTempFile("a_img.XXXXXX", &state->a_img, nullptr));
    315   EXPECT_TRUE(utils::MakeTempFile("b_img.XXXXXX", &state->b_img, nullptr));
    316 
    317   // result_img is used in minor version 2. Instead of applying the update
    318   // in-place on A, we apply it to a new image, result_img.
    319   EXPECT_TRUE(
    320       utils::MakeTempFile("result_img.XXXXXX", &state->result_img, nullptr));
    321 
    322   EXPECT_TRUE(
    323       base::CopyFile(GetBuildArtifactsPath().Append("gen/disk_ext2_4k.img"),
    324                      base::FilePath(state->a_img)));
    325 
    326   state->image_size = utils::FileSize(state->a_img);
    327 
    328   // Create ImageInfo A & B
    329   ImageInfo old_image_info;
    330   ImageInfo new_image_info;
    331 
    332   if (!full_rootfs) {
    333     old_image_info.set_channel("src-channel");
    334     old_image_info.set_board("src-board");
    335     old_image_info.set_version("src-version");
    336     old_image_info.set_key("src-key");
    337     old_image_info.set_build_channel("src-build-channel");
    338     old_image_info.set_build_version("src-build-version");
    339   }
    340 
    341   new_image_info.set_channel("test-channel");
    342   new_image_info.set_board("test-board");
    343   new_image_info.set_version("test-version");
    344   new_image_info.set_key("test-key");
    345   new_image_info.set_build_channel("test-build-channel");
    346   new_image_info.set_build_version("test-build-version");
    347 
    348   // Make some changes to the A image.
    349   {
    350     string a_mnt;
    351     ScopedLoopMounter b_mounter(state->a_img, &a_mnt, 0);
    352 
    353     brillo::Blob hardtocompress;
    354     while (hardtocompress.size() < 3 * kBlockSize) {
    355       hardtocompress.insert(hardtocompress.end(),
    356                             std::begin(kRandomString), std::end(kRandomString));
    357     }
    358     EXPECT_TRUE(utils::WriteFile(base::StringPrintf("%s/hardtocompress",
    359                                                     a_mnt.c_str()).c_str(),
    360                                  hardtocompress.data(),
    361                                  hardtocompress.size()));
    362 
    363     brillo::Blob zeros(16 * 1024, 0);
    364     EXPECT_EQ(static_cast<int>(zeros.size()),
    365               base::WriteFile(base::FilePath(base::StringPrintf(
    366                                   "%s/move-to-sparse", a_mnt.c_str())),
    367                               reinterpret_cast<const char*>(zeros.data()),
    368                               zeros.size()));
    369 
    370     EXPECT_TRUE(
    371         WriteSparseFile(base::StringPrintf("%s/move-from-sparse",
    372                                            a_mnt.c_str()), 16 * 1024));
    373 
    374     EXPECT_TRUE(WriteByteAtOffset(
    375         base::StringPrintf("%s/move-semi-sparse", a_mnt.c_str()), 4096));
    376 
    377     // Write 1 MiB of 0xff to try to catch the case where writing a bsdiff
    378     // patch fails to zero out the final block.
    379     brillo::Blob ones(1024 * 1024, 0xff);
    380     EXPECT_TRUE(utils::WriteFile(base::StringPrintf("%s/ones",
    381                                                     a_mnt.c_str()).c_str(),
    382                                  ones.data(),
    383                                  ones.size()));
    384   }
    385 
    386   if (noop) {
    387     EXPECT_TRUE(base::CopyFile(base::FilePath(state->a_img),
    388                                base::FilePath(state->b_img)));
    389     old_image_info = new_image_info;
    390   } else {
    391     if (minor_version == kSourceMinorPayloadVersion) {
    392       // Create a result image with image_size bytes of garbage.
    393       brillo::Blob ones(state->image_size, 0xff);
    394       EXPECT_TRUE(utils::WriteFile(state->result_img.c_str(),
    395                                    ones.data(),
    396                                    ones.size()));
    397       EXPECT_EQ(utils::FileSize(state->a_img),
    398                 utils::FileSize(state->result_img));
    399     }
    400 
    401     EXPECT_TRUE(
    402         base::CopyFile(GetBuildArtifactsPath().Append("gen/disk_ext2_4k.img"),
    403                        base::FilePath(state->b_img)));
    404 
    405     // Make some changes to the B image.
    406     string b_mnt;
    407     ScopedLoopMounter b_mounter(state->b_img, &b_mnt, 0);
    408     base::FilePath mnt_path(b_mnt);
    409 
    410     EXPECT_TRUE(base::CopyFile(mnt_path.Append("regular-small"),
    411                                mnt_path.Append("regular-small2")));
    412     EXPECT_TRUE(base::DeleteFile(mnt_path.Append("regular-small"), false));
    413     EXPECT_TRUE(base::Move(mnt_path.Append("regular-small2"),
    414                            mnt_path.Append("regular-small")));
    415     EXPECT_TRUE(
    416         test_utils::WriteFileString(mnt_path.Append("foo").value(), "foo"));
    417     EXPECT_EQ(0, base::WriteFile(mnt_path.Append("emptyfile"), "", 0));
    418 
    419     EXPECT_TRUE(
    420         WriteSparseFile(mnt_path.Append("fullsparse").value(), 1024 * 1024));
    421     EXPECT_TRUE(
    422         WriteSparseFile(mnt_path.Append("move-to-sparse").value(), 16 * 1024));
    423 
    424     brillo::Blob zeros(16 * 1024, 0);
    425     EXPECT_EQ(static_cast<int>(zeros.size()),
    426               base::WriteFile(mnt_path.Append("move-from-sparse"),
    427                               reinterpret_cast<const char*>(zeros.data()),
    428                               zeros.size()));
    429 
    430     EXPECT_TRUE(
    431         WriteByteAtOffset(mnt_path.Append("move-semi-sparse").value(), 4096));
    432     EXPECT_TRUE(WriteByteAtOffset(mnt_path.Append("partsparse").value(), 4096));
    433 
    434     EXPECT_TRUE(
    435         base::CopyFile(mnt_path.Append("regular-16k"), mnt_path.Append("tmp")));
    436     EXPECT_TRUE(base::Move(mnt_path.Append("tmp"),
    437                            mnt_path.Append("link-hard-regular-16k")));
    438 
    439     EXPECT_TRUE(base::DeleteFile(mnt_path.Append("link-short_symlink"), false));
    440     EXPECT_TRUE(test_utils::WriteFileString(
    441         mnt_path.Append("link-short_symlink").value(), "foobar"));
    442 
    443     brillo::Blob hardtocompress;
    444     while (hardtocompress.size() < 3 * kBlockSize) {
    445       hardtocompress.insert(hardtocompress.end(),
    446                             std::begin(kRandomString), std::end(kRandomString));
    447     }
    448     EXPECT_TRUE(utils::WriteFile(base::StringPrintf("%s/hardtocompress",
    449                                               b_mnt.c_str()).c_str(),
    450                                  hardtocompress.data(),
    451                                  hardtocompress.size()));
    452   }
    453 
    454   string old_kernel;
    455   EXPECT_TRUE(utils::MakeTempFile("old_kernel.XXXXXX",
    456                                   &state->old_kernel,
    457                                   nullptr));
    458 
    459   string new_kernel;
    460   EXPECT_TRUE(utils::MakeTempFile("new_kernel.XXXXXX",
    461                                   &state->new_kernel,
    462                                   nullptr));
    463 
    464   string result_kernel;
    465   EXPECT_TRUE(utils::MakeTempFile("result_kernel.XXXXXX",
    466                                   &state->result_kernel,
    467                                   nullptr));
    468 
    469   state->kernel_size = kDefaultKernelSize;
    470   state->old_kernel_data.resize(kDefaultKernelSize);
    471   state->new_kernel_data.resize(state->old_kernel_data.size());
    472   state->result_kernel_data.resize(state->old_kernel_data.size());
    473   test_utils::FillWithData(&state->old_kernel_data);
    474   test_utils::FillWithData(&state->new_kernel_data);
    475   test_utils::FillWithData(&state->result_kernel_data);
    476 
    477   // change the new kernel data
    478   std::copy(std::begin(kNewData), std::end(kNewData),
    479             state->new_kernel_data.begin());
    480 
    481   if (noop) {
    482     state->old_kernel_data = state->new_kernel_data;
    483   }
    484 
    485   // Write kernels to disk
    486   EXPECT_TRUE(utils::WriteFile(state->old_kernel.c_str(),
    487                                state->old_kernel_data.data(),
    488                                state->old_kernel_data.size()));
    489   EXPECT_TRUE(utils::WriteFile(state->new_kernel.c_str(),
    490                                state->new_kernel_data.data(),
    491                                state->new_kernel_data.size()));
    492   EXPECT_TRUE(utils::WriteFile(state->result_kernel.c_str(),
    493                                state->result_kernel_data.data(),
    494                                state->result_kernel_data.size()));
    495 
    496   EXPECT_TRUE(utils::MakeTempFile("delta.XXXXXX",
    497                                   &state->delta_path,
    498                                   nullptr));
    499   LOG(INFO) << "delta path: " << state->delta_path;
    500   {
    501     const string private_key =
    502         signature_test == kSignatureGenerator
    503             ? GetBuildArtifactsPath(kUnittestPrivateKeyPath)
    504             : "";
    505 
    506     PayloadGenerationConfig payload_config;
    507     payload_config.is_delta = !full_rootfs;
    508     payload_config.hard_chunk_size = chunk_size;
    509     payload_config.rootfs_partition_size = kRootFSPartitionSize;
    510     payload_config.version.major = kChromeOSMajorPayloadVersion;
    511     payload_config.version.minor = minor_version;
    512     if (!full_rootfs) {
    513       payload_config.source.partitions.emplace_back(kLegacyPartitionNameRoot);
    514       payload_config.source.partitions.emplace_back(kLegacyPartitionNameKernel);
    515       payload_config.source.partitions.front().path = state->a_img;
    516       if (!full_kernel)
    517         payload_config.source.partitions.back().path = state->old_kernel;
    518       payload_config.source.image_info = old_image_info;
    519       EXPECT_TRUE(payload_config.source.LoadImageSize());
    520       for (PartitionConfig& part : payload_config.source.partitions)
    521         EXPECT_TRUE(part.OpenFilesystem());
    522     } else {
    523       if (payload_config.hard_chunk_size == -1)
    524         // Use 1 MiB chunk size for the full unittests.
    525         payload_config.hard_chunk_size = 1024 * 1024;
    526     }
    527     payload_config.target.partitions.emplace_back(kLegacyPartitionNameRoot);
    528     payload_config.target.partitions.back().path = state->b_img;
    529     payload_config.target.partitions.emplace_back(kLegacyPartitionNameKernel);
    530     payload_config.target.partitions.back().path = state->new_kernel;
    531     payload_config.target.image_info = new_image_info;
    532     EXPECT_TRUE(payload_config.target.LoadImageSize());
    533     for (PartitionConfig& part : payload_config.target.partitions)
    534       EXPECT_TRUE(part.OpenFilesystem());
    535 
    536     EXPECT_TRUE(payload_config.Validate());
    537     EXPECT_TRUE(
    538         GenerateUpdatePayloadFile(
    539             payload_config,
    540             state->delta_path,
    541             private_key,
    542             &state->metadata_size));
    543   }
    544   // Extend the "partitions" holding the file system a bit.
    545   EXPECT_EQ(0, HANDLE_EINTR(truncate(state->a_img.c_str(),
    546                                      state->image_size + 1024 * 1024)));
    547   EXPECT_EQ(static_cast<off_t>(state->image_size + 1024 * 1024),
    548             utils::FileSize(state->a_img));
    549   EXPECT_EQ(0, HANDLE_EINTR(truncate(state->b_img.c_str(),
    550                                      state->image_size + 1024 * 1024)));
    551   EXPECT_EQ(static_cast<off_t>(state->image_size + 1024 * 1024),
    552             utils::FileSize(state->b_img));
    553 
    554   if (signature_test == kSignatureGeneratedPlaceholder ||
    555       signature_test == kSignatureGeneratedPlaceholderMismatch) {
    556     int signature_size =
    557         GetSignatureSize(GetBuildArtifactsPath(kUnittestPrivateKeyPath));
    558     LOG(INFO) << "Inserting placeholder signature.";
    559     ASSERT_TRUE(InsertSignaturePlaceholder(signature_size, state->delta_path,
    560                                            &state->metadata_size));
    561 
    562     if (signature_test == kSignatureGeneratedPlaceholderMismatch) {
    563       signature_size -= 1;
    564       LOG(INFO) << "Inserting mismatched placeholder signature.";
    565       ASSERT_FALSE(InsertSignaturePlaceholder(signature_size, state->delta_path,
    566                                               &state->metadata_size));
    567       return;
    568     }
    569   }
    570 
    571   if (signature_test == kSignatureGenerated ||
    572       signature_test == kSignatureGeneratedPlaceholder ||
    573       signature_test == kSignatureGeneratedPlaceholderMismatch) {
    574     // Generate the signed payload and update the metadata size in state to
    575     // reflect the new size after adding the signature operation to the
    576     // manifest.
    577     LOG(INFO) << "Signing payload.";
    578     SignGeneratedPayload(state->delta_path, &state->metadata_size);
    579   } else if (signature_test == kSignatureGeneratedShell ||
    580              signature_test == kSignatureGeneratedShellBadKey ||
    581              signature_test == kSignatureGeneratedShellRotateCl1 ||
    582              signature_test == kSignatureGeneratedShellRotateCl2) {
    583     SignGeneratedShellPayload(signature_test, state->delta_path);
    584   }
    585 }
    586 
    587 static void ApplyDeltaFile(bool full_kernel, bool full_rootfs, bool noop,
    588                            SignatureTest signature_test, DeltaState* state,
    589                            bool hash_checks_mandatory,
    590                            OperationHashTest op_hash_test,
    591                            DeltaPerformer** performer,
    592                            uint32_t minor_version) {
    593   // Check the metadata.
    594   {
    595     DeltaArchiveManifest manifest;
    596     EXPECT_TRUE(PayloadSigner::LoadPayloadMetadata(state->delta_path,
    597                                                    nullptr,
    598                                                    &manifest,
    599                                                    nullptr,
    600                                                    &state->metadata_size,
    601                                                    nullptr));
    602     LOG(INFO) << "Metadata size: " << state->metadata_size;
    603     EXPECT_TRUE(utils::ReadFile(state->delta_path, &state->delta));
    604 
    605     if (signature_test == kSignatureNone) {
    606       EXPECT_FALSE(manifest.has_signatures_offset());
    607       EXPECT_FALSE(manifest.has_signatures_size());
    608     } else {
    609       EXPECT_TRUE(manifest.has_signatures_offset());
    610       EXPECT_TRUE(manifest.has_signatures_size());
    611       Signatures sigs_message;
    612       EXPECT_TRUE(sigs_message.ParseFromArray(
    613           &state->delta[state->metadata_size + manifest.signatures_offset()],
    614           manifest.signatures_size()));
    615       if (signature_test == kSignatureGeneratedShellRotateCl1 ||
    616           signature_test == kSignatureGeneratedShellRotateCl2)
    617         EXPECT_EQ(2, sigs_message.signatures_size());
    618       else
    619         EXPECT_EQ(1, sigs_message.signatures_size());
    620       const Signatures_Signature& signature = sigs_message.signatures(0);
    621       EXPECT_EQ(1U, signature.version());
    622 
    623       uint64_t expected_sig_data_length = 0;
    624       vector<string> key_paths{GetBuildArtifactsPath(kUnittestPrivateKeyPath)};
    625       if (signature_test == kSignatureGeneratedShellRotateCl1 ||
    626           signature_test == kSignatureGeneratedShellRotateCl2) {
    627         key_paths.push_back(GetBuildArtifactsPath(kUnittestPrivateKey2Path));
    628       }
    629       EXPECT_TRUE(PayloadSigner::SignatureBlobLength(
    630           key_paths,
    631           &expected_sig_data_length));
    632       EXPECT_EQ(expected_sig_data_length, manifest.signatures_size());
    633       EXPECT_FALSE(signature.data().empty());
    634     }
    635 
    636     if (noop) {
    637       EXPECT_EQ(0, manifest.install_operations_size());
    638       EXPECT_EQ(1, manifest.kernel_install_operations_size());
    639     }
    640 
    641     if (full_kernel) {
    642       EXPECT_FALSE(manifest.has_old_kernel_info());
    643     } else {
    644       EXPECT_EQ(state->old_kernel_data.size(),
    645                 manifest.old_kernel_info().size());
    646       EXPECT_FALSE(manifest.old_kernel_info().hash().empty());
    647     }
    648 
    649     EXPECT_EQ(manifest.new_image_info().channel(), "test-channel");
    650     EXPECT_EQ(manifest.new_image_info().board(), "test-board");
    651     EXPECT_EQ(manifest.new_image_info().version(), "test-version");
    652     EXPECT_EQ(manifest.new_image_info().key(), "test-key");
    653     EXPECT_EQ(manifest.new_image_info().build_channel(), "test-build-channel");
    654     EXPECT_EQ(manifest.new_image_info().build_version(), "test-build-version");
    655 
    656     if (!full_rootfs) {
    657       if (noop) {
    658         EXPECT_EQ(manifest.old_image_info().channel(), "test-channel");
    659         EXPECT_EQ(manifest.old_image_info().board(), "test-board");
    660         EXPECT_EQ(manifest.old_image_info().version(), "test-version");
    661         EXPECT_EQ(manifest.old_image_info().key(), "test-key");
    662         EXPECT_EQ(manifest.old_image_info().build_channel(),
    663                   "test-build-channel");
    664         EXPECT_EQ(manifest.old_image_info().build_version(),
    665                   "test-build-version");
    666       } else {
    667         EXPECT_EQ(manifest.old_image_info().channel(), "src-channel");
    668         EXPECT_EQ(manifest.old_image_info().board(), "src-board");
    669         EXPECT_EQ(manifest.old_image_info().version(), "src-version");
    670         EXPECT_EQ(manifest.old_image_info().key(), "src-key");
    671         EXPECT_EQ(manifest.old_image_info().build_channel(),
    672                   "src-build-channel");
    673         EXPECT_EQ(manifest.old_image_info().build_version(),
    674                   "src-build-version");
    675       }
    676     }
    677 
    678 
    679     if (full_rootfs) {
    680       EXPECT_FALSE(manifest.has_old_rootfs_info());
    681       EXPECT_FALSE(manifest.has_old_image_info());
    682       EXPECT_TRUE(manifest.has_new_image_info());
    683     } else {
    684       EXPECT_EQ(state->image_size, manifest.old_rootfs_info().size());
    685       EXPECT_FALSE(manifest.old_rootfs_info().hash().empty());
    686     }
    687 
    688     EXPECT_EQ(state->new_kernel_data.size(), manifest.new_kernel_info().size());
    689     EXPECT_EQ(state->image_size, manifest.new_rootfs_info().size());
    690 
    691     EXPECT_FALSE(manifest.new_kernel_info().hash().empty());
    692     EXPECT_FALSE(manifest.new_rootfs_info().hash().empty());
    693   }
    694 
    695   MockPrefs prefs;
    696   EXPECT_CALL(prefs, SetInt64(kPrefsManifestMetadataSize,
    697                               state->metadata_size)).WillOnce(Return(true));
    698   EXPECT_CALL(prefs, SetInt64(kPrefsManifestSignatureSize, 0))
    699       .WillOnce(Return(true));
    700   EXPECT_CALL(prefs, SetInt64(kPrefsUpdateStateNextOperation, _))
    701       .WillRepeatedly(Return(true));
    702   EXPECT_CALL(prefs, GetInt64(kPrefsUpdateStateNextOperation, _))
    703       .WillOnce(Return(false));
    704   EXPECT_CALL(prefs, SetInt64(kPrefsUpdateStateNextDataOffset, _))
    705       .WillRepeatedly(Return(true));
    706   EXPECT_CALL(prefs, SetInt64(kPrefsUpdateStateNextDataLength, _))
    707       .WillRepeatedly(Return(true));
    708   EXPECT_CALL(prefs, SetString(kPrefsUpdateStateSHA256Context, _))
    709       .WillRepeatedly(Return(true));
    710   EXPECT_CALL(prefs, SetString(kPrefsUpdateStateSignedSHA256Context, _))
    711       .WillRepeatedly(Return(true));
    712   if (op_hash_test == kValidOperationData && signature_test != kSignatureNone) {
    713     EXPECT_CALL(prefs, SetString(kPrefsUpdateStateSignatureBlob, _))
    714         .WillOnce(Return(true));
    715   }
    716 
    717   EXPECT_CALL(state->mock_delegate_, ShouldCancel(_))
    718       .WillRepeatedly(Return(false));
    719 
    720   // Update the A image in place.
    721   InstallPlan* install_plan = &state->install_plan;
    722   install_plan->hash_checks_mandatory = hash_checks_mandatory;
    723   install_plan->payloads = {{.metadata_size = state->metadata_size,
    724                              .type = (full_kernel && full_rootfs)
    725                                          ? InstallPayloadType::kFull
    726                                          : InstallPayloadType::kDelta}};
    727   install_plan->source_slot = 0;
    728   install_plan->target_slot = 1;
    729 
    730   InstallPlan::Partition root_part;
    731   root_part.name = kLegacyPartitionNameRoot;
    732 
    733   InstallPlan::Partition kernel_part;
    734   kernel_part.name = kLegacyPartitionNameKernel;
    735 
    736   LOG(INFO) << "Setting payload metadata size in Omaha  = "
    737             << state->metadata_size;
    738   ASSERT_TRUE(PayloadSigner::GetMetadataSignature(
    739       state->delta.data(),
    740       state->metadata_size,
    741       GetBuildArtifactsPath(kUnittestPrivateKeyPath),
    742       &install_plan->payloads[0].metadata_signature));
    743   EXPECT_FALSE(install_plan->payloads[0].metadata_signature.empty());
    744 
    745   *performer = new DeltaPerformer(&prefs,
    746                                   &state->fake_boot_control_,
    747                                   &state->fake_hardware_,
    748                                   &state->mock_delegate_,
    749                                   install_plan,
    750                                   &install_plan->payloads[0],
    751                                   false /* is_interactive */);
    752   string public_key_path = GetBuildArtifactsPath(kUnittestPublicKeyPath);
    753   EXPECT_TRUE(utils::FileExists(public_key_path.c_str()));
    754   (*performer)->set_public_key_path(public_key_path);
    755   DeltaPerformerIntegrationTest::SetSupportedVersion(*performer, minor_version);
    756 
    757   EXPECT_EQ(static_cast<off_t>(state->image_size),
    758             HashCalculator::RawHashOfFile(
    759                 state->a_img,
    760                 state->image_size,
    761                 &root_part.source_hash));
    762   EXPECT_TRUE(HashCalculator::RawHashOfData(
    763                   state->old_kernel_data,
    764                   &kernel_part.source_hash));
    765 
    766   // The partitions should be empty before DeltaPerformer.
    767   install_plan->partitions.clear();
    768 
    769   // With minor version 2, we want the target to be the new image, result_img,
    770   // but with version 1, we want to update A in place.
    771   string target_root, target_kernel;
    772   if (minor_version == kSourceMinorPayloadVersion) {
    773     target_root = state->result_img;
    774     target_kernel = state->result_kernel;
    775   } else {
    776     target_root = state->a_img;
    777     target_kernel = state->old_kernel;
    778   }
    779 
    780   state->fake_boot_control_.SetPartitionDevice(
    781       kLegacyPartitionNameRoot, install_plan->source_slot, state->a_img);
    782   state->fake_boot_control_.SetPartitionDevice(
    783       kLegacyPartitionNameKernel, install_plan->source_slot, state->old_kernel);
    784   state->fake_boot_control_.SetPartitionDevice(
    785       kLegacyPartitionNameRoot, install_plan->target_slot, target_root);
    786   state->fake_boot_control_.SetPartitionDevice(
    787       kLegacyPartitionNameKernel, install_plan->target_slot, target_kernel);
    788 
    789   ErrorCode expected_error, actual_error;
    790   bool continue_writing;
    791   switch (op_hash_test) {
    792     case kInvalidOperationData: {
    793       // Muck with some random offset post the metadata size so that
    794       // some operation hash will result in a mismatch.
    795       int some_offset = state->metadata_size + 300;
    796       LOG(INFO) << "Tampered value at offset: " << some_offset;
    797       state->delta[some_offset]++;
    798       expected_error = ErrorCode::kDownloadOperationHashMismatch;
    799       continue_writing = false;
    800       break;
    801     }
    802 
    803     case kValidOperationData:
    804     default:
    805       // no change.
    806       expected_error = ErrorCode::kSuccess;
    807       continue_writing = true;
    808       break;
    809   }
    810 
    811   // Write at some number of bytes per operation. Arbitrarily chose 5.
    812   const size_t kBytesPerWrite = 5;
    813   for (size_t i = 0; i < state->delta.size(); i += kBytesPerWrite) {
    814     size_t count = std::min(state->delta.size() - i, kBytesPerWrite);
    815     bool write_succeeded = ((*performer)->Write(&state->delta[i],
    816                                                 count,
    817                                                 &actual_error));
    818     // Normally write_succeeded should be true every time and
    819     // actual_error should be ErrorCode::kSuccess. If so, continue the loop.
    820     // But if we seeded an operation hash error above, then write_succeeded
    821     // will be false. The failure may happen at any operation n. So, all
    822     // Writes until n-1 should succeed and the nth operation will fail with
    823     // actual_error. In this case, we should bail out of the loop because
    824     // we cannot proceed applying the delta.
    825     if (!write_succeeded) {
    826       LOG(INFO) << "Write failed. Checking if it failed with expected error";
    827       EXPECT_EQ(expected_error, actual_error);
    828       if (!continue_writing) {
    829         LOG(INFO) << "Cannot continue writing. Bailing out.";
    830         break;
    831       }
    832     }
    833 
    834     EXPECT_EQ(ErrorCode::kSuccess, actual_error);
    835   }
    836 
    837   // If we had continued all the way through, Close should succeed.
    838   // Otherwise, it should fail. Check appropriately.
    839   bool close_result = (*performer)->Close();
    840   if (continue_writing)
    841     EXPECT_EQ(0, close_result);
    842   else
    843     EXPECT_LE(0, close_result);
    844 }
    845 
    846 void VerifyPayloadResult(DeltaPerformer* performer,
    847                          DeltaState* state,
    848                          ErrorCode expected_result,
    849                          uint32_t minor_version) {
    850   if (!performer) {
    851     EXPECT_TRUE(!"Skipping payload verification since performer is null.");
    852     return;
    853   }
    854 
    855   int expected_times = (expected_result == ErrorCode::kSuccess) ? 1 : 0;
    856   EXPECT_CALL(state->mock_delegate_, DownloadComplete()).Times(expected_times);
    857 
    858   LOG(INFO) << "Verifying payload for expected result " << expected_result;
    859   brillo::Blob expected_hash;
    860   HashCalculator::RawHashOfData(state->delta, &expected_hash);
    861   EXPECT_EQ(expected_result,
    862             performer->VerifyPayload(expected_hash, state->delta.size()));
    863   LOG(INFO) << "Verified payload.";
    864 
    865   if (expected_result != ErrorCode::kSuccess) {
    866     // no need to verify new partition if VerifyPayload failed.
    867     return;
    868   }
    869 
    870   brillo::Blob updated_kernel_partition;
    871   if (minor_version == kSourceMinorPayloadVersion) {
    872     CompareFilesByBlock(state->result_kernel, state->new_kernel,
    873                         state->kernel_size);
    874     CompareFilesByBlock(state->result_img, state->b_img,
    875                         state->image_size);
    876     EXPECT_TRUE(utils::ReadFile(state->result_kernel,
    877                                 &updated_kernel_partition));
    878   } else {
    879     CompareFilesByBlock(state->old_kernel, state->new_kernel,
    880                         state->kernel_size);
    881     CompareFilesByBlock(state->a_img, state->b_img,
    882                         state->image_size);
    883     EXPECT_TRUE(utils::ReadFile(state->old_kernel, &updated_kernel_partition));
    884   }
    885 
    886   ASSERT_GE(updated_kernel_partition.size(), arraysize(kNewData));
    887   EXPECT_TRUE(std::equal(std::begin(kNewData), std::end(kNewData),
    888                          updated_kernel_partition.begin()));
    889 
    890   const auto& partitions = state->install_plan.partitions;
    891   EXPECT_EQ(2U, partitions.size());
    892   EXPECT_EQ(kLegacyPartitionNameRoot, partitions[0].name);
    893   EXPECT_EQ(kLegacyPartitionNameKernel, partitions[1].name);
    894 
    895   EXPECT_EQ(kDefaultKernelSize, partitions[1].target_size);
    896   brillo::Blob expected_new_kernel_hash;
    897   EXPECT_TRUE(HashCalculator::RawHashOfData(state->new_kernel_data,
    898                                             &expected_new_kernel_hash));
    899   EXPECT_EQ(expected_new_kernel_hash, partitions[1].target_hash);
    900 
    901   EXPECT_EQ(state->image_size, partitions[0].target_size);
    902   brillo::Blob expected_new_rootfs_hash;
    903   EXPECT_EQ(static_cast<off_t>(state->image_size),
    904             HashCalculator::RawHashOfFile(state->b_img,
    905                                           state->image_size,
    906                                           &expected_new_rootfs_hash));
    907   EXPECT_EQ(expected_new_rootfs_hash, partitions[0].target_hash);
    908 }
    909 
    910 void VerifyPayload(DeltaPerformer* performer,
    911                    DeltaState* state,
    912                    SignatureTest signature_test,
    913                    uint32_t minor_version) {
    914   ErrorCode expected_result = ErrorCode::kSuccess;
    915   switch (signature_test) {
    916     case kSignatureNone:
    917       expected_result = ErrorCode::kSignedDeltaPayloadExpectedError;
    918       break;
    919     case kSignatureGeneratedShellBadKey:
    920       expected_result = ErrorCode::kDownloadPayloadPubKeyVerificationError;
    921       break;
    922     default: break;  // appease gcc
    923   }
    924 
    925   VerifyPayloadResult(performer, state, expected_result, minor_version);
    926 }
    927 
    928 void DoSmallImageTest(bool full_kernel, bool full_rootfs, bool noop,
    929                       ssize_t chunk_size,
    930                       SignatureTest signature_test,
    931                       bool hash_checks_mandatory, uint32_t minor_version) {
    932   DeltaState state;
    933   DeltaPerformer *performer = nullptr;
    934   GenerateDeltaFile(full_kernel, full_rootfs, noop, chunk_size,
    935                     signature_test, &state, minor_version);
    936 
    937   ScopedPathUnlinker a_img_unlinker(state.a_img);
    938   ScopedPathUnlinker b_img_unlinker(state.b_img);
    939   ScopedPathUnlinker new_img_unlinker(state.result_img);
    940   ScopedPathUnlinker delta_unlinker(state.delta_path);
    941   ScopedPathUnlinker old_kernel_unlinker(state.old_kernel);
    942   ScopedPathUnlinker new_kernel_unlinker(state.new_kernel);
    943   ScopedPathUnlinker result_kernel_unlinker(state.result_kernel);
    944   ApplyDeltaFile(full_kernel, full_rootfs, noop, signature_test,
    945                  &state, hash_checks_mandatory, kValidOperationData,
    946                  &performer, minor_version);
    947   VerifyPayload(performer, &state, signature_test, minor_version);
    948   delete performer;
    949 }
    950 
    951 void DoOperationHashMismatchTest(OperationHashTest op_hash_test,
    952                                  bool hash_checks_mandatory) {
    953   DeltaState state;
    954   uint64_t minor_version = kFullPayloadMinorVersion;
    955   GenerateDeltaFile(true, true, false, -1, kSignatureGenerated, &state,
    956                     minor_version);
    957   ScopedPathUnlinker a_img_unlinker(state.a_img);
    958   ScopedPathUnlinker b_img_unlinker(state.b_img);
    959   ScopedPathUnlinker delta_unlinker(state.delta_path);
    960   ScopedPathUnlinker old_kernel_unlinker(state.old_kernel);
    961   ScopedPathUnlinker new_kernel_unlinker(state.new_kernel);
    962   DeltaPerformer *performer = nullptr;
    963   ApplyDeltaFile(true, true, false, kSignatureGenerated, &state,
    964                  hash_checks_mandatory, op_hash_test, &performer,
    965                  minor_version);
    966   delete performer;
    967 }
    968 
    969 
    970 TEST(DeltaPerformerIntegrationTest, RunAsRootSmallImageTest) {
    971   DoSmallImageTest(false, false, false, -1, kSignatureGenerator,
    972                    false, kInPlaceMinorPayloadVersion);
    973 }
    974 
    975 TEST(DeltaPerformerIntegrationTest, RunAsRootSmallImageSignaturePlaceholderTest) {
    976   DoSmallImageTest(false, false, false, -1, kSignatureGeneratedPlaceholder,
    977                    false, kInPlaceMinorPayloadVersion);
    978 }
    979 
    980 TEST(DeltaPerformerIntegrationTest, RunAsRootSmallImageSignaturePlaceholderMismatchTest) {
    981   DeltaState state;
    982   GenerateDeltaFile(false, false, false, -1,
    983                     kSignatureGeneratedPlaceholderMismatch, &state,
    984                     kInPlaceMinorPayloadVersion);
    985 }
    986 
    987 TEST(DeltaPerformerIntegrationTest, RunAsRootSmallImageChunksTest) {
    988   DoSmallImageTest(false, false, false, kBlockSize, kSignatureGenerator,
    989                    false, kInPlaceMinorPayloadVersion);
    990 }
    991 
    992 TEST(DeltaPerformerIntegrationTest, RunAsRootFullKernelSmallImageTest) {
    993   DoSmallImageTest(true, false, false, -1, kSignatureGenerator,
    994                    false, kInPlaceMinorPayloadVersion);
    995 }
    996 
    997 TEST(DeltaPerformerIntegrationTest, RunAsRootFullSmallImageTest) {
    998   DoSmallImageTest(true, true, false, -1, kSignatureGenerator,
    999                    true, kFullPayloadMinorVersion);
   1000 }
   1001 
   1002 TEST(DeltaPerformerIntegrationTest, RunAsRootNoopSmallImageTest) {
   1003   DoSmallImageTest(false, false, true, -1, kSignatureGenerator,
   1004                    false, kInPlaceMinorPayloadVersion);
   1005 }
   1006 
   1007 TEST(DeltaPerformerIntegrationTest, RunAsRootSmallImageSignNoneTest) {
   1008   DoSmallImageTest(false, false, false, -1, kSignatureNone,
   1009                    false, kInPlaceMinorPayloadVersion);
   1010 }
   1011 
   1012 TEST(DeltaPerformerIntegrationTest, RunAsRootSmallImageSignGeneratedTest) {
   1013   DoSmallImageTest(false, false, false, -1, kSignatureGenerated,
   1014                    true, kInPlaceMinorPayloadVersion);
   1015 }
   1016 
   1017 TEST(DeltaPerformerIntegrationTest, RunAsRootSmallImageSignGeneratedShellTest) {
   1018   DoSmallImageTest(false, false, false, -1, kSignatureGeneratedShell,
   1019                    false, kInPlaceMinorPayloadVersion);
   1020 }
   1021 
   1022 TEST(DeltaPerformerIntegrationTest, RunAsRootSmallImageSignGeneratedShellBadKeyTest) {
   1023   DoSmallImageTest(false, false, false, -1, kSignatureGeneratedShellBadKey,
   1024                    false, kInPlaceMinorPayloadVersion);
   1025 }
   1026 
   1027 TEST(DeltaPerformerIntegrationTest, RunAsRootSmallImageSignGeneratedShellRotateCl1Test) {
   1028   DoSmallImageTest(false, false, false, -1, kSignatureGeneratedShellRotateCl1,
   1029                    false, kInPlaceMinorPayloadVersion);
   1030 }
   1031 
   1032 TEST(DeltaPerformerIntegrationTest, RunAsRootSmallImageSignGeneratedShellRotateCl2Test) {
   1033   DoSmallImageTest(false, false, false, -1, kSignatureGeneratedShellRotateCl2,
   1034                    false, kInPlaceMinorPayloadVersion);
   1035 }
   1036 
   1037 TEST(DeltaPerformerIntegrationTest, RunAsRootSmallImageSourceOpsTest) {
   1038   DoSmallImageTest(false, false, false, -1, kSignatureGenerator,
   1039                    false, kSourceMinorPayloadVersion);
   1040 }
   1041 
   1042 TEST(DeltaPerformerIntegrationTest, RunAsRootMandatoryOperationHashMismatchTest) {
   1043   DoOperationHashMismatchTest(kInvalidOperationData, true);
   1044 }
   1045 
   1046 }  // namespace chromeos_update_engine
   1047