//
// Copyright (C) 2012 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

#include "update_engine/payload_consumer/delta_performer.h"

#include <endian.h>
#include <inttypes.h>
#include <time.h>

#include <memory>
#include <string>
#include <vector>

#include <base/files/file_path.h>
#include <base/files/file_util.h>
#include <base/files/scoped_temp_dir.h>
#include <base/strings/string_number_conversions.h>
#include <base/strings/string_util.h>
#include <base/strings/stringprintf.h>
#include <gmock/gmock.h>
#include <google/protobuf/repeated_field.h>
#include <gtest/gtest.h>

#include "update_engine/common/constants.h"
#include "update_engine/common/fake_boot_control.h"
#include "update_engine/common/fake_hardware.h"
#include "update_engine/common/fake_prefs.h"
#include "update_engine/common/test_utils.h"
#include "update_engine/common/utils.h"
#include "update_engine/payload_consumer/fake_file_descriptor.h"
#include "update_engine/payload_consumer/mock_download_action.h"
#include "update_engine/payload_consumer/payload_constants.h"
#include "update_engine/payload_generator/bzip.h"
#include "update_engine/payload_generator/extent_ranges.h"
#include "update_engine/payload_generator/payload_file.h"
#include "update_engine/payload_generator/payload_signer.h"
#include "update_engine/update_metadata.pb.h"

namespace chromeos_update_engine {

using std::string;
using std::vector;
using test_utils::GetBuildArtifactsPath;
using test_utils::System;
using test_utils::kRandomString;
using testing::_;

extern const char* kUnittestPrivateKeyPath;
extern const char* kUnittestPublicKeyPath;

namespace {

const char kBogusMetadataSignature1[] =
    "awSFIUdUZz2VWFiR+ku0Pj00V7bPQPQFYQSXjEXr3vaw3TE4xHV5CraY3/YrZpBv"
    "J5z4dSBskoeuaO1TNC/S6E05t+yt36tE4Fh79tMnJ/z9fogBDXWgXLEUyG78IEQr"
    "YH6/eBsQGT2RJtBgXIXbZ9W+5G9KmGDoPOoiaeNsDuqHiBc/58OFsrxskH8E6vMS"
    "BmMGGk82mvgzic7ApcoURbCGey1b3Mwne/hPZ/bb9CIyky8Og9IfFMdL2uAweOIR"
    "fjoTeLYZpt+WN65Vu7jJ0cQN8e1y+2yka5112wpRf/LLtPgiAjEZnsoYpLUd7CoV"
    "pLRtClp97kN2+tXGNBQqkA==";

// Different options that determine what we should fill into the
// install_plan.metadata_signature to simulate the contents received in the
// Omaha response.
enum MetadataSignatureTest {
  kEmptyMetadataSignature,
  kInvalidMetadataSignature,
  kValidMetadataSignature,
};

// Compressed data without checksum, generated with:
// echo -n "a$(head -c 4095 /dev/zero)" | xz -9 --check=none |
//     hexdump -v -e '"    " 12/1 "0x%02x, " "\n"'
const uint8_t kXzCompressedData[] = {
    0xfd, 0x37, 0x7a, 0x58, 0x5a, 0x00, 0x00, 0x00, 0xff, 0x12, 0xd9, 0x41,
    0x02, 0x00, 0x21, 0x01, 0x1c, 0x00, 0x00, 0x00, 0x10, 0xcf, 0x58, 0xcc,
    0xe0, 0x0f, 0xff, 0x00, 0x1b, 0x5d, 0x00, 0x30, 0x80, 0x33, 0xff, 0xdf,
    0xff, 0x51, 0xd6, 0xaf, 0x90, 0x1c, 0x1b, 0x4c, 0xaa, 0x3d, 0x7b, 0x28,
    0xe4, 0x7a, 0x74, 0xbc, 0xe5, 0xa7, 0x33, 0x4e, 0xcf, 0x00, 0x00, 0x00,
    0x00, 0x01, 0x2f, 0x80, 0x20, 0x00, 0x00, 0x00, 0x92, 0x7c, 0x7b, 0x24,
    0xa8, 0x00, 0x0a, 0xfc, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x59, 0x5a,
};

const uint8_t src_deflates[] = {
  /* raw      0  */ 0x11, 0x22,
  /* deflate  2  */ 0x63, 0x64, 0x62, 0x66, 0x61, 0x05, 0x00,
  /* raw      9  */ 0x33,
  /* deflate  10 */ 0x03, 0x00,
  /* raw      12 */
  /* deflate  12 */ 0x63, 0x04, 0x00,
  /* raw      15 */ 0x44, 0x55
};

const uint8_t dst_deflates[] = {
  /* deflate  0  */ 0x63, 0x64, 0x62, 0x66, 0x61, 0x05, 0x00,
  /* raw      7  */ 0x33, 0x66,
  /* deflate  9  */ 0x01, 0x05, 0x00, 0xFA, 0xFF, 0x01, 0x02, 0x03, 0x04, 0x05,
  /* deflate  19 */ 0x63, 0x04, 0x00
};

// To generate this patch either:
// - Use puffin/src/patching_unittest.cc:TestPatching
// Or
// - Use the following approach:
// * Make src_deflate a string of hex with only spaces. (e.g. "0XTE 0xST")
// * echo "0XTE 0xST" | xxd -r -p > src.bin
// * Find the location of deflates in src_deflates (in bytes) in the format of
//   "offset:length,...". (e.g. "2:7,10:2,12:3")
// * Do previous three steps for dst_deflates.
// * puffin --operation=puffdiff --src_file=src.bin --dst_file=dst.bin \
//   --src_deflates_byte="2:7,10:2,12:3" --dst_deflates_byte="0:7,9:10,19:3" \
//   --patch_file=patch.bin
// * hexdump -ve '"  " 12/1 "0x%02x, " "\n"' patch.bin
const uint8_t puffdiff_patch[] = {
  0x50, 0x55, 0x46, 0x31, 0x00, 0x00, 0x00, 0x51, 0x08, 0x01, 0x12, 0x27,
  0x0A, 0x04, 0x08, 0x10, 0x10, 0x32, 0x0A, 0x04, 0x08, 0x50, 0x10, 0x0A,
  0x0A, 0x04, 0x08, 0x60, 0x10, 0x12, 0x12, 0x04, 0x08, 0x10, 0x10, 0x58,
  0x12, 0x04, 0x08, 0x78, 0x10, 0x28, 0x12, 0x05, 0x08, 0xA8, 0x01, 0x10,
  0x38, 0x18, 0x1F, 0x1A, 0x24, 0x0A, 0x02, 0x10, 0x32, 0x0A, 0x04, 0x08,
  0x48, 0x10, 0x50, 0x0A, 0x05, 0x08, 0x98, 0x01, 0x10, 0x12, 0x12, 0x02,
  0x10, 0x58, 0x12, 0x04, 0x08, 0x70, 0x10, 0x58, 0x12, 0x05, 0x08, 0xC8,
  0x01, 0x10, 0x38, 0x18, 0x21, 0x42, 0x53, 0x44, 0x49, 0x46, 0x46, 0x34,
  0x30, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x42, 0x5A, 0x68, 0x39, 0x31, 0x41, 0x59, 0x26, 0x53, 0x59, 0x65,
  0x29, 0x8C, 0x9B, 0x00, 0x00, 0x03, 0x60, 0x40, 0x7A, 0x0E, 0x08, 0x00,
  0x40, 0x00, 0x20, 0x00, 0x21, 0x22, 0x9A, 0x3D, 0x4F, 0x50, 0x40, 0x0C,
  0x3B, 0xC7, 0x9B, 0xB2, 0x21, 0x0E, 0xE9, 0x15, 0x98, 0x7A, 0x7C, 0x5D,
  0xC9, 0x14, 0xE1, 0x42, 0x41, 0x94, 0xA6, 0x32, 0x6C, 0x42, 0x5A, 0x68,
  0x39, 0x31, 0x41, 0x59, 0x26, 0x53, 0x59, 0xF1, 0x20, 0x5F, 0x0D, 0x00,
  0x00, 0x02, 0x41, 0x15, 0x42, 0x08, 0x20, 0x00, 0x40, 0x00, 0x00, 0x02,
  0x40, 0x00, 0x20, 0x00, 0x22, 0x3D, 0x23, 0x10, 0x86, 0x03, 0x96, 0x54,
  0x11, 0x16, 0x5F, 0x17, 0x72, 0x45, 0x38, 0x50, 0x90, 0xF1, 0x20, 0x5F,
  0x0D, 0x42, 0x5A, 0x68, 0x39, 0x31, 0x41, 0x59, 0x26, 0x53, 0x59, 0x07,
  0xD4, 0xCB, 0x6E, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x20, 0x00,
  0x21, 0x18, 0x46, 0x82, 0xEE, 0x48, 0xA7, 0x0A, 0x12, 0x00, 0xFA, 0x99,
  0x6D, 0xC0};

}  // namespace

class DeltaPerformerTest : public ::testing::Test {
 protected:
  void SetUp() override {
    install_plan_.source_slot = 0;
    install_plan_.target_slot = 1;
    EXPECT_CALL(mock_delegate_, ShouldCancel(_))
        .WillRepeatedly(testing::Return(false));
  }

