blob: cc3d6e2650f5dbf94e76c1eebe2ffd527fb8d755 [file] [log] [blame]
Alex Deymoaea4c1c2015-08-19 20:24:43 -07001//
2// Copyright (C) 2012 The Android Open Source Project
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8// http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15//
Andrew de los Reyes09e56d62010-04-23 13:45:53 -070016
Alex Deymo8427b4a2014-11-05 14:00:32 -080017#include "update_engine/delta_performer.h"
18
Andrew de los Reyes09e56d62010-04-23 13:45:53 -070019#include <inttypes.h>
20
Andrew de los Reyes09e56d62010-04-23 13:45:53 -070021#include <string>
22#include <vector>
23
Allie Wood78750a42015-02-11 15:42:11 -080024#include <base/files/file_path.h>
Ben Chan06c76a42014-09-05 08:21:06 -070025#include <base/files/file_util.h>
Alex Vakulenko75039d72014-03-25 12:36:28 -070026#include <base/strings/stringprintf.h>
Alex Deymocbf09892015-09-11 16:13:16 -070027#include <base/strings/string_number_conversions.h>
Alex Deymof1cbe172015-03-05 15:58:37 -080028#include <base/strings/string_util.h>
Andrew de los Reyes09e56d62010-04-23 13:45:53 -070029#include <google/protobuf/repeated_field.h>
30#include <gtest/gtest.h>
31
Sen Jiang2d528b42015-09-25 11:18:12 -070032#include "update_engine/bzip.h"
Jay Srinivasand29695d2013-04-08 15:08:05 -070033#include "update_engine/constants.h"
David Zeuthene7f89172013-10-31 10:21:04 -070034#include "update_engine/fake_hardware.h"
Sen Jiang2d528b42015-09-25 11:18:12 -070035#include "update_engine/fake_prefs.h"
Gilad Arnold5bb4c902014-04-10 12:32:13 -070036#include "update_engine/fake_system_state.h"
Alex Deymo161c4a12014-05-16 15:56:21 -070037#include "update_engine/payload_constants.h"
Sen Jiang2d528b42015-09-25 11:18:12 -070038#include "update_engine/payload_generator/extent_ranges.h"
Sen Jiangd78b3892015-09-25 15:19:31 -070039#include "update_engine/payload_generator/payload_file.h"
Alex Deymo923d8fa2014-07-15 17:58:51 -070040#include "update_engine/payload_generator/payload_signer.h"
Andrew de los Reyes09e56d62010-04-23 13:45:53 -070041#include "update_engine/test_utils.h"
42#include "update_engine/update_metadata.pb.h"
43#include "update_engine/utils.h"
44
45namespace chromeos_update_engine {
46
Andrew de los Reyes09e56d62010-04-23 13:45:53 -070047using std::string;
48using std::vector;
Darin Petkov73058b42010-10-06 16:32:19 -070049using testing::Return;
Alex Deymo161c4a12014-05-16 15:56:21 -070050using testing::_;
Alex Deymo10875d92014-11-10 21:52:57 -080051using test_utils::kRandomString;
Alex Deymo10875d92014-11-10 21:52:57 -080052using test_utils::System;
Andrew de los Reyes09e56d62010-04-23 13:45:53 -070053
Andrew de los Reyes932bc4c2010-08-23 18:14:09 -070054extern const char* kUnittestPrivateKeyPath;
Darin Petkovd7061ab2010-10-06 14:37:09 -070055extern const char* kUnittestPublicKeyPath;
Andrew de los Reyes932bc4c2010-08-23 18:14:09 -070056
Gilad Arnoldd1c4d2d2014-06-05 14:07:53 -070057static const char* kBogusMetadataSignature1 =
58 "awSFIUdUZz2VWFiR+ku0Pj00V7bPQPQFYQSXjEXr3vaw3TE4xHV5CraY3/YrZpBv"
59 "J5z4dSBskoeuaO1TNC/S6E05t+yt36tE4Fh79tMnJ/z9fogBDXWgXLEUyG78IEQr"
60 "YH6/eBsQGT2RJtBgXIXbZ9W+5G9KmGDoPOoiaeNsDuqHiBc/58OFsrxskH8E6vMS"
61 "BmMGGk82mvgzic7ApcoURbCGey1b3Mwne/hPZ/bb9CIyky8Og9IfFMdL2uAweOIR"
62 "fjoTeLYZpt+WN65Vu7jJ0cQN8e1y+2yka5112wpRf/LLtPgiAjEZnsoYpLUd7CoV"
63 "pLRtClp97kN2+tXGNBQqkA==";
Jay Srinivasan738fdf32012-12-07 17:40:54 -080064
Andrew de los Reyes27f7d372010-10-07 11:26:07 -070065namespace {
Jay Srinivasan738fdf32012-12-07 17:40:54 -080066// Different options that determine what we should fill into the
67// install_plan.metadata_signature to simulate the contents received in the
68// Omaha response.
69enum MetadataSignatureTest {
70 kEmptyMetadataSignature,
71 kInvalidMetadataSignature,
72 kValidMetadataSignature,
73};
74
Alex Vakulenkod2779df2014-06-16 13:19:00 -070075} // namespace
Jay Srinivasan738fdf32012-12-07 17:40:54 -080076
Allie Woodfdf00512015-03-02 13:34:55 -080077class DeltaPerformerTest : public ::testing::Test {
Sen Jiang2d528b42015-09-25 11:18:12 -070078 protected:
Allie Woodfdf00512015-03-02 13:34:55 -080079
Sen Jiang2d528b42015-09-25 11:18:12 -070080 // Test helper placed where it can easily be friended from DeltaPerformer.
81 void RunManifestValidation(const DeltaArchiveManifest& manifest,
82 bool full_payload,
83 ErrorCode expected) {
Allie Woodfdf00512015-03-02 13:34:55 -080084 // The install plan is for Full or Delta.
Sen Jiang2d528b42015-09-25 11:18:12 -070085 install_plan_.is_full_update = full_payload;
Allie Woodfdf00512015-03-02 13:34:55 -080086
87 // The Manifest we are validating.
Sen Jiang2d528b42015-09-25 11:18:12 -070088 performer_.manifest_.CopyFrom(manifest);
Allie Woodfdf00512015-03-02 13:34:55 -080089
Sen Jiang2d528b42015-09-25 11:18:12 -070090 EXPECT_EQ(expected, performer_.ValidateManifest());
Allie Woodfdf00512015-03-02 13:34:55 -080091 }
92
Sen Jiang2d528b42015-09-25 11:18:12 -070093 chromeos::Blob GeneratePayload(const chromeos::Blob& blob_data,
94 const vector<AnnotatedOperation>& aops,
95 bool sign_payload,
96 int32_t minor_version) {
Sen Jiangd78b3892015-09-25 15:19:31 -070097 string blob_path;
98 EXPECT_TRUE(utils::MakeTempFile("Blob-XXXXXX", &blob_path, nullptr));
99 ScopedPathUnlinker blob_unlinker(blob_path);
100 EXPECT_TRUE(utils::WriteFile(blob_path.c_str(),
101 blob_data.data(),
102 blob_data.size()));
103
104 PayloadGenerationConfig config;
105 config.major_version = kChromeOSMajorPayloadVersion;
106 config.minor_version = minor_version;
107 config.target.rootfs.path = blob_path;
108 config.target.rootfs.size = blob_data.size();
109 config.target.kernel.path = blob_path;
110 config.target.kernel.size = blob_data.size();
111
112 PayloadFile payload;
113 EXPECT_TRUE(payload.Init(config));
114
115 payload.AddPartition(config.source.rootfs, config.target.rootfs, aops);
116
117 string payload_path;
118 EXPECT_TRUE(utils::MakeTempFile("Payload-XXXXXX", &payload_path, nullptr));
119 ScopedPathUnlinker payload_unlinker(payload_path);
120 EXPECT_TRUE(payload.WritePayload(payload_path, blob_path,
121 sign_payload ? kUnittestPrivateKeyPath : "",
Sen Jiang2d528b42015-09-25 11:18:12 -0700122 &install_plan_.metadata_size));
Sen Jiangd78b3892015-09-25 15:19:31 -0700123
124 chromeos::Blob payload_data;
125 EXPECT_TRUE(utils::ReadFile(payload_path, &payload_data));
126 return payload_data;
127 }
Allie Woodfdf00512015-03-02 13:34:55 -0800128
Sen Jiang2d528b42015-09-25 11:18:12 -0700129 // Apply |payload_data| on partition specified in |source_path|.
130 chromeos::Blob ApplyPayload(const chromeos::Blob& payload_data,
131 const string& source_path) {
132 install_plan_.source_path = source_path;
133 install_plan_.kernel_source_path = "/dev/null";
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800134
Sen Jiang2d528b42015-09-25 11:18:12 -0700135 string new_part;
136 EXPECT_TRUE(utils::MakeTempFile("Partition-XXXXXX", &new_part, nullptr));
137 ScopedPathUnlinker partition_unlinker(new_part);
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800138
Sen Jiang2d528b42015-09-25 11:18:12 -0700139 EXPECT_EQ(0, performer_.Open(new_part.c_str(), 0, 0));
140 EXPECT_TRUE(performer_.Write(payload_data.data(), payload_data.size()));
141 EXPECT_EQ(0, performer_.Close());
142
143 chromeos::Blob partition_data;
144 EXPECT_TRUE(utils::ReadFile(new_part, &partition_data));
145 return partition_data;
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800146 }
147
Sen Jiang2d528b42015-09-25 11:18:12 -0700148 // Calls delta performer's Write method by pretending to pass in bytes from a
149 // delta file whose metadata size is actual_metadata_size and tests if all
150 // checks are correctly performed if the install plan contains
151 // expected_metadata_size and that the result of the parsing are as per
152 // hash_checks_mandatory flag.
153 void DoMetadataSizeTest(uint64_t expected_metadata_size,
154 uint64_t actual_metadata_size,
155 bool hash_checks_mandatory) {
156 install_plan_.hash_checks_mandatory = hash_checks_mandatory;
157 EXPECT_EQ(0, performer_.Open("/dev/null", 0, 0));
158 EXPECT_TRUE(performer_.OpenKernel("/dev/null"));
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800159
Sen Jiang2d528b42015-09-25 11:18:12 -0700160 // Set a valid magic string and version number 1.
161 EXPECT_TRUE(performer_.Write("CrAU", 4));
162 uint64_t version = htobe64(kChromeOSMajorPayloadVersion);
163 EXPECT_TRUE(performer_.Write(&version, 8));
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800164
Sen Jiang2d528b42015-09-25 11:18:12 -0700165 install_plan_.metadata_size = expected_metadata_size;
166 ErrorCode error_code;
167 // When filling in size in manifest, exclude the size of the 20-byte header.
168 uint64_t size_in_manifest = htobe64(actual_metadata_size - 20);
169 bool result = performer_.Write(&size_in_manifest, 8, &error_code);
170 if (expected_metadata_size == actual_metadata_size ||
171 !hash_checks_mandatory) {
172 EXPECT_TRUE(result);
173 } else {
174 EXPECT_FALSE(result);
175 EXPECT_EQ(ErrorCode::kDownloadInvalidMetadataSize, error_code);
176 }
Sen Jiangd78b3892015-09-25 15:19:31 -0700177
Sen Jiang2d528b42015-09-25 11:18:12 -0700178 EXPECT_LT(performer_.Close(), 0);
179 }
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800180
Sen Jiang2d528b42015-09-25 11:18:12 -0700181 // Generates a valid delta file but tests the delta performer by suppling
182 // different metadata signatures as per metadata_signature_test flag and
183 // sees if the result of the parsing are as per hash_checks_mandatory flag.
184 void DoMetadataSignatureTest(MetadataSignatureTest metadata_signature_test,
185 bool sign_payload,
186 bool hash_checks_mandatory) {
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800187
Sen Jiang2d528b42015-09-25 11:18:12 -0700188 // Loads the payload and parses the manifest.
189 chromeos::Blob payload = GeneratePayload(chromeos::Blob(),
190 vector<AnnotatedOperation>(), sign_payload,
Alex Deymocbf09892015-09-11 16:13:16 -0700191 kFullPayloadMinorVersion);
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800192
Sen Jiang2d528b42015-09-25 11:18:12 -0700193 LOG(INFO) << "Payload size: " << payload.size();
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800194
Sen Jiang2d528b42015-09-25 11:18:12 -0700195 install_plan_.hash_checks_mandatory = hash_checks_mandatory;
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800196
Sen Jiang2d528b42015-09-25 11:18:12 -0700197 DeltaPerformer::MetadataParseResult expected_result, actual_result;
198 ErrorCode expected_error, actual_error;
199
200 // Fill up the metadata signature in install plan according to the test.
201 switch (metadata_signature_test) {
202 case kEmptyMetadataSignature:
203 install_plan_.metadata_signature.clear();
204 expected_result = DeltaPerformer::kMetadataParseError;
205 expected_error = ErrorCode::kDownloadMetadataSignatureMissingError;
206 break;
207
208 case kInvalidMetadataSignature:
209 install_plan_.metadata_signature = kBogusMetadataSignature1;
210 expected_result = DeltaPerformer::kMetadataParseError;
211 expected_error = ErrorCode::kDownloadMetadataSignatureMismatch;
212 break;
213
214 case kValidMetadataSignature:
215 default:
216 // Set the install plan's metadata size to be the same as the one
217 // in the manifest so that we pass the metadata size checks. Only
218 // then we can get to manifest signature checks.
219 ASSERT_TRUE(PayloadSigner::GetMetadataSignature(
220 payload.data(),
221 install_plan_.metadata_size,
222 kUnittestPrivateKeyPath,
223 &install_plan_.metadata_signature));
224 EXPECT_FALSE(install_plan_.metadata_signature.empty());
225 expected_result = DeltaPerformer::kMetadataParseSuccess;
226 expected_error = ErrorCode::kSuccess;
227 break;
228 }
229
230 // Ignore the expected result/error if hash checks are not mandatory.
231 if (!hash_checks_mandatory) {
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800232 expected_result = DeltaPerformer::kMetadataParseSuccess;
Gilad Arnoldd1c4d2d2014-06-05 14:07:53 -0700233 expected_error = ErrorCode::kSuccess;
Sen Jiang2d528b42015-09-25 11:18:12 -0700234 }
235
236 // Use the public key corresponding to the private key used above to
237 // sign the metadata.
238 EXPECT_TRUE(utils::FileExists(kUnittestPublicKeyPath));
239 performer_.set_public_key_path(kUnittestPublicKeyPath);
240
241 // Init actual_error with an invalid value so that we make sure
242 // ParsePayloadMetadata properly populates it in all cases.
243 actual_error = ErrorCode::kUmaReportedMax;
244 actual_result = performer_.ParsePayloadMetadata(payload, &actual_error);
245
246 EXPECT_EQ(expected_result, actual_result);
247 EXPECT_EQ(expected_error, actual_error);
248
249 // Check that the parsed metadata size is what's expected. This test
250 // implicitly confirms that the metadata signature is valid, if required.
251 EXPECT_EQ(install_plan_.metadata_size, performer_.GetMetadataSize());
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800252 }
253
Sen Jiang2d528b42015-09-25 11:18:12 -0700254 FakePrefs prefs_;
255 InstallPlan install_plan_;
256 FakeSystemState fake_system_state_;
257 DeltaPerformer performer_{&prefs_, &fake_system_state_, &install_plan_};
258};
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800259
Sen Jiang2d528b42015-09-25 11:18:12 -0700260TEST_F(DeltaPerformerTest, FullPayloadWriteTest) {
261 install_plan_.is_full_update = true;
262 chromeos::Blob expected_data = chromeos::Blob(std::begin(kRandomString),
263 std::end(kRandomString));
264 expected_data.resize(4096); // block size
265 vector<AnnotatedOperation> aops;
266 AnnotatedOperation aop;
267 *(aop.op.add_dst_extents()) = ExtentForRange(0, 1);
268 aop.op.set_data_offset(0);
269 aop.op.set_data_length(expected_data.size());
270 aop.op.set_type(InstallOperation::REPLACE);
271 aops.push_back(aop);
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800272
Sen Jiang2d528b42015-09-25 11:18:12 -0700273 chromeos::Blob payload_data = GeneratePayload(expected_data, aops, false,
Alex Deymocbf09892015-09-11 16:13:16 -0700274 kFullPayloadMinorVersion);
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800275
Sen Jiang2d528b42015-09-25 11:18:12 -0700276 EXPECT_EQ(expected_data, ApplyPayload(payload_data, ""));
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800277}
278
Sen Jiang2d528b42015-09-25 11:18:12 -0700279TEST_F(DeltaPerformerTest, ReplaceOperationTest) {
280 chromeos::Blob expected_data = chromeos::Blob(std::begin(kRandomString),
281 std::end(kRandomString));
282 expected_data.resize(4096); // block size
283 vector<AnnotatedOperation> aops;
284 AnnotatedOperation aop;
285 *(aop.op.add_dst_extents()) = ExtentForRange(0, 1);
286 aop.op.set_data_offset(0);
287 aop.op.set_data_length(expected_data.size());
288 aop.op.set_type(InstallOperation::REPLACE);
289 aops.push_back(aop);
290
291 chromeos::Blob payload_data = GeneratePayload(expected_data, aops, false,
292 kSourceMinorPayloadVersion);
293
294 EXPECT_EQ(expected_data, ApplyPayload(payload_data, "/dev/null"));
295}
296
297TEST_F(DeltaPerformerTest, ReplaceBzOperationTest) {
298 chromeos::Blob expected_data = chromeos::Blob(std::begin(kRandomString),
299 std::end(kRandomString));
300 expected_data.resize(4096); // block size
301 chromeos::Blob bz_data;
302 EXPECT_TRUE(BzipCompress(expected_data, &bz_data));
303
304 vector<AnnotatedOperation> aops;
305 AnnotatedOperation aop;
306 *(aop.op.add_dst_extents()) = ExtentForRange(0, 1);
307 aop.op.set_data_offset(0);
308 aop.op.set_data_length(bz_data.size());
309 aop.op.set_type(InstallOperation::REPLACE_BZ);
310 aops.push_back(aop);
311
312 chromeos::Blob payload_data = GeneratePayload(bz_data, aops, false,
313 kSourceMinorPayloadVersion);
314
315 EXPECT_EQ(expected_data, ApplyPayload(payload_data, "/dev/null"));
316}
317
318TEST_F(DeltaPerformerTest, SourceCopyOperationTest) {
319 chromeos::Blob expected_data = chromeos::Blob(std::begin(kRandomString),
320 std::end(kRandomString));
321 expected_data.resize(4096); // block size
322 vector<AnnotatedOperation> aops;
323 AnnotatedOperation aop;
324 *(aop.op.add_src_extents()) = ExtentForRange(0, 1);
325 *(aop.op.add_dst_extents()) = ExtentForRange(0, 1);
326 aop.op.set_type(InstallOperation::SOURCE_COPY);
327 aops.push_back(aop);
328
329 chromeos::Blob payload_data = GeneratePayload(chromeos::Blob(), aops, false,
330 kSourceMinorPayloadVersion);
331 string source_path;
332 EXPECT_TRUE(utils::MakeTempFile("Source-XXXXXX",
333 &source_path, nullptr));
334 ScopedPathUnlinker path_unlinker(source_path);
335 EXPECT_TRUE(utils::WriteFile(source_path.c_str(),
336 expected_data.data(),
337 expected_data.size()));
338
339 EXPECT_EQ(expected_data, ApplyPayload(payload_data, source_path));
340}
341
342TEST_F(DeltaPerformerTest, ExtentsToByteStringTest) {
Allie Wood56873452015-03-27 17:48:40 -0700343 uint64_t test[] = {1, 1, 4, 2, 0, 1};
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800344 COMPILE_ASSERT(arraysize(test) % 2 == 0, array_size_uneven);
345 const uint64_t block_size = 4096;
Allie Wood56873452015-03-27 17:48:40 -0700346 const uint64_t file_length = 4 * block_size - 13;
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800347
348 google::protobuf::RepeatedPtrField<Extent> extents;
349 for (size_t i = 0; i < arraysize(test); i += 2) {
Sen Jiang2d528b42015-09-25 11:18:12 -0700350 *(extents.Add()) = ExtentForRange(test[i], test[i + 1]);
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800351 }
352
Allie Wood56873452015-03-27 17:48:40 -0700353 string expected_output = "4096:4096,16384:8192,0:4083";
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800354 string actual_output;
355 EXPECT_TRUE(DeltaPerformer::ExtentsToBsdiffPositionsString(extents,
356 block_size,
357 file_length,
358 &actual_output));
359 EXPECT_EQ(expected_output, actual_output);
360}
Darin Petkov68c10d12010-10-14 09:24:37 -0700361
Sen Jiang2d528b42015-09-25 11:18:12 -0700362TEST_F(DeltaPerformerTest, ValidateManifestFullGoodTest) {
Don Garrettb8dd1d92013-11-22 17:40:02 -0800363 // The Manifest we are validating.
364 DeltaArchiveManifest manifest;
365 manifest.mutable_new_kernel_info();
366 manifest.mutable_new_rootfs_info();
Alex Deymocbf09892015-09-11 16:13:16 -0700367 manifest.set_minor_version(kFullPayloadMinorVersion);
Don Garrettb8dd1d92013-11-22 17:40:02 -0800368
Sen Jiang2d528b42015-09-25 11:18:12 -0700369 RunManifestValidation(manifest, true, ErrorCode::kSuccess);
Don Garrettb8dd1d92013-11-22 17:40:02 -0800370}
371
Sen Jiang2d528b42015-09-25 11:18:12 -0700372TEST_F(DeltaPerformerTest, ValidateManifestDeltaGoodTest) {
Don Garrettb8dd1d92013-11-22 17:40:02 -0800373 // The Manifest we are validating.
374 DeltaArchiveManifest manifest;
375 manifest.mutable_old_kernel_info();
376 manifest.mutable_old_rootfs_info();
377 manifest.mutable_new_kernel_info();
378 manifest.mutable_new_rootfs_info();
379 manifest.set_minor_version(DeltaPerformer::kSupportedMinorPayloadVersion);
380
Sen Jiang2d528b42015-09-25 11:18:12 -0700381 RunManifestValidation(manifest, false, ErrorCode::kSuccess);
Don Garrettb8dd1d92013-11-22 17:40:02 -0800382}
383
Sen Jiang2d528b42015-09-25 11:18:12 -0700384TEST_F(DeltaPerformerTest, ValidateManifestFullUnsetMinorVersion) {
Don Garrettb8dd1d92013-11-22 17:40:02 -0800385 // The Manifest we are validating.
386 DeltaArchiveManifest manifest;
387
Sen Jiang2d528b42015-09-25 11:18:12 -0700388 RunManifestValidation(manifest, true, ErrorCode::kSuccess);
Don Garrettb8dd1d92013-11-22 17:40:02 -0800389}
390
Sen Jiang2d528b42015-09-25 11:18:12 -0700391TEST_F(DeltaPerformerTest, ValidateManifestDeltaUnsetMinorVersion) {
Don Garrettb8dd1d92013-11-22 17:40:02 -0800392 // The Manifest we are validating.
393 DeltaArchiveManifest manifest;
394
Sen Jiang2d528b42015-09-25 11:18:12 -0700395 RunManifestValidation(manifest, false,
396 ErrorCode::kUnsupportedMinorPayloadVersion);
Don Garrettb8dd1d92013-11-22 17:40:02 -0800397}
398
Sen Jiang2d528b42015-09-25 11:18:12 -0700399TEST_F(DeltaPerformerTest, ValidateManifestFullOldKernelTest) {
Don Garrettb8dd1d92013-11-22 17:40:02 -0800400 // The Manifest we are validating.
401 DeltaArchiveManifest manifest;
402 manifest.mutable_old_kernel_info();
403 manifest.mutable_new_kernel_info();
404 manifest.mutable_new_rootfs_info();
405 manifest.set_minor_version(DeltaPerformer::kSupportedMinorPayloadVersion);
406
Sen Jiang2d528b42015-09-25 11:18:12 -0700407 RunManifestValidation(manifest, true, ErrorCode::kPayloadMismatchedType);
Don Garrettb8dd1d92013-11-22 17:40:02 -0800408}
409
Sen Jiang2d528b42015-09-25 11:18:12 -0700410TEST_F(DeltaPerformerTest, ValidateManifestFullOldRootfsTest) {
Don Garrettb8dd1d92013-11-22 17:40:02 -0800411 // The Manifest we are validating.
412 DeltaArchiveManifest manifest;
413 manifest.mutable_old_rootfs_info();
414 manifest.mutable_new_kernel_info();
415 manifest.mutable_new_rootfs_info();
416 manifest.set_minor_version(DeltaPerformer::kSupportedMinorPayloadVersion);
417
Sen Jiang2d528b42015-09-25 11:18:12 -0700418 RunManifestValidation(manifest, true, ErrorCode::kPayloadMismatchedType);
Don Garrettb8dd1d92013-11-22 17:40:02 -0800419}
420
Sen Jiang2d528b42015-09-25 11:18:12 -0700421TEST_F(DeltaPerformerTest, ValidateManifestBadMinorVersion) {
Don Garrettb8dd1d92013-11-22 17:40:02 -0800422 // The Manifest we are validating.
423 DeltaArchiveManifest manifest;
424
425 // Generate a bad version number.
426 manifest.set_minor_version(DeltaPerformer::kSupportedMinorPayloadVersion +
427 10000);
428
Sen Jiang2d528b42015-09-25 11:18:12 -0700429 RunManifestValidation(manifest, false,
430 ErrorCode::kUnsupportedMinorPayloadVersion);
Don Garrettb8dd1d92013-11-22 17:40:02 -0800431}
432
Sen Jiang2d528b42015-09-25 11:18:12 -0700433TEST_F(DeltaPerformerTest, BadDeltaMagicTest) {
434 EXPECT_EQ(0, performer_.Open("/dev/null", 0, 0));
435 EXPECT_TRUE(performer_.OpenKernel("/dev/null"));
436 EXPECT_TRUE(performer_.Write("junk", 4));
437 EXPECT_TRUE(performer_.Write("morejunk", 8));
438 EXPECT_FALSE(performer_.Write("morejunk", 8));
439 EXPECT_LT(performer_.Close(), 0);
Darin Petkov934bb412010-11-18 11:21:35 -0800440}
441
Sen Jiang2d528b42015-09-25 11:18:12 -0700442TEST_F(DeltaPerformerTest, WriteUpdatesPayloadState) {
443 EXPECT_EQ(0, performer_.Open("/dev/null", 0, 0));
444 EXPECT_TRUE(performer_.OpenKernel("/dev/null"));
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800445
Sen Jiang2d528b42015-09-25 11:18:12 -0700446 EXPECT_CALL(*(fake_system_state_.mock_payload_state()),
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800447 DownloadProgress(4)).Times(1);
Sen Jiang2d528b42015-09-25 11:18:12 -0700448 EXPECT_CALL(*(fake_system_state_.mock_payload_state()),
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800449 DownloadProgress(8)).Times(2);
450
Sen Jiang2d528b42015-09-25 11:18:12 -0700451 EXPECT_TRUE(performer_.Write("junk", 4));
452 EXPECT_TRUE(performer_.Write("morejunk", 8));
453 EXPECT_FALSE(performer_.Write("morejunk", 8));
454 EXPECT_LT(performer_.Close(), 0);
Jay Srinivasan2b5a0f02012-12-19 17:25:56 -0800455}
456
Sen Jiang2d528b42015-09-25 11:18:12 -0700457TEST_F(DeltaPerformerTest, MissingMandatoryMetadataSizeTest) {
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800458 DoMetadataSizeTest(0, 75456, true);
Jay Srinivasan51dcf262012-09-13 17:24:32 -0700459}
460
Sen Jiang2d528b42015-09-25 11:18:12 -0700461TEST_F(DeltaPerformerTest, MissingNonMandatoryMetadataSizeTest) {
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800462 DoMetadataSizeTest(0, 123456, false);
463}
464
Sen Jiang2d528b42015-09-25 11:18:12 -0700465TEST_F(DeltaPerformerTest, InvalidMandatoryMetadataSizeTest) {
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800466 DoMetadataSizeTest(13000, 140000, true);
467}
468
Sen Jiang2d528b42015-09-25 11:18:12 -0700469TEST_F(DeltaPerformerTest, InvalidNonMandatoryMetadataSizeTest) {
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800470 DoMetadataSizeTest(40000, 50000, false);
471}
472
Sen Jiang2d528b42015-09-25 11:18:12 -0700473TEST_F(DeltaPerformerTest, ValidMandatoryMetadataSizeTest) {
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800474 DoMetadataSizeTest(85376, 85376, true);
475}
476
Sen Jiang2d528b42015-09-25 11:18:12 -0700477TEST_F(DeltaPerformerTest, MandatoryEmptyMetadataSignatureTest) {
Sen Jiangd78b3892015-09-25 15:19:31 -0700478 DoMetadataSignatureTest(kEmptyMetadataSignature, true, true);
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800479}
480
Sen Jiang2d528b42015-09-25 11:18:12 -0700481TEST_F(DeltaPerformerTest, NonMandatoryEmptyMetadataSignatureTest) {
Sen Jiangd78b3892015-09-25 15:19:31 -0700482 DoMetadataSignatureTest(kEmptyMetadataSignature, true, false);
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800483}
484
Sen Jiang2d528b42015-09-25 11:18:12 -0700485TEST_F(DeltaPerformerTest, MandatoryInvalidMetadataSignatureTest) {
Sen Jiangd78b3892015-09-25 15:19:31 -0700486 DoMetadataSignatureTest(kInvalidMetadataSignature, true, true);
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800487}
488
Sen Jiang2d528b42015-09-25 11:18:12 -0700489TEST_F(DeltaPerformerTest, NonMandatoryInvalidMetadataSignatureTest) {
Sen Jiangd78b3892015-09-25 15:19:31 -0700490 DoMetadataSignatureTest(kInvalidMetadataSignature, true, false);
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800491}
492
Sen Jiang2d528b42015-09-25 11:18:12 -0700493TEST_F(DeltaPerformerTest, MandatoryValidMetadataSignature1Test) {
Sen Jiangd78b3892015-09-25 15:19:31 -0700494 DoMetadataSignatureTest(kValidMetadataSignature, false, true);
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800495}
496
Sen Jiang2d528b42015-09-25 11:18:12 -0700497TEST_F(DeltaPerformerTest, MandatoryValidMetadataSignature2Test) {
Sen Jiangd78b3892015-09-25 15:19:31 -0700498 DoMetadataSignatureTest(kValidMetadataSignature, true, true);
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800499}
500
Sen Jiang2d528b42015-09-25 11:18:12 -0700501TEST_F(DeltaPerformerTest, NonMandatoryValidMetadataSignatureTest) {
Sen Jiangd78b3892015-09-25 15:19:31 -0700502 DoMetadataSignatureTest(kValidMetadataSignature, true, false);
Jay Srinivasan738fdf32012-12-07 17:40:54 -0800503}
504
Sen Jiang2d528b42015-09-25 11:18:12 -0700505TEST_F(DeltaPerformerTest, UsePublicKeyFromResponse) {
David Zeuthene7f89172013-10-31 10:21:04 -0700506 base::FilePath key_path;
507
508 // The result of the GetPublicKeyResponse() method is based on three things
509 //
510 // 1. Whether it's an official build; and
511 // 2. Whether the Public RSA key to be used is in the root filesystem; and
Alex Vakulenko072359c2014-07-18 11:41:07 -0700512 // 3. Whether the response has a public key
David Zeuthene7f89172013-10-31 10:21:04 -0700513 //
514 // We test all eight combinations to ensure that we only use the
515 // public key in the response if
516 //
517 // a. it's not an official build; and
518 // b. there is no key in the root filesystem.
519
Sen Jiang2d528b42015-09-25 11:18:12 -0700520 FakeHardware* fake_hardware = fake_system_state_.fake_hardware();
David Zeuthene7f89172013-10-31 10:21:04 -0700521
522 string temp_dir;
Gilad Arnolda6742b32014-01-11 00:18:34 -0800523 EXPECT_TRUE(utils::MakeTempDirectory("PublicKeyFromResponseTests.XXXXXX",
David Zeuthene7f89172013-10-31 10:21:04 -0700524 &temp_dir));
525 string non_existing_file = temp_dir + "/non-existing";
526 string existing_file = temp_dir + "/existing";
Alex Vakulenko75039d72014-03-25 12:36:28 -0700527 EXPECT_EQ(0, System(base::StringPrintf("touch %s", existing_file.c_str())));
David Zeuthene7f89172013-10-31 10:21:04 -0700528
529 // Non-official build, non-existing public-key, key in response -> true
Don Garrett6646b442013-11-13 15:29:11 -0800530 fake_hardware->SetIsOfficialBuild(false);
Sen Jiang2d528b42015-09-25 11:18:12 -0700531 performer_.public_key_path_ = non_existing_file;
532 install_plan_.public_key_rsa = "VGVzdAo="; // result of 'echo "Test" | base64'
533 EXPECT_TRUE(performer_.GetPublicKeyFromResponse(&key_path));
David Zeuthene7f89172013-10-31 10:21:04 -0700534 EXPECT_FALSE(key_path.empty());
535 EXPECT_EQ(unlink(key_path.value().c_str()), 0);
536 // Same with official build -> false
Don Garrett6646b442013-11-13 15:29:11 -0800537 fake_hardware->SetIsOfficialBuild(true);
Sen Jiang2d528b42015-09-25 11:18:12 -0700538 EXPECT_FALSE(performer_.GetPublicKeyFromResponse(&key_path));
David Zeuthene7f89172013-10-31 10:21:04 -0700539
540 // Non-official build, existing public-key, key in response -> false
Don Garrett6646b442013-11-13 15:29:11 -0800541 fake_hardware->SetIsOfficialBuild(false);
Sen Jiang2d528b42015-09-25 11:18:12 -0700542 performer_.public_key_path_ = existing_file;
543 install_plan_.public_key_rsa = "VGVzdAo="; // result of 'echo "Test" | base64'
544 EXPECT_FALSE(performer_.GetPublicKeyFromResponse(&key_path));
David Zeuthene7f89172013-10-31 10:21:04 -0700545 // Same with official build -> false
Don Garrett6646b442013-11-13 15:29:11 -0800546 fake_hardware->SetIsOfficialBuild(true);
Sen Jiang2d528b42015-09-25 11:18:12 -0700547 EXPECT_FALSE(performer_.GetPublicKeyFromResponse(&key_path));
David Zeuthene7f89172013-10-31 10:21:04 -0700548
549 // Non-official build, non-existing public-key, no key in response -> false
Don Garrett6646b442013-11-13 15:29:11 -0800550 fake_hardware->SetIsOfficialBuild(false);
Sen Jiang2d528b42015-09-25 11:18:12 -0700551 performer_.public_key_path_ = non_existing_file;
552 install_plan_.public_key_rsa = "";
553 EXPECT_FALSE(performer_.GetPublicKeyFromResponse(&key_path));
David Zeuthene7f89172013-10-31 10:21:04 -0700554 // Same with official build -> false
Don Garrett6646b442013-11-13 15:29:11 -0800555 fake_hardware->SetIsOfficialBuild(true);
Sen Jiang2d528b42015-09-25 11:18:12 -0700556 EXPECT_FALSE(performer_.GetPublicKeyFromResponse(&key_path));
David Zeuthene7f89172013-10-31 10:21:04 -0700557
558 // Non-official build, existing public-key, no key in response -> false
Don Garrett6646b442013-11-13 15:29:11 -0800559 fake_hardware->SetIsOfficialBuild(false);
Sen Jiang2d528b42015-09-25 11:18:12 -0700560 performer_.public_key_path_ = existing_file;
561 install_plan_.public_key_rsa = "";
562 EXPECT_FALSE(performer_.GetPublicKeyFromResponse(&key_path));
David Zeuthene7f89172013-10-31 10:21:04 -0700563 // Same with official build -> false
Don Garrett6646b442013-11-13 15:29:11 -0800564 fake_hardware->SetIsOfficialBuild(true);
Sen Jiang2d528b42015-09-25 11:18:12 -0700565 EXPECT_FALSE(performer_.GetPublicKeyFromResponse(&key_path));
David Zeuthene7f89172013-10-31 10:21:04 -0700566
567 // Non-official build, non-existing public-key, key in response
568 // but invalid base64 -> false
Don Garrett6646b442013-11-13 15:29:11 -0800569 fake_hardware->SetIsOfficialBuild(false);
Sen Jiang2d528b42015-09-25 11:18:12 -0700570 performer_.public_key_path_ = non_existing_file;
571 install_plan_.public_key_rsa = "not-valid-base64";
572 EXPECT_FALSE(performer_.GetPublicKeyFromResponse(&key_path));
David Zeuthene7f89172013-10-31 10:21:04 -0700573
Alex Deymo10875d92014-11-10 21:52:57 -0800574 EXPECT_TRUE(test_utils::RecursiveUnlinkDir(temp_dir));
David Zeuthene7f89172013-10-31 10:21:04 -0700575}
576
Alex Deymocbf09892015-09-11 16:13:16 -0700577TEST_F(DeltaPerformerTest, ConfVersionsMatch) {
578 // Test that the versions in update_engine.conf that is installed to the
579 // image match the supported delta versions in the update engine.
Allie Wood78750a42015-02-11 15:42:11 -0800580 uint32_t minor_version;
Alex Deymob42b98d2015-07-06 17:42:38 -0700581 chromeos::KeyValueStore store;
582 EXPECT_TRUE(store.Load(base::FilePath("update_engine.conf")));
583 EXPECT_TRUE(utils::GetMinorVersion(store, &minor_version));
584 EXPECT_EQ(DeltaPerformer::kSupportedMinorPayloadVersion, minor_version);
Alex Deymocbf09892015-09-11 16:13:16 -0700585
586 string major_version_str;
587 uint64_t major_version;
588 EXPECT_TRUE(store.GetString("PAYLOAD_MAJOR_VERSION", &major_version_str));
589 EXPECT_TRUE(base::StringToUint64(major_version_str, &major_version));
590 EXPECT_EQ(DeltaPerformer::kSupportedMajorPayloadVersion, major_version);
Allie Wood78750a42015-02-11 15:42:11 -0800591}
592
Andrew de los Reyes09e56d62010-04-23 13:45:53 -0700593} // namespace chromeos_update_engine