blob: 7174780d484d985495b21801c8ba9bf2de320245 [file] [log] [blame]
Mike Frysinger8155d082012-04-06 15:23:18 -04001// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
Andrew de los Reyes09e56d62010-04-23 13:45:53 -07002// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include <sys/mount.h>
6#include <inttypes.h>
7
8#include <algorithm>
9#include <string>
10#include <vector>
11
Darin Petkov9fa7ec52010-10-18 11:45:23 -070012#include <base/file_util.h>
Chris Masoned903c3b2011-05-12 15:35:46 -070013#include <base/memory/scoped_ptr.h>
Darin Petkov73058b42010-10-06 16:32:19 -070014#include <base/string_util.h>
Mike Frysinger8155d082012-04-06 15:23:18 -040015#include <base/stringprintf.h>
Andrew de los Reyes09e56d62010-04-23 13:45:53 -070016#include <google/protobuf/repeated_field.h>
17#include <gtest/gtest.h>
18
Andrew de los Reyes09e56d62010-04-23 13:45:53 -070019#include "update_engine/delta_diff_generator.h"
20#include "update_engine/delta_performer.h"
Andrew de los Reyes353777c2010-10-08 10:34:30 -070021#include "update_engine/extent_ranges.h"
Darin Petkov7a22d792010-11-08 14:10:00 -080022#include "update_engine/full_update_generator.h"
Andrew de los Reyes09e56d62010-04-23 13:45:53 -070023#include "update_engine/graph_types.h"
Jay Srinivasanf0572052012-10-23 18:12:56 -070024#include "update_engine/mock_system_state.h"
Andrew de los Reyes932bc4c2010-08-23 18:14:09 -070025#include "update_engine/payload_signer.h"
Darin Petkov73058b42010-10-06 16:32:19 -070026#include "update_engine/prefs_mock.h"
Andrew de los Reyes09e56d62010-04-23 13:45:53 -070027#include "update_engine/test_utils.h"
28#include "update_engine/update_metadata.pb.h"
29#include "update_engine/utils.h"
30
31namespace chromeos_update_engine {
32
33using std::min;
34using std::string;
35using std::vector;
Darin Petkov73058b42010-10-06 16:32:19 -070036using testing::_;
37using testing::Return;
Andrew de los Reyes09e56d62010-04-23 13:45:53 -070038
Andrew de los Reyes932bc4c2010-08-23 18:14:09 -070039extern const char* kUnittestPrivateKeyPath;
Darin Petkovd7061ab2010-10-06 14:37:09 -070040extern const char* kUnittestPublicKeyPath;
Andrew de los Reyesc24e3f32011-08-30 15:45:20 -070041extern const char* kUnittestPrivateKey2Path;
42extern const char* kUnittestPublicKey2Path;
Andrew de los Reyes932bc4c2010-08-23 18:14:09 -070043
Andrew de los Reyes27f7d372010-10-07 11:26:07 -070044namespace {
Andrew de los Reyes29da8aa2011-02-15 13:34:57 -080045const size_t kBlockSize = 4096;
Andrew de los Reyes27f7d372010-10-07 11:26:07 -070046} // namespace {}
47
48
Andrew de los Reyes09e56d62010-04-23 13:45:53 -070049class DeltaPerformerTest : public ::testing::Test { };
50
51TEST(DeltaPerformerTest, ExtentsToByteStringTest) {
52 uint64_t test[] = {1, 1, 4, 2, kSparseHole, 1, 0, 1};
53 COMPILE_ASSERT(arraysize(test) % 2 == 0, array_size_uneven);
54 const uint64_t block_size = 4096;
55 const uint64_t file_length = 5 * block_size - 13;
56
57 google::protobuf::RepeatedPtrField<Extent> extents;
58 for (size_t i = 0; i < arraysize(test); i += 2) {
59 Extent* extent = extents.Add();
60 extent->set_start_block(test[i]);
61 extent->set_num_blocks(test[i + 1]);
62 }
63
64 string expected_output = "4096:4096,16384:8192,-1:4096,0:4083";
65 string actual_output;
66 EXPECT_TRUE(DeltaPerformer::ExtentsToBsdiffPositionsString(extents,
67 block_size,
68 file_length,
69 &actual_output));
70 EXPECT_EQ(expected_output, actual_output);
71}
72
Andrew de los Reyes09e56d62010-04-23 13:45:53 -070073void CompareFilesByBlock(const string& a_file, const string& b_file) {
74 vector<char> a_data, b_data;
Andrew de los Reyes3270f742010-07-15 22:28:14 -070075 EXPECT_TRUE(utils::ReadFile(a_file, &a_data)) << "file failed: " << a_file;
76 EXPECT_TRUE(utils::ReadFile(b_file, &b_data)) << "file failed: " << b_file;
Andrew de los Reyes09e56d62010-04-23 13:45:53 -070077
78 EXPECT_EQ(a_data.size(), b_data.size());
Andrew de los Reyes09e56d62010-04-23 13:45:53 -070079 EXPECT_EQ(0, a_data.size() % kBlockSize);
80 for (size_t i = 0; i < a_data.size(); i += kBlockSize) {
81 EXPECT_EQ(0, i % kBlockSize);
82 vector<char> a_sub(&a_data[i], &a_data[i + kBlockSize]);
83 vector<char> b_sub(&b_data[i], &b_data[i + kBlockSize]);
84 EXPECT_TRUE(a_sub == b_sub) << "Block " << (i/kBlockSize) << " differs";
85 }
86}
87
88namespace {
89bool WriteSparseFile(const string& path, off_t size) {
90 int fd = open(path.c_str(), O_CREAT | O_TRUNC | O_WRONLY, 0644);
91 TEST_AND_RETURN_FALSE_ERRNO(fd >= 0);
92 ScopedFdCloser fd_closer(&fd);
93 off_t rc = lseek(fd, size + 1, SEEK_SET);
94 TEST_AND_RETURN_FALSE_ERRNO(rc != static_cast<off_t>(-1));
95 int return_code = ftruncate(fd, size);
96 TEST_AND_RETURN_FALSE_ERRNO(return_code == 0);
97 return true;
98}
Darin Petkov9574f7e2011-01-13 10:48:12 -080099} // namespace {}
Andrew de los Reyes09e56d62010-04-23 13:45:53 -0700100
Darin Petkov9574f7e2011-01-13 10:48:12 -0800101namespace {
Darin Petkovcbfb0172011-01-14 15:24:45 -0800102enum SignatureTest {
103 kSignatureNone, // No payload signing.
104 kSignatureGenerator, // Sign the payload at generation time.
105 kSignatureGenerated, // Sign the payload after it's generated.
106 kSignatureGeneratedShell, // Sign the generated payload through shell cmds.
Darin Petkov52dcaeb2011-01-14 15:33:06 -0800107 kSignatureGeneratedShellBadKey, // Sign with a bad key through shell cmds.
Andrew de los Reyesc24e3f32011-08-30 15:45:20 -0700108 kSignatureGeneratedShellRotateCl1, // Rotate key, test client v1
109 kSignatureGeneratedShellRotateCl2, // Rotate key, test client v2
Darin Petkovcbfb0172011-01-14 15:24:45 -0800110};
111
Darin Petkov52dcaeb2011-01-14 15:33:06 -0800112size_t GetSignatureSize(const string& private_key_path) {
Darin Petkovcbfb0172011-01-14 15:24:45 -0800113 const vector<char> data(1, 'x');
114 vector<char> hash;
115 EXPECT_TRUE(OmahaHashCalculator::RawHashOfData(data, &hash));
116 vector<char> signature;
117 EXPECT_TRUE(PayloadSigner::SignHash(hash,
Darin Petkov52dcaeb2011-01-14 15:33:06 -0800118 private_key_path,
Darin Petkovcbfb0172011-01-14 15:24:45 -0800119 &signature));
120 return signature.size();
121}
122
123void SignGeneratedPayload(const string& payload_path) {
Darin Petkov52dcaeb2011-01-14 15:33:06 -0800124 int signature_size = GetSignatureSize(kUnittestPrivateKeyPath);
Darin Petkovcbfb0172011-01-14 15:24:45 -0800125 vector<char> hash;
Andrew de los Reyesc24e3f32011-08-30 15:45:20 -0700126 ASSERT_TRUE(PayloadSigner::HashPayloadForSigning(
127 payload_path,
128 vector<int>(1, signature_size),
129 &hash));
Darin Petkovcbfb0172011-01-14 15:24:45 -0800130 vector<char> signature;
131 ASSERT_TRUE(PayloadSigner::SignHash(hash,
132 kUnittestPrivateKeyPath,
133 &signature));
Andrew de los Reyesc24e3f32011-08-30 15:45:20 -0700134 ASSERT_TRUE(PayloadSigner::AddSignatureToPayload(
135 payload_path,
136 vector<vector<char> >(1, signature),
137 payload_path));
138 EXPECT_TRUE(PayloadSigner::VerifySignedPayload(
139 payload_path,
140 kUnittestPublicKeyPath,
141 kSignatureMessageOriginalVersion));
Darin Petkovcbfb0172011-01-14 15:24:45 -0800142}
143
Darin Petkov52dcaeb2011-01-14 15:33:06 -0800144void SignGeneratedShellPayload(SignatureTest signature_test,
145 const string& payload_path) {
146 string private_key_path = kUnittestPrivateKeyPath;
147 if (signature_test == kSignatureGeneratedShellBadKey) {
148 ASSERT_TRUE(utils::MakeTempFile("/tmp/key.XXXXXX",
149 &private_key_path,
150 NULL));
151 } else {
Andrew de los Reyesc24e3f32011-08-30 15:45:20 -0700152 ASSERT_TRUE(signature_test == kSignatureGeneratedShell ||
153 signature_test == kSignatureGeneratedShellRotateCl1 ||
154 signature_test == kSignatureGeneratedShellRotateCl2);
Darin Petkov52dcaeb2011-01-14 15:33:06 -0800155 }
156 ScopedPathUnlinker key_unlinker(private_key_path);
157 key_unlinker.set_should_remove(signature_test ==
158 kSignatureGeneratedShellBadKey);
159 // Generates a new private key that will not match the public key.
160 if (signature_test == kSignatureGeneratedShellBadKey) {
161 LOG(INFO) << "Generating a mismatched private key.";
162 ASSERT_EQ(0,
163 System(StringPrintf(
Mike Frysinger2149be42012-03-12 19:23:47 -0400164 "openssl genrsa -out %s 2048",
Darin Petkov52dcaeb2011-01-14 15:33:06 -0800165 private_key_path.c_str())));
166 }
167 int signature_size = GetSignatureSize(private_key_path);
Darin Petkovcbfb0172011-01-14 15:24:45 -0800168 string hash_file;
169 ASSERT_TRUE(utils::MakeTempFile("/tmp/hash.XXXXXX", &hash_file, NULL));
170 ScopedPathUnlinker hash_unlinker(hash_file);
Andrew de los Reyesc24e3f32011-08-30 15:45:20 -0700171 string signature_size_string;
172 if (signature_test == kSignatureGeneratedShellRotateCl1 ||
173 signature_test == kSignatureGeneratedShellRotateCl2)
174 signature_size_string = StringPrintf("%d:%d",
175 signature_size, signature_size);
176 else
177 signature_size_string = StringPrintf("%d", signature_size);
Darin Petkovcbfb0172011-01-14 15:24:45 -0800178 ASSERT_EQ(0,
179 System(StringPrintf(
Andrew de los Reyesc24e3f32011-08-30 15:45:20 -0700180 "./delta_generator -in_file %s -signature_size %s "
Darin Petkovcbfb0172011-01-14 15:24:45 -0800181 "-out_hash_file %s",
182 payload_path.c_str(),
Andrew de los Reyesc24e3f32011-08-30 15:45:20 -0700183 signature_size_string.c_str(),
Darin Petkovcbfb0172011-01-14 15:24:45 -0800184 hash_file.c_str())));
185
Andrew de los Reyesbdfaaf02011-03-30 10:35:12 -0700186 // Pad the hash
187 vector<char> hash;
188 ASSERT_TRUE(utils::ReadFile(hash_file, &hash));
189 ASSERT_TRUE(PayloadSigner::PadRSA2048SHA256Hash(&hash));
190 ASSERT_TRUE(WriteFileVector(hash_file, hash));
191
Darin Petkovcbfb0172011-01-14 15:24:45 -0800192 string sig_file;
193 ASSERT_TRUE(utils::MakeTempFile("/tmp/signature.XXXXXX", &sig_file, NULL));
194 ScopedPathUnlinker sig_unlinker(sig_file);
195 ASSERT_EQ(0,
196 System(StringPrintf(
Mike Frysinger2149be42012-03-12 19:23:47 -0400197 "openssl rsautl -raw -sign -inkey %s -in %s -out %s",
Darin Petkov52dcaeb2011-01-14 15:33:06 -0800198 private_key_path.c_str(),
Darin Petkovcbfb0172011-01-14 15:24:45 -0800199 hash_file.c_str(),
200 sig_file.c_str())));
Andrew de los Reyesc24e3f32011-08-30 15:45:20 -0700201 string sig_file2;
202 ASSERT_TRUE(utils::MakeTempFile("/tmp/signature.XXXXXX", &sig_file2, NULL));
203 ScopedPathUnlinker sig2_unlinker(sig_file2);
204 if (signature_test == kSignatureGeneratedShellRotateCl1 ||
205 signature_test == kSignatureGeneratedShellRotateCl2) {
206 ASSERT_EQ(0,
207 System(StringPrintf(
Mike Frysinger2149be42012-03-12 19:23:47 -0400208 "openssl rsautl -raw -sign -inkey %s -in %s -out %s",
Andrew de los Reyesc24e3f32011-08-30 15:45:20 -0700209 kUnittestPrivateKey2Path,
210 hash_file.c_str(),
211 sig_file2.c_str())));
212 // Append second sig file to first path
213 sig_file += ":" + sig_file2;
214 }
215
Darin Petkovcbfb0172011-01-14 15:24:45 -0800216 ASSERT_EQ(0,
217 System(StringPrintf(
218 "./delta_generator -in_file %s -signature_file %s "
219 "-out_file %s",
220 payload_path.c_str(),
221 sig_file.c_str(),
222 payload_path.c_str())));
Darin Petkov52dcaeb2011-01-14 15:33:06 -0800223 int verify_result =
Andrew de los Reyesc24e3f32011-08-30 15:45:20 -0700224 System(StringPrintf(
225 "./delta_generator -in_file %s -public_key %s -public_key_version %d",
226 payload_path.c_str(),
227 signature_test == kSignatureGeneratedShellRotateCl2 ?
228 kUnittestPublicKey2Path : kUnittestPublicKeyPath,
229 signature_test == kSignatureGeneratedShellRotateCl2 ? 2 : 1));
Darin Petkov52dcaeb2011-01-14 15:33:06 -0800230 if (signature_test == kSignatureGeneratedShellBadKey) {
231 ASSERT_NE(0, verify_result);
232 } else {
233 ASSERT_EQ(0, verify_result);
234 }
Darin Petkovcbfb0172011-01-14 15:24:45 -0800235}
236
Darin Petkov9574f7e2011-01-13 10:48:12 -0800237void DoSmallImageTest(bool full_kernel, bool full_rootfs, bool noop,
Darin Petkovcbfb0172011-01-14 15:24:45 -0800238 SignatureTest signature_test) {
Andrew de los Reyes09e56d62010-04-23 13:45:53 -0700239 string a_img, b_img;
240 EXPECT_TRUE(utils::MakeTempFile("/tmp/a_img.XXXXXX", &a_img, NULL));
241 ScopedPathUnlinker a_img_unlinker(a_img);
242 EXPECT_TRUE(utils::MakeTempFile("/tmp/b_img.XXXXXX", &b_img, NULL));
243 ScopedPathUnlinker b_img_unlinker(b_img);
244
245 CreateExtImageAtPath(a_img, NULL);
Andrew de los Reyes09e56d62010-04-23 13:45:53 -0700246
Darin Petkov7ea32332010-10-13 10:46:11 -0700247 int image_size = static_cast<int>(utils::FileSize(a_img));
248
249 // Extend the "partitions" holding the file system a bit.
250 EXPECT_EQ(0, System(base::StringPrintf(
251 "dd if=/dev/zero of=%s seek=%d bs=1 count=1",
252 a_img.c_str(),
253 image_size + 1024 * 1024 - 1)));
Darin Petkov7ea32332010-10-13 10:46:11 -0700254 EXPECT_EQ(image_size + 1024 * 1024, utils::FileSize(a_img));
Darin Petkov7ea32332010-10-13 10:46:11 -0700255
Andrew de los Reyes09e56d62010-04-23 13:45:53 -0700256 // Make some changes to the A image.
257 {
258 string a_mnt;
259 ScopedLoopMounter b_mounter(a_img, &a_mnt, 0);
260
261 EXPECT_TRUE(utils::WriteFile(StringPrintf("%s/hardtocompress",
262 a_mnt.c_str()).c_str(),
263 reinterpret_cast<const char*>(kRandomString),
264 sizeof(kRandomString) - 1));
265 // Write 1 MiB of 0xff to try to catch the case where writing a bsdiff
266 // patch fails to zero out the final block.
267 vector<char> ones(1024 * 1024, 0xff);
268 EXPECT_TRUE(utils::WriteFile(StringPrintf("%s/ones",
269 a_mnt.c_str()).c_str(),
270 &ones[0],
271 ones.size()));
272 }
273
Darin Petkov9fa7ec52010-10-18 11:45:23 -0700274 if (noop) {
275 EXPECT_TRUE(file_util::CopyFile(FilePath(a_img), FilePath(b_img)));
276 } else {
277 CreateExtImageAtPath(b_img, NULL);
278 EXPECT_EQ(0, System(base::StringPrintf(
279 "dd if=/dev/zero of=%s seek=%d bs=1 count=1",
280 b_img.c_str(),
281 image_size + 1024 * 1024 - 1)));
282 EXPECT_EQ(image_size + 1024 * 1024, utils::FileSize(b_img));
283
284 // Make some changes to the B image.
Andrew de los Reyes09e56d62010-04-23 13:45:53 -0700285 string b_mnt;
286 ScopedLoopMounter b_mounter(b_img, &b_mnt, 0);
287
288 EXPECT_EQ(0, system(StringPrintf("cp %s/hello %s/hello2", b_mnt.c_str(),
289 b_mnt.c_str()).c_str()));
290 EXPECT_EQ(0, system(StringPrintf("rm %s/hello", b_mnt.c_str()).c_str()));
291 EXPECT_EQ(0, system(StringPrintf("mv %s/hello2 %s/hello", b_mnt.c_str(),
292 b_mnt.c_str()).c_str()));
293 EXPECT_EQ(0, system(StringPrintf("echo foo > %s/foo",
294 b_mnt.c_str()).c_str()));
295 EXPECT_EQ(0, system(StringPrintf("touch %s/emptyfile",
296 b_mnt.c_str()).c_str()));
297 EXPECT_TRUE(WriteSparseFile(StringPrintf("%s/fullsparse", b_mnt.c_str()),
298 1024 * 1024));
299 EXPECT_EQ(0, system(StringPrintf("dd if=/dev/zero of=%s/partsparese bs=1 "
300 "seek=4096 count=1",
301 b_mnt.c_str()).c_str()));
Andrew de los Reyes29da8aa2011-02-15 13:34:57 -0800302 EXPECT_EQ(0, system(StringPrintf("cp %s/srchardlink0 %s/tmp && "
303 "mv %s/tmp %s/srchardlink1",
304 b_mnt.c_str(), b_mnt.c_str(),
305 b_mnt.c_str(), b_mnt.c_str()).c_str()));
Andrew de los Reyes48a0a482011-02-22 15:32:11 -0800306 EXPECT_EQ(0, system(StringPrintf("rm %s/boguslink && "
307 "echo foobar > %s/boguslink",
308 b_mnt.c_str(), b_mnt.c_str()).c_str()));
Andrew de los Reyes09e56d62010-04-23 13:45:53 -0700309 EXPECT_TRUE(utils::WriteFile(StringPrintf("%s/hardtocompress",
310 b_mnt.c_str()).c_str(),
311 reinterpret_cast<const char*>(kRandomString),
312 sizeof(kRandomString)));
313 }
314
Andrew de los Reyesf4c7ef12010-04-30 10:37:00 -0700315 string old_kernel;
316 EXPECT_TRUE(utils::MakeTempFile("/tmp/old_kernel.XXXXXX", &old_kernel, NULL));
317 ScopedPathUnlinker old_kernel_unlinker(old_kernel);
318
319 string new_kernel;
320 EXPECT_TRUE(utils::MakeTempFile("/tmp/new_kernel.XXXXXX", &new_kernel, NULL));
321 ScopedPathUnlinker new_kernel_unlinker(new_kernel);
322
323 vector<char> old_kernel_data(4096); // Something small for a test
324 vector<char> new_kernel_data(old_kernel_data.size());
325 FillWithData(&old_kernel_data);
326 FillWithData(&new_kernel_data);
Andrew de los Reyes932bc4c2010-08-23 18:14:09 -0700327
Andrew de los Reyesf4c7ef12010-04-30 10:37:00 -0700328 // change the new kernel data
329 const char* new_data_string = "This is new data.";
330 strcpy(&new_kernel_data[0], new_data_string);
331
Darin Petkov9fa7ec52010-10-18 11:45:23 -0700332 if (noop) {
333 old_kernel_data = new_kernel_data;
334 }
335
Andrew de los Reyesf4c7ef12010-04-30 10:37:00 -0700336 // Write kernels to disk
337 EXPECT_TRUE(utils::WriteFile(
338 old_kernel.c_str(), &old_kernel_data[0], old_kernel_data.size()));
339 EXPECT_TRUE(utils::WriteFile(
340 new_kernel.c_str(), &new_kernel_data[0], new_kernel_data.size()));
341
Andrew de los Reyes09e56d62010-04-23 13:45:53 -0700342 string delta_path;
343 EXPECT_TRUE(utils::MakeTempFile("/tmp/delta.XXXXXX", &delta_path, NULL));
Andrew de los Reyes932bc4c2010-08-23 18:14:09 -0700344 LOG(INFO) << "delta path: " << delta_path;
Andrew de los Reyes09e56d62010-04-23 13:45:53 -0700345 ScopedPathUnlinker delta_path_unlinker(delta_path);
346 {
347 string a_mnt, b_mnt;
348 ScopedLoopMounter a_mounter(a_img, &a_mnt, MS_RDONLY);
349 ScopedLoopMounter b_mounter(b_img, &b_mnt, MS_RDONLY);
Darin Petkovcbfb0172011-01-14 15:24:45 -0800350 const string private_key =
351 signature_test == kSignatureGenerator ? kUnittestPrivateKeyPath : "";
Andrew de los Reyes932bc4c2010-08-23 18:14:09 -0700352 EXPECT_TRUE(
Darin Petkov68c10d12010-10-14 09:24:37 -0700353 DeltaDiffGenerator::GenerateDeltaUpdateFile(
Darin Petkov7a22d792010-11-08 14:10:00 -0800354 full_rootfs ? "" : a_mnt,
355 full_rootfs ? "" : a_img,
Darin Petkov68c10d12010-10-14 09:24:37 -0700356 b_mnt,
357 b_img,
358 full_kernel ? "" : old_kernel,
359 new_kernel,
360 delta_path,
Darin Petkovcbfb0172011-01-14 15:24:45 -0800361 private_key));
Darin Petkov9574f7e2011-01-13 10:48:12 -0800362 }
363
Darin Petkovcbfb0172011-01-14 15:24:45 -0800364 if (signature_test == kSignatureGenerated) {
365 SignGeneratedPayload(delta_path);
Darin Petkov52dcaeb2011-01-14 15:33:06 -0800366 } else if (signature_test == kSignatureGeneratedShell ||
Andrew de los Reyesc24e3f32011-08-30 15:45:20 -0700367 signature_test == kSignatureGeneratedShellBadKey ||
368 signature_test == kSignatureGeneratedShellRotateCl1 ||
369 signature_test == kSignatureGeneratedShellRotateCl2) {
Darin Petkov52dcaeb2011-01-14 15:33:06 -0800370 SignGeneratedShellPayload(signature_test, delta_path);
Andrew de los Reyes09e56d62010-04-23 13:45:53 -0700371 }
372
373 // Read delta into memory.
374 vector<char> delta;
Jay Srinivasanf4318702012-09-24 11:56:24 -0700375 uint64_t metadata_size;
Darin Petkov73058b42010-10-06 16:32:19 -0700376
Darin Petkov36a58222010-10-07 22:00:09 -0700377 // Check the metadata.
Andrew de los Reyes932bc4c2010-08-23 18:14:09 -0700378 {
Andrew de los Reyes932bc4c2010-08-23 18:14:09 -0700379 DeltaArchiveManifest manifest;
Jay Srinivasanf4318702012-09-24 11:56:24 -0700380 EXPECT_TRUE(PayloadSigner::LoadPayload(delta_path, &delta, &manifest,
381 &metadata_size));
382 LOG(INFO) << "Metadata size: " << metadata_size;
Andrew de los Reyes932bc4c2010-08-23 18:14:09 -0700383
Darin Petkovcbfb0172011-01-14 15:24:45 -0800384 if (signature_test == kSignatureNone) {
385 EXPECT_FALSE(manifest.has_signatures_offset());
386 EXPECT_FALSE(manifest.has_signatures_size());
387 } else {
388 EXPECT_TRUE(manifest.has_signatures_offset());
389 EXPECT_TRUE(manifest.has_signatures_size());
390 Signatures sigs_message;
391 EXPECT_TRUE(sigs_message.ParseFromArray(
Jay Srinivasanf4318702012-09-24 11:56:24 -0700392 &delta[metadata_size + manifest.signatures_offset()],
Darin Petkovcbfb0172011-01-14 15:24:45 -0800393 manifest.signatures_size()));
Andrew de los Reyesc24e3f32011-08-30 15:45:20 -0700394 if (signature_test == kSignatureGeneratedShellRotateCl1 ||
395 signature_test == kSignatureGeneratedShellRotateCl2)
396 EXPECT_EQ(2, sigs_message.signatures_size());
397 else
398 EXPECT_EQ(1, sigs_message.signatures_size());
Darin Petkovcbfb0172011-01-14 15:24:45 -0800399 const Signatures_Signature& signature = sigs_message.signatures(0);
400 EXPECT_EQ(1, signature.version());
Andrew de los Reyes932bc4c2010-08-23 18:14:09 -0700401
Darin Petkovcbfb0172011-01-14 15:24:45 -0800402 uint64_t expected_sig_data_length = 0;
Andrew de los Reyesc24e3f32011-08-30 15:45:20 -0700403 vector<string> key_paths (1, kUnittestPrivateKeyPath);
404 if (signature_test == kSignatureGeneratedShellRotateCl1 ||
405 signature_test == kSignatureGeneratedShellRotateCl2) {
406 key_paths.push_back(kUnittestPrivateKey2Path);
407 }
Darin Petkovcbfb0172011-01-14 15:24:45 -0800408 EXPECT_TRUE(PayloadSigner::SignatureBlobLength(
Andrew de los Reyesc24e3f32011-08-30 15:45:20 -0700409 key_paths,
410 &expected_sig_data_length));
Darin Petkovcbfb0172011-01-14 15:24:45 -0800411 EXPECT_EQ(expected_sig_data_length, manifest.signatures_size());
412 EXPECT_FALSE(signature.data().empty());
413 }
Darin Petkov36a58222010-10-07 22:00:09 -0700414
Darin Petkov9fa7ec52010-10-18 11:45:23 -0700415 if (noop) {
416 EXPECT_EQ(1, manifest.install_operations_size());
417 EXPECT_EQ(1, manifest.kernel_install_operations_size());
418 }
419
Darin Petkovd43d6902010-10-14 11:17:50 -0700420 if (full_kernel) {
421 EXPECT_FALSE(manifest.has_old_kernel_info());
422 } else {
423 EXPECT_EQ(old_kernel_data.size(), manifest.old_kernel_info().size());
424 EXPECT_FALSE(manifest.old_kernel_info().hash().empty());
425 }
Darin Petkov698d0412010-10-13 10:59:44 -0700426
Darin Petkov7a22d792010-11-08 14:10:00 -0800427 if (full_rootfs) {
428 EXPECT_FALSE(manifest.has_old_rootfs_info());
429 } else {
430 EXPECT_EQ(image_size, manifest.old_rootfs_info().size());
431 EXPECT_FALSE(manifest.old_rootfs_info().hash().empty());
432 }
433
Darin Petkov36a58222010-10-07 22:00:09 -0700434 EXPECT_EQ(new_kernel_data.size(), manifest.new_kernel_info().size());
Darin Petkov7ea32332010-10-13 10:46:11 -0700435 EXPECT_EQ(image_size, manifest.new_rootfs_info().size());
Darin Petkov36a58222010-10-07 22:00:09 -0700436
Darin Petkov36a58222010-10-07 22:00:09 -0700437 EXPECT_FALSE(manifest.new_kernel_info().hash().empty());
Darin Petkov36a58222010-10-07 22:00:09 -0700438 EXPECT_FALSE(manifest.new_rootfs_info().hash().empty());
Andrew de los Reyes932bc4c2010-08-23 18:14:09 -0700439 }
440
Darin Petkov73058b42010-10-06 16:32:19 -0700441 PrefsMock prefs;
442 EXPECT_CALL(prefs, SetInt64(kPrefsManifestMetadataSize,
Jay Srinivasanf4318702012-09-24 11:56:24 -0700443 metadata_size)).WillOnce(Return(true));
Darin Petkov73058b42010-10-06 16:32:19 -0700444 EXPECT_CALL(prefs, SetInt64(kPrefsUpdateStateNextOperation, _))
445 .WillRepeatedly(Return(true));
Darin Petkov9b230572010-10-08 10:20:09 -0700446 EXPECT_CALL(prefs, GetInt64(kPrefsUpdateStateNextOperation, _))
447 .WillOnce(Return(false));
Darin Petkov73058b42010-10-06 16:32:19 -0700448 EXPECT_CALL(prefs, SetInt64(kPrefsUpdateStateNextDataOffset, _))
449 .WillRepeatedly(Return(true));
Darin Petkov437adc42010-10-07 13:12:24 -0700450 EXPECT_CALL(prefs, SetString(kPrefsUpdateStateSHA256Context, _))
Darin Petkov73058b42010-10-06 16:32:19 -0700451 .WillRepeatedly(Return(true));
Darin Petkovcbfb0172011-01-14 15:24:45 -0800452 if (signature_test != kSignatureNone) {
453 EXPECT_CALL(prefs, SetString(kPrefsUpdateStateSignedSHA256Context, _))
454 .WillOnce(Return(true));
Darin Petkov4f0a07b2011-05-25 16:47:20 -0700455 EXPECT_CALL(prefs, SetString(kPrefsUpdateStateSignatureBlob, _))
456 .WillOnce(Return(true));
Darin Petkovcbfb0172011-01-14 15:24:45 -0800457 }
Darin Petkov73058b42010-10-06 16:32:19 -0700458
Andrew de los Reyes09e56d62010-04-23 13:45:53 -0700459 // Update the A image in place.
Jay Srinivasan51dcf262012-09-13 17:24:32 -0700460 InstallPlan install_plan;
Jay Srinivasanf0572052012-10-23 18:12:56 -0700461 MockSystemState mock_system_state;
462 DeltaPerformer performer(&prefs, &mock_system_state, &install_plan);
Jay Srinivasan51dcf262012-09-13 17:24:32 -0700463 EXPECT_TRUE(utils::FileExists(kUnittestPublicKeyPath));
464 performer.set_public_key_path(kUnittestPublicKeyPath);
Andrew de los Reyes09e56d62010-04-23 13:45:53 -0700465
Darin Petkovd43d6902010-10-14 11:17:50 -0700466 EXPECT_EQ(image_size,
467 OmahaHashCalculator::RawHashOfFile(a_img,
468 image_size,
Jay Srinivasan51dcf262012-09-13 17:24:32 -0700469 &install_plan.rootfs_hash));
Darin Petkovd43d6902010-10-14 11:17:50 -0700470 EXPECT_TRUE(OmahaHashCalculator::RawHashOfData(old_kernel_data,
Jay Srinivasan51dcf262012-09-13 17:24:32 -0700471 &install_plan.kernel_hash));
Darin Petkovd43d6902010-10-14 11:17:50 -0700472
Andrew de los Reyes09e56d62010-04-23 13:45:53 -0700473 EXPECT_EQ(0, performer.Open(a_img.c_str(), 0, 0));
Andrew de los Reyesf4c7ef12010-04-30 10:37:00 -0700474 EXPECT_TRUE(performer.OpenKernel(old_kernel.c_str()));
Andrew de los Reyes09e56d62010-04-23 13:45:53 -0700475
476 // Write at some number of bytes per operation. Arbitrarily chose 5.
477 const size_t kBytesPerWrite = 5;
478 for (size_t i = 0; i < delta.size(); i += kBytesPerWrite) {
479 size_t count = min(delta.size() - i, kBytesPerWrite);
Don Garrette410e0f2011-11-10 15:39:01 -0800480 EXPECT_TRUE(performer.Write(&delta[i], count));
Andrew de los Reyes09e56d62010-04-23 13:45:53 -0700481 }
482
483 // Wrapper around close. Returns 0 on success or -errno on error.
484 EXPECT_EQ(0, performer.Close());
485
Andrew de los Reyesf4c7ef12010-04-30 10:37:00 -0700486 CompareFilesByBlock(old_kernel, new_kernel);
Darin Petkov2dd01092010-10-08 15:43:05 -0700487 CompareFilesByBlock(a_img, b_img);
Andrew de los Reyes932bc4c2010-08-23 18:14:09 -0700488
Andrew de los Reyesf4c7ef12010-04-30 10:37:00 -0700489 vector<char> updated_kernel_partition;
490 EXPECT_TRUE(utils::ReadFile(old_kernel, &updated_kernel_partition));
491 EXPECT_EQ(0, strncmp(&updated_kernel_partition[0], new_data_string,
492 strlen(new_data_string)));
Darin Petkovd7061ab2010-10-06 14:37:09 -0700493
Andrew de los Reyes771e1bd2011-08-30 14:47:23 -0700494 ActionExitCode expect_verify_result = kActionCodeSuccess;
495 switch (signature_test) {
496 case kSignatureNone:
497 expect_verify_result = kActionCodeSignedDeltaPayloadExpectedError;
498 break;
499 case kSignatureGeneratedShellBadKey:
500 expect_verify_result = kActionCodeDownloadPayloadPubKeyVerificationError;
501 break;
502 default: break; // appease gcc
503 }
504 EXPECT_EQ(expect_verify_result, performer.VerifyPayload(
Andrew de los Reyesfb830ba2011-04-04 11:42:43 -0700505 OmahaHashCalculator::OmahaHashOfData(delta),
Andrew de los Reyes771e1bd2011-08-30 14:47:23 -0700506 delta.size()));
Jay Srinivasan51dcf262012-09-13 17:24:32 -0700507
508 performer.set_public_key_path("/public/key/does/not/exists");
Andrew de los Reyes771e1bd2011-08-30 14:47:23 -0700509 EXPECT_EQ(kActionCodeSuccess, performer.VerifyPayload(
Darin Petkov52dcaeb2011-01-14 15:33:06 -0800510 OmahaHashCalculator::OmahaHashOfData(delta),
Andrew de los Reyes771e1bd2011-08-30 14:47:23 -0700511 delta.size()));
Darin Petkov3aefa862010-12-07 14:45:00 -0800512
513 uint64_t new_kernel_size;
514 vector<char> new_kernel_hash;
515 uint64_t new_rootfs_size;
516 vector<char> new_rootfs_hash;
517 EXPECT_TRUE(performer.GetNewPartitionInfo(&new_kernel_size,
518 &new_kernel_hash,
519 &new_rootfs_size,
520 &new_rootfs_hash));
521 EXPECT_EQ(4096, new_kernel_size);
522 vector<char> expected_new_kernel_hash;
523 EXPECT_TRUE(OmahaHashCalculator::RawHashOfData(new_kernel_data,
524 &expected_new_kernel_hash));
525 EXPECT_TRUE(expected_new_kernel_hash == new_kernel_hash);
526 EXPECT_EQ(image_size, new_rootfs_size);
527 vector<char> expected_new_rootfs_hash;
528 EXPECT_EQ(image_size,
529 OmahaHashCalculator::RawHashOfFile(b_img,
530 image_size,
531 &expected_new_rootfs_hash));
532 EXPECT_TRUE(expected_new_rootfs_hash == new_rootfs_hash);
Andrew de los Reyes09e56d62010-04-23 13:45:53 -0700533}
Jay Srinivasan51dcf262012-09-13 17:24:32 -0700534
535// TODO(jaysri): Refactor the previous unit test so we can reuse a lot of
536// code between these two methods.
537void DoManifestTest() {
538 bool full_kernel = false;
539 bool full_rootfs = false;
540 string a_img, b_img;
541 EXPECT_TRUE(utils::MakeTempFile("/tmp/a_img.XXXXXX", &a_img, NULL));
542 ScopedPathUnlinker a_img_unlinker(a_img);
543 EXPECT_TRUE(utils::MakeTempFile("/tmp/b_img.XXXXXX", &b_img, NULL));
544 ScopedPathUnlinker b_img_unlinker(b_img);
545
546 CreateExtImageAtPath(a_img, NULL);
547
548 int image_size = static_cast<int>(utils::FileSize(a_img));
549
550 // Extend the "partitions" holding the file system a bit.
551 EXPECT_EQ(0, System(base::StringPrintf(
552 "dd if=/dev/zero of=%s seek=%d bs=1 count=1",
553 a_img.c_str(),
554 image_size + 1024 * 1024 - 1)));
555 EXPECT_EQ(image_size + 1024 * 1024, utils::FileSize(a_img));
556
557 // Make some changes to the A image.
558 {
559 string a_mnt;
560 ScopedLoopMounter b_mounter(a_img, &a_mnt, 0);
561
562 EXPECT_TRUE(utils::WriteFile(StringPrintf("%s/hardtocompress",
563 a_mnt.c_str()).c_str(),
564 reinterpret_cast<const char*>(kRandomString),
565 sizeof(kRandomString) - 1));
566 // Write 1 MiB of 0xff to try to catch the case where writing a bsdiff
567 // patch fails to zero out the final block.
568 vector<char> ones(1024 * 1024, 0xff);
569 EXPECT_TRUE(utils::WriteFile(StringPrintf("%s/ones",
570 a_mnt.c_str()).c_str(),
571 &ones[0],
572 ones.size()));
573 }
574
575 {
576 CreateExtImageAtPath(b_img, NULL);
577 EXPECT_EQ(0, System(base::StringPrintf(
578 "dd if=/dev/zero of=%s seek=%d bs=1 count=1",
579 b_img.c_str(),
580 image_size + 1024 * 1024 - 1)));
581 EXPECT_EQ(image_size + 1024 * 1024, utils::FileSize(b_img));
582
583 // Make some changes to the B image.
584 string b_mnt;
585 ScopedLoopMounter b_mounter(b_img, &b_mnt, 0);
586
587 EXPECT_EQ(0, system(StringPrintf("cp %s/hello %s/hello2", b_mnt.c_str(),
588 b_mnt.c_str()).c_str()));
589 EXPECT_EQ(0, system(StringPrintf("rm %s/hello", b_mnt.c_str()).c_str()));
590 EXPECT_EQ(0, system(StringPrintf("mv %s/hello2 %s/hello", b_mnt.c_str(),
591 b_mnt.c_str()).c_str()));
592 EXPECT_EQ(0, system(StringPrintf("echo foo > %s/foo",
593 b_mnt.c_str()).c_str()));
594 EXPECT_EQ(0, system(StringPrintf("touch %s/emptyfile",
595 b_mnt.c_str()).c_str()));
596 EXPECT_TRUE(WriteSparseFile(StringPrintf("%s/fullsparse", b_mnt.c_str()),
597 1024 * 1024));
598 EXPECT_EQ(0, system(StringPrintf("dd if=/dev/zero of=%s/partsparese bs=1 "
599 "seek=4096 count=1",
600 b_mnt.c_str()).c_str()));
601 EXPECT_EQ(0, system(StringPrintf("cp %s/srchardlink0 %s/tmp && "
602 "mv %s/tmp %s/srchardlink1",
603 b_mnt.c_str(), b_mnt.c_str(),
604 b_mnt.c_str(), b_mnt.c_str()).c_str()));
605 EXPECT_EQ(0, system(StringPrintf("rm %s/boguslink && "
606 "echo foobar > %s/boguslink",
607 b_mnt.c_str(), b_mnt.c_str()).c_str()));
608 EXPECT_TRUE(utils::WriteFile(StringPrintf("%s/hardtocompress",
609 b_mnt.c_str()).c_str(),
610 reinterpret_cast<const char*>(kRandomString),
611 sizeof(kRandomString)));
612 }
613
614 string old_kernel;
615 EXPECT_TRUE(utils::MakeTempFile("/tmp/old_kernel.XXXXXX", &old_kernel, NULL));
616 ScopedPathUnlinker old_kernel_unlinker(old_kernel);
617
618 string new_kernel;
619 EXPECT_TRUE(utils::MakeTempFile("/tmp/new_kernel.XXXXXX", &new_kernel, NULL));
620 ScopedPathUnlinker new_kernel_unlinker(new_kernel);
621
622 vector<char> old_kernel_data(4096); // Something small for a test
623 vector<char> new_kernel_data(old_kernel_data.size());
624 FillWithData(&old_kernel_data);
625 FillWithData(&new_kernel_data);
626
627 // change the new kernel data
628 const char* new_data_string = "This is new data.";
629 strcpy(&new_kernel_data[0], new_data_string);
630
631 // Write kernels to disk
632 EXPECT_TRUE(utils::WriteFile(
633 old_kernel.c_str(), &old_kernel_data[0], old_kernel_data.size()));
634 EXPECT_TRUE(utils::WriteFile(
635 new_kernel.c_str(), &new_kernel_data[0], new_kernel_data.size()));
636
637 string delta_path;
638 EXPECT_TRUE(utils::MakeTempFile("/tmp/delta.XXXXXX", &delta_path, NULL));
639 LOG(INFO) << "delta path: " << delta_path;
640 ScopedPathUnlinker delta_path_unlinker(delta_path);
641 {
642 string a_mnt, b_mnt;
643 ScopedLoopMounter a_mounter(a_img, &a_mnt, MS_RDONLY);
644 ScopedLoopMounter b_mounter(b_img, &b_mnt, MS_RDONLY);
645 const string private_key = kUnittestPrivateKeyPath;
646 EXPECT_TRUE(
647 DeltaDiffGenerator::GenerateDeltaUpdateFile(
648 full_rootfs ? "" : a_mnt,
649 full_rootfs ? "" : a_img,
650 b_mnt,
651 b_img,
652 full_kernel ? "" : old_kernel,
653 new_kernel,
654 delta_path,
655 private_key));
656 }
657
658 // Read delta into memory.
659 vector<char> delta;
Jay Srinivasanf4318702012-09-24 11:56:24 -0700660 uint64_t metadata_size;
Jay Srinivasan51dcf262012-09-13 17:24:32 -0700661 // Check the metadata.
662 {
Jay Srinivasan51dcf262012-09-13 17:24:32 -0700663 DeltaArchiveManifest manifest;
Jay Srinivasanf4318702012-09-24 11:56:24 -0700664 EXPECT_TRUE(PayloadSigner::LoadPayload(delta_path, &delta, &manifest,
665 &metadata_size));
666
667 LOG(INFO) << "Metadata size: " << metadata_size;
Jay Srinivasan51dcf262012-09-13 17:24:32 -0700668
669 {
670 EXPECT_TRUE(manifest.has_signatures_offset());
671 EXPECT_TRUE(manifest.has_signatures_size());
672 Signatures sigs_message;
673 EXPECT_TRUE(sigs_message.ParseFromArray(
Jay Srinivasanf4318702012-09-24 11:56:24 -0700674 &delta[metadata_size + manifest.signatures_offset()],
Jay Srinivasan51dcf262012-09-13 17:24:32 -0700675 manifest.signatures_size()));
676 EXPECT_EQ(1, sigs_message.signatures_size());
677 const Signatures_Signature& signature = sigs_message.signatures(0);
678 EXPECT_EQ(1, signature.version());
679
680 uint64_t expected_sig_data_length = 0;
681 vector<string> key_paths (1, kUnittestPrivateKeyPath);
682 EXPECT_TRUE(PayloadSigner::SignatureBlobLength(
683 key_paths,
684 &expected_sig_data_length));
685 EXPECT_EQ(expected_sig_data_length, manifest.signatures_size());
686 EXPECT_FALSE(signature.data().empty());
687 }
688
689 if (full_kernel) {
690 EXPECT_FALSE(manifest.has_old_kernel_info());
691 } else {
692 EXPECT_EQ(old_kernel_data.size(), manifest.old_kernel_info().size());
693 EXPECT_FALSE(manifest.old_kernel_info().hash().empty());
694 }
695
696 if (full_rootfs) {
697 EXPECT_FALSE(manifest.has_old_rootfs_info());
698 } else {
699 EXPECT_EQ(image_size, manifest.old_rootfs_info().size());
700 EXPECT_FALSE(manifest.old_rootfs_info().hash().empty());
701 }
702
703 EXPECT_EQ(new_kernel_data.size(), manifest.new_kernel_info().size());
704 EXPECT_EQ(image_size, manifest.new_rootfs_info().size());
705
706 EXPECT_FALSE(manifest.new_kernel_info().hash().empty());
707 EXPECT_FALSE(manifest.new_rootfs_info().hash().empty());
708
709 }
710
711 PrefsMock prefs;
712 EXPECT_CALL(prefs, SetInt64(kPrefsManifestMetadataSize,
Jay Srinivasanf4318702012-09-24 11:56:24 -0700713 metadata_size)).WillOnce(Return(true));
Jay Srinivasan51dcf262012-09-13 17:24:32 -0700714 EXPECT_CALL(prefs, SetInt64(kPrefsUpdateStateNextOperation, _))
715 .WillRepeatedly(Return(true));
716 EXPECT_CALL(prefs, GetInt64(kPrefsUpdateStateNextOperation, _))
717 .WillOnce(Return(false));
718 EXPECT_CALL(prefs, SetInt64(kPrefsUpdateStateNextDataOffset, _))
719 .WillRepeatedly(Return(true));
720 EXPECT_CALL(prefs, SetString(kPrefsUpdateStateSHA256Context, _))
721 .WillRepeatedly(Return(true));
722 EXPECT_CALL(prefs, SetString(kPrefsUpdateStateSignedSHA256Context, _))
723 .WillRepeatedly(Return(true));
724 EXPECT_CALL(prefs, SetString(kPrefsUpdateStateSignatureBlob, _))
725 .WillOnce(Return(true));
726
727 // Update the A image in place.
728 InstallPlan install_plan;
Jay Srinivasanf4318702012-09-24 11:56:24 -0700729 install_plan.metadata_size = metadata_size;
730 LOG(INFO) << "Setting payload metadata size in Omaha = " << metadata_size;
731 ASSERT_TRUE(PayloadSigner::GetMetadataSignature(
732 &delta[0],
733 metadata_size,
Jay Srinivasan51dcf262012-09-13 17:24:32 -0700734 kUnittestPrivateKeyPath,
Jay Srinivasanf4318702012-09-24 11:56:24 -0700735 &install_plan.metadata_signature));
736 EXPECT_FALSE(install_plan.metadata_signature.empty());
Jay Srinivasan51dcf262012-09-13 17:24:32 -0700737
Jay Srinivasanf0572052012-10-23 18:12:56 -0700738 MockSystemState mock_system_state;
739 DeltaPerformer performer(&prefs, &mock_system_state, &install_plan);
Jay Srinivasan51dcf262012-09-13 17:24:32 -0700740 EXPECT_TRUE(utils::FileExists(kUnittestPublicKeyPath));
741 performer.set_public_key_path(kUnittestPublicKeyPath);
742
743 EXPECT_EQ(image_size,
744 OmahaHashCalculator::RawHashOfFile(a_img,
745 image_size,
746 &install_plan.rootfs_hash));
747 EXPECT_TRUE(OmahaHashCalculator::RawHashOfData(old_kernel_data,
748 &install_plan.kernel_hash));
749
750 EXPECT_EQ(0, performer.Open(a_img.c_str(), 0, 0));
751 EXPECT_TRUE(performer.OpenKernel(old_kernel.c_str()));
752
753 // Write at some number of bytes per operation. Arbitrarily chose 5.
754 const size_t kBytesPerWrite = 5;
755 for (size_t i = 0; i < delta.size(); i += kBytesPerWrite) {
756 size_t count = min(delta.size() - i, kBytesPerWrite);
757 EXPECT_TRUE(performer.Write(&delta[i], count));
758 }
759
760 // Wrapper around close. Returns 0 on success or -errno on error.
761 EXPECT_EQ(0, performer.Close());
762
763 CompareFilesByBlock(old_kernel, new_kernel);
764 CompareFilesByBlock(a_img, b_img);
765
766 vector<char> updated_kernel_partition;
767 EXPECT_TRUE(utils::ReadFile(old_kernel, &updated_kernel_partition));
768 EXPECT_EQ(0, strncmp(&updated_kernel_partition[0], new_data_string,
769 strlen(new_data_string)));
770
771 ActionExitCode expect_verify_result = kActionCodeSuccess;
772 LOG(INFO) << "Verifying Payload ...";
773 EXPECT_EQ(expect_verify_result, performer.VerifyPayload(
774 OmahaHashCalculator::OmahaHashOfData(delta),
775 delta.size()));
776
777 LOG(INFO) << "Verified Payload";
778
779 uint64_t new_kernel_size;
780 vector<char> new_kernel_hash;
781 uint64_t new_rootfs_size;
782 vector<char> new_rootfs_hash;
783 EXPECT_TRUE(performer.GetNewPartitionInfo(&new_kernel_size,
784 &new_kernel_hash,
785 &new_rootfs_size,
786 &new_rootfs_hash));
787 EXPECT_EQ(4096, new_kernel_size);
788 vector<char> expected_new_kernel_hash;
789 EXPECT_TRUE(OmahaHashCalculator::RawHashOfData(new_kernel_data,
790 &expected_new_kernel_hash));
791 EXPECT_TRUE(expected_new_kernel_hash == new_kernel_hash);
792 EXPECT_EQ(image_size, new_rootfs_size);
793 vector<char> expected_new_rootfs_hash;
794 EXPECT_EQ(image_size,
795 OmahaHashCalculator::RawHashOfFile(b_img,
796 image_size,
797 &expected_new_rootfs_hash));
798 EXPECT_TRUE(expected_new_rootfs_hash == new_rootfs_hash);
799}
Andrew de los Reyesc24e3f32011-08-30 15:45:20 -0700800} // namespace {}
Darin Petkov68c10d12010-10-14 09:24:37 -0700801
802TEST(DeltaPerformerTest, RunAsRootSmallImageTest) {
Darin Petkovcbfb0172011-01-14 15:24:45 -0800803 DoSmallImageTest(false, false, false, kSignatureGenerator);
Darin Petkov68c10d12010-10-14 09:24:37 -0700804}
805
806TEST(DeltaPerformerTest, RunAsRootFullKernelSmallImageTest) {
Darin Petkovcbfb0172011-01-14 15:24:45 -0800807 DoSmallImageTest(true, false, false, kSignatureGenerator);
Darin Petkov7a22d792010-11-08 14:10:00 -0800808}
809
810TEST(DeltaPerformerTest, RunAsRootFullSmallImageTest) {
Darin Petkovcbfb0172011-01-14 15:24:45 -0800811 DoSmallImageTest(true, true, false, kSignatureGenerator);
Darin Petkov9fa7ec52010-10-18 11:45:23 -0700812}
813
814TEST(DeltaPerformerTest, RunAsRootNoopSmallImageTest) {
Darin Petkovcbfb0172011-01-14 15:24:45 -0800815 DoSmallImageTest(false, false, true, kSignatureGenerator);
Darin Petkov9574f7e2011-01-13 10:48:12 -0800816}
817
Darin Petkovcbfb0172011-01-14 15:24:45 -0800818TEST(DeltaPerformerTest, RunAsRootSmallImageSignNoneTest) {
819 DoSmallImageTest(false, false, false, kSignatureNone);
820}
821
822TEST(DeltaPerformerTest, RunAsRootSmallImageSignGeneratedTest) {
823 DoSmallImageTest(false, false, false, kSignatureGenerated);
824}
825
826TEST(DeltaPerformerTest, RunAsRootSmallImageSignGeneratedShellTest) {
827 DoSmallImageTest(false, false, false, kSignatureGeneratedShell);
Andrew de los Reyes27f7d372010-10-07 11:26:07 -0700828}
829
Darin Petkov52dcaeb2011-01-14 15:33:06 -0800830TEST(DeltaPerformerTest, RunAsRootSmallImageSignGeneratedShellBadKeyTest) {
831 DoSmallImageTest(false, false, false, kSignatureGeneratedShellBadKey);
832}
833
Andrew de los Reyesc24e3f32011-08-30 15:45:20 -0700834TEST(DeltaPerformerTest, RunAsRootSmallImageSignGeneratedShellRotateCl1Test) {
835 DoSmallImageTest(false, false, false, kSignatureGeneratedShellRotateCl1);
836}
837
838TEST(DeltaPerformerTest, RunAsRootSmallImageSignGeneratedShellRotateCl2Test) {
839 DoSmallImageTest(false, false, false, kSignatureGeneratedShellRotateCl2);
840}
841
Darin Petkov934bb412010-11-18 11:21:35 -0800842TEST(DeltaPerformerTest, BadDeltaMagicTest) {
843 PrefsMock prefs;
Jay Srinivasan51dcf262012-09-13 17:24:32 -0700844 InstallPlan install_plan;
Jay Srinivasanf0572052012-10-23 18:12:56 -0700845 MockSystemState mock_system_state;
846 DeltaPerformer performer(&prefs, &mock_system_state, &install_plan);
Darin Petkov934bb412010-11-18 11:21:35 -0800847 EXPECT_EQ(0, performer.Open("/dev/null", 0, 0));
848 EXPECT_TRUE(performer.OpenKernel("/dev/null"));
Don Garrette410e0f2011-11-10 15:39:01 -0800849 EXPECT_TRUE(performer.Write("junk", 4));
850 EXPECT_TRUE(performer.Write("morejunk", 8));
851 EXPECT_FALSE(performer.Write("morejunk", 8));
Darin Petkov934bb412010-11-18 11:21:35 -0800852 EXPECT_LT(performer.Close(), 0);
853}
854
Andrew de los Reyes353777c2010-10-08 10:34:30 -0700855TEST(DeltaPerformerTest, IsIdempotentOperationTest) {
856 DeltaArchiveManifest_InstallOperation op;
857 EXPECT_TRUE(DeltaPerformer::IsIdempotentOperation(op));
858 *(op.add_dst_extents()) = ExtentForRange(0, 5);
859 EXPECT_TRUE(DeltaPerformer::IsIdempotentOperation(op));
860 *(op.add_src_extents()) = ExtentForRange(4, 1);
861 EXPECT_FALSE(DeltaPerformer::IsIdempotentOperation(op));
862 op.clear_src_extents();
863 *(op.add_src_extents()) = ExtentForRange(5, 3);
864 EXPECT_TRUE(DeltaPerformer::IsIdempotentOperation(op));
865 *(op.add_dst_extents()) = ExtentForRange(20, 6);
866 EXPECT_TRUE(DeltaPerformer::IsIdempotentOperation(op));
867 *(op.add_src_extents()) = ExtentForRange(19, 2);
868 EXPECT_FALSE(DeltaPerformer::IsIdempotentOperation(op));
869}
870
Jay Srinivasan51dcf262012-09-13 17:24:32 -0700871TEST(DeltaPerformerTest, RunAsRootRunValidManifestTest) {
872 DoManifestTest();
873}
874
875
Andrew de los Reyes09e56d62010-04-23 13:45:53 -0700876} // namespace chromeos_update_engine