blob: 96b780cd8da2bc6613f2d34526555ffc82472a3c [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;
374 EXPECT_TRUE(utils::ReadFile(delta_path, &delta));
375
Darin Petkov73058b42010-10-06 16:32:19 -0700376 uint64_t manifest_metadata_size;
377
Darin Petkov36a58222010-10-07 22:00:09 -0700378 // Check the metadata.
Andrew de los Reyes932bc4c2010-08-23 18:14:09 -0700379 {
380 LOG(INFO) << "delta size: " << delta.size();
381 DeltaArchiveManifest manifest;
382 const int kManifestSizeOffset = 12;
383 const int kManifestOffset = 20;
384 uint64_t manifest_size = 0;
385 memcpy(&manifest_size, &delta[kManifestSizeOffset], sizeof(manifest_size));
386 manifest_size = be64toh(manifest_size);
387 LOG(INFO) << "manifest size: " << manifest_size;
388 EXPECT_TRUE(manifest.ParseFromArray(&delta[kManifestOffset],
389 manifest_size));
Darin Petkov73058b42010-10-06 16:32:19 -0700390 manifest_metadata_size = kManifestOffset + manifest_size;
Andrew de los Reyes932bc4c2010-08-23 18:14:09 -0700391
Darin Petkovcbfb0172011-01-14 15:24:45 -0800392 if (signature_test == kSignatureNone) {
393 EXPECT_FALSE(manifest.has_signatures_offset());
394 EXPECT_FALSE(manifest.has_signatures_size());
395 } else {
396 EXPECT_TRUE(manifest.has_signatures_offset());
397 EXPECT_TRUE(manifest.has_signatures_size());
398 Signatures sigs_message;
399 EXPECT_TRUE(sigs_message.ParseFromArray(
400 &delta[manifest_metadata_size + manifest.signatures_offset()],
401 manifest.signatures_size()));
Andrew de los Reyesc24e3f32011-08-30 15:45:20 -0700402 if (signature_test == kSignatureGeneratedShellRotateCl1 ||
403 signature_test == kSignatureGeneratedShellRotateCl2)
404 EXPECT_EQ(2, sigs_message.signatures_size());
405 else
406 EXPECT_EQ(1, sigs_message.signatures_size());
Darin Petkovcbfb0172011-01-14 15:24:45 -0800407 const Signatures_Signature& signature = sigs_message.signatures(0);
408 EXPECT_EQ(1, signature.version());
Andrew de los Reyes932bc4c2010-08-23 18:14:09 -0700409
Darin Petkovcbfb0172011-01-14 15:24:45 -0800410 uint64_t expected_sig_data_length = 0;
Andrew de los Reyesc24e3f32011-08-30 15:45:20 -0700411 vector<string> key_paths (1, kUnittestPrivateKeyPath);
412 if (signature_test == kSignatureGeneratedShellRotateCl1 ||
413 signature_test == kSignatureGeneratedShellRotateCl2) {
414 key_paths.push_back(kUnittestPrivateKey2Path);
415 }
Darin Petkovcbfb0172011-01-14 15:24:45 -0800416 EXPECT_TRUE(PayloadSigner::SignatureBlobLength(
Andrew de los Reyesc24e3f32011-08-30 15:45:20 -0700417 key_paths,
418 &expected_sig_data_length));
Darin Petkovcbfb0172011-01-14 15:24:45 -0800419 EXPECT_EQ(expected_sig_data_length, manifest.signatures_size());
420 EXPECT_FALSE(signature.data().empty());
421 }
Darin Petkov36a58222010-10-07 22:00:09 -0700422
Darin Petkov9fa7ec52010-10-18 11:45:23 -0700423 if (noop) {
424 EXPECT_EQ(1, manifest.install_operations_size());
425 EXPECT_EQ(1, manifest.kernel_install_operations_size());
426 }
427
Darin Petkovd43d6902010-10-14 11:17:50 -0700428 if (full_kernel) {
429 EXPECT_FALSE(manifest.has_old_kernel_info());
430 } else {
431 EXPECT_EQ(old_kernel_data.size(), manifest.old_kernel_info().size());
432 EXPECT_FALSE(manifest.old_kernel_info().hash().empty());
433 }
Darin Petkov698d0412010-10-13 10:59:44 -0700434
Darin Petkov7a22d792010-11-08 14:10:00 -0800435 if (full_rootfs) {
436 EXPECT_FALSE(manifest.has_old_rootfs_info());
437 } else {
438 EXPECT_EQ(image_size, manifest.old_rootfs_info().size());
439 EXPECT_FALSE(manifest.old_rootfs_info().hash().empty());
440 }
441
Darin Petkov36a58222010-10-07 22:00:09 -0700442 EXPECT_EQ(new_kernel_data.size(), manifest.new_kernel_info().size());
Darin Petkov7ea32332010-10-13 10:46:11 -0700443 EXPECT_EQ(image_size, manifest.new_rootfs_info().size());
Darin Petkov36a58222010-10-07 22:00:09 -0700444
Darin Petkov36a58222010-10-07 22:00:09 -0700445 EXPECT_FALSE(manifest.new_kernel_info().hash().empty());
Darin Petkov36a58222010-10-07 22:00:09 -0700446 EXPECT_FALSE(manifest.new_rootfs_info().hash().empty());
Andrew de los Reyes932bc4c2010-08-23 18:14:09 -0700447 }
448
Darin Petkov73058b42010-10-06 16:32:19 -0700449 PrefsMock prefs;
450 EXPECT_CALL(prefs, SetInt64(kPrefsManifestMetadataSize,
451 manifest_metadata_size)).WillOnce(Return(true));
452 EXPECT_CALL(prefs, SetInt64(kPrefsUpdateStateNextOperation, _))
453 .WillRepeatedly(Return(true));
Darin Petkov9b230572010-10-08 10:20:09 -0700454 EXPECT_CALL(prefs, GetInt64(kPrefsUpdateStateNextOperation, _))
455 .WillOnce(Return(false));
Darin Petkov73058b42010-10-06 16:32:19 -0700456 EXPECT_CALL(prefs, SetInt64(kPrefsUpdateStateNextDataOffset, _))
457 .WillRepeatedly(Return(true));
Darin Petkov437adc42010-10-07 13:12:24 -0700458 EXPECT_CALL(prefs, SetString(kPrefsUpdateStateSHA256Context, _))
Darin Petkov73058b42010-10-06 16:32:19 -0700459 .WillRepeatedly(Return(true));
Darin Petkovcbfb0172011-01-14 15:24:45 -0800460 if (signature_test != kSignatureNone) {
461 EXPECT_CALL(prefs, SetString(kPrefsUpdateStateSignedSHA256Context, _))
462 .WillOnce(Return(true));
Darin Petkov4f0a07b2011-05-25 16:47:20 -0700463 EXPECT_CALL(prefs, SetString(kPrefsUpdateStateSignatureBlob, _))
464 .WillOnce(Return(true));
Darin Petkovcbfb0172011-01-14 15:24:45 -0800465 }
Darin Petkov73058b42010-10-06 16:32:19 -0700466
Andrew de los Reyes09e56d62010-04-23 13:45:53 -0700467 // Update the A image in place.
Jay Srinivasan51dcf262012-09-13 17:24:32 -0700468 InstallPlan install_plan;
469 DeltaPerformer performer(&prefs, &install_plan);
470 EXPECT_TRUE(utils::FileExists(kUnittestPublicKeyPath));
471 performer.set_public_key_path(kUnittestPublicKeyPath);
Andrew de los Reyes09e56d62010-04-23 13:45:53 -0700472
Darin Petkovd43d6902010-10-14 11:17:50 -0700473 EXPECT_EQ(image_size,
474 OmahaHashCalculator::RawHashOfFile(a_img,
475 image_size,
Jay Srinivasan51dcf262012-09-13 17:24:32 -0700476 &install_plan.rootfs_hash));
Darin Petkovd43d6902010-10-14 11:17:50 -0700477 EXPECT_TRUE(OmahaHashCalculator::RawHashOfData(old_kernel_data,
Jay Srinivasan51dcf262012-09-13 17:24:32 -0700478 &install_plan.kernel_hash));
Darin Petkovd43d6902010-10-14 11:17:50 -0700479
Andrew de los Reyes09e56d62010-04-23 13:45:53 -0700480 EXPECT_EQ(0, performer.Open(a_img.c_str(), 0, 0));
Andrew de los Reyesf4c7ef12010-04-30 10:37:00 -0700481 EXPECT_TRUE(performer.OpenKernel(old_kernel.c_str()));
Andrew de los Reyes09e56d62010-04-23 13:45:53 -0700482
483 // Write at some number of bytes per operation. Arbitrarily chose 5.
484 const size_t kBytesPerWrite = 5;
485 for (size_t i = 0; i < delta.size(); i += kBytesPerWrite) {
486 size_t count = min(delta.size() - i, kBytesPerWrite);
Don Garrette410e0f2011-11-10 15:39:01 -0800487 EXPECT_TRUE(performer.Write(&delta[i], count));
Andrew de los Reyes09e56d62010-04-23 13:45:53 -0700488 }
489
490 // Wrapper around close. Returns 0 on success or -errno on error.
491 EXPECT_EQ(0, performer.Close());
492
Andrew de los Reyesf4c7ef12010-04-30 10:37:00 -0700493 CompareFilesByBlock(old_kernel, new_kernel);
Darin Petkov2dd01092010-10-08 15:43:05 -0700494 CompareFilesByBlock(a_img, b_img);
Andrew de los Reyes932bc4c2010-08-23 18:14:09 -0700495
Andrew de los Reyesf4c7ef12010-04-30 10:37:00 -0700496 vector<char> updated_kernel_partition;
497 EXPECT_TRUE(utils::ReadFile(old_kernel, &updated_kernel_partition));
498 EXPECT_EQ(0, strncmp(&updated_kernel_partition[0], new_data_string,
499 strlen(new_data_string)));
Darin Petkovd7061ab2010-10-06 14:37:09 -0700500
Andrew de los Reyes771e1bd2011-08-30 14:47:23 -0700501 ActionExitCode expect_verify_result = kActionCodeSuccess;
502 switch (signature_test) {
503 case kSignatureNone:
504 expect_verify_result = kActionCodeSignedDeltaPayloadExpectedError;
505 break;
506 case kSignatureGeneratedShellBadKey:
507 expect_verify_result = kActionCodeDownloadPayloadPubKeyVerificationError;
508 break;
509 default: break; // appease gcc
510 }
511 EXPECT_EQ(expect_verify_result, performer.VerifyPayload(
Andrew de los Reyesfb830ba2011-04-04 11:42:43 -0700512 OmahaHashCalculator::OmahaHashOfData(delta),
Andrew de los Reyes771e1bd2011-08-30 14:47:23 -0700513 delta.size()));
Jay Srinivasan51dcf262012-09-13 17:24:32 -0700514
515 performer.set_public_key_path("/public/key/does/not/exists");
Andrew de los Reyes771e1bd2011-08-30 14:47:23 -0700516 EXPECT_EQ(kActionCodeSuccess, performer.VerifyPayload(
Darin Petkov52dcaeb2011-01-14 15:33:06 -0800517 OmahaHashCalculator::OmahaHashOfData(delta),
Andrew de los Reyes771e1bd2011-08-30 14:47:23 -0700518 delta.size()));
Darin Petkov3aefa862010-12-07 14:45:00 -0800519
520 uint64_t new_kernel_size;
521 vector<char> new_kernel_hash;
522 uint64_t new_rootfs_size;
523 vector<char> new_rootfs_hash;
524 EXPECT_TRUE(performer.GetNewPartitionInfo(&new_kernel_size,
525 &new_kernel_hash,
526 &new_rootfs_size,
527 &new_rootfs_hash));
528 EXPECT_EQ(4096, new_kernel_size);
529 vector<char> expected_new_kernel_hash;
530 EXPECT_TRUE(OmahaHashCalculator::RawHashOfData(new_kernel_data,
531 &expected_new_kernel_hash));
532 EXPECT_TRUE(expected_new_kernel_hash == new_kernel_hash);
533 EXPECT_EQ(image_size, new_rootfs_size);
534 vector<char> expected_new_rootfs_hash;
535 EXPECT_EQ(image_size,
536 OmahaHashCalculator::RawHashOfFile(b_img,
537 image_size,
538 &expected_new_rootfs_hash));
539 EXPECT_TRUE(expected_new_rootfs_hash == new_rootfs_hash);
Andrew de los Reyes09e56d62010-04-23 13:45:53 -0700540}
Jay Srinivasan51dcf262012-09-13 17:24:32 -0700541
542// TODO(jaysri): Refactor the previous unit test so we can reuse a lot of
543// code between these two methods.
544void DoManifestTest() {
545 bool full_kernel = false;
546 bool full_rootfs = false;
547 string a_img, b_img;
548 EXPECT_TRUE(utils::MakeTempFile("/tmp/a_img.XXXXXX", &a_img, NULL));
549 ScopedPathUnlinker a_img_unlinker(a_img);
550 EXPECT_TRUE(utils::MakeTempFile("/tmp/b_img.XXXXXX", &b_img, NULL));
551 ScopedPathUnlinker b_img_unlinker(b_img);
552
553 CreateExtImageAtPath(a_img, NULL);
554
555 int image_size = static_cast<int>(utils::FileSize(a_img));
556
557 // Extend the "partitions" holding the file system a bit.
558 EXPECT_EQ(0, System(base::StringPrintf(
559 "dd if=/dev/zero of=%s seek=%d bs=1 count=1",
560 a_img.c_str(),
561 image_size + 1024 * 1024 - 1)));
562 EXPECT_EQ(image_size + 1024 * 1024, utils::FileSize(a_img));
563
564 // Make some changes to the A image.
565 {
566 string a_mnt;
567 ScopedLoopMounter b_mounter(a_img, &a_mnt, 0);
568
569 EXPECT_TRUE(utils::WriteFile(StringPrintf("%s/hardtocompress",
570 a_mnt.c_str()).c_str(),
571 reinterpret_cast<const char*>(kRandomString),
572 sizeof(kRandomString) - 1));
573 // Write 1 MiB of 0xff to try to catch the case where writing a bsdiff
574 // patch fails to zero out the final block.
575 vector<char> ones(1024 * 1024, 0xff);
576 EXPECT_TRUE(utils::WriteFile(StringPrintf("%s/ones",
577 a_mnt.c_str()).c_str(),
578 &ones[0],
579 ones.size()));
580 }
581
582 {
583 CreateExtImageAtPath(b_img, NULL);
584 EXPECT_EQ(0, System(base::StringPrintf(
585 "dd if=/dev/zero of=%s seek=%d bs=1 count=1",
586 b_img.c_str(),
587 image_size + 1024 * 1024 - 1)));
588 EXPECT_EQ(image_size + 1024 * 1024, utils::FileSize(b_img));
589
590 // Make some changes to the B image.
591 string b_mnt;
592 ScopedLoopMounter b_mounter(b_img, &b_mnt, 0);
593
594 EXPECT_EQ(0, system(StringPrintf("cp %s/hello %s/hello2", b_mnt.c_str(),
595 b_mnt.c_str()).c_str()));
596 EXPECT_EQ(0, system(StringPrintf("rm %s/hello", b_mnt.c_str()).c_str()));
597 EXPECT_EQ(0, system(StringPrintf("mv %s/hello2 %s/hello", b_mnt.c_str(),
598 b_mnt.c_str()).c_str()));
599 EXPECT_EQ(0, system(StringPrintf("echo foo > %s/foo",
600 b_mnt.c_str()).c_str()));
601 EXPECT_EQ(0, system(StringPrintf("touch %s/emptyfile",
602 b_mnt.c_str()).c_str()));
603 EXPECT_TRUE(WriteSparseFile(StringPrintf("%s/fullsparse", b_mnt.c_str()),
604 1024 * 1024));
605 EXPECT_EQ(0, system(StringPrintf("dd if=/dev/zero of=%s/partsparese bs=1 "
606 "seek=4096 count=1",
607 b_mnt.c_str()).c_str()));
608 EXPECT_EQ(0, system(StringPrintf("cp %s/srchardlink0 %s/tmp && "
609 "mv %s/tmp %s/srchardlink1",
610 b_mnt.c_str(), b_mnt.c_str(),
611 b_mnt.c_str(), b_mnt.c_str()).c_str()));
612 EXPECT_EQ(0, system(StringPrintf("rm %s/boguslink && "
613 "echo foobar > %s/boguslink",
614 b_mnt.c_str(), b_mnt.c_str()).c_str()));
615 EXPECT_TRUE(utils::WriteFile(StringPrintf("%s/hardtocompress",
616 b_mnt.c_str()).c_str(),
617 reinterpret_cast<const char*>(kRandomString),
618 sizeof(kRandomString)));
619 }
620
621 string old_kernel;
622 EXPECT_TRUE(utils::MakeTempFile("/tmp/old_kernel.XXXXXX", &old_kernel, NULL));
623 ScopedPathUnlinker old_kernel_unlinker(old_kernel);
624
625 string new_kernel;
626 EXPECT_TRUE(utils::MakeTempFile("/tmp/new_kernel.XXXXXX", &new_kernel, NULL));
627 ScopedPathUnlinker new_kernel_unlinker(new_kernel);
628
629 vector<char> old_kernel_data(4096); // Something small for a test
630 vector<char> new_kernel_data(old_kernel_data.size());
631 FillWithData(&old_kernel_data);
632 FillWithData(&new_kernel_data);
633
634 // change the new kernel data
635 const char* new_data_string = "This is new data.";
636 strcpy(&new_kernel_data[0], new_data_string);
637
638 // Write kernels to disk
639 EXPECT_TRUE(utils::WriteFile(
640 old_kernel.c_str(), &old_kernel_data[0], old_kernel_data.size()));
641 EXPECT_TRUE(utils::WriteFile(
642 new_kernel.c_str(), &new_kernel_data[0], new_kernel_data.size()));
643
644 string delta_path;
645 EXPECT_TRUE(utils::MakeTempFile("/tmp/delta.XXXXXX", &delta_path, NULL));
646 LOG(INFO) << "delta path: " << delta_path;
647 ScopedPathUnlinker delta_path_unlinker(delta_path);
648 {
649 string a_mnt, b_mnt;
650 ScopedLoopMounter a_mounter(a_img, &a_mnt, MS_RDONLY);
651 ScopedLoopMounter b_mounter(b_img, &b_mnt, MS_RDONLY);
652 const string private_key = kUnittestPrivateKeyPath;
653 EXPECT_TRUE(
654 DeltaDiffGenerator::GenerateDeltaUpdateFile(
655 full_rootfs ? "" : a_mnt,
656 full_rootfs ? "" : a_img,
657 b_mnt,
658 b_img,
659 full_kernel ? "" : old_kernel,
660 new_kernel,
661 delta_path,
662 private_key));
663 }
664
665 // Read delta into memory.
666 vector<char> delta;
667 EXPECT_TRUE(utils::ReadFile(delta_path, &delta));
668
669 uint64_t manifest_metadata_size;
670 const int kManifestSizeOffset = 12;
671 const int kManifestOffset = 20;
672 // Check the metadata.
673 {
674 LOG(INFO) << "delta size: " << delta.size();
675 DeltaArchiveManifest manifest;
676 uint64_t manifest_size = 0;
677 memcpy(&manifest_size, &delta[kManifestSizeOffset], sizeof(manifest_size));
678 manifest_size = be64toh(manifest_size);
679 LOG(INFO) << "manifest size: " << manifest_size;
680 EXPECT_TRUE(manifest.ParseFromArray(&delta[kManifestOffset],
681 manifest_size));
682 manifest_metadata_size = kManifestOffset + manifest_size;
683
684 {
685 EXPECT_TRUE(manifest.has_signatures_offset());
686 EXPECT_TRUE(manifest.has_signatures_size());
687 Signatures sigs_message;
688 EXPECT_TRUE(sigs_message.ParseFromArray(
689 &delta[manifest_metadata_size + manifest.signatures_offset()],
690 manifest.signatures_size()));
691 EXPECT_EQ(1, sigs_message.signatures_size());
692 const Signatures_Signature& signature = sigs_message.signatures(0);
693 EXPECT_EQ(1, signature.version());
694
695 uint64_t expected_sig_data_length = 0;
696 vector<string> key_paths (1, kUnittestPrivateKeyPath);
697 EXPECT_TRUE(PayloadSigner::SignatureBlobLength(
698 key_paths,
699 &expected_sig_data_length));
700 EXPECT_EQ(expected_sig_data_length, manifest.signatures_size());
701 EXPECT_FALSE(signature.data().empty());
702 }
703
704 if (full_kernel) {
705 EXPECT_FALSE(manifest.has_old_kernel_info());
706 } else {
707 EXPECT_EQ(old_kernel_data.size(), manifest.old_kernel_info().size());
708 EXPECT_FALSE(manifest.old_kernel_info().hash().empty());
709 }
710
711 if (full_rootfs) {
712 EXPECT_FALSE(manifest.has_old_rootfs_info());
713 } else {
714 EXPECT_EQ(image_size, manifest.old_rootfs_info().size());
715 EXPECT_FALSE(manifest.old_rootfs_info().hash().empty());
716 }
717
718 EXPECT_EQ(new_kernel_data.size(), manifest.new_kernel_info().size());
719 EXPECT_EQ(image_size, manifest.new_rootfs_info().size());
720
721 EXPECT_FALSE(manifest.new_kernel_info().hash().empty());
722 EXPECT_FALSE(manifest.new_rootfs_info().hash().empty());
723
724 }
725
726 PrefsMock prefs;
727 EXPECT_CALL(prefs, SetInt64(kPrefsManifestMetadataSize,
728 manifest_metadata_size)).WillOnce(Return(true));
729 EXPECT_CALL(prefs, SetInt64(kPrefsUpdateStateNextOperation, _))
730 .WillRepeatedly(Return(true));
731 EXPECT_CALL(prefs, GetInt64(kPrefsUpdateStateNextOperation, _))
732 .WillOnce(Return(false));
733 EXPECT_CALL(prefs, SetInt64(kPrefsUpdateStateNextDataOffset, _))
734 .WillRepeatedly(Return(true));
735 EXPECT_CALL(prefs, SetString(kPrefsUpdateStateSHA256Context, _))
736 .WillRepeatedly(Return(true));
737 EXPECT_CALL(prefs, SetString(kPrefsUpdateStateSignedSHA256Context, _))
738 .WillRepeatedly(Return(true));
739 EXPECT_CALL(prefs, SetString(kPrefsUpdateStateSignatureBlob, _))
740 .WillOnce(Return(true));
741
742 // Update the A image in place.
743 InstallPlan install_plan;
744 install_plan.manifest_size = manifest_metadata_size;
745 LOG(INFO) << "Setting Omaha manifest size = " << manifest_metadata_size;
746 ASSERT_TRUE(PayloadSigner::GetManifestSignature(
747 &delta[kManifestOffset],
748 manifest_metadata_size-kManifestOffset,
749 kUnittestPrivateKeyPath,
750 &install_plan.manifest_signature));
751 EXPECT_FALSE(install_plan.manifest_signature.empty());
752
753 DeltaPerformer performer(&prefs, &install_plan);
754 EXPECT_TRUE(utils::FileExists(kUnittestPublicKeyPath));
755 performer.set_public_key_path(kUnittestPublicKeyPath);
756
757 EXPECT_EQ(image_size,
758 OmahaHashCalculator::RawHashOfFile(a_img,
759 image_size,
760 &install_plan.rootfs_hash));
761 EXPECT_TRUE(OmahaHashCalculator::RawHashOfData(old_kernel_data,
762 &install_plan.kernel_hash));
763
764 EXPECT_EQ(0, performer.Open(a_img.c_str(), 0, 0));
765 EXPECT_TRUE(performer.OpenKernel(old_kernel.c_str()));
766
767 // Write at some number of bytes per operation. Arbitrarily chose 5.
768 const size_t kBytesPerWrite = 5;
769 for (size_t i = 0; i < delta.size(); i += kBytesPerWrite) {
770 size_t count = min(delta.size() - i, kBytesPerWrite);
771 EXPECT_TRUE(performer.Write(&delta[i], count));
772 }
773
774 // Wrapper around close. Returns 0 on success or -errno on error.
775 EXPECT_EQ(0, performer.Close());
776
777 CompareFilesByBlock(old_kernel, new_kernel);
778 CompareFilesByBlock(a_img, b_img);
779
780 vector<char> updated_kernel_partition;
781 EXPECT_TRUE(utils::ReadFile(old_kernel, &updated_kernel_partition));
782 EXPECT_EQ(0, strncmp(&updated_kernel_partition[0], new_data_string,
783 strlen(new_data_string)));
784
785 ActionExitCode expect_verify_result = kActionCodeSuccess;
786 LOG(INFO) << "Verifying Payload ...";
787 EXPECT_EQ(expect_verify_result, performer.VerifyPayload(
788 OmahaHashCalculator::OmahaHashOfData(delta),
789 delta.size()));
790
791 LOG(INFO) << "Verified Payload";
792
793 uint64_t new_kernel_size;
794 vector<char> new_kernel_hash;
795 uint64_t new_rootfs_size;
796 vector<char> new_rootfs_hash;
797 EXPECT_TRUE(performer.GetNewPartitionInfo(&new_kernel_size,
798 &new_kernel_hash,
799 &new_rootfs_size,
800 &new_rootfs_hash));
801 EXPECT_EQ(4096, new_kernel_size);
802 vector<char> expected_new_kernel_hash;
803 EXPECT_TRUE(OmahaHashCalculator::RawHashOfData(new_kernel_data,
804 &expected_new_kernel_hash));
805 EXPECT_TRUE(expected_new_kernel_hash == new_kernel_hash);
806 EXPECT_EQ(image_size, new_rootfs_size);
807 vector<char> expected_new_rootfs_hash;
808 EXPECT_EQ(image_size,
809 OmahaHashCalculator::RawHashOfFile(b_img,
810 image_size,
811 &expected_new_rootfs_hash));
812 EXPECT_TRUE(expected_new_rootfs_hash == new_rootfs_hash);
813}
Andrew de los Reyesc24e3f32011-08-30 15:45:20 -0700814} // namespace {}
Darin Petkov68c10d12010-10-14 09:24:37 -0700815
816TEST(DeltaPerformerTest, RunAsRootSmallImageTest) {
Darin Petkovcbfb0172011-01-14 15:24:45 -0800817 DoSmallImageTest(false, false, false, kSignatureGenerator);
Darin Petkov68c10d12010-10-14 09:24:37 -0700818}
819
820TEST(DeltaPerformerTest, RunAsRootFullKernelSmallImageTest) {
Darin Petkovcbfb0172011-01-14 15:24:45 -0800821 DoSmallImageTest(true, false, false, kSignatureGenerator);
Darin Petkov7a22d792010-11-08 14:10:00 -0800822}
823
824TEST(DeltaPerformerTest, RunAsRootFullSmallImageTest) {
Darin Petkovcbfb0172011-01-14 15:24:45 -0800825 DoSmallImageTest(true, true, false, kSignatureGenerator);
Darin Petkov9fa7ec52010-10-18 11:45:23 -0700826}
827
828TEST(DeltaPerformerTest, RunAsRootNoopSmallImageTest) {
Darin Petkovcbfb0172011-01-14 15:24:45 -0800829 DoSmallImageTest(false, false, true, kSignatureGenerator);
Darin Petkov9574f7e2011-01-13 10:48:12 -0800830}
831
Darin Petkovcbfb0172011-01-14 15:24:45 -0800832TEST(DeltaPerformerTest, RunAsRootSmallImageSignNoneTest) {
833 DoSmallImageTest(false, false, false, kSignatureNone);
834}
835
836TEST(DeltaPerformerTest, RunAsRootSmallImageSignGeneratedTest) {
837 DoSmallImageTest(false, false, false, kSignatureGenerated);
838}
839
840TEST(DeltaPerformerTest, RunAsRootSmallImageSignGeneratedShellTest) {
841 DoSmallImageTest(false, false, false, kSignatureGeneratedShell);
Andrew de los Reyes27f7d372010-10-07 11:26:07 -0700842}
843
Darin Petkov52dcaeb2011-01-14 15:33:06 -0800844TEST(DeltaPerformerTest, RunAsRootSmallImageSignGeneratedShellBadKeyTest) {
845 DoSmallImageTest(false, false, false, kSignatureGeneratedShellBadKey);
846}
847
Andrew de los Reyesc24e3f32011-08-30 15:45:20 -0700848TEST(DeltaPerformerTest, RunAsRootSmallImageSignGeneratedShellRotateCl1Test) {
849 DoSmallImageTest(false, false, false, kSignatureGeneratedShellRotateCl1);
850}
851
852TEST(DeltaPerformerTest, RunAsRootSmallImageSignGeneratedShellRotateCl2Test) {
853 DoSmallImageTest(false, false, false, kSignatureGeneratedShellRotateCl2);
854}
855
Darin Petkov934bb412010-11-18 11:21:35 -0800856TEST(DeltaPerformerTest, BadDeltaMagicTest) {
857 PrefsMock prefs;
Jay Srinivasan51dcf262012-09-13 17:24:32 -0700858 InstallPlan install_plan;
859 DeltaPerformer performer(&prefs, &install_plan);
Darin Petkov934bb412010-11-18 11:21:35 -0800860 EXPECT_EQ(0, performer.Open("/dev/null", 0, 0));
861 EXPECT_TRUE(performer.OpenKernel("/dev/null"));
Don Garrette410e0f2011-11-10 15:39:01 -0800862 EXPECT_TRUE(performer.Write("junk", 4));
863 EXPECT_TRUE(performer.Write("morejunk", 8));
864 EXPECT_FALSE(performer.Write("morejunk", 8));
Darin Petkov934bb412010-11-18 11:21:35 -0800865 EXPECT_LT(performer.Close(), 0);
866}
867
Andrew de los Reyes353777c2010-10-08 10:34:30 -0700868TEST(DeltaPerformerTest, IsIdempotentOperationTest) {
869 DeltaArchiveManifest_InstallOperation op;
870 EXPECT_TRUE(DeltaPerformer::IsIdempotentOperation(op));
871 *(op.add_dst_extents()) = ExtentForRange(0, 5);
872 EXPECT_TRUE(DeltaPerformer::IsIdempotentOperation(op));
873 *(op.add_src_extents()) = ExtentForRange(4, 1);
874 EXPECT_FALSE(DeltaPerformer::IsIdempotentOperation(op));
875 op.clear_src_extents();
876 *(op.add_src_extents()) = ExtentForRange(5, 3);
877 EXPECT_TRUE(DeltaPerformer::IsIdempotentOperation(op));
878 *(op.add_dst_extents()) = ExtentForRange(20, 6);
879 EXPECT_TRUE(DeltaPerformer::IsIdempotentOperation(op));
880 *(op.add_src_extents()) = ExtentForRange(19, 2);
881 EXPECT_FALSE(DeltaPerformer::IsIdempotentOperation(op));
882}
883
Jay Srinivasan51dcf262012-09-13 17:24:32 -0700884TEST(DeltaPerformerTest, RunAsRootRunValidManifestTest) {
885 DoManifestTest();
886}
887
888
Andrew de los Reyes09e56d62010-04-23 13:45:53 -0700889} // namespace chromeos_update_engine