  // Test helper placed where it can easily be friended from DeltaPerformer.
  void RunManifestValidation(const DeltaArchiveManifest& manifest,
                             uint64_t major_version,
                             InstallPayloadType payload_type,
                             ErrorCode expected) {
    payload_.type = payload_type;

    // The Manifest we are validating.
    performer_.manifest_.CopyFrom(manifest);
    performer_.major_payload_version_ = major_version;

    EXPECT_EQ(expected, performer_.ValidateManifest());
  }

  brillo::Blob GeneratePayload(const brillo::Blob& blob_data,
                               const vector<AnnotatedOperation>& aops,
                               bool sign_payload) {
    return GeneratePayload(blob_data,
                           aops,
                           sign_payload,
                           kMaxSupportedMajorPayloadVersion,
                           kMaxSupportedMinorPayloadVersion);
  }

  brillo::Blob GeneratePayload(const brillo::Blob& blob_data,
                               const vector<AnnotatedOperation>& aops,
                               bool sign_payload,
                               uint64_t major_version,
                               uint32_t minor_version) {
    test_utils::ScopedTempFile blob_file("Blob-XXXXXX");
    EXPECT_TRUE(test_utils::WriteFileVector(blob_file.path(), blob_data));

    PayloadGenerationConfig config;
    config.version.major = major_version;
    config.version.minor = minor_version;

    PayloadFile payload;
    EXPECT_TRUE(payload.Init(config));

    PartitionConfig old_part(kPartitionNameRoot);
    if (minor_version != kFullPayloadMinorVersion) {
      // When generating a delta payload we need to include the old partition
      // information to mark it as a delta payload.
      old_part.path = "/dev/null";
      old_part.size = 0;
    }
    PartitionConfig new_part(kPartitionNameRoot);
    new_part.path = "/dev/zero";
    new_part.size = 1234;

    payload.AddPartition(old_part, new_part, aops);

    // We include a kernel partition without operations.
    old_part.name = kPartitionNameKernel;
    new_part.name = kPartitionNameKernel;
    new_part.size = 0;
    payload.AddPartition(old_part, new_part, {});

    test_utils::ScopedTempFile payload_file("Payload-XXXXXX");
    string private_key =
        sign_payload ? GetBuildArtifactsPath(kUnittestPrivateKeyPath) : "";
    EXPECT_TRUE(payload.WritePayload(payload_file.path(),
                                     blob_file.path(),
                                     private_key,
                                     &payload_.metadata_size));

    brillo::Blob payload_data;
    EXPECT_TRUE(utils::ReadFile(payload_file.path(), &payload_data));
    return payload_data;
  }

