blob: f95ebed5dcd787bdb40e17f77bee3ec70abdb322 [file] [log] [blame]
Jed Estepb8a693b2016-03-09 17:51:34 -08001/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agree to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include <fcntl.h>
18#include <gtest/gtest.h>
19#include <stdio.h>
20#include <stdlib.h>
21#include <sys/stat.h>
22#include <sys/statvfs.h>
23#include <sys/types.h>
24#include <time.h>
25
Tao Baofada91c2016-10-27 18:16:06 -070026#include <memory>
Jed Estepb8a693b2016-03-09 17:51:34 -080027#include <string>
Tao Baofada91c2016-10-27 18:16:06 -070028#include <vector>
Jed Estepb8a693b2016-03-09 17:51:34 -080029
30#include <android-base/file.h>
31#include <android-base/stringprintf.h>
32#include <android-base/test_utils.h>
Tao Baofada91c2016-10-27 18:16:06 -070033#include <openssl/sha.h>
Jed Estepb8a693b2016-03-09 17:51:34 -080034
35#include "applypatch/applypatch.h"
Tao Bao36c35112016-10-25 14:17:26 -070036#include "applypatch/applypatch_modes.h"
Jed Estepb8a693b2016-03-09 17:51:34 -080037#include "common/test_constants.h"
Jed Estepb8a693b2016-03-09 17:51:34 -080038#include "print_sha1.h"
39
40static const std::string DATA_PATH = getenv("ANDROID_DATA");
41static const std::string TESTDATA_PATH = "/recovery/testdata";
Jed Estepb8a693b2016-03-09 17:51:34 -080042
Tao Bao36c35112016-10-25 14:17:26 -070043static void sha1sum(const std::string& fname, std::string* sha1, size_t* fsize = nullptr) {
44 ASSERT_NE(nullptr, sha1);
Tao Baofada91c2016-10-27 18:16:06 -070045
Tao Bao36c35112016-10-25 14:17:26 -070046 std::string data;
47 ASSERT_TRUE(android::base::ReadFileToString(fname, &data));
Jed Estepb8a693b2016-03-09 17:51:34 -080048
Tao Bao36c35112016-10-25 14:17:26 -070049 if (fsize != nullptr) {
50 *fsize = data.size();
51 }
52
53 uint8_t digest[SHA_DIGEST_LENGTH];
54 SHA1(reinterpret_cast<const uint8_t*>(data.c_str()), data.size(), digest);
55 *sha1 = print_sha1(digest);
Jed Estepb8a693b2016-03-09 17:51:34 -080056}
57
58static void mangle_file(const std::string& fname) {
Tao Bao36c35112016-10-25 14:17:26 -070059 std::string content;
60 content.reserve(1024);
61 for (size_t i = 0; i < 1024; i++) {
62 content[i] = rand() % 256;
63 }
64 ASSERT_TRUE(android::base::WriteStringToFile(content, fname));
Jed Estepb8a693b2016-03-09 17:51:34 -080065}
66
Tao Baofada91c2016-10-27 18:16:06 -070067static bool file_cmp(const std::string& f1, const std::string& f2) {
Tao Bao36c35112016-10-25 14:17:26 -070068 std::string c1;
69 android::base::ReadFileToString(f1, &c1);
70 std::string c2;
71 android::base::ReadFileToString(f2, &c2);
72 return c1 == c2;
Jed Estepb8a693b2016-03-09 17:51:34 -080073}
74
Chih-Hung Hsieh8b238112016-08-26 14:54:29 -070075static std::string from_testdata_base(const std::string& fname) {
Tao Bao36c35112016-10-25 14:17:26 -070076 return DATA_PATH + NATIVE_TEST_PATH + TESTDATA_PATH + "/" + fname;
Jed Estepb8a693b2016-03-09 17:51:34 -080077}
78
79class ApplyPatchTest : public ::testing::Test {
Tao Bao36c35112016-10-25 14:17:26 -070080 public:
81 static void SetUpTestCase() {
82 // set up files
83 old_file = from_testdata_base("old.file");
84 new_file = from_testdata_base("new.file");
85 patch_file = from_testdata_base("patch.bsdiff");
86 rand_file = "/cache/applypatch_test_rand.file";
87 cache_file = "/cache/saved.file";
Jed Estepb8a693b2016-03-09 17:51:34 -080088
Tao Bao36c35112016-10-25 14:17:26 -070089 // write stuff to rand_file
90 ASSERT_TRUE(android::base::WriteStringToFile("hello", rand_file));
Jed Estepb8a693b2016-03-09 17:51:34 -080091
Tao Bao36c35112016-10-25 14:17:26 -070092 // set up SHA constants
93 sha1sum(old_file, &old_sha1);
94 sha1sum(new_file, &new_sha1);
95 srand(time(nullptr));
96 bad_sha1_a = android::base::StringPrintf("%040x", rand());
97 bad_sha1_b = android::base::StringPrintf("%040x", rand());
Jed Estepb8a693b2016-03-09 17:51:34 -080098
Tao Bao36c35112016-10-25 14:17:26 -070099 struct stat st;
100 stat(&new_file[0], &st);
101 new_size = st.st_size;
102 }
Jed Estepb8a693b2016-03-09 17:51:34 -0800103
Tao Bao36c35112016-10-25 14:17:26 -0700104 static std::string old_file;
105 static std::string new_file;
106 static std::string rand_file;
107 static std::string cache_file;
108 static std::string patch_file;
Jed Estepb8a693b2016-03-09 17:51:34 -0800109
Tao Bao36c35112016-10-25 14:17:26 -0700110 static std::string old_sha1;
111 static std::string new_sha1;
112 static std::string bad_sha1_a;
113 static std::string bad_sha1_b;
Jed Estepb8a693b2016-03-09 17:51:34 -0800114
Tao Bao36c35112016-10-25 14:17:26 -0700115 static size_t new_size;
Jed Estepb8a693b2016-03-09 17:51:34 -0800116};
117
118std::string ApplyPatchTest::old_file;
119std::string ApplyPatchTest::new_file;
120
Tao Baofada91c2016-10-27 18:16:06 -0700121static void cp(const std::string& src, const std::string& tgt) {
Tao Bao36c35112016-10-25 14:17:26 -0700122 std::string cmd = "cp " + src + " " + tgt;
123 system(cmd.c_str());
Jed Estepb8a693b2016-03-09 17:51:34 -0800124}
125
126static void backup_old() {
Tao Bao36c35112016-10-25 14:17:26 -0700127 cp(ApplyPatchTest::old_file, ApplyPatchTest::cache_file);
Jed Estepb8a693b2016-03-09 17:51:34 -0800128}
129
130static void restore_old() {
Tao Bao36c35112016-10-25 14:17:26 -0700131 cp(ApplyPatchTest::cache_file, ApplyPatchTest::old_file);
Jed Estepb8a693b2016-03-09 17:51:34 -0800132}
133
134class ApplyPatchCacheTest : public ApplyPatchTest {
Tao Bao36c35112016-10-25 14:17:26 -0700135 public:
136 virtual void SetUp() {
137 backup_old();
138 }
Jed Estepb8a693b2016-03-09 17:51:34 -0800139
Tao Bao36c35112016-10-25 14:17:26 -0700140 virtual void TearDown() {
141 restore_old();
142 }
Jed Estepb8a693b2016-03-09 17:51:34 -0800143};
144
145class ApplyPatchFullTest : public ApplyPatchCacheTest {
Tao Bao36c35112016-10-25 14:17:26 -0700146 public:
147 static void SetUpTestCase() {
148 ApplyPatchTest::SetUpTestCase();
Jed Estepb8a693b2016-03-09 17:51:34 -0800149
Tao Bao36c35112016-10-25 14:17:26 -0700150 output_f = new TemporaryFile();
151 output_loc = std::string(output_f->path);
Jed Estepb8a693b2016-03-09 17:51:34 -0800152
Tao Bao36c35112016-10-25 14:17:26 -0700153 struct FileContents fc;
Jed Estepb8a693b2016-03-09 17:51:34 -0800154
Tao Bao36c35112016-10-25 14:17:26 -0700155 ASSERT_EQ(0, LoadFileContents(&rand_file[0], &fc));
156 patches.push_back(
157 std::make_unique<Value>(VAL_BLOB, std::string(fc.data.begin(), fc.data.end())));
Jed Estepb8a693b2016-03-09 17:51:34 -0800158
Tao Bao36c35112016-10-25 14:17:26 -0700159 ASSERT_EQ(0, LoadFileContents(&patch_file[0], &fc));
160 patches.push_back(
161 std::make_unique<Value>(VAL_BLOB, std::string(fc.data.begin(), fc.data.end())));
162 }
Tao Baofada91c2016-10-27 18:16:06 -0700163
Tao Bao36c35112016-10-25 14:17:26 -0700164 static void TearDownTestCase() {
165 delete output_f;
166 patches.clear();
167 }
Tao Baofada91c2016-10-27 18:16:06 -0700168
Tao Bao36c35112016-10-25 14:17:26 -0700169 static std::vector<std::unique_ptr<Value>> patches;
170 static TemporaryFile* output_f;
171 static std::string output_loc;
Jed Estepb8a693b2016-03-09 17:51:34 -0800172};
173
174class ApplyPatchDoubleCacheTest : public ApplyPatchFullTest {
Tao Bao36c35112016-10-25 14:17:26 -0700175 public:
176 virtual void SetUp() {
177 ApplyPatchCacheTest::SetUp();
178 cp(cache_file, "/cache/reallysaved.file");
179 }
Jed Estepb8a693b2016-03-09 17:51:34 -0800180
Tao Bao36c35112016-10-25 14:17:26 -0700181 virtual void TearDown() {
182 cp("/cache/reallysaved.file", cache_file);
183 ApplyPatchCacheTest::TearDown();
184 }
Jed Estepb8a693b2016-03-09 17:51:34 -0800185};
186
187std::string ApplyPatchTest::rand_file;
188std::string ApplyPatchTest::patch_file;
189std::string ApplyPatchTest::cache_file;
190std::string ApplyPatchTest::old_sha1;
191std::string ApplyPatchTest::new_sha1;
192std::string ApplyPatchTest::bad_sha1_a;
193std::string ApplyPatchTest::bad_sha1_b;
194
195size_t ApplyPatchTest::new_size;
196
Tao Baofada91c2016-10-27 18:16:06 -0700197std::vector<std::unique_ptr<Value>> ApplyPatchFullTest::patches;
Jed Estepb8a693b2016-03-09 17:51:34 -0800198TemporaryFile* ApplyPatchFullTest::output_f;
199std::string ApplyPatchFullTest::output_loc;
200
Tianjie Xua5fd5ab2016-10-18 15:18:22 -0700201TEST_F(ApplyPatchTest, CheckModeSkip) {
Tao Bao36c35112016-10-25 14:17:26 -0700202 std::vector<std::string> sha1s;
203 ASSERT_EQ(0, applypatch_check(&old_file[0], sha1s));
Tianjie Xua5fd5ab2016-10-18 15:18:22 -0700204}
205
Jed Estepb8a693b2016-03-09 17:51:34 -0800206TEST_F(ApplyPatchTest, CheckModeSingle) {
Tao Bao36c35112016-10-25 14:17:26 -0700207 std::vector<std::string> sha1s = { old_sha1 };
208 ASSERT_EQ(0, applypatch_check(&old_file[0], sha1s));
Jed Estepb8a693b2016-03-09 17:51:34 -0800209}
210
211TEST_F(ApplyPatchTest, CheckModeMultiple) {
Tao Bao36c35112016-10-25 14:17:26 -0700212 std::vector<std::string> sha1s = { bad_sha1_a, old_sha1, bad_sha1_b };
213 ASSERT_EQ(0, applypatch_check(&old_file[0], sha1s));
Jed Estepb8a693b2016-03-09 17:51:34 -0800214}
215
216TEST_F(ApplyPatchTest, CheckModeFailure) {
Tao Bao36c35112016-10-25 14:17:26 -0700217 std::vector<std::string> sha1s = { bad_sha1_a, bad_sha1_b };
218 ASSERT_NE(0, applypatch_check(&old_file[0], sha1s));
Jed Estepb8a693b2016-03-09 17:51:34 -0800219}
220
221TEST_F(ApplyPatchCacheTest, CheckCacheCorruptedSingle) {
Tao Bao36c35112016-10-25 14:17:26 -0700222 mangle_file(old_file);
223 std::vector<std::string> sha1s = { old_sha1 };
224 ASSERT_EQ(0, applypatch_check(&old_file[0], sha1s));
Jed Estepb8a693b2016-03-09 17:51:34 -0800225}
226
227TEST_F(ApplyPatchCacheTest, CheckCacheCorruptedMultiple) {
Tao Bao36c35112016-10-25 14:17:26 -0700228 mangle_file(old_file);
229 std::vector<std::string> sha1s = { bad_sha1_a, old_sha1, bad_sha1_b };
230 ASSERT_EQ(0, applypatch_check(&old_file[0], sha1s));
Jed Estepb8a693b2016-03-09 17:51:34 -0800231}
232
233TEST_F(ApplyPatchCacheTest, CheckCacheCorruptedFailure) {
Tao Bao36c35112016-10-25 14:17:26 -0700234 mangle_file(old_file);
235 std::vector<std::string> sha1s = { bad_sha1_a, bad_sha1_b };
236 ASSERT_NE(0, applypatch_check(&old_file[0], sha1s));
Jed Estepb8a693b2016-03-09 17:51:34 -0800237}
238
239TEST_F(ApplyPatchCacheTest, CheckCacheMissingSingle) {
Tao Bao36c35112016-10-25 14:17:26 -0700240 unlink(&old_file[0]);
241 std::vector<std::string> sha1s = { old_sha1 };
242 ASSERT_EQ(0, applypatch_check(&old_file[0], sha1s));
Jed Estepb8a693b2016-03-09 17:51:34 -0800243}
244
245TEST_F(ApplyPatchCacheTest, CheckCacheMissingMultiple) {
Tao Bao36c35112016-10-25 14:17:26 -0700246 unlink(&old_file[0]);
247 std::vector<std::string> sha1s = { bad_sha1_a, old_sha1, bad_sha1_b };
248 ASSERT_EQ(0, applypatch_check(&old_file[0], sha1s));
Jed Estepb8a693b2016-03-09 17:51:34 -0800249}
250
251TEST_F(ApplyPatchCacheTest, CheckCacheMissingFailure) {
Tao Bao36c35112016-10-25 14:17:26 -0700252 unlink(&old_file[0]);
253 std::vector<std::string> sha1s = { bad_sha1_a, bad_sha1_b };
254 ASSERT_NE(0, applypatch_check(&old_file[0], sha1s));
Jed Estepb8a693b2016-03-09 17:51:34 -0800255}
256
257TEST_F(ApplyPatchFullTest, ApplyInPlace) {
Tao Bao36c35112016-10-25 14:17:26 -0700258 std::vector<std::string> sha1s = { bad_sha1_a, old_sha1 };
259 ASSERT_EQ(0, applypatch(&old_file[0], "-", &new_sha1[0], new_size, sha1s, patches, nullptr));
260 ASSERT_TRUE(file_cmp(old_file, new_file));
261
262 // reapply, applypatch is idempotent so it should succeed
263 ASSERT_EQ(0, applypatch(&old_file[0], "-", &new_sha1[0], new_size, sha1s, patches, nullptr));
264 ASSERT_TRUE(file_cmp(old_file, new_file));
Jed Estepb8a693b2016-03-09 17:51:34 -0800265}
266
267TEST_F(ApplyPatchFullTest, ApplyInNewLocation) {
Tao Bao36c35112016-10-25 14:17:26 -0700268 std::vector<std::string> sha1s = { bad_sha1_a, old_sha1 };
269 // Apply bsdiff patch to new location.
270 ASSERT_EQ(
271 0, applypatch(&old_file[0], &output_loc[0], &new_sha1[0], new_size, sha1s, patches, nullptr));
272 ASSERT_TRUE(file_cmp(output_loc, new_file));
Tao Baofada91c2016-10-27 18:16:06 -0700273
Tao Bao36c35112016-10-25 14:17:26 -0700274 // Reapply to the same location.
275 ASSERT_EQ(
276 0, applypatch(&old_file[0], &output_loc[0], &new_sha1[0], new_size, sha1s, patches, nullptr));
277 ASSERT_TRUE(file_cmp(output_loc, new_file));
Jed Estepb8a693b2016-03-09 17:51:34 -0800278}
279
280TEST_F(ApplyPatchFullTest, ApplyCorruptedInNewLocation) {
Tao Bao36c35112016-10-25 14:17:26 -0700281 std::vector<std::string> sha1s = { bad_sha1_a, old_sha1 };
282 // Apply bsdiff patch to new location with corrupted source.
283 mangle_file(old_file);
284 ASSERT_EQ(
285 0, applypatch(&old_file[0], &output_loc[0], &new_sha1[0], new_size, sha1s, patches, nullptr));
286 ASSERT_TRUE(file_cmp(output_loc, new_file));
Tao Baofada91c2016-10-27 18:16:06 -0700287
Tao Bao36c35112016-10-25 14:17:26 -0700288 // Reapply bsdiff patch to new location with corrupted source.
289 ASSERT_EQ(
290 0, applypatch(&old_file[0], &output_loc[0], &new_sha1[0], new_size, sha1s, patches, nullptr));
291 ASSERT_TRUE(file_cmp(output_loc, new_file));
Jed Estepb8a693b2016-03-09 17:51:34 -0800292}
293
294TEST_F(ApplyPatchDoubleCacheTest, ApplyDoubleCorruptedInNewLocation) {
Tao Bao36c35112016-10-25 14:17:26 -0700295 std::vector<std::string> sha1s = { bad_sha1_a, old_sha1 };
Tao Baofada91c2016-10-27 18:16:06 -0700296
Tao Bao36c35112016-10-25 14:17:26 -0700297 // Apply bsdiff patch to new location with corrupted source and copy (no new file).
298 // Expected to fail.
299 mangle_file(old_file);
300 mangle_file(cache_file);
301 ASSERT_NE(
302 0, applypatch(&old_file[0], &output_loc[0], &new_sha1[0], new_size, sha1s, patches, nullptr));
303 ASSERT_FALSE(file_cmp(output_loc, new_file));
Tao Baofada91c2016-10-27 18:16:06 -0700304
Tao Bao36c35112016-10-25 14:17:26 -0700305 // Expected to fail again on retry.
306 ASSERT_NE(
307 0, applypatch(&old_file[0], &output_loc[0], &new_sha1[0], new_size, sha1s, patches, nullptr));
308 ASSERT_FALSE(file_cmp(output_loc, new_file));
Tao Baofada91c2016-10-27 18:16:06 -0700309
Tao Bao36c35112016-10-25 14:17:26 -0700310 // Expected to fail with incorrect new file.
311 mangle_file(output_loc);
312 ASSERT_NE(
313 0, applypatch(&old_file[0], &output_loc[0], &new_sha1[0], new_size, sha1s, patches, nullptr));
314 ASSERT_FALSE(file_cmp(output_loc, new_file));
315}
316
317TEST(ApplyPatchModes, InvalidArgs) {
318 // At least two args (including the filename).
319 ASSERT_EQ(2, applypatch_modes(1, (const char* []){ "applypatch" }));
320
321 // Unrecognized args.
322 ASSERT_EQ(2, applypatch_modes(2, (const char* []){ "applypatch", "-x" }));
323}
324
325TEST(ApplyPatchModes, PatchMode) {
326 std::string boot_img = from_testdata_base("boot.img");
327 size_t boot_img_size;
328 std::string boot_img_sha1;
329 sha1sum(boot_img, &boot_img_sha1, &boot_img_size);
330
331 std::string recovery_img = from_testdata_base("recovery.img");
332 size_t recovery_img_size;
333 std::string recovery_img_sha1;
334 sha1sum(recovery_img, &recovery_img_sha1, &recovery_img_size);
335
336 std::string bonus_file = from_testdata_base("bonus.file");
337
338 // applypatch -b <bonus-file> <src-file> <tgt-file> <tgt-sha1> <tgt-size> <src-sha1>:<patch>
339 TemporaryFile tmp1;
340 std::vector<const char*> args = {
341 "applypatch",
342 "-b",
343 bonus_file.c_str(),
344 boot_img.c_str(),
345 tmp1.path,
346 recovery_img_sha1.c_str(),
347 std::to_string(recovery_img_size).c_str(),
348 (boot_img_sha1 + ":" + from_testdata_base("recovery-from-boot.p")).c_str()
349 };
350 ASSERT_EQ(0, applypatch_modes(args.size(), args.data()));
351
352 // applypatch <src-file> <tgt-file> <tgt-sha1> <tgt-size> <src-sha1>:<patch>
353 TemporaryFile tmp2;
354 std::vector<const char*> args2 = {
355 "applypatch",
356 boot_img.c_str(),
357 tmp2.path,
358 recovery_img_sha1.c_str(),
359 std::to_string(recovery_img_size).c_str(),
360 (boot_img_sha1 + ":" + from_testdata_base("recovery-from-boot-with-bonus.p")).c_str()
361 };
362 ASSERT_EQ(0, applypatch_modes(args2.size(), args2.data()));
363
364 // applypatch -b <bonus-file> <src-file> <tgt-file> <tgt-sha1> <tgt-size> \
365 // <src-sha1-fake>:<patch1> <src-sha1>:<patch2>
366 TemporaryFile tmp3;
367 std::string bad_sha1_a = android::base::StringPrintf("%040x", rand());
368 std::string bad_sha1_b = android::base::StringPrintf("%040x", rand());
369 std::vector<const char*> args3 = {
370 "applypatch",
371 "-b",
372 bonus_file.c_str(),
373 boot_img.c_str(),
374 tmp3.path,
375 recovery_img_sha1.c_str(),
376 std::to_string(recovery_img_size).c_str(),
377 (bad_sha1_a + ":" + from_testdata_base("recovery-from-boot.p")).c_str(),
378 (boot_img_sha1 + ":" + from_testdata_base("recovery-from-boot.p")).c_str(),
379 (bad_sha1_b + ":" + from_testdata_base("recovery-from-boot.p")).c_str(),
380 };
381 ASSERT_EQ(0, applypatch_modes(args3.size(), args3.data()));
382}
383
384TEST(ApplyPatchModes, PatchModeInvalidArgs) {
385 // Invalid bonus file.
386 ASSERT_NE(0, applypatch_modes(3, (const char* []){ "applypatch", "-b", "/doesntexist" }));
387
388 std::string bonus_file = from_testdata_base("bonus.file");
389 // With bonus file, but missing args.
390 ASSERT_EQ(2, applypatch_modes(3, (const char* []){ "applypatch", "-b", bonus_file.c_str() }));
391
392 std::string boot_img = from_testdata_base("boot.img");
393 size_t boot_img_size;
394 std::string boot_img_sha1;
395 sha1sum(boot_img, &boot_img_sha1, &boot_img_size);
396
397 std::string recovery_img = from_testdata_base("recovery.img");
398 size_t recovery_img_size;
399 std::string recovery_img_sha1;
400 sha1sum(recovery_img, &recovery_img_sha1, &recovery_img_size);
401
402 // Bonus file is not supported in flash mode.
403 // applypatch -b <bonus-file> <src-file> <tgt-file> <tgt-sha1> <tgt-size>
404 TemporaryFile tmp4;
405 std::vector<const char*> args4 = {
406 "applypatch",
407 "-b",
408 bonus_file.c_str(),
409 boot_img.c_str(),
410 tmp4.path,
411 recovery_img_sha1.c_str(),
412 std::to_string(recovery_img_size).c_str() };
413 ASSERT_NE(0, applypatch_modes(args4.size(), args4.data()));
414
415 // Failed to parse patch args.
416 TemporaryFile tmp5;
417 std::vector<const char*> args5 = {
418 "applypatch",
419 boot_img.c_str(),
420 tmp5.path,
421 recovery_img_sha1.c_str(),
422 std::to_string(recovery_img_size).c_str(),
423 ("invalid-sha1:filename" + from_testdata_base("recovery-from-boot-with-bonus.p")).c_str(),
424 };
425 ASSERT_NE(0, applypatch_modes(args5.size(), args5.data()));
426
427 // Target size cannot be zero.
428 TemporaryFile tmp6;
429 std::vector<const char*> args6 = {
430 "applypatch",
431 boot_img.c_str(),
432 tmp6.path,
433 recovery_img_sha1.c_str(),
434 "0", // target size
435 (boot_img_sha1 + ":" + from_testdata_base("recovery-from-boot-with-bonus.p")).c_str()
436 };
437 ASSERT_NE(0, applypatch_modes(args6.size(), args6.data()));
438}
439
440TEST(ApplyPatchModes, CheckModeInvalidArgs) {
441 // Insufficient args.
442 ASSERT_EQ(2, applypatch_modes(2, (const char* []){ "applypatch", "-c" }));
443}
444
445TEST(ApplyPatchModes, SpaceModeInvalidArgs) {
446 // Insufficient args.
447 ASSERT_EQ(2, applypatch_modes(2, (const char* []){ "applypatch", "-s" }));
448
449 // Invalid bytes arg.
450 ASSERT_EQ(1, applypatch_modes(3, (const char* []){ "applypatch", "-s", "x" }));
451
452 // 0 is invalid.
453 ASSERT_EQ(1, applypatch_modes(3, (const char* []){ "applypatch", "-s", "0" }));
454
455 // 0x10 is fine.
456 ASSERT_EQ(0, applypatch_modes(3, (const char* []){ "applypatch", "-s", "0x10" }));
457}
458
459TEST(ApplyPatchModes, ShowLicenses) {
460 ASSERT_EQ(0, applypatch_modes(2, (const char* []){ "applypatch", "-l" }));
Jed Estepb8a693b2016-03-09 17:51:34 -0800461}