blob: bfb57ebd3eb45819f02942a36057c9917bcb31ed [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"
Andrew de los Reyes932bc4c2010-08-23 18:14:09 -070024#include "update_engine/payload_signer.h"
Darin Petkov73058b42010-10-06 16:32:19 -070025#include "update_engine/prefs_mock.h"
Andrew de los Reyes09e56d62010-04-23 13:45:53 -070026#include "update_engine/test_utils.h"
27#include "update_engine/update_metadata.pb.h"
28#include "update_engine/utils.h"
29
30namespace chromeos_update_engine {
31
32using std::min;
33using std::string;
34using std::vector;
Darin Petkov73058b42010-10-06 16:32:19 -070035using testing::_;
36using testing::Return;
Andrew de los Reyes09e56d62010-04-23 13:45:53 -070037
Andrew de los Reyes932bc4c2010-08-23 18:14:09 -070038extern const char* kUnittestPrivateKeyPath;
Darin Petkovd7061ab2010-10-06 14:37:09 -070039extern const char* kUnittestPublicKeyPath;
Andrew de los Reyesc24e3f32011-08-30 15:45:20 -070040extern const char* kUnittestPrivateKey2Path;
41extern const char* kUnittestPublicKey2Path;
Andrew de los Reyes932bc4c2010-08-23 18:14:09 -070042
Andrew de los Reyes27f7d372010-10-07 11:26:07 -070043namespace {
Andrew de los Reyes29da8aa2011-02-15 13:34:57 -080044const size_t kBlockSize = 4096;
Andrew de los Reyes27f7d372010-10-07 11:26:07 -070045} // namespace {}
46
47
Andrew de los Reyes09e56d62010-04-23 13:45:53 -070048class DeltaPerformerTest : public ::testing::Test { };
49
50TEST(DeltaPerformerTest, ExtentsToByteStringTest) {
51 uint64_t test[] = {1, 1, 4, 2, kSparseHole, 1, 0, 1};
52 COMPILE_ASSERT(arraysize(test) % 2 == 0, array_size_uneven);
53 const uint64_t block_size = 4096;
54 const uint64_t file_length = 5 * block_size - 13;
55
56 google::protobuf::RepeatedPtrField<Extent> extents;
57 for (size_t i = 0; i < arraysize(test); i += 2) {
58 Extent* extent = extents.Add();
59 extent->set_start_block(test[i]);
60 extent->set_num_blocks(test[i + 1]);
61 }
62
63 string expected_output = "4096:4096,16384:8192,-1:4096,0:4083";
64 string actual_output;
65 EXPECT_TRUE(DeltaPerformer::ExtentsToBsdiffPositionsString(extents,
66 block_size,
67 file_length,
68 &actual_output));
69 EXPECT_EQ(expected_output, actual_output);
70}
71
Andrew de los Reyes09e56d62010-04-23 13:45:53 -070072void CompareFilesByBlock(const string& a_file, const string& b_file) {
73 vector<char> a_data, b_data;
Andrew de los Reyes3270f742010-07-15 22:28:14 -070074 EXPECT_TRUE(utils::ReadFile(a_file, &a_data)) << "file failed: " << a_file;
75 EXPECT_TRUE(utils::ReadFile(b_file, &b_data)) << "file failed: " << b_file;
Andrew de los Reyes09e56d62010-04-23 13:45:53 -070076
77 EXPECT_EQ(a_data.size(), b_data.size());
Andrew de los Reyes09e56d62010-04-23 13:45:53 -070078 EXPECT_EQ(0, a_data.size() % kBlockSize);
79 for (size_t i = 0; i < a_data.size(); i += kBlockSize) {
80 EXPECT_EQ(0, i % kBlockSize);
81 vector<char> a_sub(&a_data[i], &a_data[i + kBlockSize]);
82 vector<char> b_sub(&b_data[i], &b_data[i + kBlockSize]);
83 EXPECT_TRUE(a_sub == b_sub) << "Block " << (i/kBlockSize) << " differs";
84 }
85}
86
87namespace {
88bool WriteSparseFile(const string& path, off_t size) {
89 int fd = open(path.c_str(), O_CREAT | O_TRUNC | O_WRONLY, 0644);
90 TEST_AND_RETURN_FALSE_ERRNO(fd >= 0);
91 ScopedFdCloser fd_closer(&fd);
92 off_t rc = lseek(fd, size + 1, SEEK_SET);
93 TEST_AND_RETURN_FALSE_ERRNO(rc != static_cast<off_t>(-1));
94 int return_code = ftruncate(fd, size);
95 TEST_AND_RETURN_FALSE_ERRNO(return_code == 0);
96 return true;
97}
Darin Petkov9574f7e2011-01-13 10:48:12 -080098} // namespace {}
Andrew de los Reyes09e56d62010-04-23 13:45:53 -070099
Darin Petkov9574f7e2011-01-13 10:48:12 -0800100namespace {
Darin Petkovcbfb0172011-01-14 15:24:45 -0800101enum SignatureTest {
102 kSignatureNone, // No payload signing.
103 kSignatureGenerator, // Sign the payload at generation time.
104 kSignatureGenerated, // Sign the payload after it's generated.
105 kSignatureGeneratedShell, // Sign the generated payload through shell cmds.
Darin Petkov52dcaeb2011-01-14 15:33:06 -0800106 kSignatureGeneratedShellBadKey, // Sign with a bad key through shell cmds.
Andrew de los Reyesc24e3f32011-08-30 15:45:20 -0700107 kSignatureGeneratedShellRotateCl1, // Rotate key, test client v1
108 kSignatureGeneratedShellRotateCl2, // Rotate key, test client v2
Darin Petkovcbfb0172011-01-14 15:24:45 -0800109};
110
Darin Petkov52dcaeb2011-01-14 15:33:06 -0800111size_t GetSignatureSize(const string& private_key_path) {
Darin Petkovcbfb0172011-01-14 15:24:45 -0800112 const vector<char> data(1, 'x');
113 vector<char> hash;
114 EXPECT_TRUE(OmahaHashCalculator::RawHashOfData(data, &hash));
115 vector<char> signature;
116 EXPECT_TRUE(PayloadSigner::SignHash(hash,
Darin Petkov52dcaeb2011-01-14 15:33:06 -0800117 private_key_path,
Darin Petkovcbfb0172011-01-14 15:24:45 -0800118 &signature));
119 return signature.size();
120}
121
122void SignGeneratedPayload(const string& payload_path) {
Darin Petkov52dcaeb2011-01-14 15:33:06 -0800123 int signature_size = GetSignatureSize(kUnittestPrivateKeyPath);
Darin Petkovcbfb0172011-01-14 15:24:45 -0800124 vector<char> hash;
Andrew de los Reyesc24e3f32011-08-30 15:45:20 -0700125 ASSERT_TRUE(PayloadSigner::HashPayloadForSigning(
126 payload_path,
127 vector<int>(1, signature_size),
128 &hash));
Darin Petkovcbfb0172011-01-14 15:24:45 -0800129 vector<char> signature;
130 ASSERT_TRUE(PayloadSigner::SignHash(hash,
131 kUnittestPrivateKeyPath,
132 &signature));
Andrew de los Reyesc24e3f32011-08-30 15:45:20 -0700133 ASSERT_TRUE(PayloadSigner::AddSignatureToPayload(
134 payload_path,
135 vector<vector<char> >(1, signature),
136 payload_path));
137 EXPECT_TRUE(PayloadSigner::VerifySignedPayload(
138 payload_path,
139 kUnittestPublicKeyPath,
140 kSignatureMessageOriginalVersion));
Darin Petkovcbfb0172011-01-14 15:24:45 -0800141}
142
Darin Petkov52dcaeb2011-01-14 15:33:06 -0800143void SignGeneratedShellPayload(SignatureTest signature_test,
144 const string& payload_path) {
145 string private_key_path = kUnittestPrivateKeyPath;
146 if (signature_test == kSignatureGeneratedShellBadKey) {
147 ASSERT_TRUE(utils::MakeTempFile("/tmp/key.XXXXXX",
148 &private_key_path,
149 NULL));
150 } else {
Andrew de los Reyesc24e3f32011-08-30 15:45:20 -0700151 ASSERT_TRUE(signature_test == kSignatureGeneratedShell ||
152 signature_test == kSignatureGeneratedShellRotateCl1 ||
153 signature_test == kSignatureGeneratedShellRotateCl2);
Darin Petkov52dcaeb2011-01-14 15:33:06 -0800154 }
155 ScopedPathUnlinker key_unlinker(private_key_path);
156 key_unlinker.set_should_remove(signature_test ==
157 kSignatureGeneratedShellBadKey);
158 // Generates a new private key that will not match the public key.
159 if (signature_test == kSignatureGeneratedShellBadKey) {
160 LOG(INFO) << "Generating a mismatched private key.";
161 ASSERT_EQ(0,
162 System(StringPrintf(
Mike Frysinger2149be42012-03-12 19:23:47 -0400163 "openssl genrsa -out %s 2048",
Darin Petkov52dcaeb2011-01-14 15:33:06 -0800164 private_key_path.c_str())));
165 }
166 int signature_size = GetSignatureSize(private_key_path);
Darin Petkovcbfb0172011-01-14 15:24:45 -0800167 string hash_file;
168 ASSERT_TRUE(utils::MakeTempFile("/tmp/hash.XXXXXX", &hash_file, NULL));
169 ScopedPathUnlinker hash_unlinker(hash_file);
Andrew de los Reyesc24e3f32011-08-30 15:45:20 -0700170 string signature_size_string;
171 if (signature_test == kSignatureGeneratedShellRotateCl1 ||
172 signature_test == kSignatureGeneratedShellRotateCl2)
173 signature_size_string = StringPrintf("%d:%d",
174 signature_size, signature_size);
175 else
176 signature_size_string = StringPrintf("%d", signature_size);
Darin Petkovcbfb0172011-01-14 15:24:45 -0800177 ASSERT_EQ(0,
178 System(StringPrintf(
Andrew de los Reyesc24e3f32011-08-30 15:45:20 -0700179 "./delta_generator -in_file %s -signature_size %s "
Darin Petkovcbfb0172011-01-14 15:24:45 -0800180 "-out_hash_file %s",
181 payload_path.c_str(),
Andrew de los Reyesc24e3f32011-08-30 15:45:20 -0700182 signature_size_string.c_str(),
Darin Petkovcbfb0172011-01-14 15:24:45 -0800183 hash_file.c_str())));
184
Andrew de los Reyesbdfaaf02011-03-30 10:35:12 -0700185 // Pad the hash
186 vector<char> hash;
187 ASSERT_TRUE(utils::ReadFile(hash_file, &hash));
188 ASSERT_TRUE(PayloadSigner::PadRSA2048SHA256Hash(&hash));
189 ASSERT_TRUE(WriteFileVector(hash_file, hash));
190
Darin Petkovcbfb0172011-01-14 15:24:45 -0800191 string sig_file;
192 ASSERT_TRUE(utils::MakeTempFile("/tmp/signature.XXXXXX", &sig_file, NULL));
193 ScopedPathUnlinker sig_unlinker(sig_file);
194 ASSERT_EQ(0,
195 System(StringPrintf(
Mike Frysinger2149be42012-03-12 19:23:47 -0400196 "openssl rsautl -raw -sign -inkey %s -in %s -out %s",
Darin Petkov52dcaeb2011-01-14 15:33:06 -0800197 private_key_path.c_str(),
Darin Petkovcbfb0172011-01-14 15:24:45 -0800198 hash_file.c_str(),
199 sig_file.c_str())));
Andrew de los Reyesc24e3f32011-08-30 15:45:20 -0700200 string sig_file2;
201 ASSERT_TRUE(utils::MakeTempFile("/tmp/signature.XXXXXX", &sig_file2, NULL));
202 ScopedPathUnlinker sig2_unlinker(sig_file2);
203 if (signature_test == kSignatureGeneratedShellRotateCl1 ||
204 signature_test == kSignatureGeneratedShellRotateCl2) {
205 ASSERT_EQ(0,
206 System(StringPrintf(
Mike Frysinger2149be42012-03-12 19:23:47 -0400207 "openssl rsautl -raw -sign -inkey %s -in %s -out %s",
Andrew de los Reyesc24e3f32011-08-30 15:45:20 -0700208 kUnittestPrivateKey2Path,
209 hash_file.c_str(),
210 sig_file2.c_str())));
211 // Append second sig file to first path
212 sig_file += ":" + sig_file2;
213 }
214
Darin Petkovcbfb0172011-01-14 15:24:45 -0800215 ASSERT_EQ(0,
216 System(StringPrintf(
217 "./delta_generator -in_file %s -signature_file %s "
218 "-out_file %s",
219 payload_path.c_str(),
220 sig_file.c_str(),
221 payload_path.c_str())));
Darin Petkov52dcaeb2011-01-14 15:33:06 -0800222 int verify_result =
Andrew de los Reyesc24e3f32011-08-30 15:45:20 -0700223 System(StringPrintf(
224 "./delta_generator -in_file %s -public_key %s -public_key_version %d",
225 payload_path.c_str(),
226 signature_test == kSignatureGeneratedShellRotateCl2 ?
227 kUnittestPublicKey2Path : kUnittestPublicKeyPath,
228 signature_test == kSignatureGeneratedShellRotateCl2 ? 2 : 1));
Darin Petkov52dcaeb2011-01-14 15:33:06 -0800229 if (signature_test == kSignatureGeneratedShellBadKey) {
230 ASSERT_NE(0, verify_result);
231 } else {
232 ASSERT_EQ(0, verify_result);
233 }
Darin Petkovcbfb0172011-01-14 15:24:45 -0800234}
235
Darin Petkov9574f7e2011-01-13 10:48:12 -0800236void DoSmallImageTest(bool full_kernel, bool full_rootfs, bool noop,
Darin Petkovcbfb0172011-01-14 15:24:45 -0800237 SignatureTest signature_test) {
Andrew de los Reyes09e56d62010-04-23 13:45:53 -0700238 string a_img, b_img;
239 EXPECT_TRUE(utils::MakeTempFile("/tmp/a_img.XXXXXX", &a_img, NULL));
240 ScopedPathUnlinker a_img_unlinker(a_img);
241 EXPECT_TRUE(utils::MakeTempFile("/tmp/b_img.XXXXXX", &b_img, NULL));
242 ScopedPathUnlinker b_img_unlinker(b_img);
243
244 CreateExtImageAtPath(a_img, NULL);
Andrew de los Reyes09e56d62010-04-23 13:45:53 -0700245
Darin Petkov7ea32332010-10-13 10:46:11 -0700246 int image_size = static_cast<int>(utils::FileSize(a_img));
247
248 // Extend the "partitions" holding the file system a bit.
249 EXPECT_EQ(0, System(base::StringPrintf(
250 "dd if=/dev/zero of=%s seek=%d bs=1 count=1",
251 a_img.c_str(),
252 image_size + 1024 * 1024 - 1)));
Darin Petkov7ea32332010-10-13 10:46:11 -0700253 EXPECT_EQ(image_size + 1024 * 1024, utils::FileSize(a_img));
Darin Petkov7ea32332010-10-13 10:46:11 -0700254
Andrew de los Reyes09e56d62010-04-23 13:45:53 -0700255 // Make some changes to the A image.
256 {
257 string a_mnt;
258 ScopedLoopMounter b_mounter(a_img, &a_mnt, 0);
259
260 EXPECT_TRUE(utils::WriteFile(StringPrintf("%s/hardtocompress",
261 a_mnt.c_str()).c_str(),
262 reinterpret_cast<const char*>(kRandomString),
263 sizeof(kRandomString) - 1));
264 // Write 1 MiB of 0xff to try to catch the case where writing a bsdiff
265 // patch fails to zero out the final block.
266 vector<char> ones(1024 * 1024, 0xff);
267 EXPECT_TRUE(utils::WriteFile(StringPrintf("%s/ones",
268 a_mnt.c_str()).c_str(),
269 &ones[0],
270 ones.size()));
271 }
272
Darin Petkov9fa7ec52010-10-18 11:45:23 -0700273 if (noop) {
274 EXPECT_TRUE(file_util::CopyFile(FilePath(a_img), FilePath(b_img)));
275 } else {
276 CreateExtImageAtPath(b_img, NULL);
277 EXPECT_EQ(0, System(base::StringPrintf(
278 "dd if=/dev/zero of=%s seek=%d bs=1 count=1",
279 b_img.c_str(),
280 image_size + 1024 * 1024 - 1)));
281 EXPECT_EQ(image_size + 1024 * 1024, utils::FileSize(b_img));
282
283 // Make some changes to the B image.
Andrew de los Reyes09e56d62010-04-23 13:45:53 -0700284 string b_mnt;
285 ScopedLoopMounter b_mounter(b_img, &b_mnt, 0);
286
287 EXPECT_EQ(0, system(StringPrintf("cp %s/hello %s/hello2", b_mnt.c_str(),
288 b_mnt.c_str()).c_str()));
289 EXPECT_EQ(0, system(StringPrintf("rm %s/hello", b_mnt.c_str()).c_str()));
290 EXPECT_EQ(0, system(StringPrintf("mv %s/hello2 %s/hello", b_mnt.c_str(),
291 b_mnt.c_str()).c_str()));
292 EXPECT_EQ(0, system(StringPrintf("echo foo > %s/foo",
293 b_mnt.c_str()).c_str()));
294 EXPECT_EQ(0, system(StringPrintf("touch %s/emptyfile",
295 b_mnt.c_str()).c_str()));
296 EXPECT_TRUE(WriteSparseFile(StringPrintf("%s/fullsparse", b_mnt.c_str()),
297 1024 * 1024));
298 EXPECT_EQ(0, system(StringPrintf("dd if=/dev/zero of=%s/partsparese bs=1 "
299 "seek=4096 count=1",
300 b_mnt.c_str()).c_str()));
Andrew de los Reyes29da8aa2011-02-15 13:34:57 -0800301 EXPECT_EQ(0, system(StringPrintf("cp %s/srchardlink0 %s/tmp && "
302 "mv %s/tmp %s/srchardlink1",
303 b_mnt.c_str(), b_mnt.c_str(),
304 b_mnt.c_str(), b_mnt.c_str()).c_str()));
Andrew de los Reyes48a0a482011-02-22 15:32:11 -0800305 EXPECT_EQ(0, system(StringPrintf("rm %s/boguslink && "
306 "echo foobar > %s/boguslink",
307 b_mnt.c_str(), b_mnt.c_str()).c_str()));
Andrew de los Reyes09e56d62010-04-23 13:45:53 -0700308 EXPECT_TRUE(utils::WriteFile(StringPrintf("%s/hardtocompress",
309 b_mnt.c_str()).c_str(),
310 reinterpret_cast<const char*>(kRandomString),
311 sizeof(kRandomString)));
312 }
313
Andrew de los Reyesf4c7ef12010-04-30 10:37:00 -0700314 string old_kernel;
315 EXPECT_TRUE(utils::MakeTempFile("/tmp/old_kernel.XXXXXX", &old_kernel, NULL));
316 ScopedPathUnlinker old_kernel_unlinker(old_kernel);
317
318 string new_kernel;
319 EXPECT_TRUE(utils::MakeTempFile("/tmp/new_kernel.XXXXXX", &new_kernel, NULL));
320 ScopedPathUnlinker new_kernel_unlinker(new_kernel);
321
322 vector<char> old_kernel_data(4096); // Something small for a test
323 vector<char> new_kernel_data(old_kernel_data.size());
324 FillWithData(&old_kernel_data);
325 FillWithData(&new_kernel_data);
Andrew de los Reyes932bc4c2010-08-23 18:14:09 -0700326
Andrew de los Reyesf4c7ef12010-04-30 10:37:00 -0700327 // change the new kernel data
328 const char* new_data_string = "This is new data.";
329 strcpy(&new_kernel_data[0], new_data_string);
330
Darin Petkov9fa7ec52010-10-18 11:45:23 -0700331 if (noop) {
332 old_kernel_data = new_kernel_data;
333 }
334
Andrew de los Reyesf4c7ef12010-04-30 10:37:00 -0700335 // Write kernels to disk
336 EXPECT_TRUE(utils::WriteFile(
337 old_kernel.c_str(), &old_kernel_data[0], old_kernel_data.size()));
338 EXPECT_TRUE(utils::WriteFile(
339 new_kernel.c_str(), &new_kernel_data[0], new_kernel_data.size()));
340
Andrew de los Reyes09e56d62010-04-23 13:45:53 -0700341 string delta_path;
342 EXPECT_TRUE(utils::MakeTempFile("/tmp/delta.XXXXXX", &delta_path, NULL));
Andrew de los Reyes932bc4c2010-08-23 18:14:09 -0700343 LOG(INFO) << "delta path: " << delta_path;
Andrew de los Reyes09e56d62010-04-23 13:45:53 -0700344 ScopedPathUnlinker delta_path_unlinker(delta_path);
345 {
346 string a_mnt, b_mnt;
347 ScopedLoopMounter a_mounter(a_img, &a_mnt, MS_RDONLY);
348 ScopedLoopMounter b_mounter(b_img, &b_mnt, MS_RDONLY);
Darin Petkovcbfb0172011-01-14 15:24:45 -0800349 const string private_key =
350 signature_test == kSignatureGenerator ? kUnittestPrivateKeyPath : "";
Andrew de los Reyes932bc4c2010-08-23 18:14:09 -0700351 EXPECT_TRUE(
Darin Petkov68c10d12010-10-14 09:24:37 -0700352 DeltaDiffGenerator::GenerateDeltaUpdateFile(
Darin Petkov7a22d792010-11-08 14:10:00 -0800353 full_rootfs ? "" : a_mnt,
354 full_rootfs ? "" : a_img,
Darin Petkov68c10d12010-10-14 09:24:37 -0700355 b_mnt,
356 b_img,
357 full_kernel ? "" : old_kernel,
358 new_kernel,
359 delta_path,
Darin Petkovcbfb0172011-01-14 15:24:45 -0800360 private_key));
Darin Petkov9574f7e2011-01-13 10:48:12 -0800361 }
362
Darin Petkovcbfb0172011-01-14 15:24:45 -0800363 if (signature_test == kSignatureGenerated) {
364 SignGeneratedPayload(delta_path);
Darin Petkov52dcaeb2011-01-14 15:33:06 -0800365 } else if (signature_test == kSignatureGeneratedShell ||
Andrew de los Reyesc24e3f32011-08-30 15:45:20 -0700366 signature_test == kSignatureGeneratedShellBadKey ||
367 signature_test == kSignatureGeneratedShellRotateCl1 ||
368 signature_test == kSignatureGeneratedShellRotateCl2) {
Darin Petkov52dcaeb2011-01-14 15:33:06 -0800369 SignGeneratedShellPayload(signature_test, delta_path);
Andrew de los Reyes09e56d62010-04-23 13:45:53 -0700370 }
371
372 // Read delta into memory.
373 vector<char> delta;
Jay Srinivasanf4318702012-09-24 11:56:24 -0700374 uint64_t metadata_size;
Darin Petkov73058b42010-10-06 16:32:19 -0700375
Darin Petkov36a58222010-10-07 22:00:09 -0700376 // Check the metadata.
Andrew de los Reyes932bc4c2010-08-23 18:14:09 -0700377 {
Andrew de los Reyes932bc4c2010-08-23 18:14:09 -0700378 DeltaArchiveManifest manifest;
Jay Srinivasanf4318702012-09-24 11:56:24 -0700379 EXPECT_TRUE(PayloadSigner::LoadPayload(delta_path, &delta, &manifest,
380 &metadata_size));
381 LOG(INFO) << "Metadata size: " << metadata_size;
Andrew de los Reyes932bc4c2010-08-23 18:14:09 -0700382
Darin Petkovcbfb0172011-01-14 15:24:45 -0800383 if (signature_test == kSignatureNone) {
384 EXPECT_FALSE(manifest.has_signatures_offset());
385 EXPECT_FALSE(manifest.has_signatures_size());
386 } else {
387 EXPECT_TRUE(manifest.has_signatures_offset());
388 EXPECT_TRUE(manifest.has_signatures_size());
389 Signatures sigs_message;
390 EXPECT_TRUE(sigs_message.ParseFromArray(
Jay Srinivasanf4318702012-09-24 11:56:24 -0700391 &delta[metadata_size + manifest.signatures_offset()],
Darin Petkovcbfb0172011-01-14 15:24:45 -0800392 manifest.signatures_size()));
Andrew de los Reyesc24e3f32011-08-30 15:45:20 -0700393 if (signature_test == kSignatureGeneratedShellRotateCl1 ||
394 signature_test == kSignatureGeneratedShellRotateCl2)
395 EXPECT_EQ(2, sigs_message.signatures_size());
396 else
397 EXPECT_EQ(1, sigs_message.signatures_size());
Darin Petkovcbfb0172011-01-14 15:24:45 -0800398 const Signatures_Signature& signature = sigs_message.signatures(0);
399 EXPECT_EQ(1, signature.version());
Andrew de los Reyes932bc4c2010-08-23 18:14:09 -0700400
Darin Petkovcbfb0172011-01-14 15:24:45 -0800401 uint64_t expected_sig_data_length = 0;
Andrew de los Reyesc24e3f32011-08-30 15:45:20 -0700402 vector<string> key_paths (1, kUnittestPrivateKeyPath);
403 if (signature_test == kSignatureGeneratedShellRotateCl1 ||
404 signature_test == kSignatureGeneratedShellRotateCl2) {
405 key_paths.push_back(kUnittestPrivateKey2Path);
406 }
Darin Petkovcbfb0172011-01-14 15:24:45 -0800407 EXPECT_TRUE(PayloadSigner::SignatureBlobLength(
Andrew de los Reyesc24e3f32011-08-30 15:45:20 -0700408 key_paths,
409 &expected_sig_data_length));
Darin Petkovcbfb0172011-01-14 15:24:45 -0800410 EXPECT_EQ(expected_sig_data_length, manifest.signatures_size());
411 EXPECT_FALSE(signature.data().empty());
412 }
Darin Petkov36a58222010-10-07 22:00:09 -0700413
Darin Petkov9fa7ec52010-10-18 11:45:23 -0700414 if (noop) {
415 EXPECT_EQ(1, manifest.install_operations_size());
416 EXPECT_EQ(1, manifest.kernel_install_operations_size());
417 }
418
Darin Petkovd43d6902010-10-14 11:17:50 -0700419 if (full_kernel) {
420 EXPECT_FALSE(manifest.has_old_kernel_info());
421 } else {
422 EXPECT_EQ(old_kernel_data.size(), manifest.old_kernel_info().size());
423 EXPECT_FALSE(manifest.old_kernel_info().hash().empty());
424 }
Darin Petkov698d0412010-10-13 10:59:44 -0700425
Darin Petkov7a22d792010-11-08 14:10:00 -0800426 if (full_rootfs) {
427 EXPECT_FALSE(manifest.has_old_rootfs_info());
428 } else {
429 EXPECT_EQ(image_size, manifest.old_rootfs_info().size());
430 EXPECT_FALSE(manifest.old_rootfs_info().hash().empty());
431 }
432
Darin Petkov36a58222010-10-07 22:00:09 -0700433 EXPECT_EQ(new_kernel_data.size(), manifest.new_kernel_info().size());
Darin Petkov7ea32332010-10-13 10:46:11 -0700434 EXPECT_EQ(image_size, manifest.new_rootfs_info().size());
Darin Petkov36a58222010-10-07 22:00:09 -0700435
Darin Petkov36a58222010-10-07 22:00:09 -0700436 EXPECT_FALSE(manifest.new_kernel_info().hash().empty());
Darin Petkov36a58222010-10-07 22:00:09 -0700437 EXPECT_FALSE(manifest.new_rootfs_info().hash().empty());
Andrew de los Reyes932bc4c2010-08-23 18:14:09 -0700438 }
439
Darin Petkov73058b42010-10-06 16:32:19 -0700440 PrefsMock prefs;
441 EXPECT_CALL(prefs, SetInt64(kPrefsManifestMetadataSize,
Jay Srinivasanf4318702012-09-24 11:56:24 -0700442 metadata_size)).WillOnce(Return(true));
Darin Petkov73058b42010-10-06 16:32:19 -0700443 EXPECT_CALL(prefs, SetInt64(kPrefsUpdateStateNextOperation, _))
444 .WillRepeatedly(Return(true));
Darin Petkov9b230572010-10-08 10:20:09 -0700445 EXPECT_CALL(prefs, GetInt64(kPrefsUpdateStateNextOperation, _))
446 .WillOnce(Return(false));
Darin Petkov73058b42010-10-06 16:32:19 -0700447 EXPECT_CALL(prefs, SetInt64(kPrefsUpdateStateNextDataOffset, _))
448 .WillRepeatedly(Return(true));
Darin Petkov437adc42010-10-07 13:12:24 -0700449 EXPECT_CALL(prefs, SetString(kPrefsUpdateStateSHA256Context, _))
Darin Petkov73058b42010-10-06 16:32:19 -0700450 .WillRepeatedly(Return(true));
Darin Petkovcbfb0172011-01-14 15:24:45 -0800451 if (signature_test != kSignatureNone) {
452 EXPECT_CALL(prefs, SetString(kPrefsUpdateStateSignedSHA256Context, _))
453 .WillOnce(Return(true));
Darin Petkov4f0a07b2011-05-25 16:47:20 -0700454 EXPECT_CALL(prefs, SetString(kPrefsUpdateStateSignatureBlob, _))
455 .WillOnce(Return(true));
Darin Petkovcbfb0172011-01-14 15:24:45 -0800456 }
Darin Petkov73058b42010-10-06 16:32:19 -0700457
Andrew de los Reyes09e56d62010-04-23 13:45:53 -0700458 // Update the A image in place.
Jay Srinivasan51dcf262012-09-13 17:24:32 -0700459 InstallPlan install_plan;
460 DeltaPerformer performer(&prefs, &install_plan);
461 EXPECT_TRUE(utils::FileExists(kUnittestPublicKeyPath));
462 performer.set_public_key_path(kUnittestPublicKeyPath);
Andrew de los Reyes09e56d62010-04-23 13:45:53 -0700463
Darin Petkovd43d6902010-10-14 11:17:50 -0700464 EXPECT_EQ(image_size,
465 OmahaHashCalculator::RawHashOfFile(a_img,
466 image_size,
Jay Srinivasan51dcf262012-09-13 17:24:32 -0700467 &install_plan.rootfs_hash));
Darin Petkovd43d6902010-10-14 11:17:50 -0700468 EXPECT_TRUE(OmahaHashCalculator::RawHashOfData(old_kernel_data,
Jay Srinivasan51dcf262012-09-13 17:24:32 -0700469 &install_plan.kernel_hash));
Darin Petkovd43d6902010-10-14 11:17:50 -0700470
Andrew de los Reyes09e56d62010-04-23 13:45:53 -0700471 EXPECT_EQ(0, performer.Open(a_img.c_str(), 0, 0));
Andrew de los Reyesf4c7ef12010-04-30 10:37:00 -0700472 EXPECT_TRUE(performer.OpenKernel(old_kernel.c_str()));
Andrew de los Reyes09e56d62010-04-23 13:45:53 -0700473
474 // Write at some number of bytes per operation. Arbitrarily chose 5.
475 const size_t kBytesPerWrite = 5;
476 for (size_t i = 0; i < delta.size(); i += kBytesPerWrite) {
477 size_t count = min(delta.size() - i, kBytesPerWrite);
Don Garrette410e0f2011-11-10 15:39:01 -0800478 EXPECT_TRUE(performer.Write(&delta[i], count));
Andrew de los Reyes09e56d62010-04-23 13:45:53 -0700479 }
480
481 // Wrapper around close. Returns 0 on success or -errno on error.
482 EXPECT_EQ(0, performer.Close());
483
Andrew de los Reyesf4c7ef12010-04-30 10:37:00 -0700484 CompareFilesByBlock(old_kernel, new_kernel);
Darin Petkov2dd01092010-10-08 15:43:05 -0700485 CompareFilesByBlock(a_img, b_img);
Andrew de los Reyes932bc4c2010-08-23 18:14:09 -0700486
Andrew de los Reyesf4c7ef12010-04-30 10:37:00 -0700487 vector<char> updated_kernel_partition;
488 EXPECT_TRUE(utils::ReadFile(old_kernel, &updated_kernel_partition));
489 EXPECT_EQ(0, strncmp(&updated_kernel_partition[0], new_data_string,
490 strlen(new_data_string)));
Darin Petkovd7061ab2010-10-06 14:37:09 -0700491
Andrew de los Reyes771e1bd2011-08-30 14:47:23 -0700492 ActionExitCode expect_verify_result = kActionCodeSuccess;
493 switch (signature_test) {
494 case kSignatureNone:
495 expect_verify_result = kActionCodeSignedDeltaPayloadExpectedError;
496 break;
497 case kSignatureGeneratedShellBadKey:
498 expect_verify_result = kActionCodeDownloadPayloadPubKeyVerificationError;
499 break;
500 default: break; // appease gcc
501 }
502 EXPECT_EQ(expect_verify_result, performer.VerifyPayload(
Andrew de los Reyesfb830ba2011-04-04 11:42:43 -0700503 OmahaHashCalculator::OmahaHashOfData(delta),
Andrew de los Reyes771e1bd2011-08-30 14:47:23 -0700504 delta.size()));
Jay Srinivasan51dcf262012-09-13 17:24:32 -0700505
506 performer.set_public_key_path("/public/key/does/not/exists");
Andrew de los Reyes771e1bd2011-08-30 14:47:23 -0700507 EXPECT_EQ(kActionCodeSuccess, performer.VerifyPayload(
Darin Petkov52dcaeb2011-01-14 15:33:06 -0800508 OmahaHashCalculator::OmahaHashOfData(delta),
Andrew de los Reyes771e1bd2011-08-30 14:47:23 -0700509 delta.size()));
Darin Petkov3aefa862010-12-07 14:45:00 -0800510
511 uint64_t new_kernel_size;
512 vector<char> new_kernel_hash;
513 uint64_t new_rootfs_size;
514 vector<char> new_rootfs_hash;
515 EXPECT_TRUE(performer.GetNewPartitionInfo(&new_kernel_size,
516 &new_kernel_hash,
517 &new_rootfs_size,
518 &new_rootfs_hash));
519 EXPECT_EQ(4096, new_kernel_size);
520 vector<char> expected_new_kernel_hash;
521 EXPECT_TRUE(OmahaHashCalculator::RawHashOfData(new_kernel_data,
522 &expected_new_kernel_hash));
523 EXPECT_TRUE(expected_new_kernel_hash == new_kernel_hash);
524 EXPECT_EQ(image_size, new_rootfs_size);
525 vector<char> expected_new_rootfs_hash;
526 EXPECT_EQ(image_size,
527 OmahaHashCalculator::RawHashOfFile(b_img,
528 image_size,
529 &expected_new_rootfs_hash));
530 EXPECT_TRUE(expected_new_rootfs_hash == new_rootfs_hash);
Andrew de los Reyes09e56d62010-04-23 13:45:53 -0700531}
Jay Srinivasan51dcf262012-09-13 17:24:32 -0700532
533// TODO(jaysri): Refactor the previous unit test so we can reuse a lot of
534// code between these two methods.
535void DoManifestTest() {
536 bool full_kernel = false;
537 bool full_rootfs = false;
538 string a_img, b_img;
539 EXPECT_TRUE(utils::MakeTempFile("/tmp/a_img.XXXXXX", &a_img, NULL));
540 ScopedPathUnlinker a_img_unlinker(a_img);
541 EXPECT_TRUE(utils::MakeTempFile("/tmp/b_img.XXXXXX", &b_img, NULL));
542 ScopedPathUnlinker b_img_unlinker(b_img);
543
544 CreateExtImageAtPath(a_img, NULL);
545
546 int image_size = static_cast<int>(utils::FileSize(a_img));
547
548 // Extend the "partitions" holding the file system a bit.
549 EXPECT_EQ(0, System(base::StringPrintf(
550 "dd if=/dev/zero of=%s seek=%d bs=1 count=1",
551 a_img.c_str(),
552 image_size + 1024 * 1024 - 1)));
553 EXPECT_EQ(image_size + 1024 * 1024, utils::FileSize(a_img));
554
555 // Make some changes to the A image.
556 {
557 string a_mnt;
558 ScopedLoopMounter b_mounter(a_img, &a_mnt, 0);
559
560 EXPECT_TRUE(utils::WriteFile(StringPrintf("%s/hardtocompress",
561 a_mnt.c_str()).c_str(),
562 reinterpret_cast<const char*>(kRandomString),
563 sizeof(kRandomString) - 1));
564 // Write 1 MiB of 0xff to try to catch the case where writing a bsdiff
565 // patch fails to zero out the final block.
566 vector<char> ones(1024 * 1024, 0xff);
567 EXPECT_TRUE(utils::WriteFile(StringPrintf("%s/ones",
568 a_mnt.c_str()).c_str(),
569 &ones[0],
570 ones.size()));
571 }
572
573 {
574 CreateExtImageAtPath(b_img, NULL);
575 EXPECT_EQ(0, System(base::StringPrintf(
576 "dd if=/dev/zero of=%s seek=%d bs=1 count=1",
577 b_img.c_str(),
578 image_size + 1024 * 1024 - 1)));
579 EXPECT_EQ(image_size + 1024 * 1024, utils::FileSize(b_img));
580
581 // Make some changes to the B image.
582 string b_mnt;
583 ScopedLoopMounter b_mounter(b_img, &b_mnt, 0);
584
585 EXPECT_EQ(0, system(StringPrintf("cp %s/hello %s/hello2", b_mnt.c_str(),
586 b_mnt.c_str()).c_str()));
587 EXPECT_EQ(0, system(StringPrintf("rm %s/hello", b_mnt.c_str()).c_str()));
588 EXPECT_EQ(0, system(StringPrintf("mv %s/hello2 %s/hello", b_mnt.c_str(),
589 b_mnt.c_str()).c_str()));
590 EXPECT_EQ(0, system(StringPrintf("echo foo > %s/foo",
591 b_mnt.c_str()).c_str()));
592 EXPECT_EQ(0, system(StringPrintf("touch %s/emptyfile",
593 b_mnt.c_str()).c_str()));
594 EXPECT_TRUE(WriteSparseFile(StringPrintf("%s/fullsparse", b_mnt.c_str()),
595 1024 * 1024));
596 EXPECT_EQ(0, system(StringPrintf("dd if=/dev/zero of=%s/partsparese bs=1 "
597 "seek=4096 count=1",
598 b_mnt.c_str()).c_str()));
599 EXPECT_EQ(0, system(StringPrintf("cp %s/srchardlink0 %s/tmp && "
600 "mv %s/tmp %s/srchardlink1",
601 b_mnt.c_str(), b_mnt.c_str(),
602 b_mnt.c_str(), b_mnt.c_str()).c_str()));
603 EXPECT_EQ(0, system(StringPrintf("rm %s/boguslink && "
604 "echo foobar > %s/boguslink",
605 b_mnt.c_str(), b_mnt.c_str()).c_str()));
606 EXPECT_TRUE(utils::WriteFile(StringPrintf("%s/hardtocompress",
607 b_mnt.c_str()).c_str(),
608 reinterpret_cast<const char*>(kRandomString),
609 sizeof(kRandomString)));
610 }
611
612 string old_kernel;
613 EXPECT_TRUE(utils::MakeTempFile("/tmp/old_kernel.XXXXXX", &old_kernel, NULL));
614 ScopedPathUnlinker old_kernel_unlinker(old_kernel);
615
616 string new_kernel;
617 EXPECT_TRUE(utils::MakeTempFile("/tmp/new_kernel.XXXXXX", &new_kernel, NULL));
618 ScopedPathUnlinker new_kernel_unlinker(new_kernel);
619
620 vector<char> old_kernel_data(4096); // Something small for a test
621 vector<char> new_kernel_data(old_kernel_data.size());
622 FillWithData(&old_kernel_data);
623 FillWithData(&new_kernel_data);
624
625 // change the new kernel data
626 const char* new_data_string = "This is new data.";
627 strcpy(&new_kernel_data[0], new_data_string);
628
629 // Write kernels to disk
630 EXPECT_TRUE(utils::WriteFile(
631 old_kernel.c_str(), &old_kernel_data[0], old_kernel_data.size()));
632 EXPECT_TRUE(utils::WriteFile(
633 new_kernel.c_str(), &new_kernel_data[0], new_kernel_data.size()));
634
635 string delta_path;
636 EXPECT_TRUE(utils::MakeTempFile("/tmp/delta.XXXXXX", &delta_path, NULL));
637 LOG(INFO) << "delta path: " << delta_path;
638 ScopedPathUnlinker delta_path_unlinker(delta_path);
639 {
640 string a_mnt, b_mnt;
641 ScopedLoopMounter a_mounter(a_img, &a_mnt, MS_RDONLY);
642 ScopedLoopMounter b_mounter(b_img, &b_mnt, MS_RDONLY);
643 const string private_key = kUnittestPrivateKeyPath;
644 EXPECT_TRUE(
645 DeltaDiffGenerator::GenerateDeltaUpdateFile(
646 full_rootfs ? "" : a_mnt,
647 full_rootfs ? "" : a_img,
648 b_mnt,
649 b_img,
650 full_kernel ? "" : old_kernel,
651 new_kernel,
652 delta_path,
653 private_key));
654 }
655
656 // Read delta into memory.
657 vector<char> delta;
Jay Srinivasanf4318702012-09-24 11:56:24 -0700658 uint64_t metadata_size;
Jay Srinivasan51dcf262012-09-13 17:24:32 -0700659 // Check the metadata.
660 {
Jay Srinivasan51dcf262012-09-13 17:24:32 -0700661 DeltaArchiveManifest manifest;
Jay Srinivasanf4318702012-09-24 11:56:24 -0700662 EXPECT_TRUE(PayloadSigner::LoadPayload(delta_path, &delta, &manifest,
663 &metadata_size));
664
665 LOG(INFO) << "Metadata size: " << metadata_size;
Jay Srinivasan51dcf262012-09-13 17:24:32 -0700666
667 {
668 EXPECT_TRUE(manifest.has_signatures_offset());
669 EXPECT_TRUE(manifest.has_signatures_size());
670 Signatures sigs_message;
671 EXPECT_TRUE(sigs_message.ParseFromArray(
Jay Srinivasanf4318702012-09-24 11:56:24 -0700672 &delta[metadata_size + manifest.signatures_offset()],
Jay Srinivasan51dcf262012-09-13 17:24:32 -0700673 manifest.signatures_size()));
674 EXPECT_EQ(1, sigs_message.signatures_size());
675 const Signatures_Signature& signature = sigs_message.signatures(0);
676 EXPECT_EQ(1, signature.version());
677
678 uint64_t expected_sig_data_length = 0;
679 vector<string> key_paths (1, kUnittestPrivateKeyPath);
680 EXPECT_TRUE(PayloadSigner::SignatureBlobLength(
681 key_paths,
682 &expected_sig_data_length));
683 EXPECT_EQ(expected_sig_data_length, manifest.signatures_size());
684 EXPECT_FALSE(signature.data().empty());
685 }
686
687 if (full_kernel) {
688 EXPECT_FALSE(manifest.has_old_kernel_info());
689 } else {
690 EXPECT_EQ(old_kernel_data.size(), manifest.old_kernel_info().size());
691 EXPECT_FALSE(manifest.old_kernel_info().hash().empty());
692 }
693
694 if (full_rootfs) {
695 EXPECT_FALSE(manifest.has_old_rootfs_info());
696 } else {
697 EXPECT_EQ(image_size, manifest.old_rootfs_info().size());
698 EXPECT_FALSE(manifest.old_rootfs_info().hash().empty());
699 }
700
701 EXPECT_EQ(new_kernel_data.size(), manifest.new_kernel_info().size());
702 EXPECT_EQ(image_size, manifest.new_rootfs_info().size());
703
704 EXPECT_FALSE(manifest.new_kernel_info().hash().empty());
705 EXPECT_FALSE(manifest.new_rootfs_info().hash().empty());
706
707 }
708
709 PrefsMock prefs;
710 EXPECT_CALL(prefs, SetInt64(kPrefsManifestMetadataSize,
Jay Srinivasanf4318702012-09-24 11:56:24 -0700711 metadata_size)).WillOnce(Return(true));
Jay Srinivasan51dcf262012-09-13 17:24:32 -0700712 EXPECT_CALL(prefs, SetInt64(kPrefsUpdateStateNextOperation, _))
713 .WillRepeatedly(Return(true));
714 EXPECT_CALL(prefs, GetInt64(kPrefsUpdateStateNextOperation, _))
715 .WillOnce(Return(false));
716 EXPECT_CALL(prefs, SetInt64(kPrefsUpdateStateNextDataOffset, _))
717 .WillRepeatedly(Return(true));
718 EXPECT_CALL(prefs, SetString(kPrefsUpdateStateSHA256Context, _))
719 .WillRepeatedly(Return(true));
720 EXPECT_CALL(prefs, SetString(kPrefsUpdateStateSignedSHA256Context, _))
721 .WillRepeatedly(Return(true));
722 EXPECT_CALL(prefs, SetString(kPrefsUpdateStateSignatureBlob, _))
723 .WillOnce(Return(true));
724
725 // Update the A image in place.
726 InstallPlan install_plan;
Jay Srinivasanf4318702012-09-24 11:56:24 -0700727 install_plan.metadata_size = metadata_size;
728 LOG(INFO) << "Setting payload metadata size in Omaha = " << metadata_size;
729 ASSERT_TRUE(PayloadSigner::GetMetadataSignature(
730 &delta[0],
731 metadata_size,
Jay Srinivasan51dcf262012-09-13 17:24:32 -0700732 kUnittestPrivateKeyPath,
Jay Srinivasanf4318702012-09-24 11:56:24 -0700733 &install_plan.metadata_signature));
734 EXPECT_FALSE(install_plan.metadata_signature.empty());
Jay Srinivasan51dcf262012-09-13 17:24:32 -0700735
736 DeltaPerformer performer(&prefs, &install_plan);
737 EXPECT_TRUE(utils::FileExists(kUnittestPublicKeyPath));
738 performer.set_public_key_path(kUnittestPublicKeyPath);
739
740 EXPECT_EQ(image_size,
741 OmahaHashCalculator::RawHashOfFile(a_img,
742 image_size,
743 &install_plan.rootfs_hash));
744 EXPECT_TRUE(OmahaHashCalculator::RawHashOfData(old_kernel_data,
745 &install_plan.kernel_hash));
746
747 EXPECT_EQ(0, performer.Open(a_img.c_str(), 0, 0));
748 EXPECT_TRUE(performer.OpenKernel(old_kernel.c_str()));
749
750 // Write at some number of bytes per operation. Arbitrarily chose 5.
751 const size_t kBytesPerWrite = 5;
752 for (size_t i = 0; i < delta.size(); i += kBytesPerWrite) {
753 size_t count = min(delta.size() - i, kBytesPerWrite);
754 EXPECT_TRUE(performer.Write(&delta[i], count));
755 }
756
757 // Wrapper around close. Returns 0 on success or -errno on error.
758 EXPECT_EQ(0, performer.Close());
759
760 CompareFilesByBlock(old_kernel, new_kernel);
761 CompareFilesByBlock(a_img, b_img);
762
763 vector<char> updated_kernel_partition;
764 EXPECT_TRUE(utils::ReadFile(old_kernel, &updated_kernel_partition));
765 EXPECT_EQ(0, strncmp(&updated_kernel_partition[0], new_data_string,
766 strlen(new_data_string)));
767
768 ActionExitCode expect_verify_result = kActionCodeSuccess;
769 LOG(INFO) << "Verifying Payload ...";
770 EXPECT_EQ(expect_verify_result, performer.VerifyPayload(
771 OmahaHashCalculator::OmahaHashOfData(delta),
772 delta.size()));
773
774 LOG(INFO) << "Verified Payload";
775
776 uint64_t new_kernel_size;
777 vector<char> new_kernel_hash;
778 uint64_t new_rootfs_size;
779 vector<char> new_rootfs_hash;
780 EXPECT_TRUE(performer.GetNewPartitionInfo(&new_kernel_size,
781 &new_kernel_hash,
782 &new_rootfs_size,
783 &new_rootfs_hash));
784 EXPECT_EQ(4096, new_kernel_size);
785 vector<char> expected_new_kernel_hash;
786 EXPECT_TRUE(OmahaHashCalculator::RawHashOfData(new_kernel_data,
787 &expected_new_kernel_hash));
788 EXPECT_TRUE(expected_new_kernel_hash == new_kernel_hash);
789 EXPECT_EQ(image_size, new_rootfs_size);
790 vector<char> expected_new_rootfs_hash;
791 EXPECT_EQ(image_size,
792 OmahaHashCalculator::RawHashOfFile(b_img,
793 image_size,
794 &expected_new_rootfs_hash));
795 EXPECT_TRUE(expected_new_rootfs_hash == new_rootfs_hash);
796}
Andrew de los Reyesc24e3f32011-08-30 15:45:20 -0700797} // namespace {}
Darin Petkov68c10d12010-10-14 09:24:37 -0700798
799TEST(DeltaPerformerTest, RunAsRootSmallImageTest) {
Darin Petkovcbfb0172011-01-14 15:24:45 -0800800 DoSmallImageTest(false, false, false, kSignatureGenerator);
Darin Petkov68c10d12010-10-14 09:24:37 -0700801}
802
803TEST(DeltaPerformerTest, RunAsRootFullKernelSmallImageTest) {
Darin Petkovcbfb0172011-01-14 15:24:45 -0800804 DoSmallImageTest(true, false, false, kSignatureGenerator);
Darin Petkov7a22d792010-11-08 14:10:00 -0800805}
806
807TEST(DeltaPerformerTest, RunAsRootFullSmallImageTest) {
Darin Petkovcbfb0172011-01-14 15:24:45 -0800808 DoSmallImageTest(true, true, false, kSignatureGenerator);
Darin Petkov9fa7ec52010-10-18 11:45:23 -0700809}
810
811TEST(DeltaPerformerTest, RunAsRootNoopSmallImageTest) {
Darin Petkovcbfb0172011-01-14 15:24:45 -0800812 DoSmallImageTest(false, false, true, kSignatureGenerator);
Darin Petkov9574f7e2011-01-13 10:48:12 -0800813}
814
Darin Petkovcbfb0172011-01-14 15:24:45 -0800815TEST(DeltaPerformerTest, RunAsRootSmallImageSignNoneTest) {
816 DoSmallImageTest(false, false, false, kSignatureNone);
817}
818
819TEST(DeltaPerformerTest, RunAsRootSmallImageSignGeneratedTest) {
820 DoSmallImageTest(false, false, false, kSignatureGenerated);
821}
822
823TEST(DeltaPerformerTest, RunAsRootSmallImageSignGeneratedShellTest) {
824 DoSmallImageTest(false, false, false, kSignatureGeneratedShell);
Andrew de los Reyes27f7d372010-10-07 11:26:07 -0700825}
826
Darin Petkov52dcaeb2011-01-14 15:33:06 -0800827TEST(DeltaPerformerTest, RunAsRootSmallImageSignGeneratedShellBadKeyTest) {
828 DoSmallImageTest(false, false, false, kSignatureGeneratedShellBadKey);
829}
830
Andrew de los Reyesc24e3f32011-08-30 15:45:20 -0700831TEST(DeltaPerformerTest, RunAsRootSmallImageSignGeneratedShellRotateCl1Test) {
832 DoSmallImageTest(false, false, false, kSignatureGeneratedShellRotateCl1);
833}
834
835TEST(DeltaPerformerTest, RunAsRootSmallImageSignGeneratedShellRotateCl2Test) {
836 DoSmallImageTest(false, false, false, kSignatureGeneratedShellRotateCl2);
837}
838
Darin Petkov934bb412010-11-18 11:21:35 -0800839TEST(DeltaPerformerTest, BadDeltaMagicTest) {
840 PrefsMock prefs;
Jay Srinivasan51dcf262012-09-13 17:24:32 -0700841 InstallPlan install_plan;
842 DeltaPerformer performer(&prefs, &install_plan);
Darin Petkov934bb412010-11-18 11:21:35 -0800843 EXPECT_EQ(0, performer.Open("/dev/null", 0, 0));
844 EXPECT_TRUE(performer.OpenKernel("/dev/null"));
Don Garrette410e0f2011-11-10 15:39:01 -0800845 EXPECT_TRUE(performer.Write("junk", 4));
846 EXPECT_TRUE(performer.Write("morejunk", 8));
847 EXPECT_FALSE(performer.Write("morejunk", 8));
Darin Petkov934bb412010-11-18 11:21:35 -0800848 EXPECT_LT(performer.Close(), 0);
849}
850
Andrew de los Reyes353777c2010-10-08 10:34:30 -0700851TEST(DeltaPerformerTest, IsIdempotentOperationTest) {
852 DeltaArchiveManifest_InstallOperation op;
853 EXPECT_TRUE(DeltaPerformer::IsIdempotentOperation(op));
854 *(op.add_dst_extents()) = ExtentForRange(0, 5);
855 EXPECT_TRUE(DeltaPerformer::IsIdempotentOperation(op));
856 *(op.add_src_extents()) = ExtentForRange(4, 1);
857 EXPECT_FALSE(DeltaPerformer::IsIdempotentOperation(op));
858 op.clear_src_extents();
859 *(op.add_src_extents()) = ExtentForRange(5, 3);
860 EXPECT_TRUE(DeltaPerformer::IsIdempotentOperation(op));
861 *(op.add_dst_extents()) = ExtentForRange(20, 6);
862 EXPECT_TRUE(DeltaPerformer::IsIdempotentOperation(op));
863 *(op.add_src_extents()) = ExtentForRange(19, 2);
864 EXPECT_FALSE(DeltaPerformer::IsIdempotentOperation(op));
865}
866
Jay Srinivasan51dcf262012-09-13 17:24:32 -0700867TEST(DeltaPerformerTest, RunAsRootRunValidManifestTest) {
868 DoManifestTest();
869}
870
871
Andrew de los Reyes09e56d62010-04-23 13:45:53 -0700872} // namespace chromeos_update_engine