  brillo::Blob GenerateSourceCopyPayload(const brillo::Blob& copied_data,
                                         bool add_hash) {
    PayloadGenerationConfig config;
    const uint64_t kDefaultBlockSize = config.block_size;
    EXPECT_EQ(0U, copied_data.size() % kDefaultBlockSize);
    uint64_t num_blocks = copied_data.size() / kDefaultBlockSize;
    AnnotatedOperation aop;
    *(aop.op.add_src_extents()) = ExtentForRange(0, num_blocks);
    *(aop.op.add_dst_extents()) = ExtentForRange(0, num_blocks);
    aop.op.set_type(InstallOperation::SOURCE_COPY);
    brillo::Blob src_hash;
    EXPECT_TRUE(HashCalculator::RawHashOfData(copied_data, &src_hash));
    if (add_hash)
      aop.op.set_src_sha256_hash(src_hash.data(), src_hash.size());

    return GeneratePayload(brillo::Blob(), {aop}, false);
  }

  // Apply |payload_data| on partition specified in |source_path|.
  // Expect result of performer_.Write() to be |expect_success|.
  // Returns the result of the payload application.
  brillo::Blob ApplyPayload(const brillo::Blob& payload_data,
                            const string& source_path,
                            bool expect_success) {
    return ApplyPayloadToData(payload_data, source_path, brillo::Blob(),
                              expect_success);
  }

  // Apply the payload provided in |payload_data| reading from the |source_path|
  // file and writing the contents to a new partition. The existing data in the
  // new target file are set to |target_data| before applying the payload.
  // Expect result of performer_.Write() to be |expect_success|.
  // Returns the result of the payload application.
  brillo::Blob ApplyPayloadToData(const brillo::Blob& payload_data,
                                  const string& source_path,
                                  const brillo::Blob& target_data,
                                  bool expect_success) {
    test_utils::ScopedTempFile new_part("Partition-XXXXXX");
    EXPECT_TRUE(test_utils::WriteFileVector(new_part.path(), target_data));

    // We installed the operations only in the rootfs partition, but the
    // delta performer needs to access all the partitions.
    fake_boot_control_.SetPartitionDevice(
        kPartitionNameRoot, install_plan_.target_slot, new_part.path());
    fake_boot_control_.SetPartitionDevice(
        kPartitionNameRoot, install_plan_.source_slot, source_path);
    fake_boot_control_.SetPartitionDevice(
        kPartitionNameKernel, install_plan_.target_slot, "/dev/null");
    fake_boot_control_.SetPartitionDevice(
        kPartitionNameKernel, install_plan_.source_slot, "/dev/null");

    EXPECT_EQ(expect_success,
              performer_.Write(payload_data.data(), payload_data.size()));
    EXPECT_EQ(0, performer_.Close());

    brillo::Blob partition_data;
    EXPECT_TRUE(utils::ReadFile(new_part.path(), &partition_data));
    return partition_data;
  }

  // Calls delta performer's Write method by pretending to pass in bytes from a
  // delta file whose metadata size is actual_metadata_size and tests if all
  // checks are correctly performed if the install plan contains
  // expected_metadata_size and that the result of the parsing are as per
  // hash_checks_mandatory flag.
  void DoMetadataSizeTest(uint64_t expected_metadata_size,
                          uint64_t actual_metadata_size,
                          bool hash_checks_mandatory) {
    install_plan_.hash_checks_mandatory = hash_checks_mandatory;

    // Set a valid magic string and version number 1.
    EXPECT_TRUE(performer_.Write("CrAU", 4));
    uint64_t version = htobe64(kChromeOSMajorPayloadVersion);
    EXPECT_TRUE(performer_.Write(&version, 8));

    payload_.metadata_size = expected_metadata_size;
    ErrorCode error_code;
    // When filling in size in manifest, exclude the size of the 20-byte header.
    uint64_t size_in_manifest = htobe64(actual_metadata_size - 20);
    bool result = performer_.Write(&size_in_manifest, 8, &error_code);
    if (expected_metadata_size == actual_metadata_size ||
        !hash_checks_mandatory) {
      EXPECT_TRUE(result);
    } else {
      EXPECT_FALSE(result);
      EXPECT_EQ(ErrorCode::kDownloadInvalidMetadataSize, error_code);
    }

    EXPECT_LT(performer_.Close(), 0);
  }

  // Generates a valid delta file but tests the delta performer by suppling
  // different metadata signatures as per metadata_signature_test flag and
  // sees if the result of the parsing are as per hash_checks_mandatory flag.
  void DoMetadataSignatureTest(MetadataSignatureTest metadata_signature_test,
                               bool sign_payload,
                               bool hash_checks_mandatory) {
    // Loads the payload and parses the manifest.
    brillo::Blob payload = GeneratePayload(brillo::Blob(),
        vector<AnnotatedOperation>(), sign_payload,
        kChromeOSMajorPayloadVersion, kFullPayloadMinorVersion);

    LOG(INFO) << "Payload size: " << payload.size();

    install_plan_.hash_checks_mandatory = hash_checks_mandatory;

    MetadataParseResult expected_result, actual_result;
    ErrorCode expected_error, actual_error;

    // Fill up the metadata signature in install plan according to the test.
    switch (metadata_signature_test) {
      case kEmptyMetadataSignature:
        payload_.metadata_signature.clear();
        expected_result = MetadataParseResult::kError;
        expected_error = ErrorCode::kDownloadMetadataSignatureMissingError;
        break;

      case kInvalidMetadataSignature:
        payload_.metadata_signature = kBogusMetadataSignature1;
        expected_result = MetadataParseResult::kError;
        expected_error = ErrorCode::kDownloadMetadataSignatureMismatch;
        break;

      case kValidMetadataSignature:
      default:
        // Set the install plan's metadata size to be the same as the one
        // in the manifest so that we pass the metadata size checks. Only
        // then we can get to manifest signature checks.
        ASSERT_TRUE(PayloadSigner::GetMetadataSignature(
            payload.data(),
            payload_.metadata_size,
            GetBuildArtifactsPath(kUnittestPrivateKeyPath),
            &payload_.metadata_signature));
        EXPECT_FALSE(payload_.metadata_signature.empty());
        expected_result = MetadataParseResult::kSuccess;
        expected_error = ErrorCode::kSuccess;
        break;
    }

    // Ignore the expected result/error if hash checks are not mandatory.
    if (!hash_checks_mandatory) {
      expected_result = MetadataParseResult::kSuccess;
      expected_error = ErrorCode::kSuccess;
    }

    // Use the public key corresponding to the private key used above to
    // sign the metadata.
    string public_key_path = GetBuildArtifactsPath(kUnittestPublicKeyPath);
    EXPECT_TRUE(utils::FileExists(public_key_path.c_str()));
    performer_.set_public_key_path(public_key_path);

    // Init actual_error with an invalid value so that we make sure
    // ParsePayloadMetadata properly populates it in all cases.
    actual_error = ErrorCode::kUmaReportedMax;
    actual_result = performer_.ParsePayloadMetadata(payload, &actual_error);

    EXPECT_EQ(expected_result, actual_result);
    EXPECT_EQ(expected_error, actual_error);

    // Check that the parsed metadata size is what's expected. This test
    // implicitly confirms that the metadata signature is valid, if required.
    EXPECT_EQ(payload_.metadata_size, performer_.metadata_size_);
  }

