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