1aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo//
2aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// Copyright (C) 2012 The Android Open Source Project
3aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo//
4aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// Licensed under the Apache License, Version 2.0 (the "License");
5aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// you may not use this file except in compliance with the License.
6aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// You may obtain a copy of the License at
7aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo//
8aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo//      http://www.apache.org/licenses/LICENSE-2.0
9aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo//
10aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// Unless required by applicable law or agreed to in writing, software
11aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// distributed under the License is distributed on an "AS IS" BASIS,
12aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// See the License for the specific language governing permissions and
14aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// limitations under the License.
15aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo//
1609e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyes
1739910dcd1d68987ccee7c3031dc269233a8490bbAlex Deymo#include "update_engine/payload_consumer/delta_performer.h"
188427b4a6d0e6e02beedbb53798272f8ddc39386fAlex Deymo
1980f70ff45f8ea9a679c0c3ed0dc143dd2fe2b63eAlex Deymo#include <endian.h>
2009e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyes#include <inttypes.h>
2109e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyes
2209e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyes#include <string>
2309e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyes#include <vector>
2409e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyes
2578750a450ce84b2d335134402d041aa8773ab8efAllie Wood#include <base/files/file_path.h>
2606c76a49bfd29c8abdb8abd5b646a6583783191aBen Chan#include <base/files/file_util.h>
27371615b025bdd8106faf65c1ba7439a1236f21bcSen Jiang#include <base/files/scoped_temp_dir.h>
28cbf09896be9a627cd04dd54ef6875bed88daa3d8Alex Deymo#include <base/strings/string_number_conversions.h>
29f1cbe1783dd025bd7243a8df12f20548196cc023Alex Deymo#include <base/strings/string_util.h>
302d621a3cf2da7ff3b2a178594cb97ada6c4350d3Alex Deymo#include <base/strings/stringprintf.h>
31542c19bf271011913a9f352f58e140224c936736Alex Deymo#include <gmock/gmock.h>
3209e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyes#include <google/protobuf/repeated_field.h>
3309e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyes#include <gtest/gtest.h>
3409e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyes
3539910dcd1d68987ccee7c3031dc269233a8490bbAlex Deymo#include "update_engine/common/constants.h"
36542c19bf271011913a9f352f58e140224c936736Alex Deymo#include "update_engine/common/fake_boot_control.h"
3739910dcd1d68987ccee7c3031dc269233a8490bbAlex Deymo#include "update_engine/common/fake_hardware.h"
3839910dcd1d68987ccee7c3031dc269233a8490bbAlex Deymo#include "update_engine/common/fake_prefs.h"
3939910dcd1d68987ccee7c3031dc269233a8490bbAlex Deymo#include "update_engine/common/test_utils.h"
4039910dcd1d68987ccee7c3031dc269233a8490bbAlex Deymo#include "update_engine/common/utils.h"
41542c19bf271011913a9f352f58e140224c936736Alex Deymo#include "update_engine/payload_consumer/mock_download_action.h"
4239910dcd1d68987ccee7c3031dc269233a8490bbAlex Deymo#include "update_engine/payload_consumer/payload_constants.h"
430bc2611b49aba30202fdb9c23871430eb67e4738Alex Deymo#include "update_engine/payload_generator/bzip.h"
442d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang#include "update_engine/payload_generator/extent_ranges.h"
45d78b3892232ae46cb0b8a7a96dea59b2df46a83fSen Jiang#include "update_engine/payload_generator/payload_file.h"
46923d8faa6b341ce5e16a760749e98cc6703ca2fdAlex Deymo#include "update_engine/payload_generator/payload_signer.h"
4709e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyes#include "update_engine/update_metadata.pb.h"
4809e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyes
4909e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyesnamespace chromeos_update_engine {
5009e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyes
5109e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyesusing std::string;
5209e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyesusing std::vector;
53260f03bc4d3a3de436e056c686c814444358823aSen Jiangusing test_utils::GetBuildArtifactsPath;
5410875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymousing test_utils::System;
552d621a3cf2da7ff3b2a178594cb97ada6c4350d3Alex Deymousing test_utils::kRandomString;
56542c19bf271011913a9f352f58e140224c936736Alex Deymousing testing::_;
5709e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyes
58932bc4c1c271bc1b03da9a1bfe7c37017c58bffaAndrew de los Reyesextern const char* kUnittestPrivateKeyPath;
59d7061ab058db55cb715617e8fa5f8e70ff4a5d67Darin Petkovextern const char* kUnittestPublicKeyPath;
60932bc4c1c271bc1b03da9a1bfe7c37017c58bffaAndrew de los Reyes
61e0d04282910d423ddc950dd38224c001efc41d42Sen Jiangnamespace {
62e0d04282910d423ddc950dd38224c001efc41d42Sen Jiang
63e0d04282910d423ddc950dd38224c001efc41d42Sen Jiangconst char kBogusMetadataSignature1[] =
64d1c4d2dd3daed1d507038046c0355fbafb85260cGilad Arnold    "awSFIUdUZz2VWFiR+ku0Pj00V7bPQPQFYQSXjEXr3vaw3TE4xHV5CraY3/YrZpBv"
65d1c4d2dd3daed1d507038046c0355fbafb85260cGilad Arnold    "J5z4dSBskoeuaO1TNC/S6E05t+yt36tE4Fh79tMnJ/z9fogBDXWgXLEUyG78IEQr"
66d1c4d2dd3daed1d507038046c0355fbafb85260cGilad Arnold    "YH6/eBsQGT2RJtBgXIXbZ9W+5G9KmGDoPOoiaeNsDuqHiBc/58OFsrxskH8E6vMS"
67d1c4d2dd3daed1d507038046c0355fbafb85260cGilad Arnold    "BmMGGk82mvgzic7ApcoURbCGey1b3Mwne/hPZ/bb9CIyky8Og9IfFMdL2uAweOIR"
68d1c4d2dd3daed1d507038046c0355fbafb85260cGilad Arnold    "fjoTeLYZpt+WN65Vu7jJ0cQN8e1y+2yka5112wpRf/LLtPgiAjEZnsoYpLUd7CoV"
69d1c4d2dd3daed1d507038046c0355fbafb85260cGilad Arnold    "pLRtClp97kN2+tXGNBQqkA==";
70738fdf37c15284b60dac703408b8de19eef9c6a3Jay Srinivasan
71738fdf37c15284b60dac703408b8de19eef9c6a3Jay Srinivasan// Different options that determine what we should fill into the
72738fdf37c15284b60dac703408b8de19eef9c6a3Jay Srinivasan// install_plan.metadata_signature to simulate the contents received in the
73738fdf37c15284b60dac703408b8de19eef9c6a3Jay Srinivasan// Omaha response.
74738fdf37c15284b60dac703408b8de19eef9c6a3Jay Srinivasanenum MetadataSignatureTest {
75738fdf37c15284b60dac703408b8de19eef9c6a3Jay Srinivasan  kEmptyMetadataSignature,
76738fdf37c15284b60dac703408b8de19eef9c6a3Jay Srinivasan  kInvalidMetadataSignature,
77738fdf37c15284b60dac703408b8de19eef9c6a3Jay Srinivasan  kValidMetadataSignature,
78738fdf37c15284b60dac703408b8de19eef9c6a3Jay Srinivasan};
79738fdf37c15284b60dac703408b8de19eef9c6a3Jay Srinivasan
802d621a3cf2da7ff3b2a178594cb97ada6c4350d3Alex Deymo// Compressed data without checksum, generated with:
812d621a3cf2da7ff3b2a178594cb97ada6c4350d3Alex Deymo// echo -n a | xz -9 --check=none | hexdump -v -e '"    " 12/1 "0x%02x, " "\n"'
822d621a3cf2da7ff3b2a178594cb97ada6c4350d3Alex Deymoconst uint8_t kXzCompressedData[] = {
832d621a3cf2da7ff3b2a178594cb97ada6c4350d3Alex Deymo    0xfd, 0x37, 0x7a, 0x58, 0x5a, 0x00, 0x00, 0x00, 0xff, 0x12, 0xd9, 0x41,
842d621a3cf2da7ff3b2a178594cb97ada6c4350d3Alex Deymo    0x02, 0x00, 0x21, 0x01, 0x1c, 0x00, 0x00, 0x00, 0x10, 0xcf, 0x58, 0xcc,
852d621a3cf2da7ff3b2a178594cb97ada6c4350d3Alex Deymo    0x01, 0x00, 0x00, 0x61, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x11, 0x01,
862d621a3cf2da7ff3b2a178594cb97ada6c4350d3Alex Deymo    0xad, 0xa6, 0x58, 0x04, 0x06, 0x72, 0x9e, 0x7a, 0x01, 0x00, 0x00, 0x00,
872d621a3cf2da7ff3b2a178594cb97ada6c4350d3Alex Deymo    0x00, 0x00, 0x59, 0x5a,
882d621a3cf2da7ff3b2a178594cb97ada6c4350d3Alex Deymo};
892d621a3cf2da7ff3b2a178594cb97ada6c4350d3Alex Deymo
90bc3e6b00d2ed50d5fd77f2a74348608e52935e6dSen Jiang// Gzipped 'abc', generated with:
91bc3e6b00d2ed50d5fd77f2a74348608e52935e6dSen Jiang// echo -n abc | minigzip | hexdump -v -e '"    " 12/1 "0x%02x, " "\n"'
92bc3e6b00d2ed50d5fd77f2a74348608e52935e6dSen Jiangconst uint8_t kSourceGzippedData[] = {
93bc3e6b00d2ed50d5fd77f2a74348608e52935e6dSen Jiang    0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x4b, 0x4c,
94bc3e6b00d2ed50d5fd77f2a74348608e52935e6dSen Jiang    0x4a, 0x06, 0x00, 0xc2, 0x41, 0x24, 0x35, 0x03, 0x00, 0x00, 0x00,
95bc3e6b00d2ed50d5fd77f2a74348608e52935e6dSen Jiang};
96bc3e6b00d2ed50d5fd77f2a74348608e52935e6dSen Jiang
97bc3e6b00d2ed50d5fd77f2a74348608e52935e6dSen Jiang// Gzipped 'def', generated with:
98bc3e6b00d2ed50d5fd77f2a74348608e52935e6dSen Jiang// echo -n def | minigzip | hexdump -v -e '"    " 12/1 "0x%02x, " "\n"'
99bc3e6b00d2ed50d5fd77f2a74348608e52935e6dSen Jiangconst uint8_t kTargetGzippedData[] = {
100bc3e6b00d2ed50d5fd77f2a74348608e52935e6dSen Jiang    0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x4b, 0x49,
101bc3e6b00d2ed50d5fd77f2a74348608e52935e6dSen Jiang    0x4d, 0x03, 0x00, 0x61, 0xe1, 0xc4, 0x0c, 0x03, 0x00, 0x00, 0x00,
102bc3e6b00d2ed50d5fd77f2a74348608e52935e6dSen Jiang};
103bc3e6b00d2ed50d5fd77f2a74348608e52935e6dSen Jiang
104bc3e6b00d2ed50d5fd77f2a74348608e52935e6dSen Jiang// Imgdiff data, generated with:
105bc3e6b00d2ed50d5fd77f2a74348608e52935e6dSen Jiang// echo -n abc | minigzip > abc && truncate -s 4096 abc
106bc3e6b00d2ed50d5fd77f2a74348608e52935e6dSen Jiang// echo -n def | minigzip > def && truncate -s 4096 def
107bc3e6b00d2ed50d5fd77f2a74348608e52935e6dSen Jiang// imgdiff abc def patch && hexdump -v -e '"    " 12/1 "0x%02x, " "\n"' patch
108bc3e6b00d2ed50d5fd77f2a74348608e52935e6dSen Jiangconst uint8_t kImgdiffData[] = {
109bc3e6b00d2ed50d5fd77f2a74348608e52935e6dSen Jiang    0x49, 0x4d, 0x47, 0x44, 0x49, 0x46, 0x46, 0x32, 0x03, 0x00, 0x00, 0x00,
110bc3e6b00d2ed50d5fd77f2a74348608e52935e6dSen Jiang    0x03, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x1f, 0x8b, 0x08, 0x00,
111bc3e6b00d2ed50d5fd77f2a74348608e52935e6dSen Jiang    0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x02, 0x00, 0x00, 0x00, 0x0a, 0x00,
112bc3e6b00d2ed50d5fd77f2a74348608e52935e6dSen Jiang    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00,
113bc3e6b00d2ed50d5fd77f2a74348608e52935e6dSen Jiang    0x00, 0x00, 0x7a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00,
114bc3e6b00d2ed50d5fd77f2a74348608e52935e6dSen Jiang    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
115bc3e6b00d2ed50d5fd77f2a74348608e52935e6dSen Jiang    0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0xf1, 0xff,
116bc3e6b00d2ed50d5fd77f2a74348608e52935e6dSen Jiang    0xff, 0xff, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
117bc3e6b00d2ed50d5fd77f2a74348608e52935e6dSen Jiang    0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf1, 0x0f,
118bc3e6b00d2ed50d5fd77f2a74348608e52935e6dSen Jiang    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00,
119bc3e6b00d2ed50d5fd77f2a74348608e52935e6dSen Jiang    0x00, 0x00, 0x42, 0x53, 0x44, 0x49, 0x46, 0x46, 0x34, 0x30, 0x2a, 0x00,
120bc3e6b00d2ed50d5fd77f2a74348608e52935e6dSen Jiang    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00,
121bc3e6b00d2ed50d5fd77f2a74348608e52935e6dSen Jiang    0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x5a,
122bc3e6b00d2ed50d5fd77f2a74348608e52935e6dSen Jiang    0x68, 0x39, 0x31, 0x41, 0x59, 0x26, 0x53, 0x59, 0xc3, 0xc8, 0xfb, 0x1f,
123bc3e6b00d2ed50d5fd77f2a74348608e52935e6dSen Jiang    0x00, 0x00, 0x01, 0x40, 0x00, 0x5c, 0x00, 0x20, 0x00, 0x30, 0xcd, 0x34,
124bc3e6b00d2ed50d5fd77f2a74348608e52935e6dSen Jiang    0x12, 0x34, 0x54, 0x60, 0x5c, 0xce, 0x2e, 0xe4, 0x8a, 0x70, 0xa1, 0x21,
125bc3e6b00d2ed50d5fd77f2a74348608e52935e6dSen Jiang    0x87, 0x91, 0xf6, 0x3e, 0x42, 0x5a, 0x68, 0x39, 0x17, 0x72, 0x45, 0x38,
126bc3e6b00d2ed50d5fd77f2a74348608e52935e6dSen Jiang    0x50, 0x90, 0x00, 0x00, 0x00, 0x00, 0x42, 0x5a, 0x68, 0x39, 0x31, 0x41,
127bc3e6b00d2ed50d5fd77f2a74348608e52935e6dSen Jiang    0x59, 0x26, 0x53, 0x59, 0x42, 0x3c, 0xb0, 0xf9, 0x00, 0x00, 0x00, 0x01,
128bc3e6b00d2ed50d5fd77f2a74348608e52935e6dSen Jiang    0x00, 0x07, 0x00, 0x20, 0x00, 0x21, 0x98, 0x19, 0x84, 0x61, 0x77, 0x24,
129bc3e6b00d2ed50d5fd77f2a74348608e52935e6dSen Jiang    0x53, 0x85, 0x09, 0x04, 0x23, 0xcb, 0x0f, 0x90, 0x42, 0x53, 0x44, 0x49,
130bc3e6b00d2ed50d5fd77f2a74348608e52935e6dSen Jiang    0x46, 0x46, 0x34, 0x30, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
131bc3e6b00d2ed50d5fd77f2a74348608e52935e6dSen Jiang    0x35, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf1, 0x0f, 0x00, 0x00,
132bc3e6b00d2ed50d5fd77f2a74348608e52935e6dSen Jiang    0x00, 0x00, 0x00, 0x00, 0x42, 0x5a, 0x68, 0x39, 0x31, 0x41, 0x59, 0x26,
133bc3e6b00d2ed50d5fd77f2a74348608e52935e6dSen Jiang    0x53, 0x59, 0x6f, 0x02, 0x77, 0xf3, 0x00, 0x00, 0x07, 0x40, 0x41, 0xe0,
134bc3e6b00d2ed50d5fd77f2a74348608e52935e6dSen Jiang    0x10, 0xc0, 0x00, 0x00, 0x02, 0x20, 0x00, 0x20, 0x00, 0x21, 0x29, 0xa3,
135bc3e6b00d2ed50d5fd77f2a74348608e52935e6dSen Jiang    0x10, 0x86, 0x03, 0x84, 0x04, 0xae, 0x5f, 0x17, 0x72, 0x45, 0x38, 0x50,
136bc3e6b00d2ed50d5fd77f2a74348608e52935e6dSen Jiang    0x90, 0x6f, 0x02, 0x77, 0xf3, 0x42, 0x5a, 0x68, 0x39, 0x31, 0x41, 0x59,
137bc3e6b00d2ed50d5fd77f2a74348608e52935e6dSen Jiang    0x26, 0x53, 0x59, 0x71, 0x62, 0xbd, 0xa7, 0x00, 0x00, 0x20, 0x40, 0x32,
138bc3e6b00d2ed50d5fd77f2a74348608e52935e6dSen Jiang    0xc0, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x80, 0x00, 0x48, 0x20, 0x00,
139bc3e6b00d2ed50d5fd77f2a74348608e52935e6dSen Jiang    0x30, 0xc0, 0x02, 0xa5, 0x19, 0xa5, 0x92, 0x6f, 0xc2, 0x5d, 0xac, 0x0e,
140bc3e6b00d2ed50d5fd77f2a74348608e52935e6dSen Jiang    0x17, 0x72, 0x45, 0x38, 0x50, 0x90, 0x71, 0x62, 0xbd, 0xa7, 0x42, 0x5a,
141bc3e6b00d2ed50d5fd77f2a74348608e52935e6dSen Jiang    0x68, 0x39, 0x17, 0x72, 0x45, 0x38, 0x50, 0x90, 0x00, 0x00, 0x00, 0x00,
142bc3e6b00d2ed50d5fd77f2a74348608e52935e6dSen Jiang};
143bc3e6b00d2ed50d5fd77f2a74348608e52935e6dSen Jiang
144d2779df63aaad8b65fc5d4badee7dbc9bed7f2b6Alex Vakulenko}  // namespace
145738fdf37c15284b60dac703408b8de19eef9c6a3Jay Srinivasan
146fdf005161523d9873a281f2a96d51dd4a3261f4fAllie Woodclass DeltaPerformerTest : public ::testing::Test {
1472d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang protected:
148e5e5fe926e9ea45b1a381af1bee91a86643ffd72Alex Deymo  void SetUp() override {
149e5e5fe926e9ea45b1a381af1bee91a86643ffd72Alex Deymo    install_plan_.source_slot = 0;
150e5e5fe926e9ea45b1a381af1bee91a86643ffd72Alex Deymo    install_plan_.target_slot = 1;
151542c19bf271011913a9f352f58e140224c936736Alex Deymo    EXPECT_CALL(mock_delegate_, ShouldCancel(_))
152542c19bf271011913a9f352f58e140224c936736Alex Deymo        .WillRepeatedly(testing::Return(false));
153e5e5fe926e9ea45b1a381af1bee91a86643ffd72Alex Deymo  }
154fdf005161523d9873a281f2a96d51dd4a3261f4fAllie Wood
1552d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang  // Test helper placed where it can easily be friended from DeltaPerformer.
1562d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang  void RunManifestValidation(const DeltaArchiveManifest& manifest,
1573e728feb92bfd5514bff55aa7dc455da80e18906Sen Jiang                             uint64_t major_version,
15864d9878470aa7b388e971862181daf6260851602Alex Deymo                             InstallPayloadType payload_type,
1592d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang                             ErrorCode expected) {
16064d9878470aa7b388e971862181daf6260851602Alex Deymo    install_plan_.payload_type = payload_type;
161fdf005161523d9873a281f2a96d51dd4a3261f4fAllie Wood
162fdf005161523d9873a281f2a96d51dd4a3261f4fAllie Wood    // The Manifest we are validating.
1632d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang    performer_.manifest_.CopyFrom(manifest);
1643e728feb92bfd5514bff55aa7dc455da80e18906Sen Jiang    performer_.major_payload_version_ = major_version;
165fdf005161523d9873a281f2a96d51dd4a3261f4fAllie Wood
1662d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang    EXPECT_EQ(expected, performer_.ValidateManifest());
167fdf005161523d9873a281f2a96d51dd4a3261f4fAllie Wood  }
168fdf005161523d9873a281f2a96d51dd4a3261f4fAllie Wood
1693f39d5cc753905874d8d93bef94f857b8808f19eAlex Vakulenko  brillo::Blob GeneratePayload(const brillo::Blob& blob_data,
1703f39d5cc753905874d8d93bef94f857b8808f19eAlex Vakulenko                               const vector<AnnotatedOperation>& aops,
171889c65d1914ed8a151f451a2933fa94d6e577aa6Sen Jiang                               bool sign_payload) {
172889c65d1914ed8a151f451a2933fa94d6e577aa6Sen Jiang    return GeneratePayload(blob_data, aops, sign_payload,
173889c65d1914ed8a151f451a2933fa94d6e577aa6Sen Jiang                           DeltaPerformer::kSupportedMajorPayloadVersion,
174889c65d1914ed8a151f451a2933fa94d6e577aa6Sen Jiang                           DeltaPerformer::kSupportedMinorPayloadVersion);
175889c65d1914ed8a151f451a2933fa94d6e577aa6Sen Jiang  }
176889c65d1914ed8a151f451a2933fa94d6e577aa6Sen Jiang
177889c65d1914ed8a151f451a2933fa94d6e577aa6Sen Jiang  brillo::Blob GeneratePayload(const brillo::Blob& blob_data,
178889c65d1914ed8a151f451a2933fa94d6e577aa6Sen Jiang                               const vector<AnnotatedOperation>& aops,
1793f39d5cc753905874d8d93bef94f857b8808f19eAlex Vakulenko                               bool sign_payload,
18076bfa74e52aea188aaf17aec186b0ef4269d39b3Sen Jiang                               uint64_t major_version,
18176bfa74e52aea188aaf17aec186b0ef4269d39b3Sen Jiang                               uint32_t minor_version) {
182d78b3892232ae46cb0b8a7a96dea59b2df46a83fSen Jiang    string blob_path;
183d78b3892232ae46cb0b8a7a96dea59b2df46a83fSen Jiang    EXPECT_TRUE(utils::MakeTempFile("Blob-XXXXXX", &blob_path, nullptr));
184d78b3892232ae46cb0b8a7a96dea59b2df46a83fSen Jiang    ScopedPathUnlinker blob_unlinker(blob_path);
185d78b3892232ae46cb0b8a7a96dea59b2df46a83fSen Jiang    EXPECT_TRUE(utils::WriteFile(blob_path.c_str(),
186d78b3892232ae46cb0b8a7a96dea59b2df46a83fSen Jiang                                 blob_data.data(),
187d78b3892232ae46cb0b8a7a96dea59b2df46a83fSen Jiang                                 blob_data.size()));
188d78b3892232ae46cb0b8a7a96dea59b2df46a83fSen Jiang
189d78b3892232ae46cb0b8a7a96dea59b2df46a83fSen Jiang    PayloadGenerationConfig config;
190a4073ef63482fd08c3678982f7d153360b088094Alex Deymo    config.version.major = major_version;
191a4073ef63482fd08c3678982f7d153360b088094Alex Deymo    config.version.minor = minor_version;
192d78b3892232ae46cb0b8a7a96dea59b2df46a83fSen Jiang
193d78b3892232ae46cb0b8a7a96dea59b2df46a83fSen Jiang    PayloadFile payload;
194d78b3892232ae46cb0b8a7a96dea59b2df46a83fSen Jiang    EXPECT_TRUE(payload.Init(config));
195d78b3892232ae46cb0b8a7a96dea59b2df46a83fSen Jiang
196981eb1151f42480ea10cb5283ab2108454a16c92Sen Jiang    PartitionConfig old_part(kLegacyPartitionNameRoot);
19764d9878470aa7b388e971862181daf6260851602Alex Deymo    if (minor_version != kFullPayloadMinorVersion) {
19864d9878470aa7b388e971862181daf6260851602Alex Deymo      // When generating a delta payload we need to include the old partition
19964d9878470aa7b388e971862181daf6260851602Alex Deymo      // information to mark it as a delta payload.
20064d9878470aa7b388e971862181daf6260851602Alex Deymo      old_part.path = "/dev/null";
20164d9878470aa7b388e971862181daf6260851602Alex Deymo      old_part.size = 0;
20264d9878470aa7b388e971862181daf6260851602Alex Deymo    }
203981eb1151f42480ea10cb5283ab2108454a16c92Sen Jiang    PartitionConfig new_part(kLegacyPartitionNameRoot);
204e5e5fe926e9ea45b1a381af1bee91a86643ffd72Alex Deymo    new_part.path = "/dev/zero";
205e5e5fe926e9ea45b1a381af1bee91a86643ffd72Alex Deymo    new_part.size = 1234;
206981eb1151f42480ea10cb5283ab2108454a16c92Sen Jiang
207981eb1151f42480ea10cb5283ab2108454a16c92Sen Jiang    payload.AddPartition(old_part, new_part, aops);
208d78b3892232ae46cb0b8a7a96dea59b2df46a83fSen Jiang
209e5e5fe926e9ea45b1a381af1bee91a86643ffd72Alex Deymo    // We include a kernel partition without operations.
210e5e5fe926e9ea45b1a381af1bee91a86643ffd72Alex Deymo    old_part.name = kLegacyPartitionNameKernel;
211e5e5fe926e9ea45b1a381af1bee91a86643ffd72Alex Deymo    new_part.name = kLegacyPartitionNameKernel;
212e5e5fe926e9ea45b1a381af1bee91a86643ffd72Alex Deymo    new_part.size = 0;
213e5e5fe926e9ea45b1a381af1bee91a86643ffd72Alex Deymo    payload.AddPartition(old_part, new_part, {});
214e5e5fe926e9ea45b1a381af1bee91a86643ffd72Alex Deymo
215d78b3892232ae46cb0b8a7a96dea59b2df46a83fSen Jiang    string payload_path;
216d78b3892232ae46cb0b8a7a96dea59b2df46a83fSen Jiang    EXPECT_TRUE(utils::MakeTempFile("Payload-XXXXXX", &payload_path, nullptr));
217d78b3892232ae46cb0b8a7a96dea59b2df46a83fSen Jiang    ScopedPathUnlinker payload_unlinker(payload_path);
218260f03bc4d3a3de436e056c686c814444358823aSen Jiang    string private_key =
219260f03bc4d3a3de436e056c686c814444358823aSen Jiang        sign_payload ? GetBuildArtifactsPath(kUnittestPrivateKeyPath) : "";
220260f03bc4d3a3de436e056c686c814444358823aSen Jiang    EXPECT_TRUE(payload.WritePayload(
221260f03bc4d3a3de436e056c686c814444358823aSen Jiang        payload_path, blob_path, private_key, &install_plan_.metadata_size));
222d78b3892232ae46cb0b8a7a96dea59b2df46a83fSen Jiang
2233f39d5cc753905874d8d93bef94f857b8808f19eAlex Vakulenko    brillo::Blob payload_data;
224d78b3892232ae46cb0b8a7a96dea59b2df46a83fSen Jiang    EXPECT_TRUE(utils::ReadFile(payload_path, &payload_data));
225d78b3892232ae46cb0b8a7a96dea59b2df46a83fSen Jiang    return payload_data;
226d78b3892232ae46cb0b8a7a96dea59b2df46a83fSen Jiang  }
227fdf005161523d9873a281f2a96d51dd4a3261f4fAllie Wood
2282d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang  // Apply |payload_data| on partition specified in |source_path|.
2292ec4aab50fa8ed4afd9fa86a0125ed68674ebd01Sen Jiang  // Expect result of performer_.Write() to be |expect_success|.
2302ec4aab50fa8ed4afd9fa86a0125ed68674ebd01Sen Jiang  // Returns the result of the payload application.
2313f39d5cc753905874d8d93bef94f857b8808f19eAlex Vakulenko  brillo::Blob ApplyPayload(const brillo::Blob& payload_data,
2322ec4aab50fa8ed4afd9fa86a0125ed68674ebd01Sen Jiang                            const string& source_path,
2332ec4aab50fa8ed4afd9fa86a0125ed68674ebd01Sen Jiang                            bool expect_success) {
2342ec4aab50fa8ed4afd9fa86a0125ed68674ebd01Sen Jiang    return ApplyPayloadToData(payload_data, source_path, brillo::Blob(),
2352ec4aab50fa8ed4afd9fa86a0125ed68674ebd01Sen Jiang                              expect_success);
23679715ad989b427a05c94305cfcc907b3a65b4316Alex Deymo  }
2372d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang
23879715ad989b427a05c94305cfcc907b3a65b4316Alex Deymo  // Apply the payload provided in |payload_data| reading from the |source_path|
23979715ad989b427a05c94305cfcc907b3a65b4316Alex Deymo  // file and writing the contents to a new partition. The existing data in the
24079715ad989b427a05c94305cfcc907b3a65b4316Alex Deymo  // new target file are set to |target_data| before applying the payload.
2412ec4aab50fa8ed4afd9fa86a0125ed68674ebd01Sen Jiang  // Expect result of performer_.Write() to be |expect_success|.
24279715ad989b427a05c94305cfcc907b3a65b4316Alex Deymo  // Returns the result of the payload application.
2433f39d5cc753905874d8d93bef94f857b8808f19eAlex Vakulenko  brillo::Blob ApplyPayloadToData(const brillo::Blob& payload_data,
2443f39d5cc753905874d8d93bef94f857b8808f19eAlex Vakulenko                                  const string& source_path,
2452ec4aab50fa8ed4afd9fa86a0125ed68674ebd01Sen Jiang                                  const brillo::Blob& target_data,
2462ec4aab50fa8ed4afd9fa86a0125ed68674ebd01Sen Jiang                                  bool expect_success) {
2472d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang    string new_part;
2482d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang    EXPECT_TRUE(utils::MakeTempFile("Partition-XXXXXX", &new_part, nullptr));
2492d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang    ScopedPathUnlinker partition_unlinker(new_part);
25079715ad989b427a05c94305cfcc907b3a65b4316Alex Deymo    EXPECT_TRUE(utils::WriteFile(new_part.c_str(), target_data.data(),
25179715ad989b427a05c94305cfcc907b3a65b4316Alex Deymo                                 target_data.size()));
25279715ad989b427a05c94305cfcc907b3a65b4316Alex Deymo
253e5e5fe926e9ea45b1a381af1bee91a86643ffd72Alex Deymo    // We installed the operations only in the rootfs partition, but the
254e5e5fe926e9ea45b1a381af1bee91a86643ffd72Alex Deymo    // delta performer needs to access all the partitions.
255542c19bf271011913a9f352f58e140224c936736Alex Deymo    fake_boot_control_.SetPartitionDevice(
256e5e5fe926e9ea45b1a381af1bee91a86643ffd72Alex Deymo        kLegacyPartitionNameRoot, install_plan_.target_slot, new_part);
257542c19bf271011913a9f352f58e140224c936736Alex Deymo    fake_boot_control_.SetPartitionDevice(
258e5e5fe926e9ea45b1a381af1bee91a86643ffd72Alex Deymo        kLegacyPartitionNameRoot, install_plan_.source_slot, source_path);
259542c19bf271011913a9f352f58e140224c936736Alex Deymo    fake_boot_control_.SetPartitionDevice(
260e5e5fe926e9ea45b1a381af1bee91a86643ffd72Alex Deymo        kLegacyPartitionNameKernel, install_plan_.target_slot, "/dev/null");
261542c19bf271011913a9f352f58e140224c936736Alex Deymo    fake_boot_control_.SetPartitionDevice(
262e5e5fe926e9ea45b1a381af1bee91a86643ffd72Alex Deymo        kLegacyPartitionNameKernel, install_plan_.source_slot, "/dev/null");
2632d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang
2642ec4aab50fa8ed4afd9fa86a0125ed68674ebd01Sen Jiang    EXPECT_EQ(expect_success,
2652ec4aab50fa8ed4afd9fa86a0125ed68674ebd01Sen Jiang              performer_.Write(payload_data.data(), payload_data.size()));
2662d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang    EXPECT_EQ(0, performer_.Close());
2672d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang
2683f39d5cc753905874d8d93bef94f857b8808f19eAlex Vakulenko    brillo::Blob partition_data;
2692d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang    EXPECT_TRUE(utils::ReadFile(new_part, &partition_data));
2702d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang    return partition_data;
27151dcf260754837962dd22db3b7babee181471e7dJay Srinivasan  }
27251dcf260754837962dd22db3b7babee181471e7dJay Srinivasan
2732d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang  // Calls delta performer's Write method by pretending to pass in bytes from a
2742d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang  // delta file whose metadata size is actual_metadata_size and tests if all
2752d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang  // checks are correctly performed if the install plan contains
2762d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang  // expected_metadata_size and that the result of the parsing are as per
2772d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang  // hash_checks_mandatory flag.
2782d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang  void DoMetadataSizeTest(uint64_t expected_metadata_size,
2792d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang                          uint64_t actual_metadata_size,
2802d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang                          bool hash_checks_mandatory) {
2812d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang    install_plan_.hash_checks_mandatory = hash_checks_mandatory;
2822d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang
2832d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang    // Set a valid magic string and version number 1.
2842d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang    EXPECT_TRUE(performer_.Write("CrAU", 4));
2852d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang    uint64_t version = htobe64(kChromeOSMajorPayloadVersion);
2862d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang    EXPECT_TRUE(performer_.Write(&version, 8));
2872d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang
2882d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang    install_plan_.metadata_size = expected_metadata_size;
2892d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang    ErrorCode error_code;
2902d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang    // When filling in size in manifest, exclude the size of the 20-byte header.
2912d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang    uint64_t size_in_manifest = htobe64(actual_metadata_size - 20);
2922d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang    bool result = performer_.Write(&size_in_manifest, 8, &error_code);
2932d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang    if (expected_metadata_size == actual_metadata_size ||
2942d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang        !hash_checks_mandatory) {
2952d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang      EXPECT_TRUE(result);
2962d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang    } else {
2972d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang      EXPECT_FALSE(result);
2982d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang      EXPECT_EQ(ErrorCode::kDownloadInvalidMetadataSize, error_code);
2992d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang    }
3002d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang
3012d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang    EXPECT_LT(performer_.Close(), 0);
3022d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang  }
30351dcf260754837962dd22db3b7babee181471e7dJay Srinivasan
3042d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang  // Generates a valid delta file but tests the delta performer by suppling
3052d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang  // different metadata signatures as per metadata_signature_test flag and
3062d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang  // sees if the result of the parsing are as per hash_checks_mandatory flag.
3072d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang  void DoMetadataSignatureTest(MetadataSignatureTest metadata_signature_test,
3082d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang                               bool sign_payload,
3092d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang                               bool hash_checks_mandatory) {
3102d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang    // Loads the payload and parses the manifest.
3113f39d5cc753905874d8d93bef94f857b8808f19eAlex Vakulenko    brillo::Blob payload = GeneratePayload(brillo::Blob(),
3122d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang        vector<AnnotatedOperation>(), sign_payload,
31376bfa74e52aea188aaf17aec186b0ef4269d39b3Sen Jiang        kChromeOSMajorPayloadVersion, kFullPayloadMinorVersion);
3142d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang
3152d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang    LOG(INFO) << "Payload size: " << payload.size();
3162d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang
3172d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang    install_plan_.hash_checks_mandatory = hash_checks_mandatory;
3182d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang
3192d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang    DeltaPerformer::MetadataParseResult expected_result, actual_result;
3202d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang    ErrorCode expected_error, actual_error;
3212d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang
3222d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang    // Fill up the metadata signature in install plan according to the test.
3232d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang    switch (metadata_signature_test) {
3242d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang      case kEmptyMetadataSignature:
3252d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang        install_plan_.metadata_signature.clear();
3262d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang        expected_result = DeltaPerformer::kMetadataParseError;
3272d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang        expected_error = ErrorCode::kDownloadMetadataSignatureMissingError;
3282d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang        break;
3292d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang
3302d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang      case kInvalidMetadataSignature:
3312d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang        install_plan_.metadata_signature = kBogusMetadataSignature1;
3322d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang        expected_result = DeltaPerformer::kMetadataParseError;
3332d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang        expected_error = ErrorCode::kDownloadMetadataSignatureMismatch;
3342d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang        break;
3352d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang
3362d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang      case kValidMetadataSignature:
3372d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang      default:
3382d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang        // Set the install plan's metadata size to be the same as the one
3392d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang        // in the manifest so that we pass the metadata size checks. Only
3402d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang        // then we can get to manifest signature checks.
3412d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang        ASSERT_TRUE(PayloadSigner::GetMetadataSignature(
3422d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang            payload.data(),
3432d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang            install_plan_.metadata_size,
344260f03bc4d3a3de436e056c686c814444358823aSen Jiang            GetBuildArtifactsPath(kUnittestPrivateKeyPath),
3452d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang            &install_plan_.metadata_signature));
3462d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang        EXPECT_FALSE(install_plan_.metadata_signature.empty());
3472d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang        expected_result = DeltaPerformer::kMetadataParseSuccess;
3482d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang        expected_error = ErrorCode::kSuccess;
3492d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang        break;
3502d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang    }
3512d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang
3522d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang    // Ignore the expected result/error if hash checks are not mandatory.
3532d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang    if (!hash_checks_mandatory) {
354738fdf37c15284b60dac703408b8de19eef9c6a3Jay Srinivasan      expected_result = DeltaPerformer::kMetadataParseSuccess;
355d1c4d2dd3daed1d507038046c0355fbafb85260cGilad Arnold      expected_error = ErrorCode::kSuccess;
3562d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang    }
3572d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang
3582d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang    // Use the public key corresponding to the private key used above to
3592d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang    // sign the metadata.
360260f03bc4d3a3de436e056c686c814444358823aSen Jiang    string public_key_path = GetBuildArtifactsPath(kUnittestPublicKeyPath);
361260f03bc4d3a3de436e056c686c814444358823aSen Jiang    EXPECT_TRUE(utils::FileExists(public_key_path.c_str()));
362260f03bc4d3a3de436e056c686c814444358823aSen Jiang    performer_.set_public_key_path(public_key_path);
36351dcf260754837962dd22db3b7babee181471e7dJay Srinivasan
3642d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang    // Init actual_error with an invalid value so that we make sure
3652d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang    // ParsePayloadMetadata properly populates it in all cases.
3662d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang    actual_error = ErrorCode::kUmaReportedMax;
3672d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang    actual_result = performer_.ParsePayloadMetadata(payload, &actual_error);
3682d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang
3692d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang    EXPECT_EQ(expected_result, actual_result);
3702d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang    EXPECT_EQ(expected_error, actual_error);
3712d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang
3722d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang    // Check that the parsed metadata size is what's expected. This test
3732d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang    // implicitly confirms that the metadata signature is valid, if required.
3742d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang    EXPECT_EQ(install_plan_.metadata_size, performer_.GetMetadataSize());
37551dcf260754837962dd22db3b7babee181471e7dJay Srinivasan  }
37651dcf260754837962dd22db3b7babee181471e7dJay Srinivasan
377b8060e435f0edb8efef4891a99fa18f642e01aa2Sen Jiang  void SetSupportedMajorVersion(uint64_t major_version) {
378b8060e435f0edb8efef4891a99fa18f642e01aa2Sen Jiang    performer_.supported_major_version_ = major_version;
379b8060e435f0edb8efef4891a99fa18f642e01aa2Sen Jiang  }
3802d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang  FakePrefs prefs_;
3812d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang  InstallPlan install_plan_;
382542c19bf271011913a9f352f58e140224c936736Alex Deymo  FakeBootControl fake_boot_control_;
383542c19bf271011913a9f352f58e140224c936736Alex Deymo  FakeHardware fake_hardware_;
384542c19bf271011913a9f352f58e140224c936736Alex Deymo  MockDownloadActionDelegate mock_delegate_;
385542c19bf271011913a9f352f58e140224c936736Alex Deymo  DeltaPerformer performer_{
386542c19bf271011913a9f352f58e140224c936736Alex Deymo      &prefs_, &fake_boot_control_, &fake_hardware_, &mock_delegate_, &install_plan_};
3872d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang};
3882d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang
3892d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen JiangTEST_F(DeltaPerformerTest, FullPayloadWriteTest) {
39064d9878470aa7b388e971862181daf6260851602Alex Deymo  install_plan_.payload_type = InstallPayloadType::kFull;
3913f39d5cc753905874d8d93bef94f857b8808f19eAlex Vakulenko  brillo::Blob expected_data = brillo::Blob(std::begin(kRandomString),
3923f39d5cc753905874d8d93bef94f857b8808f19eAlex Vakulenko                                            std::end(kRandomString));
3932d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang  expected_data.resize(4096);  // block size
3942d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang  vector<AnnotatedOperation> aops;
3952d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang  AnnotatedOperation aop;
3962d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang  *(aop.op.add_dst_extents()) = ExtentForRange(0, 1);
3972d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang  aop.op.set_data_offset(0);
3982d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang  aop.op.set_data_length(expected_data.size());
3992d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang  aop.op.set_type(InstallOperation::REPLACE);
4002d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang  aops.push_back(aop);
4012d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang
4023f39d5cc753905874d8d93bef94f857b8808f19eAlex Vakulenko  brillo::Blob payload_data = GeneratePayload(expected_data, aops, false,
40376bfa74e52aea188aaf17aec186b0ef4269d39b3Sen Jiang      kChromeOSMajorPayloadVersion, kFullPayloadMinorVersion);
4042d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang
4052ec4aab50fa8ed4afd9fa86a0125ed68674ebd01Sen Jiang  EXPECT_EQ(expected_data, ApplyPayload(payload_data, "/dev/null", true));
4062d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang}
4072d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang
408542c19bf271011913a9f352f58e140224c936736Alex DeymoTEST_F(DeltaPerformerTest, ShouldCancelTest) {
40964d9878470aa7b388e971862181daf6260851602Alex Deymo  install_plan_.payload_type = InstallPayloadType::kFull;
410542c19bf271011913a9f352f58e140224c936736Alex Deymo  brillo::Blob expected_data = brillo::Blob(std::begin(kRandomString),
411542c19bf271011913a9f352f58e140224c936736Alex Deymo                                            std::end(kRandomString));
412542c19bf271011913a9f352f58e140224c936736Alex Deymo  expected_data.resize(4096);  // block size
413542c19bf271011913a9f352f58e140224c936736Alex Deymo  vector<AnnotatedOperation> aops;
414542c19bf271011913a9f352f58e140224c936736Alex Deymo  AnnotatedOperation aop;
415542c19bf271011913a9f352f58e140224c936736Alex Deymo  *(aop.op.add_dst_extents()) = ExtentForRange(0, 1);
416542c19bf271011913a9f352f58e140224c936736Alex Deymo  aop.op.set_data_offset(0);
417542c19bf271011913a9f352f58e140224c936736Alex Deymo  aop.op.set_data_length(expected_data.size());
418542c19bf271011913a9f352f58e140224c936736Alex Deymo  aop.op.set_type(InstallOperation::REPLACE);
419542c19bf271011913a9f352f58e140224c936736Alex Deymo  aops.push_back(aop);
420542c19bf271011913a9f352f58e140224c936736Alex Deymo
421542c19bf271011913a9f352f58e140224c936736Alex Deymo  brillo::Blob payload_data = GeneratePayload(expected_data, aops, false,
422542c19bf271011913a9f352f58e140224c936736Alex Deymo      kChromeOSMajorPayloadVersion, kFullPayloadMinorVersion);
423542c19bf271011913a9f352f58e140224c936736Alex Deymo
424542c19bf271011913a9f352f58e140224c936736Alex Deymo  testing::Mock::VerifyAndClearExpectations(&mock_delegate_);
425542c19bf271011913a9f352f58e140224c936736Alex Deymo  EXPECT_CALL(mock_delegate_, ShouldCancel(_))
426542c19bf271011913a9f352f58e140224c936736Alex Deymo      .WillOnce(
427542c19bf271011913a9f352f58e140224c936736Alex Deymo          testing::DoAll(testing::SetArgumentPointee<0>(ErrorCode::kError),
428542c19bf271011913a9f352f58e140224c936736Alex Deymo                         testing::Return(true)));
429542c19bf271011913a9f352f58e140224c936736Alex Deymo
430542c19bf271011913a9f352f58e140224c936736Alex Deymo  ApplyPayload(payload_data, "/dev/null", false);
431542c19bf271011913a9f352f58e140224c936736Alex Deymo}
432542c19bf271011913a9f352f58e140224c936736Alex Deymo
4332d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen JiangTEST_F(DeltaPerformerTest, ReplaceOperationTest) {
4343f39d5cc753905874d8d93bef94f857b8808f19eAlex Vakulenko  brillo::Blob expected_data = brillo::Blob(std::begin(kRandomString),
4353f39d5cc753905874d8d93bef94f857b8808f19eAlex Vakulenko                                            std::end(kRandomString));
4362d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang  expected_data.resize(4096);  // block size
4372d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang  vector<AnnotatedOperation> aops;
4382d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang  AnnotatedOperation aop;
4392d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang  *(aop.op.add_dst_extents()) = ExtentForRange(0, 1);
4402d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang  aop.op.set_data_offset(0);
4412d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang  aop.op.set_data_length(expected_data.size());
4422d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang  aop.op.set_type(InstallOperation::REPLACE);
4432d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang  aops.push_back(aop);
4442d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang
445889c65d1914ed8a151f451a2933fa94d6e577aa6Sen Jiang  brillo::Blob payload_data = GeneratePayload(expected_data, aops, false);
4462d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang
4472ec4aab50fa8ed4afd9fa86a0125ed68674ebd01Sen Jiang  EXPECT_EQ(expected_data, ApplyPayload(payload_data, "/dev/null", true));
4482d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang}
4492d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang
4502d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen JiangTEST_F(DeltaPerformerTest, ReplaceBzOperationTest) {
4513f39d5cc753905874d8d93bef94f857b8808f19eAlex Vakulenko  brillo::Blob expected_data = brillo::Blob(std::begin(kRandomString),
4523f39d5cc753905874d8d93bef94f857b8808f19eAlex Vakulenko                                            std::end(kRandomString));
4532d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang  expected_data.resize(4096);  // block size
4543f39d5cc753905874d8d93bef94f857b8808f19eAlex Vakulenko  brillo::Blob bz_data;
4552d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang  EXPECT_TRUE(BzipCompress(expected_data, &bz_data));
4562d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang
4572d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang  vector<AnnotatedOperation> aops;
4582d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang  AnnotatedOperation aop;
4592d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang  *(aop.op.add_dst_extents()) = ExtentForRange(0, 1);
4602d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang  aop.op.set_data_offset(0);
4612d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang  aop.op.set_data_length(bz_data.size());
4622d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang  aop.op.set_type(InstallOperation::REPLACE_BZ);
4632d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang  aops.push_back(aop);
4642d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang
465889c65d1914ed8a151f451a2933fa94d6e577aa6Sen Jiang  brillo::Blob payload_data = GeneratePayload(bz_data, aops, false);
4662d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang
4672ec4aab50fa8ed4afd9fa86a0125ed68674ebd01Sen Jiang  EXPECT_EQ(expected_data, ApplyPayload(payload_data, "/dev/null", true));
4682d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang}
4692d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang
4702d621a3cf2da7ff3b2a178594cb97ada6c4350d3Alex DeymoTEST_F(DeltaPerformerTest, ReplaceXzOperationTest) {
4713f39d5cc753905874d8d93bef94f857b8808f19eAlex Vakulenko  brillo::Blob xz_data(std::begin(kXzCompressedData),
4722d621a3cf2da7ff3b2a178594cb97ada6c4350d3Alex Deymo                         std::end(kXzCompressedData));
4732d621a3cf2da7ff3b2a178594cb97ada6c4350d3Alex Deymo  // The compressed xz data contains only a single "a", but the operation should
4742d621a3cf2da7ff3b2a178594cb97ada6c4350d3Alex Deymo  // pad the rest of the two blocks with zeros.
4753f39d5cc753905874d8d93bef94f857b8808f19eAlex Vakulenko  brillo::Blob expected_data = brillo::Blob(4096, 0);
4762d621a3cf2da7ff3b2a178594cb97ada6c4350d3Alex Deymo  expected_data[0] = 'a';
4772d621a3cf2da7ff3b2a178594cb97ada6c4350d3Alex Deymo
4782d621a3cf2da7ff3b2a178594cb97ada6c4350d3Alex Deymo  AnnotatedOperation aop;
4792d621a3cf2da7ff3b2a178594cb97ada6c4350d3Alex Deymo  *(aop.op.add_dst_extents()) = ExtentForRange(0, 1);
4802d621a3cf2da7ff3b2a178594cb97ada6c4350d3Alex Deymo  aop.op.set_data_offset(0);
4812d621a3cf2da7ff3b2a178594cb97ada6c4350d3Alex Deymo  aop.op.set_data_length(xz_data.size());
4822d621a3cf2da7ff3b2a178594cb97ada6c4350d3Alex Deymo  aop.op.set_type(InstallOperation::REPLACE_XZ);
4832d621a3cf2da7ff3b2a178594cb97ada6c4350d3Alex Deymo  vector<AnnotatedOperation> aops = {aop};
4842d621a3cf2da7ff3b2a178594cb97ada6c4350d3Alex Deymo
485889c65d1914ed8a151f451a2933fa94d6e577aa6Sen Jiang  brillo::Blob payload_data = GeneratePayload(xz_data, aops, false);
4862d621a3cf2da7ff3b2a178594cb97ada6c4350d3Alex Deymo
4872ec4aab50fa8ed4afd9fa86a0125ed68674ebd01Sen Jiang  EXPECT_EQ(expected_data, ApplyPayload(payload_data, "/dev/null", true));
4882d621a3cf2da7ff3b2a178594cb97ada6c4350d3Alex Deymo}
4892d621a3cf2da7ff3b2a178594cb97ada6c4350d3Alex Deymo
49079715ad989b427a05c94305cfcc907b3a65b4316Alex DeymoTEST_F(DeltaPerformerTest, ZeroOperationTest) {
4913f39d5cc753905874d8d93bef94f857b8808f19eAlex Vakulenko  brillo::Blob existing_data = brillo::Blob(4096 * 10, 'a');
4923f39d5cc753905874d8d93bef94f857b8808f19eAlex Vakulenko  brillo::Blob expected_data = existing_data;
49379715ad989b427a05c94305cfcc907b3a65b4316Alex Deymo  // Blocks 4, 5 and 7 should have zeros instead of 'a' after the operation is
49479715ad989b427a05c94305cfcc907b3a65b4316Alex Deymo  // applied.
49579715ad989b427a05c94305cfcc907b3a65b4316Alex Deymo  std::fill(expected_data.data() + 4096 * 4, expected_data.data() + 4096 * 6,
49679715ad989b427a05c94305cfcc907b3a65b4316Alex Deymo            0);
49779715ad989b427a05c94305cfcc907b3a65b4316Alex Deymo  std::fill(expected_data.data() + 4096 * 7, expected_data.data() + 4096 * 8,
49879715ad989b427a05c94305cfcc907b3a65b4316Alex Deymo            0);
49979715ad989b427a05c94305cfcc907b3a65b4316Alex Deymo
50079715ad989b427a05c94305cfcc907b3a65b4316Alex Deymo  AnnotatedOperation aop;
50179715ad989b427a05c94305cfcc907b3a65b4316Alex Deymo  *(aop.op.add_dst_extents()) = ExtentForRange(4, 2);
50279715ad989b427a05c94305cfcc907b3a65b4316Alex Deymo  *(aop.op.add_dst_extents()) = ExtentForRange(7, 1);
50379715ad989b427a05c94305cfcc907b3a65b4316Alex Deymo  aop.op.set_type(InstallOperation::ZERO);
50479715ad989b427a05c94305cfcc907b3a65b4316Alex Deymo  vector<AnnotatedOperation> aops = {aop};
50579715ad989b427a05c94305cfcc907b3a65b4316Alex Deymo
506889c65d1914ed8a151f451a2933fa94d6e577aa6Sen Jiang  brillo::Blob payload_data = GeneratePayload(brillo::Blob(), aops, false);
50779715ad989b427a05c94305cfcc907b3a65b4316Alex Deymo
50879715ad989b427a05c94305cfcc907b3a65b4316Alex Deymo  EXPECT_EQ(expected_data,
5092ec4aab50fa8ed4afd9fa86a0125ed68674ebd01Sen Jiang            ApplyPayloadToData(payload_data, "/dev/null", existing_data, true));
51079715ad989b427a05c94305cfcc907b3a65b4316Alex Deymo}
51179715ad989b427a05c94305cfcc907b3a65b4316Alex Deymo
5122d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen JiangTEST_F(DeltaPerformerTest, SourceCopyOperationTest) {
5132ec4aab50fa8ed4afd9fa86a0125ed68674ebd01Sen Jiang  brillo::Blob expected_data(std::begin(kRandomString),
5142ec4aab50fa8ed4afd9fa86a0125ed68674ebd01Sen Jiang                             std::end(kRandomString));
5152d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang  expected_data.resize(4096);  // block size
5162d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang  AnnotatedOperation aop;
5172d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang  *(aop.op.add_src_extents()) = ExtentForRange(0, 1);
5182d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang  *(aop.op.add_dst_extents()) = ExtentForRange(0, 1);
5192d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang  aop.op.set_type(InstallOperation::SOURCE_COPY);
5202ec4aab50fa8ed4afd9fa86a0125ed68674ebd01Sen Jiang  brillo::Blob src_hash;
5212ec4aab50fa8ed4afd9fa86a0125ed68674ebd01Sen Jiang  EXPECT_TRUE(HashCalculator::RawHashOfData(expected_data, &src_hash));
5222ec4aab50fa8ed4afd9fa86a0125ed68674ebd01Sen Jiang  aop.op.set_src_sha256_hash(src_hash.data(), src_hash.size());
5232d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang
524889c65d1914ed8a151f451a2933fa94d6e577aa6Sen Jiang  brillo::Blob payload_data = GeneratePayload(brillo::Blob(), {aop}, false);
525889c65d1914ed8a151f451a2933fa94d6e577aa6Sen Jiang
5262d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang  string source_path;
5272d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang  EXPECT_TRUE(utils::MakeTempFile("Source-XXXXXX",
5282d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang                                  &source_path, nullptr));
5292d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang  ScopedPathUnlinker path_unlinker(source_path);
5302d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang  EXPECT_TRUE(utils::WriteFile(source_path.c_str(),
5312d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang                               expected_data.data(),
5322d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang                               expected_data.size()));
5332d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang
5342ec4aab50fa8ed4afd9fa86a0125ed68674ebd01Sen Jiang  EXPECT_EQ(expected_data, ApplyPayload(payload_data, source_path, true));
5352ec4aab50fa8ed4afd9fa86a0125ed68674ebd01Sen Jiang}
5362ec4aab50fa8ed4afd9fa86a0125ed68674ebd01Sen Jiang
537bc3e6b00d2ed50d5fd77f2a74348608e52935e6dSen JiangTEST_F(DeltaPerformerTest, ImgdiffOperationTest) {
538bc3e6b00d2ed50d5fd77f2a74348608e52935e6dSen Jiang  brillo::Blob imgdiff_data(std::begin(kImgdiffData), std::end(kImgdiffData));
539bc3e6b00d2ed50d5fd77f2a74348608e52935e6dSen Jiang
540bc3e6b00d2ed50d5fd77f2a74348608e52935e6dSen Jiang  AnnotatedOperation aop;
541bc3e6b00d2ed50d5fd77f2a74348608e52935e6dSen Jiang  *(aop.op.add_src_extents()) = ExtentForRange(0, 1);
542bc3e6b00d2ed50d5fd77f2a74348608e52935e6dSen Jiang  *(aop.op.add_dst_extents()) = ExtentForRange(0, 1);
543bc3e6b00d2ed50d5fd77f2a74348608e52935e6dSen Jiang  aop.op.set_data_offset(0);
544bc3e6b00d2ed50d5fd77f2a74348608e52935e6dSen Jiang  aop.op.set_data_length(imgdiff_data.size());
545bc3e6b00d2ed50d5fd77f2a74348608e52935e6dSen Jiang  aop.op.set_type(InstallOperation::IMGDIFF);
546bc3e6b00d2ed50d5fd77f2a74348608e52935e6dSen Jiang
547bc3e6b00d2ed50d5fd77f2a74348608e52935e6dSen Jiang  brillo::Blob payload_data = GeneratePayload(imgdiff_data, {aop}, false);
548bc3e6b00d2ed50d5fd77f2a74348608e52935e6dSen Jiang
549bc3e6b00d2ed50d5fd77f2a74348608e52935e6dSen Jiang  string source_path;
550bc3e6b00d2ed50d5fd77f2a74348608e52935e6dSen Jiang  EXPECT_TRUE(utils::MakeTempFile("Source-XXXXXX", &source_path, nullptr));
551bc3e6b00d2ed50d5fd77f2a74348608e52935e6dSen Jiang  ScopedPathUnlinker path_unlinker(source_path);
552bc3e6b00d2ed50d5fd77f2a74348608e52935e6dSen Jiang  brillo::Blob source_data(std::begin(kSourceGzippedData),
553bc3e6b00d2ed50d5fd77f2a74348608e52935e6dSen Jiang                           std::end(kSourceGzippedData));
554bc3e6b00d2ed50d5fd77f2a74348608e52935e6dSen Jiang  source_data.resize(4096);  // block size
555bc3e6b00d2ed50d5fd77f2a74348608e52935e6dSen Jiang  EXPECT_TRUE(utils::WriteFile(
556bc3e6b00d2ed50d5fd77f2a74348608e52935e6dSen Jiang      source_path.c_str(), source_data.data(), source_data.size()));
557bc3e6b00d2ed50d5fd77f2a74348608e52935e6dSen Jiang
558bc3e6b00d2ed50d5fd77f2a74348608e52935e6dSen Jiang  brillo::Blob target_data(std::begin(kTargetGzippedData),
559bc3e6b00d2ed50d5fd77f2a74348608e52935e6dSen Jiang                           std::end(kTargetGzippedData));
560bc3e6b00d2ed50d5fd77f2a74348608e52935e6dSen Jiang  target_data.resize(4096);  // block size
561bc3e6b00d2ed50d5fd77f2a74348608e52935e6dSen Jiang  EXPECT_EQ(target_data, ApplyPayload(payload_data, source_path, true));
562bc3e6b00d2ed50d5fd77f2a74348608e52935e6dSen Jiang}
563bc3e6b00d2ed50d5fd77f2a74348608e52935e6dSen Jiang
5642ec4aab50fa8ed4afd9fa86a0125ed68674ebd01Sen JiangTEST_F(DeltaPerformerTest, SourceHashMismatchTest) {
5652ec4aab50fa8ed4afd9fa86a0125ed68674ebd01Sen Jiang  brillo::Blob expected_data = {'f', 'o', 'o'};
5662ec4aab50fa8ed4afd9fa86a0125ed68674ebd01Sen Jiang  brillo::Blob actual_data = {'b', 'a', 'r'};
5672ec4aab50fa8ed4afd9fa86a0125ed68674ebd01Sen Jiang  expected_data.resize(4096);  // block size
5682ec4aab50fa8ed4afd9fa86a0125ed68674ebd01Sen Jiang  actual_data.resize(4096);    // block size
5692ec4aab50fa8ed4afd9fa86a0125ed68674ebd01Sen Jiang
5702ec4aab50fa8ed4afd9fa86a0125ed68674ebd01Sen Jiang  AnnotatedOperation aop;
5712ec4aab50fa8ed4afd9fa86a0125ed68674ebd01Sen Jiang  *(aop.op.add_src_extents()) = ExtentForRange(0, 1);
5722ec4aab50fa8ed4afd9fa86a0125ed68674ebd01Sen Jiang  *(aop.op.add_dst_extents()) = ExtentForRange(0, 1);
5732ec4aab50fa8ed4afd9fa86a0125ed68674ebd01Sen Jiang  aop.op.set_type(InstallOperation::SOURCE_COPY);
5742ec4aab50fa8ed4afd9fa86a0125ed68674ebd01Sen Jiang  brillo::Blob src_hash;
5752ec4aab50fa8ed4afd9fa86a0125ed68674ebd01Sen Jiang  EXPECT_TRUE(HashCalculator::RawHashOfData(expected_data, &src_hash));
5762ec4aab50fa8ed4afd9fa86a0125ed68674ebd01Sen Jiang  aop.op.set_src_sha256_hash(src_hash.data(), src_hash.size());
5772ec4aab50fa8ed4afd9fa86a0125ed68674ebd01Sen Jiang
578889c65d1914ed8a151f451a2933fa94d6e577aa6Sen Jiang  brillo::Blob payload_data = GeneratePayload(brillo::Blob(), {aop}, false);
579889c65d1914ed8a151f451a2933fa94d6e577aa6Sen Jiang
5802ec4aab50fa8ed4afd9fa86a0125ed68674ebd01Sen Jiang  string source_path;
5812ec4aab50fa8ed4afd9fa86a0125ed68674ebd01Sen Jiang  EXPECT_TRUE(utils::MakeTempFile("Source-XXXXXX", &source_path, nullptr));
5822ec4aab50fa8ed4afd9fa86a0125ed68674ebd01Sen Jiang  ScopedPathUnlinker path_unlinker(source_path);
5832ec4aab50fa8ed4afd9fa86a0125ed68674ebd01Sen Jiang  EXPECT_TRUE(utils::WriteFile(source_path.c_str(), actual_data.data(),
5842ec4aab50fa8ed4afd9fa86a0125ed68674ebd01Sen Jiang                               actual_data.size()));
5852ec4aab50fa8ed4afd9fa86a0125ed68674ebd01Sen Jiang
5862ec4aab50fa8ed4afd9fa86a0125ed68674ebd01Sen Jiang  EXPECT_EQ(actual_data, ApplyPayload(payload_data, source_path, false));
587738fdf37c15284b60dac703408b8de19eef9c6a3Jay Srinivasan}
58851dcf260754837962dd22db3b7babee181471e7dJay Srinivasan
5892d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen JiangTEST_F(DeltaPerformerTest, ExtentsToByteStringTest) {
590568734533c25a5783ea004aeb0da38244dcd3e5bAllie Wood  uint64_t test[] = {1, 1, 4, 2, 0, 1};
5910103c36caa2e38e034e0d22185736b9ccfb35c58Alex Vakulenko  static_assert(arraysize(test) % 2 == 0, "Array size uneven");
592738fdf37c15284b60dac703408b8de19eef9c6a3Jay Srinivasan  const uint64_t block_size = 4096;
593568734533c25a5783ea004aeb0da38244dcd3e5bAllie Wood  const uint64_t file_length = 4 * block_size - 13;
59451dcf260754837962dd22db3b7babee181471e7dJay Srinivasan
595738fdf37c15284b60dac703408b8de19eef9c6a3Jay Srinivasan  google::protobuf::RepeatedPtrField<Extent> extents;
596738fdf37c15284b60dac703408b8de19eef9c6a3Jay Srinivasan  for (size_t i = 0; i < arraysize(test); i += 2) {
5972d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang    *(extents.Add()) = ExtentForRange(test[i], test[i + 1]);
598738fdf37c15284b60dac703408b8de19eef9c6a3Jay Srinivasan  }
59951dcf260754837962dd22db3b7babee181471e7dJay Srinivasan
600568734533c25a5783ea004aeb0da38244dcd3e5bAllie Wood  string expected_output = "4096:4096,16384:8192,0:4083";
601738fdf37c15284b60dac703408b8de19eef9c6a3Jay Srinivasan  string actual_output;
602738fdf37c15284b60dac703408b8de19eef9c6a3Jay Srinivasan  EXPECT_TRUE(DeltaPerformer::ExtentsToBsdiffPositionsString(extents,
603738fdf37c15284b60dac703408b8de19eef9c6a3Jay Srinivasan                                                             block_size,
604738fdf37c15284b60dac703408b8de19eef9c6a3Jay Srinivasan                                                             file_length,
605738fdf37c15284b60dac703408b8de19eef9c6a3Jay Srinivasan                                                             &actual_output));
606738fdf37c15284b60dac703408b8de19eef9c6a3Jay Srinivasan  EXPECT_EQ(expected_output, actual_output);
60751dcf260754837962dd22db3b7babee181471e7dJay Srinivasan}
60868c10d1505c25e80bdf24aa074cfb1d7a05ca899Darin Petkov
6092d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen JiangTEST_F(DeltaPerformerTest, ValidateManifestFullGoodTest) {
610b8dd1d9e78c0ce14268aa38e472c0ee7a0e53bc5Don Garrett  // The Manifest we are validating.
611b8dd1d9e78c0ce14268aa38e472c0ee7a0e53bc5Don Garrett  DeltaArchiveManifest manifest;
612b8dd1d9e78c0ce14268aa38e472c0ee7a0e53bc5Don Garrett  manifest.mutable_new_kernel_info();
613b8dd1d9e78c0ce14268aa38e472c0ee7a0e53bc5Don Garrett  manifest.mutable_new_rootfs_info();
614cbf09896be9a627cd04dd54ef6875bed88daa3d8Alex Deymo  manifest.set_minor_version(kFullPayloadMinorVersion);
615b8dd1d9e78c0ce14268aa38e472c0ee7a0e53bc5Don Garrett
61664d9878470aa7b388e971862181daf6260851602Alex Deymo  RunManifestValidation(manifest,
61764d9878470aa7b388e971862181daf6260851602Alex Deymo                        kChromeOSMajorPayloadVersion,
61864d9878470aa7b388e971862181daf6260851602Alex Deymo                        InstallPayloadType::kFull,
6193e728feb92bfd5514bff55aa7dc455da80e18906Sen Jiang                        ErrorCode::kSuccess);
620b8dd1d9e78c0ce14268aa38e472c0ee7a0e53bc5Don Garrett}
621b8dd1d9e78c0ce14268aa38e472c0ee7a0e53bc5Don Garrett
6222d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen JiangTEST_F(DeltaPerformerTest, ValidateManifestDeltaGoodTest) {
623b8dd1d9e78c0ce14268aa38e472c0ee7a0e53bc5Don Garrett  // The Manifest we are validating.
624b8dd1d9e78c0ce14268aa38e472c0ee7a0e53bc5Don Garrett  DeltaArchiveManifest manifest;
625b8dd1d9e78c0ce14268aa38e472c0ee7a0e53bc5Don Garrett  manifest.mutable_old_kernel_info();
626b8dd1d9e78c0ce14268aa38e472c0ee7a0e53bc5Don Garrett  manifest.mutable_old_rootfs_info();
627b8dd1d9e78c0ce14268aa38e472c0ee7a0e53bc5Don Garrett  manifest.mutable_new_kernel_info();
628b8dd1d9e78c0ce14268aa38e472c0ee7a0e53bc5Don Garrett  manifest.mutable_new_rootfs_info();
629b8dd1d9e78c0ce14268aa38e472c0ee7a0e53bc5Don Garrett  manifest.set_minor_version(DeltaPerformer::kSupportedMinorPayloadVersion);
630b8dd1d9e78c0ce14268aa38e472c0ee7a0e53bc5Don Garrett
63164d9878470aa7b388e971862181daf6260851602Alex Deymo  RunManifestValidation(manifest,
63264d9878470aa7b388e971862181daf6260851602Alex Deymo                        kChromeOSMajorPayloadVersion,
63364d9878470aa7b388e971862181daf6260851602Alex Deymo                        InstallPayloadType::kDelta,
6343e728feb92bfd5514bff55aa7dc455da80e18906Sen Jiang                        ErrorCode::kSuccess);
635b8dd1d9e78c0ce14268aa38e472c0ee7a0e53bc5Don Garrett}
636b8dd1d9e78c0ce14268aa38e472c0ee7a0e53bc5Don Garrett
6372d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen JiangTEST_F(DeltaPerformerTest, ValidateManifestFullUnsetMinorVersion) {
638b8dd1d9e78c0ce14268aa38e472c0ee7a0e53bc5Don Garrett  // The Manifest we are validating.
639b8dd1d9e78c0ce14268aa38e472c0ee7a0e53bc5Don Garrett  DeltaArchiveManifest manifest;
640b8dd1d9e78c0ce14268aa38e472c0ee7a0e53bc5Don Garrett
64164d9878470aa7b388e971862181daf6260851602Alex Deymo  RunManifestValidation(manifest,
64264d9878470aa7b388e971862181daf6260851602Alex Deymo                        DeltaPerformer::kSupportedMajorPayloadVersion,
64364d9878470aa7b388e971862181daf6260851602Alex Deymo                        InstallPayloadType::kFull,
64464d9878470aa7b388e971862181daf6260851602Alex Deymo                        ErrorCode::kSuccess);
645b8dd1d9e78c0ce14268aa38e472c0ee7a0e53bc5Don Garrett}
646b8dd1d9e78c0ce14268aa38e472c0ee7a0e53bc5Don Garrett
6472d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen JiangTEST_F(DeltaPerformerTest, ValidateManifestDeltaUnsetMinorVersion) {
648b8dd1d9e78c0ce14268aa38e472c0ee7a0e53bc5Don Garrett  // The Manifest we are validating.
649b8dd1d9e78c0ce14268aa38e472c0ee7a0e53bc5Don Garrett  DeltaArchiveManifest manifest;
65064d9878470aa7b388e971862181daf6260851602Alex Deymo  // Add an empty old_rootfs_info() to trick the DeltaPerformer into think that
65164d9878470aa7b388e971862181daf6260851602Alex Deymo  // this is a delta payload manifest with a missing minor version.
65264d9878470aa7b388e971862181daf6260851602Alex Deymo  manifest.mutable_old_rootfs_info();
653b8dd1d9e78c0ce14268aa38e472c0ee7a0e53bc5Don Garrett
65464d9878470aa7b388e971862181daf6260851602Alex Deymo  RunManifestValidation(manifest,
65564d9878470aa7b388e971862181daf6260851602Alex Deymo                        DeltaPerformer::kSupportedMajorPayloadVersion,
65664d9878470aa7b388e971862181daf6260851602Alex Deymo                        InstallPayloadType::kDelta,
65764d9878470aa7b388e971862181daf6260851602Alex Deymo                        ErrorCode::kUnsupportedMinorPayloadVersion);
658b8dd1d9e78c0ce14268aa38e472c0ee7a0e53bc5Don Garrett}
659b8dd1d9e78c0ce14268aa38e472c0ee7a0e53bc5Don Garrett
6602d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen JiangTEST_F(DeltaPerformerTest, ValidateManifestFullOldKernelTest) {
661b8dd1d9e78c0ce14268aa38e472c0ee7a0e53bc5Don Garrett  // The Manifest we are validating.
662b8dd1d9e78c0ce14268aa38e472c0ee7a0e53bc5Don Garrett  DeltaArchiveManifest manifest;
663b8dd1d9e78c0ce14268aa38e472c0ee7a0e53bc5Don Garrett  manifest.mutable_old_kernel_info();
664b8dd1d9e78c0ce14268aa38e472c0ee7a0e53bc5Don Garrett  manifest.mutable_new_kernel_info();
665b8dd1d9e78c0ce14268aa38e472c0ee7a0e53bc5Don Garrett  manifest.mutable_new_rootfs_info();
666b8dd1d9e78c0ce14268aa38e472c0ee7a0e53bc5Don Garrett  manifest.set_minor_version(DeltaPerformer::kSupportedMinorPayloadVersion);
667b8dd1d9e78c0ce14268aa38e472c0ee7a0e53bc5Don Garrett
66864d9878470aa7b388e971862181daf6260851602Alex Deymo  RunManifestValidation(manifest,
66964d9878470aa7b388e971862181daf6260851602Alex Deymo                        kChromeOSMajorPayloadVersion,
67064d9878470aa7b388e971862181daf6260851602Alex Deymo                        InstallPayloadType::kFull,
6713e728feb92bfd5514bff55aa7dc455da80e18906Sen Jiang                        ErrorCode::kPayloadMismatchedType);
672b8dd1d9e78c0ce14268aa38e472c0ee7a0e53bc5Don Garrett}
673b8dd1d9e78c0ce14268aa38e472c0ee7a0e53bc5Don Garrett
6742d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen JiangTEST_F(DeltaPerformerTest, ValidateManifestFullOldRootfsTest) {
675b8dd1d9e78c0ce14268aa38e472c0ee7a0e53bc5Don Garrett  // The Manifest we are validating.
676b8dd1d9e78c0ce14268aa38e472c0ee7a0e53bc5Don Garrett  DeltaArchiveManifest manifest;
677b8dd1d9e78c0ce14268aa38e472c0ee7a0e53bc5Don Garrett  manifest.mutable_old_rootfs_info();
678b8dd1d9e78c0ce14268aa38e472c0ee7a0e53bc5Don Garrett  manifest.mutable_new_kernel_info();
679b8dd1d9e78c0ce14268aa38e472c0ee7a0e53bc5Don Garrett  manifest.mutable_new_rootfs_info();
680b8dd1d9e78c0ce14268aa38e472c0ee7a0e53bc5Don Garrett  manifest.set_minor_version(DeltaPerformer::kSupportedMinorPayloadVersion);
681b8dd1d9e78c0ce14268aa38e472c0ee7a0e53bc5Don Garrett
68264d9878470aa7b388e971862181daf6260851602Alex Deymo  RunManifestValidation(manifest,
68364d9878470aa7b388e971862181daf6260851602Alex Deymo                        kChromeOSMajorPayloadVersion,
68464d9878470aa7b388e971862181daf6260851602Alex Deymo                        InstallPayloadType::kFull,
6853e728feb92bfd5514bff55aa7dc455da80e18906Sen Jiang                        ErrorCode::kPayloadMismatchedType);
686b8dd1d9e78c0ce14268aa38e472c0ee7a0e53bc5Don Garrett}
687b8dd1d9e78c0ce14268aa38e472c0ee7a0e53bc5Don Garrett
688c8f6b7a7bc43d48ccd7a11f7aba91742c87f8b1cSen JiangTEST_F(DeltaPerformerTest, ValidateManifestFullPartitionUpdateTest) {
689c8f6b7a7bc43d48ccd7a11f7aba91742c87f8b1cSen Jiang  // The Manifest we are validating.
690c8f6b7a7bc43d48ccd7a11f7aba91742c87f8b1cSen Jiang  DeltaArchiveManifest manifest;
691c8f6b7a7bc43d48ccd7a11f7aba91742c87f8b1cSen Jiang  PartitionUpdate* partition = manifest.add_partitions();
692c8f6b7a7bc43d48ccd7a11f7aba91742c87f8b1cSen Jiang  partition->mutable_old_partition_info();
693c8f6b7a7bc43d48ccd7a11f7aba91742c87f8b1cSen Jiang  partition->mutable_new_partition_info();
694c8f6b7a7bc43d48ccd7a11f7aba91742c87f8b1cSen Jiang  manifest.set_minor_version(DeltaPerformer::kSupportedMinorPayloadVersion);
695c8f6b7a7bc43d48ccd7a11f7aba91742c87f8b1cSen Jiang
69664d9878470aa7b388e971862181daf6260851602Alex Deymo  RunManifestValidation(manifest,
69764d9878470aa7b388e971862181daf6260851602Alex Deymo                        kBrilloMajorPayloadVersion,
69864d9878470aa7b388e971862181daf6260851602Alex Deymo                        InstallPayloadType::kFull,
6993e728feb92bfd5514bff55aa7dc455da80e18906Sen Jiang                        ErrorCode::kPayloadMismatchedType);
700c8f6b7a7bc43d48ccd7a11f7aba91742c87f8b1cSen Jiang}
701c8f6b7a7bc43d48ccd7a11f7aba91742c87f8b1cSen Jiang
7022d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen JiangTEST_F(DeltaPerformerTest, ValidateManifestBadMinorVersion) {
703b8dd1d9e78c0ce14268aa38e472c0ee7a0e53bc5Don Garrett  // The Manifest we are validating.
704b8dd1d9e78c0ce14268aa38e472c0ee7a0e53bc5Don Garrett  DeltaArchiveManifest manifest;
705b8dd1d9e78c0ce14268aa38e472c0ee7a0e53bc5Don Garrett
706b8dd1d9e78c0ce14268aa38e472c0ee7a0e53bc5Don Garrett  // Generate a bad version number.
707b8dd1d9e78c0ce14268aa38e472c0ee7a0e53bc5Don Garrett  manifest.set_minor_version(DeltaPerformer::kSupportedMinorPayloadVersion +
708b8dd1d9e78c0ce14268aa38e472c0ee7a0e53bc5Don Garrett                             10000);
70964d9878470aa7b388e971862181daf6260851602Alex Deymo  // Mark the manifest as a delta payload by setting old_rootfs_info.
71064d9878470aa7b388e971862181daf6260851602Alex Deymo  manifest.mutable_old_rootfs_info();
711b8dd1d9e78c0ce14268aa38e472c0ee7a0e53bc5Don Garrett
71264d9878470aa7b388e971862181daf6260851602Alex Deymo  RunManifestValidation(manifest,
71364d9878470aa7b388e971862181daf6260851602Alex Deymo                        DeltaPerformer::kSupportedMajorPayloadVersion,
71464d9878470aa7b388e971862181daf6260851602Alex Deymo                        InstallPayloadType::kDelta,
71564d9878470aa7b388e971862181daf6260851602Alex Deymo                        ErrorCode::kUnsupportedMinorPayloadVersion);
716b8dd1d9e78c0ce14268aa38e472c0ee7a0e53bc5Don Garrett}
717b8dd1d9e78c0ce14268aa38e472c0ee7a0e53bc5Don Garrett
718b8060e435f0edb8efef4891a99fa18f642e01aa2Sen JiangTEST_F(DeltaPerformerTest, BrilloMetadataSignatureSizeTest) {
719b8060e435f0edb8efef4891a99fa18f642e01aa2Sen Jiang  EXPECT_TRUE(performer_.Write(kDeltaMagic, sizeof(kDeltaMagic)));
720b8060e435f0edb8efef4891a99fa18f642e01aa2Sen Jiang
721b8060e435f0edb8efef4891a99fa18f642e01aa2Sen Jiang  uint64_t major_version = htobe64(kBrilloMajorPayloadVersion);
722b8060e435f0edb8efef4891a99fa18f642e01aa2Sen Jiang  EXPECT_TRUE(performer_.Write(&major_version, 8));
723b8060e435f0edb8efef4891a99fa18f642e01aa2Sen Jiang
724b8060e435f0edb8efef4891a99fa18f642e01aa2Sen Jiang  uint64_t manifest_size = rand() % 256;
725b8060e435f0edb8efef4891a99fa18f642e01aa2Sen Jiang  uint64_t manifest_size_be = htobe64(manifest_size);
726b8060e435f0edb8efef4891a99fa18f642e01aa2Sen Jiang  EXPECT_TRUE(performer_.Write(&manifest_size_be, 8));
727b8060e435f0edb8efef4891a99fa18f642e01aa2Sen Jiang
728b8060e435f0edb8efef4891a99fa18f642e01aa2Sen Jiang  uint32_t metadata_signature_size = rand() % 256;
729b8060e435f0edb8efef4891a99fa18f642e01aa2Sen Jiang  uint32_t metadata_signature_size_be = htobe32(metadata_signature_size);
730b8060e435f0edb8efef4891a99fa18f642e01aa2Sen Jiang  EXPECT_TRUE(performer_.Write(&metadata_signature_size_be, 4));
731b8060e435f0edb8efef4891a99fa18f642e01aa2Sen Jiang
732b8060e435f0edb8efef4891a99fa18f642e01aa2Sen Jiang  EXPECT_LT(performer_.Close(), 0);
733b8060e435f0edb8efef4891a99fa18f642e01aa2Sen Jiang
734b8060e435f0edb8efef4891a99fa18f642e01aa2Sen Jiang  EXPECT_TRUE(performer_.IsHeaderParsed());
735b8060e435f0edb8efef4891a99fa18f642e01aa2Sen Jiang  EXPECT_EQ(kBrilloMajorPayloadVersion, performer_.GetMajorVersion());
736b8060e435f0edb8efef4891a99fa18f642e01aa2Sen Jiang  uint64_t manifest_offset;
737b8060e435f0edb8efef4891a99fa18f642e01aa2Sen Jiang  EXPECT_TRUE(performer_.GetManifestOffset(&manifest_offset));
73880f70ff45f8ea9a679c0c3ed0dc143dd2fe2b63eAlex Deymo  EXPECT_EQ(24U, manifest_offset);  // 4 + 8 + 8 + 4
73976bfa74e52aea188aaf17aec186b0ef4269d39b3Sen Jiang  EXPECT_EQ(manifest_offset + manifest_size, performer_.GetMetadataSize());
74076bfa74e52aea188aaf17aec186b0ef4269d39b3Sen Jiang  EXPECT_EQ(metadata_signature_size, performer_.metadata_signature_size_);
74176bfa74e52aea188aaf17aec186b0ef4269d39b3Sen Jiang}
74276bfa74e52aea188aaf17aec186b0ef4269d39b3Sen Jiang
74376bfa74e52aea188aaf17aec186b0ef4269d39b3Sen JiangTEST_F(DeltaPerformerTest, BrilloVerifyMetadataSignatureTest) {
74476bfa74e52aea188aaf17aec186b0ef4269d39b3Sen Jiang  brillo::Blob payload_data = GeneratePayload({}, {}, true,
74576bfa74e52aea188aaf17aec186b0ef4269d39b3Sen Jiang                                              kBrilloMajorPayloadVersion,
74676bfa74e52aea188aaf17aec186b0ef4269d39b3Sen Jiang                                              kSourceMinorPayloadVersion);
74776bfa74e52aea188aaf17aec186b0ef4269d39b3Sen Jiang  install_plan_.hash_checks_mandatory = true;
74876bfa74e52aea188aaf17aec186b0ef4269d39b3Sen Jiang  // Just set these value so that we can use ValidateMetadataSignature directly.
74976bfa74e52aea188aaf17aec186b0ef4269d39b3Sen Jiang  performer_.major_payload_version_ = kBrilloMajorPayloadVersion;
75076bfa74e52aea188aaf17aec186b0ef4269d39b3Sen Jiang  performer_.metadata_size_ = install_plan_.metadata_size;
75176bfa74e52aea188aaf17aec186b0ef4269d39b3Sen Jiang  uint64_t signature_length;
752260f03bc4d3a3de436e056c686c814444358823aSen Jiang  EXPECT_TRUE(PayloadSigner::SignatureBlobLength(
753260f03bc4d3a3de436e056c686c814444358823aSen Jiang      {GetBuildArtifactsPath(kUnittestPrivateKeyPath)}, &signature_length));
75476bfa74e52aea188aaf17aec186b0ef4269d39b3Sen Jiang  performer_.metadata_signature_size_ = signature_length;
755260f03bc4d3a3de436e056c686c814444358823aSen Jiang  performer_.set_public_key_path(GetBuildArtifactsPath(kUnittestPublicKeyPath));
75676bfa74e52aea188aaf17aec186b0ef4269d39b3Sen Jiang  EXPECT_EQ(ErrorCode::kSuccess,
75776bfa74e52aea188aaf17aec186b0ef4269d39b3Sen Jiang            performer_.ValidateMetadataSignature(payload_data));
758b8060e435f0edb8efef4891a99fa18f642e01aa2Sen Jiang}
759b8060e435f0edb8efef4891a99fa18f642e01aa2Sen Jiang
7602d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen JiangTEST_F(DeltaPerformerTest, BadDeltaMagicTest) {
7612d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang  EXPECT_TRUE(performer_.Write("junk", 4));
7622d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang  EXPECT_FALSE(performer_.Write("morejunk", 8));
7632d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang  EXPECT_LT(performer_.Close(), 0);
764934bb411c431ed901ece20b815073adeb0846902Darin Petkov}
765934bb411c431ed901ece20b815073adeb0846902Darin Petkov
7662d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen JiangTEST_F(DeltaPerformerTest, MissingMandatoryMetadataSizeTest) {
767738fdf37c15284b60dac703408b8de19eef9c6a3Jay Srinivasan  DoMetadataSizeTest(0, 75456, true);
76851dcf260754837962dd22db3b7babee181471e7dJay Srinivasan}
76951dcf260754837962dd22db3b7babee181471e7dJay Srinivasan
7702d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen JiangTEST_F(DeltaPerformerTest, MissingNonMandatoryMetadataSizeTest) {
771738fdf37c15284b60dac703408b8de19eef9c6a3Jay Srinivasan  DoMetadataSizeTest(0, 123456, false);
772738fdf37c15284b60dac703408b8de19eef9c6a3Jay Srinivasan}
773738fdf37c15284b60dac703408b8de19eef9c6a3Jay Srinivasan
7742d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen JiangTEST_F(DeltaPerformerTest, InvalidMandatoryMetadataSizeTest) {
775738fdf37c15284b60dac703408b8de19eef9c6a3Jay Srinivasan  DoMetadataSizeTest(13000, 140000, true);
776738fdf37c15284b60dac703408b8de19eef9c6a3Jay Srinivasan}
777738fdf37c15284b60dac703408b8de19eef9c6a3Jay Srinivasan
7782d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen JiangTEST_F(DeltaPerformerTest, InvalidNonMandatoryMetadataSizeTest) {
779738fdf37c15284b60dac703408b8de19eef9c6a3Jay Srinivasan  DoMetadataSizeTest(40000, 50000, false);
780738fdf37c15284b60dac703408b8de19eef9c6a3Jay Srinivasan}
781738fdf37c15284b60dac703408b8de19eef9c6a3Jay Srinivasan
7822d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen JiangTEST_F(DeltaPerformerTest, ValidMandatoryMetadataSizeTest) {
783738fdf37c15284b60dac703408b8de19eef9c6a3Jay Srinivasan  DoMetadataSizeTest(85376, 85376, true);
784738fdf37c15284b60dac703408b8de19eef9c6a3Jay Srinivasan}
785738fdf37c15284b60dac703408b8de19eef9c6a3Jay Srinivasan
7862d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen JiangTEST_F(DeltaPerformerTest, MandatoryEmptyMetadataSignatureTest) {
787d78b3892232ae46cb0b8a7a96dea59b2df46a83fSen Jiang  DoMetadataSignatureTest(kEmptyMetadataSignature, true, true);
788738fdf37c15284b60dac703408b8de19eef9c6a3Jay Srinivasan}
789738fdf37c15284b60dac703408b8de19eef9c6a3Jay Srinivasan
7902d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen JiangTEST_F(DeltaPerformerTest, NonMandatoryEmptyMetadataSignatureTest) {
791d78b3892232ae46cb0b8a7a96dea59b2df46a83fSen Jiang  DoMetadataSignatureTest(kEmptyMetadataSignature, true, false);
792738fdf37c15284b60dac703408b8de19eef9c6a3Jay Srinivasan}
793738fdf37c15284b60dac703408b8de19eef9c6a3Jay Srinivasan
7942d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen JiangTEST_F(DeltaPerformerTest, MandatoryInvalidMetadataSignatureTest) {
795d78b3892232ae46cb0b8a7a96dea59b2df46a83fSen Jiang  DoMetadataSignatureTest(kInvalidMetadataSignature, true, true);
796738fdf37c15284b60dac703408b8de19eef9c6a3Jay Srinivasan}
797738fdf37c15284b60dac703408b8de19eef9c6a3Jay Srinivasan
7982d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen JiangTEST_F(DeltaPerformerTest, NonMandatoryInvalidMetadataSignatureTest) {
799d78b3892232ae46cb0b8a7a96dea59b2df46a83fSen Jiang  DoMetadataSignatureTest(kInvalidMetadataSignature, true, false);
800738fdf37c15284b60dac703408b8de19eef9c6a3Jay Srinivasan}
801738fdf37c15284b60dac703408b8de19eef9c6a3Jay Srinivasan
8022d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen JiangTEST_F(DeltaPerformerTest, MandatoryValidMetadataSignature1Test) {
803d78b3892232ae46cb0b8a7a96dea59b2df46a83fSen Jiang  DoMetadataSignatureTest(kValidMetadataSignature, false, true);
804738fdf37c15284b60dac703408b8de19eef9c6a3Jay Srinivasan}
805738fdf37c15284b60dac703408b8de19eef9c6a3Jay Srinivasan
8062d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen JiangTEST_F(DeltaPerformerTest, MandatoryValidMetadataSignature2Test) {
807d78b3892232ae46cb0b8a7a96dea59b2df46a83fSen Jiang  DoMetadataSignatureTest(kValidMetadataSignature, true, true);
808738fdf37c15284b60dac703408b8de19eef9c6a3Jay Srinivasan}
809738fdf37c15284b60dac703408b8de19eef9c6a3Jay Srinivasan
8102d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen JiangTEST_F(DeltaPerformerTest, NonMandatoryValidMetadataSignatureTest) {
811d78b3892232ae46cb0b8a7a96dea59b2df46a83fSen Jiang  DoMetadataSignatureTest(kValidMetadataSignature, true, false);
812738fdf37c15284b60dac703408b8de19eef9c6a3Jay Srinivasan}
813738fdf37c15284b60dac703408b8de19eef9c6a3Jay Srinivasan
8142d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen JiangTEST_F(DeltaPerformerTest, UsePublicKeyFromResponse) {
815e7f8917f378773fbfee0b2d21f1cb6b3ba8bdcabDavid Zeuthen  base::FilePath key_path;
816e7f8917f378773fbfee0b2d21f1cb6b3ba8bdcabDavid Zeuthen
817e7f8917f378773fbfee0b2d21f1cb6b3ba8bdcabDavid Zeuthen  // The result of the GetPublicKeyResponse() method is based on three things
818e7f8917f378773fbfee0b2d21f1cb6b3ba8bdcabDavid Zeuthen  //
819e7f8917f378773fbfee0b2d21f1cb6b3ba8bdcabDavid Zeuthen  //  1. Whether it's an official build; and
820e7f8917f378773fbfee0b2d21f1cb6b3ba8bdcabDavid Zeuthen  //  2. Whether the Public RSA key to be used is in the root filesystem; and
821072359ca138504065e1e0c1189eb38c09576d324Alex Vakulenko  //  3. Whether the response has a public key
822e7f8917f378773fbfee0b2d21f1cb6b3ba8bdcabDavid Zeuthen  //
823e7f8917f378773fbfee0b2d21f1cb6b3ba8bdcabDavid Zeuthen  // We test all eight combinations to ensure that we only use the
824e7f8917f378773fbfee0b2d21f1cb6b3ba8bdcabDavid Zeuthen  // public key in the response if
825e7f8917f378773fbfee0b2d21f1cb6b3ba8bdcabDavid Zeuthen  //
826e7f8917f378773fbfee0b2d21f1cb6b3ba8bdcabDavid Zeuthen  //  a. it's not an official build; and
827e7f8917f378773fbfee0b2d21f1cb6b3ba8bdcabDavid Zeuthen  //  b. there is no key in the root filesystem.
828e7f8917f378773fbfee0b2d21f1cb6b3ba8bdcabDavid Zeuthen
829371615b025bdd8106faf65c1ba7439a1236f21bcSen Jiang  base::ScopedTempDir temp_dir;
830371615b025bdd8106faf65c1ba7439a1236f21bcSen Jiang  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
831371615b025bdd8106faf65c1ba7439a1236f21bcSen Jiang  string non_existing_file = temp_dir.path().Append("non-existing").value();
832371615b025bdd8106faf65c1ba7439a1236f21bcSen Jiang  string existing_file = temp_dir.path().Append("existing").value();
83375039d7397f03dff77bdf4e26398049ff88edc4cAlex Vakulenko  EXPECT_EQ(0, System(base::StringPrintf("touch %s", existing_file.c_str())));
834e7f8917f378773fbfee0b2d21f1cb6b3ba8bdcabDavid Zeuthen
835e7f8917f378773fbfee0b2d21f1cb6b3ba8bdcabDavid Zeuthen  // Non-official build, non-existing public-key, key in response -> true
836542c19bf271011913a9f352f58e140224c936736Alex Deymo  fake_hardware_.SetIsOfficialBuild(false);
8372d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang  performer_.public_key_path_ = non_existing_file;
8382d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang  install_plan_.public_key_rsa = "VGVzdAo="; // result of 'echo "Test" | base64'
8392d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang  EXPECT_TRUE(performer_.GetPublicKeyFromResponse(&key_path));
840e7f8917f378773fbfee0b2d21f1cb6b3ba8bdcabDavid Zeuthen  EXPECT_FALSE(key_path.empty());
841e7f8917f378773fbfee0b2d21f1cb6b3ba8bdcabDavid Zeuthen  EXPECT_EQ(unlink(key_path.value().c_str()), 0);
842e7f8917f378773fbfee0b2d21f1cb6b3ba8bdcabDavid Zeuthen  // Same with official build -> false
843542c19bf271011913a9f352f58e140224c936736Alex Deymo  fake_hardware_.SetIsOfficialBuild(true);
8442d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang  EXPECT_FALSE(performer_.GetPublicKeyFromResponse(&key_path));
845e7f8917f378773fbfee0b2d21f1cb6b3ba8bdcabDavid Zeuthen
846e7f8917f378773fbfee0b2d21f1cb6b3ba8bdcabDavid Zeuthen  // Non-official build, existing public-key, key in response -> false
847542c19bf271011913a9f352f58e140224c936736Alex Deymo  fake_hardware_.SetIsOfficialBuild(false);
8482d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang  performer_.public_key_path_ = existing_file;
8492d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang  install_plan_.public_key_rsa = "VGVzdAo="; // result of 'echo "Test" | base64'
8502d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang  EXPECT_FALSE(performer_.GetPublicKeyFromResponse(&key_path));
851e7f8917f378773fbfee0b2d21f1cb6b3ba8bdcabDavid Zeuthen  // Same with official build -> false
852542c19bf271011913a9f352f58e140224c936736Alex Deymo  fake_hardware_.SetIsOfficialBuild(true);
8532d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang  EXPECT_FALSE(performer_.GetPublicKeyFromResponse(&key_path));
854e7f8917f378773fbfee0b2d21f1cb6b3ba8bdcabDavid Zeuthen
855e7f8917f378773fbfee0b2d21f1cb6b3ba8bdcabDavid Zeuthen  // Non-official build, non-existing public-key, no key in response -> false
856542c19bf271011913a9f352f58e140224c936736Alex Deymo  fake_hardware_.SetIsOfficialBuild(false);
8572d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang  performer_.public_key_path_ = non_existing_file;
8582d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang  install_plan_.public_key_rsa = "";
8592d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang  EXPECT_FALSE(performer_.GetPublicKeyFromResponse(&key_path));
860e7f8917f378773fbfee0b2d21f1cb6b3ba8bdcabDavid Zeuthen  // Same with official build -> false
861542c19bf271011913a9f352f58e140224c936736Alex Deymo  fake_hardware_.SetIsOfficialBuild(true);
8622d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang  EXPECT_FALSE(performer_.GetPublicKeyFromResponse(&key_path));
863e7f8917f378773fbfee0b2d21f1cb6b3ba8bdcabDavid Zeuthen
864e7f8917f378773fbfee0b2d21f1cb6b3ba8bdcabDavid Zeuthen  // Non-official build, existing public-key, no key in response -> false
865542c19bf271011913a9f352f58e140224c936736Alex Deymo  fake_hardware_.SetIsOfficialBuild(false);
8662d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang  performer_.public_key_path_ = existing_file;
8672d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang  install_plan_.public_key_rsa = "";
8682d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang  EXPECT_FALSE(performer_.GetPublicKeyFromResponse(&key_path));
869e7f8917f378773fbfee0b2d21f1cb6b3ba8bdcabDavid Zeuthen  // Same with official build -> false
870542c19bf271011913a9f352f58e140224c936736Alex Deymo  fake_hardware_.SetIsOfficialBuild(true);
8712d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang  EXPECT_FALSE(performer_.GetPublicKeyFromResponse(&key_path));
872e7f8917f378773fbfee0b2d21f1cb6b3ba8bdcabDavid Zeuthen
873e7f8917f378773fbfee0b2d21f1cb6b3ba8bdcabDavid Zeuthen  // Non-official build, non-existing public-key, key in response
874e7f8917f378773fbfee0b2d21f1cb6b3ba8bdcabDavid Zeuthen  // but invalid base64 -> false
875542c19bf271011913a9f352f58e140224c936736Alex Deymo  fake_hardware_.SetIsOfficialBuild(false);
8762d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang  performer_.public_key_path_ = non_existing_file;
8772d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang  install_plan_.public_key_rsa = "not-valid-base64";
8782d528b4cd15682a7c84a415ae3cb15b7616d2b5dSen Jiang  EXPECT_FALSE(performer_.GetPublicKeyFromResponse(&key_path));
879e7f8917f378773fbfee0b2d21f1cb6b3ba8bdcabDavid Zeuthen}
880e7f8917f378773fbfee0b2d21f1cb6b3ba8bdcabDavid Zeuthen
881cbf09896be9a627cd04dd54ef6875bed88daa3d8Alex DeymoTEST_F(DeltaPerformerTest, ConfVersionsMatch) {
882cbf09896be9a627cd04dd54ef6875bed88daa3d8Alex Deymo  // Test that the versions in update_engine.conf that is installed to the
883cbf09896be9a627cd04dd54ef6875bed88daa3d8Alex Deymo  // image match the supported delta versions in the update engine.
88478750a450ce84b2d335134402d041aa8773ab8efAllie Wood  uint32_t minor_version;
8853f39d5cc753905874d8d93bef94f857b8808f19eAlex Vakulenko  brillo::KeyValueStore store;
886ee63c6ecf2487eaaeb80c37a70e0f7248d026ca8Sen Jiang  EXPECT_TRUE(store.Load(GetBuildArtifactsPath().Append("update_engine.conf")));
887b42b98db059a12c44110588fc0b3d5f82d32a2f8Alex Deymo  EXPECT_TRUE(utils::GetMinorVersion(store, &minor_version));
888b42b98db059a12c44110588fc0b3d5f82d32a2f8Alex Deymo  EXPECT_EQ(DeltaPerformer::kSupportedMinorPayloadVersion, minor_version);
889cbf09896be9a627cd04dd54ef6875bed88daa3d8Alex Deymo
890cbf09896be9a627cd04dd54ef6875bed88daa3d8Alex Deymo  string major_version_str;
891cbf09896be9a627cd04dd54ef6875bed88daa3d8Alex Deymo  uint64_t major_version;
892cbf09896be9a627cd04dd54ef6875bed88daa3d8Alex Deymo  EXPECT_TRUE(store.GetString("PAYLOAD_MAJOR_VERSION", &major_version_str));
893cbf09896be9a627cd04dd54ef6875bed88daa3d8Alex Deymo  EXPECT_TRUE(base::StringToUint64(major_version_str, &major_version));
894cbf09896be9a627cd04dd54ef6875bed88daa3d8Alex Deymo  EXPECT_EQ(DeltaPerformer::kSupportedMajorPayloadVersion, major_version);
89578750a450ce84b2d335134402d041aa8773ab8efAllie Wood}
89678750a450ce84b2d335134402d041aa8773ab8efAllie Wood
897e0d04282910d423ddc950dd38224c001efc41d42Sen Jiang// Test that we recognize our own zlib compressor implementation as supported.
898e0d04282910d423ddc950dd38224c001efc41d42Sen Jiang// All other equivalent implementations should be added to
899e0d04282910d423ddc950dd38224c001efc41d42Sen Jiang// kCompatibleZlibFingerprint.
900e0d04282910d423ddc950dd38224c001efc41d42Sen JiangTEST_F(DeltaPerformerTest, ZlibFingerprintMatch) {
901e0d04282910d423ddc950dd38224c001efc41d42Sen Jiang  string fingerprint;
902a6dc0fe787733d489f403b5162d99a78e17517f4Alex Deymo#ifdef __ANDROID__
903a6dc0fe787733d489f403b5162d99a78e17517f4Alex Deymo  const std::string kZlibFingerprintPath =
904a6dc0fe787733d489f403b5162d99a78e17517f4Alex Deymo      test_utils::GetBuildArtifactsPath("zlib_fingerprint");
905a6dc0fe787733d489f403b5162d99a78e17517f4Alex Deymo#else
906a6dc0fe787733d489f403b5162d99a78e17517f4Alex Deymo  const std::string kZlibFingerprintPath = "/etc/zlib_fingerprint";
907a6dc0fe787733d489f403b5162d99a78e17517f4Alex Deymo#endif  // __ANDROID__
908e0d04282910d423ddc950dd38224c001efc41d42Sen Jiang  EXPECT_TRUE(base::ReadFileToString(base::FilePath(kZlibFingerprintPath),
909e0d04282910d423ddc950dd38224c001efc41d42Sen Jiang                                     &fingerprint));
910e0d04282910d423ddc950dd38224c001efc41d42Sen Jiang  EXPECT_TRUE(utils::IsZlibCompatible(fingerprint));
911e0d04282910d423ddc950dd38224c001efc41d42Sen Jiang}
912e0d04282910d423ddc950dd38224c001efc41d42Sen Jiang
91309e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyes}  // namespace chromeos_update_engine
914