  // Helper function to pretend that the ECC file descriptor was already opened.
  // Returns a pointer to the created file descriptor.
  FakeFileDescriptor* SetFakeECCFile(size_t size) {
    EXPECT_FALSE(performer_.source_ecc_fd_) << "source_ecc_fd_ already open.";
    FakeFileDescriptor* ret = new FakeFileDescriptor();
    fake_ecc_fd_.reset(ret);
    // Call open to simulate it was already opened.
    ret->Open("", 0);
    ret->SetFileSize(size);
    performer_.source_ecc_fd_ = fake_ecc_fd_;
    return ret;
  }

  uint64_t GetSourceEccRecoveredFailures() const {
    return performer_.source_ecc_recovered_failures_;
  }

  FakePrefs prefs_;
  InstallPlan install_plan_;
  InstallPlan::Payload payload_;
  FakeBootControl fake_boot_control_;
  FakeHardware fake_hardware_;
  MockDownloadActionDelegate mock_delegate_;
  FileDescriptorPtr fake_ecc_fd_;
  DeltaPerformer performer_{&prefs_,
                            &fake_boot_control_,
                            &fake_hardware_,
                            &mock_delegate_,
                            &install_plan_,
                            &payload_,
                            false /* interactive*/};
};

TEST_F(DeltaPerformerTest, FullPayloadWriteTest) {
  payload_.type = InstallPayloadType::kFull;
  brillo::Blob expected_data = brillo::Blob(std::begin(kRandomString),
                                            std::end(kRandomString));
  expected_data.resize(4096);  // block size
  vector<AnnotatedOperation> aops;
  AnnotatedOperation aop;
  *(aop.op.add_dst_extents()) = ExtentForRange(0, 1);
  aop.op.set_data_offset(0);
  aop.op.set_data_length(expected_data.size());
  aop.op.set_type(InstallOperation::REPLACE);
  aops.push_back(aop);

  brillo::Blob payload_data = GeneratePayload(expected_data, aops, false,
      kChromeOSMajorPayloadVersion, kFullPayloadMinorVersion);

  EXPECT_EQ(expected_data, ApplyPayload(payload_data, "/dev/null", true));
}

TEST_F(DeltaPerformerTest, ShouldCancelTest) {
  payload_.type = InstallPayloadType::kFull;
  brillo::Blob expected_data = brillo::Blob(std::begin(kRandomString),
                                            std::end(kRandomString));
  expected_data.resize(4096);  // block size
  vector<AnnotatedOperation> aops;
  AnnotatedOperation aop;
  *(aop.op.add_dst_extents()) = ExtentForRange(0, 1);
  aop.op.set_data_offset(0);
  aop.op.set_data_length(expected_data.size());
  aop.op.set_type(InstallOperation::REPLACE);
  aops.push_back(aop);

  brillo::Blob payload_data = GeneratePayload(expected_data, aops, false,
      kChromeOSMajorPayloadVersion, kFullPayloadMinorVersion);

  testing::Mock::VerifyAndClearExpectations(&mock_delegate_);
  EXPECT_CALL(mock_delegate_, ShouldCancel(_))
      .WillOnce(
          testing::DoAll(testing::SetArgPointee<0>(ErrorCode::kError),
                         testing::Return(true)));

  ApplyPayload(payload_data, "/dev/null", false);
}

TEST_F(DeltaPerformerTest, ReplaceOperationTest) {
  brillo::Blob expected_data = brillo::Blob(std::begin(kRandomString),
                                            std::end(kRandomString));
  expected_data.resize(4096);  // block size
  vector<AnnotatedOperation> aops;
  AnnotatedOperation aop;
  *(aop.op.add_dst_extents()) = ExtentForRange(0, 1);
  aop.op.set_data_offset(0);
  aop.op.set_data_length(expected_data.size());
  aop.op.set_type(InstallOperation::REPLACE);
  aops.push_back(aop);

  brillo::Blob payload_data = GeneratePayload(expected_data, aops, false);

  EXPECT_EQ(expected_data, ApplyPayload(payload_data, "/dev/null", true));
}

TEST_F(DeltaPerformerTest, ReplaceBzOperationTest) {
  brillo::Blob expected_data = brillo::Blob(std::begin(kRandomString),
                                            std::end(kRandomString));
  expected_data.resize(4096);  // block size
  brillo::Blob bz_data;
  EXPECT_TRUE(BzipCompress(expected_data, &bz_data));

  vector<AnnotatedOperation> aops;
  AnnotatedOperation aop;
  *(aop.op.add_dst_extents()) = ExtentForRange(0, 1);
  aop.op.set_data_offset(0);
  aop.op.set_data_length(bz_data.size());
  aop.op.set_type(InstallOperation::REPLACE_BZ);
  aops.push_back(aop);

  brillo::Blob payload_data = GeneratePayload(bz_data, aops, false);

  EXPECT_EQ(expected_data, ApplyPayload(payload_data, "/dev/null", true));
}

TEST_F(DeltaPerformerTest, ReplaceXzOperationTest) {
  brillo::Blob xz_data(std::begin(kXzCompressedData),
                         std::end(kXzCompressedData));
  // The compressed xz data contains a single "a" and padded with zero for the
  // rest of the block.
  brillo::Blob expected_data = brillo::Blob(4096, 0);
  expected_data[0] = 'a';

  AnnotatedOperation aop;
  *(aop.op.add_dst_extents()) = ExtentForRange(0, 1);
  aop.op.set_data_offset(0);
  aop.op.set_data_length(xz_data.size());
  aop.op.set_type(InstallOperation::REPLACE_XZ);
  vector<AnnotatedOperation> aops = {aop};

  brillo::Blob payload_data = GeneratePayload(xz_data, aops, false);

  EXPECT_EQ(expected_data, ApplyPayload(payload_data, "/dev/null", true));
}

TEST_F(DeltaPerformerTest, ZeroOperationTest) {
  brillo::Blob existing_data = brillo::Blob(4096 * 10, 'a');
  brillo::Blob expected_data = existing_data;
  // Blocks 4, 5 and 7 should have zeros instead of 'a' after the operation is
  // applied.
  std::fill(expected_data.data() + 4096 * 4, expected_data.data() + 4096 * 6,
            0);
  std::fill(expected_data.data() + 4096 * 7, expected_data.data() + 4096 * 8,
            0);

  AnnotatedOperation aop;
  *(aop.op.add_dst_extents()) = ExtentForRange(4, 2);
  *(aop.op.add_dst_extents()) = ExtentForRange(7, 1);
  aop.op.set_type(InstallOperation::ZERO);
  vector<AnnotatedOperation> aops = {aop};

  brillo::Blob payload_data = GeneratePayload(brillo::Blob(), aops, false);

  EXPECT_EQ(expected_data,
            ApplyPayloadToData(payload_data, "/dev/null", existing_data, true));
}

TEST_F(DeltaPerformerTest, SourceCopyOperationTest) {
  brillo::Blob expected_data(std::begin(kRandomString),
                             std::end(kRandomString));
  expected_data.resize(4096);  // block size
  AnnotatedOperation aop;
  *(aop.op.add_src_extents()) = ExtentForRange(0, 1);
  *(aop.op.add_dst_extents()) = ExtentForRange(0, 1);
  aop.op.set_type(InstallOperation::SOURCE_COPY);
  brillo::Blob src_hash;
  EXPECT_TRUE(HashCalculator::RawHashOfData(expected_data, &src_hash));
  aop.op.set_src_sha256_hash(src_hash.data(), src_hash.size());

  brillo::Blob payload_data = GeneratePayload(brillo::Blob(), {aop}, false);

  test_utils::ScopedTempFile source("Source-XXXXXX");
  EXPECT_TRUE(test_utils::WriteFileVector(source.path(), expected_data));

  EXPECT_EQ(expected_data, ApplyPayload(payload_data, source.path(), true));
}

TEST_F(DeltaPerformerTest, PuffdiffOperationTest) {
  AnnotatedOperation aop;
  *(aop.op.add_src_extents()) = ExtentForRange(0, 1);
  *(aop.op.add_dst_extents()) = ExtentForRange(0, 1);
  brillo::Blob puffdiff_payload(std::begin(puffdiff_patch),
                                std::end(puffdiff_patch));
  aop.op.set_data_offset(0);
  aop.op.set_data_length(puffdiff_payload.size());
  aop.op.set_type(InstallOperation::PUFFDIFF);
  brillo::Blob src(std::begin(src_deflates), std::end(src_deflates));
  src.resize(4096);  // block size
  brillo::Blob src_hash;
  EXPECT_TRUE(HashCalculator::RawHashOfData(src, &src_hash));
  aop.op.set_src_sha256_hash(src_hash.data(), src_hash.size());

  brillo::Blob payload_data = GeneratePayload(puffdiff_payload, {aop}, false);

  test_utils::ScopedTempFile source("Source-XXXXXX");
  EXPECT_TRUE(test_utils::WriteFileVector(source.path(), src));

  brillo::Blob dst(std::begin(dst_deflates), std::end(dst_deflates));
  EXPECT_EQ(dst, ApplyPayload(payload_data, source.path(), true));
}

TEST_F(DeltaPerformerTest, SourceHashMismatchTest) {
  brillo::Blob expected_data = {'f', 'o', 'o'};
  brillo::Blob actual_data = {'b', 'a', 'r'};
  expected_data.resize(4096);  // block size
  actual_data.resize(4096);    // block size

  AnnotatedOperation aop;
  *(aop.op.add_src_extents()) = ExtentForRange(0, 1);
  *(aop.op.add_dst_extents()) = ExtentForRange(0, 1);
  aop.op.set_type(InstallOperation::SOURCE_COPY);
  brillo::Blob src_hash;
  EXPECT_TRUE(HashCalculator::RawHashOfData(expected_data, &src_hash));
  aop.op.set_src_sha256_hash(src_hash.data(), src_hash.size());

  brillo::Blob payload_data = GeneratePayload(brillo::Blob(), {aop}, false);

  test_utils::ScopedTempFile source("Source-XXXXXX");
  EXPECT_TRUE(test_utils::WriteFileVector(source.path(), actual_data));

  EXPECT_EQ(actual_data, ApplyPayload(payload_data, source.path(), false));
}

// Test that the error-corrected file descriptor is used to read the partition
// since the source partition doesn't match the operation hash.
TEST_F(DeltaPerformerTest, ErrorCorrectionSourceCopyFallbackTest) {
  constexpr size_t kCopyOperationSize = 4 * 4096;
  test_utils::ScopedTempFile source("Source-XXXXXX");
  // Write invalid data to the source image, which doesn't match the expected
  // hash.
  brillo::Blob invalid_data(kCopyOperationSize, 0x55);
  EXPECT_TRUE(test_utils::WriteFileVector(source.path(), invalid_data));

  // Setup the fec file descriptor as the fake stream, which matches
  // |expected_data|.
  FakeFileDescriptor* fake_fec = SetFakeECCFile(kCopyOperationSize);
  brillo::Blob expected_data = FakeFileDescriptorData(kCopyOperationSize);

  brillo::Blob payload_data = GenerateSourceCopyPayload(expected_data, true);
  EXPECT_EQ(expected_data, ApplyPayload(payload_data, source.path(), true));
  // Verify that the fake_fec was actually used.
  EXPECT_EQ(1U, fake_fec->GetReadOps().size());
  EXPECT_EQ(1U, GetSourceEccRecoveredFailures());
}

// Test that the error-corrected file descriptor is used to read a partition
// when no hash is available for SOURCE_COPY but it falls back to the normal
// file descriptor when the size of the error corrected one is too small.
TEST_F(DeltaPerformerTest, ErrorCorrectionSourceCopyWhenNoHashFallbackTest) {
  constexpr size_t kCopyOperationSize = 4 * 4096;
  test_utils::ScopedTempFile source("Source-XXXXXX");
  // Setup the source path with the right expected data.
  brillo::Blob expected_data = FakeFileDescriptorData(kCopyOperationSize);
  EXPECT_TRUE(test_utils::WriteFileVector(source.path(), expected_data));

  // Setup the fec file descriptor as the fake stream, with smaller data than
  // the expected.
  FakeFileDescriptor* fake_fec = SetFakeECCFile(kCopyOperationSize / 2);

  // The payload operation doesn't include an operation hash.
  brillo::Blob payload_data = GenerateSourceCopyPayload(expected_data, false);
  EXPECT_EQ(expected_data, ApplyPayload(payload_data, source.path(), true));
  // Verify that the fake_fec was attempted to be used. Since the file
  // descriptor is shorter it can actually do more than one read to realize it
  // reached the EOF.
  EXPECT_LE(1U, fake_fec->GetReadOps().size());
  // This fallback doesn't count as an error-corrected operation since the
  // operation hash was not available.
  EXPECT_EQ(0U, GetSourceEccRecoveredFailures());
}

TEST_F(DeltaPerformerTest, ChooseSourceFDTest) {
  constexpr size_t kSourceSize = 4 * 4096;
  test_utils::ScopedTempFile source("Source-XXXXXX");
  // Write invalid data to the source image, which doesn't match the expected
  // hash.
  brillo::Blob invalid_data(kSourceSize, 0x55);
  EXPECT_TRUE(test_utils::WriteFileVector(source.path(), invalid_data));

  performer_.source_fd_ = std::make_shared<EintrSafeFileDescriptor>();
  performer_.source_fd_->Open(source.path().c_str(), O_RDONLY);
  performer_.block_size_ = 4096;

  // Setup the fec file descriptor as the fake stream, which matches
  // |expected_data|.
  FakeFileDescriptor* fake_fec = SetFakeECCFile(kSourceSize);
  brillo::Blob expected_data = FakeFileDescriptorData(kSourceSize);

  InstallOperation op;
  *(op.add_src_extents()) = ExtentForRange(0, kSourceSize / 4096);
  brillo::Blob src_hash;
  EXPECT_TRUE(HashCalculator::RawHashOfData(expected_data, &src_hash));
  op.set_src_sha256_hash(src_hash.data(), src_hash.size());

  ErrorCode error = ErrorCode::kSuccess;
  EXPECT_EQ(performer_.source_ecc_fd_, performer_.ChooseSourceFD(op, &error));
  EXPECT_EQ(ErrorCode::kSuccess, error);
  // Verify that the fake_fec was actually used.
  EXPECT_EQ(1U, fake_fec->GetReadOps().size());
  EXPECT_EQ(1U, GetSourceEccRecoveredFailures());
}

TEST_F(DeltaPerformerTest, ExtentsToByteStringTest) {
  uint64_t test[] = {1, 1, 4, 2, 0, 1};
  static_assert(arraysize(test) % 2 == 0, "Array size uneven");
  const uint64_t block_size = 4096;
  const uint64_t file_length = 4 * block_size - 13;

  google::protobuf::RepeatedPtrField<Extent> extents;
  for (size_t i = 0; i < arraysize(test); i += 2) {
    *(extents.Add()) = ExtentForRange(test[i], test[i + 1]);
  }

  string expected_output = "4096:4096,16384:8192,0:4083";
  string actual_output;
  EXPECT_TRUE(DeltaPerformer::ExtentsToBsdiffPositionsString(extents,
                                                             block_size,
                                                             file_length,
                                                             &actual_output));
  EXPECT_EQ(expected_output, actual_output);
}

TEST_F(DeltaPerformerTest, ValidateManifestFullGoodTest) {
  // The Manifest we are validating.
  DeltaArchiveManifest manifest;
  manifest.mutable_new_kernel_info();
  manifest.mutable_new_rootfs_info();
  manifest.set_minor_version(kFullPayloadMinorVersion);

  RunManifestValidation(manifest,
                        kChromeOSMajorPayloadVersion,
                        InstallPayloadType::kFull,
                        ErrorCode::kSuccess);
}

TEST_F(DeltaPerformerTest, ValidateManifestDeltaGoodTest) {
  // The Manifest we are validating.
  DeltaArchiveManifest manifest;
  manifest.mutable_old_kernel_info();
  manifest.mutable_old_rootfs_info();
  manifest.mutable_new_kernel_info();
  manifest.mutable_new_rootfs_info();
  manifest.set_minor_version(kMaxSupportedMinorPayloadVersion);

  RunManifestValidation(manifest,
                        kChromeOSMajorPayloadVersion,
                        InstallPayloadType::kDelta,
                        ErrorCode::kSuccess);
}

TEST_F(DeltaPerformerTest, ValidateManifestDeltaMinGoodTest) {
  // The Manifest we are validating.
  DeltaArchiveManifest manifest;
  manifest.mutable_old_kernel_info();
  manifest.mutable_old_rootfs_info();
  manifest.mutable_new_kernel_info();
  manifest.mutable_new_rootfs_info();
  manifest.set_minor_version(kMinSupportedMinorPayloadVersion);

  RunManifestValidation(manifest,
                        kChromeOSMajorPayloadVersion,
                        InstallPayloadType::kDelta,
                        ErrorCode::kSuccess);
}

TEST_F(DeltaPerformerTest, ValidateManifestFullUnsetMinorVersion) {
  // The Manifest we are validating.
  DeltaArchiveManifest manifest;

  RunManifestValidation(manifest,
                        kMaxSupportedMajorPayloadVersion,
                        InstallPayloadType::kFull,
                        ErrorCode::kSuccess);
}

TEST_F(DeltaPerformerTest, ValidateManifestDeltaUnsetMinorVersion) {
  // The Manifest we are validating.
  DeltaArchiveManifest manifest;
  // Add an empty old_rootfs_info() to trick the DeltaPerformer into think that
  // this is a delta payload manifest with a missing minor version.
  manifest.mutable_old_rootfs_info();

  RunManifestValidation(manifest,
                        kMaxSupportedMajorPayloadVersion,
                        InstallPayloadType::kDelta,
                        ErrorCode::kUnsupportedMinorPayloadVersion);
}

TEST_F(DeltaPerformerTest, ValidateManifestFullOldKernelTest) {
  // The Manifest we are validating.
  DeltaArchiveManifest manifest;
  manifest.mutable_old_kernel_info();
  manifest.mutable_new_kernel_info();
  manifest.mutable_new_rootfs_info();
  manifest.set_minor_version(kMaxSupportedMinorPayloadVersion);

  RunManifestValidation(manifest,
                        kChromeOSMajorPayloadVersion,
                        InstallPayloadType::kFull,
                        ErrorCode::kPayloadMismatchedType);
}

TEST_F(DeltaPerformerTest, ValidateManifestFullOldRootfsTest) {
  // The Manifest we are validating.
  DeltaArchiveManifest manifest;
  manifest.mutable_old_rootfs_info();
  manifest.mutable_new_kernel_info();
  manifest.mutable_new_rootfs_info();
  manifest.set_minor_version(kMaxSupportedMinorPayloadVersion);

  RunManifestValidation(manifest,
                        kChromeOSMajorPayloadVersion,
                        InstallPayloadType::kFull,
                        ErrorCode::kPayloadMismatchedType);
}

TEST_F(DeltaPerformerTest, ValidateManifestFullPartitionUpdateTest) {
  // The Manifest we are validating.
  DeltaArchiveManifest manifest;
  PartitionUpdate* partition = manifest.add_partitions();
  partition->mutable_old_partition_info();
  partition->mutable_new_partition_info();
  manifest.set_minor_version(kMaxSupportedMinorPayloadVersion);

  RunManifestValidation(manifest,
                        kBrilloMajorPayloadVersion,
                        InstallPayloadType::kFull,
                        ErrorCode::kPayloadMismatchedType);
}

TEST_F(DeltaPerformerTest, ValidateManifestBadMinorVersion) {
  // The Manifest we are validating.
  DeltaArchiveManifest manifest;

  // Generate a bad version number.
  manifest.set_minor_version(kMaxSupportedMinorPayloadVersion + 10000);
  // Mark the manifest as a delta payload by setting old_rootfs_info.
  manifest.mutable_old_rootfs_info();

  RunManifestValidation(manifest,
                        kMaxSupportedMajorPayloadVersion,
                        InstallPayloadType::kDelta,
                        ErrorCode::kUnsupportedMinorPayloadVersion);
}

TEST_F(DeltaPerformerTest, ValidateManifestDowngrade) {
  // The Manifest we are validating.
  DeltaArchiveManifest manifest;

  manifest.set_minor_version(kFullPayloadMinorVersion);
  manifest.set_max_timestamp(1);
  fake_hardware_.SetBuildTimestamp(2);

  RunManifestValidation(manifest,
                        kMaxSupportedMajorPayloadVersion,
                        InstallPayloadType::kFull,
                        ErrorCode::kPayloadTimestampError);
}

TEST_F(DeltaPerformerTest, BrilloMetadataSignatureSizeTest) {
  unsigned int seed = time(nullptr);
  EXPECT_TRUE(performer_.Write(kDeltaMagic, sizeof(kDeltaMagic)));

  uint64_t major_version = htobe64(kBrilloMajorPayloadVersion);
  EXPECT_TRUE(performer_.Write(&major_version, 8));

  uint64_t manifest_size = rand_r(&seed) % 256;
  uint64_t manifest_size_be = htobe64(manifest_size);
  EXPECT_TRUE(performer_.Write(&manifest_size_be, 8));

  uint32_t metadata_signature_size = rand_r(&seed) % 256;
  uint32_t metadata_signature_size_be = htobe32(metadata_signature_size);
  EXPECT_TRUE(performer_.Write(&metadata_signature_size_be, 4));

  EXPECT_LT(performer_.Close(), 0);

  EXPECT_TRUE(performer_.IsHeaderParsed());
  EXPECT_EQ(kBrilloMajorPayloadVersion, performer_.major_payload_version_);
  EXPECT_EQ(24 + manifest_size, performer_.metadata_size_);  // 4 + 8 + 8 + 4
  EXPECT_EQ(metadata_signature_size, performer_.metadata_signature_size_);
}

TEST_F(DeltaPerformerTest, BrilloParsePayloadMetadataTest) {
  brillo::Blob payload_data = GeneratePayload({}, {}, true,
                                              kBrilloMajorPayloadVersion,
                                              kSourceMinorPayloadVersion);
  install_plan_.hash_checks_mandatory = true;
  performer_.set_public_key_path(GetBuildArtifactsPath(kUnittestPublicKeyPath));
  ErrorCode error;
  EXPECT_EQ(MetadataParseResult::kSuccess,
            performer_.ParsePayloadMetadata(payload_data, &error));
  EXPECT_EQ(ErrorCode::kSuccess, error);
}

TEST_F(DeltaPerformerTest, BadDeltaMagicTest) {
  EXPECT_TRUE(performer_.Write("junk", 4));
  EXPECT_FALSE(performer_.Write("morejunk", 8));
  EXPECT_LT(performer_.Close(), 0);
}

TEST_F(DeltaPerformerTest, MissingMandatoryMetadataSizeTest) {
  DoMetadataSizeTest(0, 75456, true);
}

TEST_F(DeltaPerformerTest, MissingNonMandatoryMetadataSizeTest) {
  DoMetadataSizeTest(0, 123456, false);
}

TEST_F(DeltaPerformerTest, InvalidMandatoryMetadataSizeTest) {
  DoMetadataSizeTest(13000, 140000, true);
}

TEST_F(DeltaPerformerTest, InvalidNonMandatoryMetadataSizeTest) {
  DoMetadataSizeTest(40000, 50000, false);
}

TEST_F(DeltaPerformerTest, ValidMandatoryMetadataSizeTest) {
  DoMetadataSizeTest(85376, 85376, true);
}

TEST_F(DeltaPerformerTest, MandatoryEmptyMetadataSignatureTest) {
  DoMetadataSignatureTest(kEmptyMetadataSignature, true, true);
}

TEST_F(DeltaPerformerTest, NonMandatoryEmptyMetadataSignatureTest) {
  DoMetadataSignatureTest(kEmptyMetadataSignature, true, false);
}

TEST_F(DeltaPerformerTest, MandatoryInvalidMetadataSignatureTest) {
  DoMetadataSignatureTest(kInvalidMetadataSignature, true, true);
}

TEST_F(DeltaPerformerTest, NonMandatoryInvalidMetadataSignatureTest) {
  DoMetadataSignatureTest(kInvalidMetadataSignature, true, false);
}

TEST_F(DeltaPerformerTest, MandatoryValidMetadataSignature1Test) {
  DoMetadataSignatureTest(kValidMetadataSignature, false, true);
}

TEST_F(DeltaPerformerTest, MandatoryValidMetadataSignature2Test) {
  DoMetadataSignatureTest(kValidMetadataSignature, true, true);
}

TEST_F(DeltaPerformerTest, NonMandatoryValidMetadataSignatureTest) {
  DoMetadataSignatureTest(kValidMetadataSignature, true, false);
}

TEST_F(DeltaPerformerTest, UsePublicKeyFromResponse) {
  // The result of the GetPublicKeyResponse() method is based on three things
  //
  //  1. Whether it's an official build; and
  //  2. Whether the Public RSA key to be used is in the root filesystem; and
  //  3. Whether the response has a public key
  //
  // We test all eight combinations to ensure that we only use the
  // public key in the response if
  //
  //  a. it's not an official build; and
  //  b. there is no key in the root filesystem.

  base::ScopedTempDir temp_dir;
  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
  string non_existing_file = temp_dir.GetPath().Append("non-existing").value();
  string existing_file = temp_dir.GetPath().Append("existing").value();
  constexpr char kExistingKey[] = "Existing";
  ASSERT_TRUE(test_utils::WriteFileString(existing_file, kExistingKey));

  // Non-official build, non-existing public-key, key in response ->
  // kResponseKey
  fake_hardware_.SetIsOfficialBuild(false);
  performer_.public_key_path_ = non_existing_file;
  // This is the result of 'echo -n "Response" | base64' and is not meant to be
  // a valid public key, but it is valid base-64.
  constexpr char kResponseKey[] = "Response";
  constexpr char kBase64ResponseKey[] = "UmVzcG9uc2U=";
  install_plan_.public_key_rsa = kBase64ResponseKey;
  string public_key;
  EXPECT_TRUE(performer_.GetPublicKey(&public_key));
  EXPECT_EQ(public_key, kResponseKey);
  // Same with official build -> no key
  fake_hardware_.SetIsOfficialBuild(true);
  EXPECT_TRUE(performer_.GetPublicKey(&public_key));
  EXPECT_TRUE(public_key.empty());

  // Non-official build, existing public-key, key in response -> kExistingKey
  fake_hardware_.SetIsOfficialBuild(false);
  performer_.public_key_path_ = existing_file;
  install_plan_.public_key_rsa = kBase64ResponseKey;
  EXPECT_TRUE(performer_.GetPublicKey(&public_key));
  EXPECT_EQ(public_key, kExistingKey);
  // Same with official build -> kExistingKey
  fake_hardware_.SetIsOfficialBuild(true);
  EXPECT_TRUE(performer_.GetPublicKey(&public_key));
  EXPECT_EQ(public_key, kExistingKey);

  // Non-official build, non-existing public-key, no key in response -> no key
  fake_hardware_.SetIsOfficialBuild(false);
  performer_.public_key_path_ = non_existing_file;
  install_plan_.public_key_rsa = "";
  EXPECT_TRUE(performer_.GetPublicKey(&public_key));
  EXPECT_TRUE(public_key.empty());
  // Same with official build -> no key
  fake_hardware_.SetIsOfficialBuild(true);
  EXPECT_TRUE(performer_.GetPublicKey(&public_key));
  EXPECT_TRUE(public_key.empty());

  // Non-official build, existing public-key, no key in response -> kExistingKey
  fake_hardware_.SetIsOfficialBuild(false);
  performer_.public_key_path_ = existing_file;
  install_plan_.public_key_rsa = "";
  EXPECT_TRUE(performer_.GetPublicKey(&public_key));
  EXPECT_EQ(public_key, kExistingKey);
  // Same with official build -> kExistingKey
  fake_hardware_.SetIsOfficialBuild(true);
  EXPECT_TRUE(performer_.GetPublicKey(&public_key));
  EXPECT_EQ(public_key, kExistingKey);

  // Non-official build, non-existing public-key, key in response
  // but invalid base64 -> false
  fake_hardware_.SetIsOfficialBuild(false);
  performer_.public_key_path_ = non_existing_file;
  install_plan_.public_key_rsa = "not-valid-base64";
  EXPECT_FALSE(performer_.GetPublicKey(&public_key));
}

TEST_F(DeltaPerformerTest, ConfVersionsMatch) {
  // Test that the versions in update_engine.conf that is installed to the
  // image match the maximum supported delta versions in the update engine.
  uint32_t minor_version;
  brillo::KeyValueStore store;
  EXPECT_TRUE(store.Load(GetBuildArtifactsPath().Append("update_engine.conf")));
  EXPECT_TRUE(utils::GetMinorVersion(store, &minor_version));
  EXPECT_EQ(kMaxSupportedMinorPayloadVersion, minor_version);

  string major_version_str;
  uint64_t major_version;
  EXPECT_TRUE(store.GetString("PAYLOAD_MAJOR_VERSION", &major_version_str));
  EXPECT_TRUE(base::StringToUint64(major_version_str, &major_version));
  EXPECT_EQ(kMaxSupportedMajorPayloadVersion, major_version);
}

}  // namespace chromeos_update_engine
