summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTianjie Xu2017-11-06 13:02:01 -0600
committerandroid-build-merger2017-11-06 13:02:01 -0600
commitc1ab2bb5354354ad13da37dd2b664d861d9e2111 (patch)
treee5b3cb24be5eff1e6796814b3a023160a42acd97
parent6d61e2123bbdcde16d9000671e2a25e1f410cf32 (diff)
parentbf41f2aa238a9d928473c69c93308eb0b4f9719d (diff)
downloadplatform-bootable-recovery-c1ab2bb5354354ad13da37dd2b664d861d9e2111.tar.gz
platform-bootable-recovery-c1ab2bb5354354ad13da37dd2b664d861d9e2111.tar.xz
platform-bootable-recovery-c1ab2bb5354354ad13da37dd2b664d861d9e2111.zip
Merge "Switch to bionic gtest in bootable/recovery"
am: bf41f2aa23 Change-Id: I90238f94c3f3eeafe3f24d417f7f6c66ac3cf5fd
-rw-r--r--applypatch/applypatch.cpp18
-rw-r--r--applypatch/freecache.cpp7
-rw-r--r--applypatch/include/applypatch/applypatch.h11
-rw-r--r--bootloader_message/bootloader_message.cpp33
-rw-r--r--bootloader_message/include/bootloader_message/bootloader_message.h5
-rw-r--r--minadbd/Android.mk9
-rw-r--r--tests/Android.mk10
-rw-r--r--tests/component/applypatch_test.cpp131
-rw-r--r--tests/component/bootloader_message_test.cpp140
-rw-r--r--tests/component/uncrypt_test.cpp99
10 files changed, 188 insertions, 275 deletions
diff --git a/applypatch/applypatch.cpp b/applypatch/applypatch.cpp
index c8b75df7..2153b5f1 100644
--- a/applypatch/applypatch.cpp
+++ b/applypatch/applypatch.cpp
@@ -42,6 +42,8 @@
42#include "otafault/ota_io.h" 42#include "otafault/ota_io.h"
43#include "otautil/print_sha1.h" 43#include "otautil/print_sha1.h"
44 44
45std::string cache_temp_source = "/cache/saved.file";
46
45static int LoadPartitionContents(const std::string& filename, FileContents* file); 47static int LoadPartitionContents(const std::string& filename, FileContents* file);
46static size_t FileSink(const unsigned char* data, size_t len, int fd); 48static size_t FileSink(const unsigned char* data, size_t len, int fd);
47static int GenerateTarget(const FileContents& source_file, const std::unique_ptr<Value>& patch, 49static int GenerateTarget(const FileContents& source_file, const std::unique_ptr<Value>& patch,
@@ -411,12 +413,10 @@ int applypatch_check(const char* filename, const std::vector<std::string>& patch
411 (!patch_sha1_str.empty() && FindMatchingPatch(file.sha1, patch_sha1_str) < 0)) { 413 (!patch_sha1_str.empty() && FindMatchingPatch(file.sha1, patch_sha1_str) < 0)) {
412 printf("file \"%s\" doesn't have any of expected sha1 sums; checking cache\n", filename); 414 printf("file \"%s\" doesn't have any of expected sha1 sums; checking cache\n", filename);
413 415
414 // If the source file is missing or corrupted, it might be because 416 // If the source file is missing or corrupted, it might be because we were killed in the middle
415 // we were killed in the middle of patching it. A copy of it 417 // of patching it. A copy of it should have been made in cache_temp_source. If that file
416 // should have been made in CACHE_TEMP_SOURCE. If that file 418 // exists and matches the sha1 we're looking for, the check still passes.
417 // exists and matches the sha1 we're looking for, the check still 419 if (LoadFileContents(cache_temp_source.c_str(), &file) != 0) {
418 // passes.
419 if (LoadFileContents(CACHE_TEMP_SOURCE, &file) != 0) {
420 printf("failed to load cache file\n"); 420 printf("failed to load cache file\n");
421 return 1; 421 return 1;
422 } 422 }
@@ -539,7 +539,7 @@ int applypatch(const char* source_filename, const char* target_filename,
539 printf("source file is bad; trying copy\n"); 539 printf("source file is bad; trying copy\n");
540 540
541 FileContents copy_file; 541 FileContents copy_file;
542 if (LoadFileContents(CACHE_TEMP_SOURCE, &copy_file) < 0) { 542 if (LoadFileContents(cache_temp_source.c_str(), &copy_file) < 0) {
543 printf("failed to read copy file\n"); 543 printf("failed to read copy file\n");
544 return 1; 544 return 1;
545 } 545 }
@@ -634,7 +634,7 @@ static int GenerateTarget(const FileContents& source_file, const std::unique_ptr
634 printf("not enough free space on /cache\n"); 634 printf("not enough free space on /cache\n");
635 return 1; 635 return 1;
636 } 636 }
637 if (SaveFileContents(CACHE_TEMP_SOURCE, &source_file) < 0) { 637 if (SaveFileContents(cache_temp_source.c_str(), &source_file) < 0) {
638 printf("failed to back up source file\n"); 638 printf("failed to back up source file\n");
639 return 1; 639 return 1;
640 } 640 }
@@ -680,7 +680,7 @@ static int GenerateTarget(const FileContents& source_file, const std::unique_ptr
680 } 680 }
681 681
682 // Delete the backup copy of the source. 682 // Delete the backup copy of the source.
683 unlink(CACHE_TEMP_SOURCE); 683 unlink(cache_temp_source.c_str());
684 684
685 // Success! 685 // Success!
686 return 0; 686 return 0;
diff --git a/applypatch/freecache.cpp b/applypatch/freecache.cpp
index 331cae26..0a40baa9 100644
--- a/applypatch/freecache.cpp
+++ b/applypatch/freecache.cpp
@@ -90,10 +90,9 @@ static std::set<std::string> FindExpendableFiles() {
90 while ((de = readdir(d.get())) != 0) { 90 while ((de = readdir(d.get())) != 0) {
91 std::string path = std::string(dirs[i]) + "/" + de->d_name; 91 std::string path = std::string(dirs[i]) + "/" + de->d_name;
92 92
93 // We can't delete CACHE_TEMP_SOURCE; if it's there we might have 93 // We can't delete cache_temp_source; if it's there we might have restarted during
94 // restarted during installation and could be depending on it to 94 // installation and could be depending on it to be there.
95 // be there. 95 if (path == cache_temp_source) {
96 if (path == CACHE_TEMP_SOURCE) {
97 continue; 96 continue;
98 } 97 }
99 98
diff --git a/applypatch/include/applypatch/applypatch.h b/applypatch/include/applypatch/applypatch.h
index 2a3b3ef3..bcb8a412 100644
--- a/applypatch/include/applypatch/applypatch.h
+++ b/applypatch/include/applypatch/applypatch.h
@@ -36,12 +36,11 @@ struct FileContents {
36 struct stat st; 36 struct stat st;
37}; 37};
38 38
39// When there isn't enough room on the target filesystem to hold the 39// When there isn't enough room on the target filesystem to hold the patched version of the file,
40// patched version of the file, we copy the original here and delete 40// we copy the original here and delete it to free up space. If the expected source file doesn't
41// it to free up space. If the expected source file doesn't exist, or 41// exist, or is corrupted, we look to see if the cached file contains the bits we want and use it as
42// is corrupted, we look to see if this file contains the bits we want 42// the source instead. The default location for the cached source is "/cache/saved.file".
43// and use it as the source instead. 43extern std::string cache_temp_source;
44#define CACHE_TEMP_SOURCE "/cache/saved.file"
45 44
46using SinkFn = std::function<size_t(const unsigned char*, size_t)>; 45using SinkFn = std::function<size_t(const unsigned char*, size_t)>;
47 46
diff --git a/bootloader_message/bootloader_message.cpp b/bootloader_message/bootloader_message.cpp
index f91446b4..aaeffdc5 100644
--- a/bootloader_message/bootloader_message.cpp
+++ b/bootloader_message/bootloader_message.cpp
@@ -159,14 +159,8 @@ bool clear_bootloader_message(std::string* err) {
159 159
160bool write_bootloader_message(const std::vector<std::string>& options, std::string* err) { 160bool write_bootloader_message(const std::vector<std::string>& options, std::string* err) {
161 bootloader_message boot = {}; 161 bootloader_message boot = {};
162 strlcpy(boot.command, "boot-recovery", sizeof(boot.command)); 162 update_bootloader_message_in_struct(&boot, options);
163 strlcpy(boot.recovery, "recovery\n", sizeof(boot.recovery)); 163
164 for (const auto& s : options) {
165 strlcat(boot.recovery, s.c_str(), sizeof(boot.recovery));
166 if (s.back() != '\n') {
167 strlcat(boot.recovery, "\n", sizeof(boot.recovery));
168 }
169 }
170 return write_bootloader_message(boot, err); 164 return write_bootloader_message(boot, err);
171} 165}
172 166
@@ -175,20 +169,27 @@ bool update_bootloader_message(const std::vector<std::string>& options, std::str
175 if (!read_bootloader_message(&boot, err)) { 169 if (!read_bootloader_message(&boot, err)) {
176 return false; 170 return false;
177 } 171 }
172 update_bootloader_message_in_struct(&boot, options);
178 173
179 // Zero out the entire fields. 174 return write_bootloader_message(boot, err);
180 memset(boot.command, 0, sizeof(boot.command)); 175}
181 memset(boot.recovery, 0, sizeof(boot.recovery)); 176
177bool update_bootloader_message_in_struct(bootloader_message* boot,
178 const std::vector<std::string>& options) {
179 if (!boot) return false;
180 // Replace the command & recovery fields.
181 memset(boot->command, 0, sizeof(boot->command));
182 memset(boot->recovery, 0, sizeof(boot->recovery));
182 183
183 strlcpy(boot.command, "boot-recovery", sizeof(boot.command)); 184 strlcpy(boot->command, "boot-recovery", sizeof(boot->command));
184 strlcpy(boot.recovery, "recovery\n", sizeof(boot.recovery)); 185 strlcpy(boot->recovery, "recovery\n", sizeof(boot->recovery));
185 for (const auto& s : options) { 186 for (const auto& s : options) {
186 strlcat(boot.recovery, s.c_str(), sizeof(boot.recovery)); 187 strlcat(boot->recovery, s.c_str(), sizeof(boot->recovery));
187 if (s.back() != '\n') { 188 if (s.back() != '\n') {
188 strlcat(boot.recovery, "\n", sizeof(boot.recovery)); 189 strlcat(boot->recovery, "\n", sizeof(boot->recovery));
189 } 190 }
190 } 191 }
191 return write_bootloader_message(boot, err); 192 return true;
192} 193}
193 194
194bool write_reboot_bootloader(std::string* err) { 195bool write_reboot_bootloader(std::string* err) {
diff --git a/bootloader_message/include/bootloader_message/bootloader_message.h b/bootloader_message/include/bootloader_message/bootloader_message.h
index 2ffbfc9e..798f3bb8 100644
--- a/bootloader_message/include/bootloader_message/bootloader_message.h
+++ b/bootloader_message/include/bootloader_message/bootloader_message.h
@@ -207,6 +207,11 @@ bool write_bootloader_message(const std::vector<std::string>& options, std::stri
207// only update the command and recovery fields. 207// only update the command and recovery fields.
208bool update_bootloader_message(const std::vector<std::string>& options, std::string* err); 208bool update_bootloader_message(const std::vector<std::string>& options, std::string* err);
209 209
210// Update bootloader message (boots into recovery with the |options|) in |boot|. Will only update
211// the command and recovery fields.
212bool update_bootloader_message_in_struct(bootloader_message* boot,
213 const std::vector<std::string>& options);
214
210// Clear BCB. 215// Clear BCB.
211bool clear_bootloader_message(std::string* err); 216bool clear_bootloader_message(std::string* err);
212 217
diff --git a/minadbd/Android.mk b/minadbd/Android.mk
index 803171d9..3c9ab3a7 100644
--- a/minadbd/Android.mk
+++ b/minadbd/Android.mk
@@ -46,7 +46,12 @@ LOCAL_COMPATIBILITY_SUITE := device-tests
46LOCAL_SRC_FILES := fuse_adb_provider_test.cpp 46LOCAL_SRC_FILES := fuse_adb_provider_test.cpp
47LOCAL_CFLAGS := $(minadbd_cflags) 47LOCAL_CFLAGS := $(minadbd_cflags)
48LOCAL_C_INCLUDES := $(LOCAL_PATH) system/core/adb 48LOCAL_C_INCLUDES := $(LOCAL_PATH) system/core/adb
49LOCAL_STATIC_LIBRARIES := libminadbd 49LOCAL_STATIC_LIBRARIES := \
50LOCAL_SHARED_LIBRARIES := liblog libbase libcutils 50 libBionicGtestMain \
51 libminadbd
52LOCAL_SHARED_LIBRARIES := \
53 liblog \
54 libbase \
55 libcutils
51 56
52include $(BUILD_NATIVE_TEST) 57include $(BUILD_NATIVE_TEST)
diff --git a/tests/Android.mk b/tests/Android.mk
index 8ebb6030..d911c25e 100644
--- a/tests/Android.mk
+++ b/tests/Android.mk
@@ -30,7 +30,8 @@ LOCAL_STATIC_LIBRARIES := \
30 libutils \ 30 libutils \
31 libz \ 31 libz \
32 libselinux \ 32 libselinux \
33 libbase 33 libbase \
34 libBionicGtestMain
34 35
35LOCAL_SRC_FILES := \ 36LOCAL_SRC_FILES := \
36 unit/asn1_decoder_test.cpp \ 37 unit/asn1_decoder_test.cpp \
@@ -50,7 +51,8 @@ LOCAL_CFLAGS := -Wall -Werror
50LOCAL_MODULE := recovery_manual_test 51LOCAL_MODULE := recovery_manual_test
51LOCAL_STATIC_LIBRARIES := \ 52LOCAL_STATIC_LIBRARIES := \
52 libminui \ 53 libminui \
53 libbase 54 libbase \
55 libBionicGtestMain
54 56
55LOCAL_SRC_FILES := manual/recovery_test.cpp 57LOCAL_SRC_FILES := manual/recovery_test.cpp
56LOCAL_SHARED_LIBRARIES := \ 58LOCAL_SHARED_LIBRARIES := \
@@ -163,6 +165,7 @@ LOCAL_STATIC_LIBRARIES := \
163 libsquashfs_utils \ 165 libsquashfs_utils \
164 libcutils \ 166 libcutils \
165 libbrotli \ 167 libbrotli \
168 libBionicGtestMain \
166 $(tune2fs_static_libraries) 169 $(tune2fs_static_libraries)
167 170
168testdata_files := $(call find-subdir-files, testdata/*) 171testdata_files := $(call find-subdir-files, testdata/*)
@@ -212,7 +215,8 @@ LOCAL_STATIC_LIBRARIES := \
212 libbz \ 215 libbz \
213 libdivsufsort64 \ 216 libdivsufsort64 \
214 libdivsufsort \ 217 libdivsufsort \
215 libz 218 libz \
219 libBionicGtestMain
216LOCAL_SHARED_LIBRARIES := \ 220LOCAL_SHARED_LIBRARIES := \
217 liblog 221 liblog
218include $(BUILD_HOST_NATIVE_TEST) 222include $(BUILD_HOST_NATIVE_TEST)
diff --git a/tests/component/applypatch_test.cpp b/tests/component/applypatch_test.cpp
index 15ec08fe..21c9a52d 100644
--- a/tests/component/applypatch_test.cpp
+++ b/tests/component/applypatch_test.cpp
@@ -53,8 +53,7 @@ static void sha1sum(const std::string& fname, std::string* sha1, size_t* fsize =
53} 53}
54 54
55static void mangle_file(const std::string& fname) { 55static void mangle_file(const std::string& fname) {
56 std::string content; 56 std::string content(1024, '\0');
57 content.reserve(1024);
58 for (size_t i = 0; i < 1024; i++) { 57 for (size_t i = 0; i < 1024; i++) {
59 content[i] = rand() % 256; 58 content[i] = rand() % 256;
60 } 59 }
@@ -63,16 +62,11 @@ static void mangle_file(const std::string& fname) {
63 62
64class ApplyPatchTest : public ::testing::Test { 63class ApplyPatchTest : public ::testing::Test {
65 public: 64 public:
66 static void SetUpTestCase() { 65 virtual void SetUp() override {
67 // set up files 66 // set up files
68 old_file = from_testdata_base("old.file"); 67 old_file = from_testdata_base("old.file");
69 new_file = from_testdata_base("new.file"); 68 new_file = from_testdata_base("new.file");
70 patch_file = from_testdata_base("patch.bsdiff"); 69 nonexistent_file = from_testdata_base("nonexistent.file");
71 rand_file = "/cache/applypatch_test_rand.file";
72 cache_file = "/cache/saved.file";
73
74 // write stuff to rand_file
75 ASSERT_TRUE(android::base::WriteStringToFile("hello", rand_file));
76 70
77 // set up SHA constants 71 // set up SHA constants
78 sha1sum(old_file, &old_sha1, &old_size); 72 sha1sum(old_file, &old_sha1, &old_size);
@@ -82,56 +76,35 @@ class ApplyPatchTest : public ::testing::Test {
82 bad_sha1_b = android::base::StringPrintf("%040x", rand()); 76 bad_sha1_b = android::base::StringPrintf("%040x", rand());
83 } 77 }
84 78
85 static std::string old_file; 79 std::string old_file;
86 static std::string new_file; 80 std::string new_file;
87 static std::string rand_file; 81 std::string nonexistent_file;
88 static std::string cache_file;
89 static std::string patch_file;
90 82
91 static std::string old_sha1; 83 std::string old_sha1;
92 static std::string new_sha1; 84 std::string new_sha1;
93 static std::string bad_sha1_a; 85 std::string bad_sha1_a;
94 static std::string bad_sha1_b; 86 std::string bad_sha1_b;
95 87
96 static size_t old_size; 88 size_t old_size;
97 static size_t new_size; 89 size_t new_size;
98}; 90};
99 91
100static void cp(const std::string& src, const std::string& tgt) {
101 std::string cmd = "cp " + src + " " + tgt;
102 system(cmd.c_str());
103}
104
105static void backup_old() {
106 cp(ApplyPatchTest::old_file, ApplyPatchTest::cache_file);
107}
108
109static void restore_old() {
110 cp(ApplyPatchTest::cache_file, ApplyPatchTest::old_file);
111}
112
113class ApplyPatchCacheTest : public ApplyPatchTest { 92class ApplyPatchCacheTest : public ApplyPatchTest {
114 public: 93 protected:
115 virtual void SetUp() { 94 void SetUp() override {
116 backup_old(); 95 ApplyPatchTest::SetUp();
96 cache_temp_source = old_file;
117 } 97 }
98};
118 99
119 virtual void TearDown() { 100class ApplyPatchModesTest : public ::testing::Test {
120 restore_old(); 101 protected:
102 void SetUp() override {
103 cache_temp_source = cache_source.path;
121 } 104 }
122};
123 105
124std::string ApplyPatchTest::old_file; 106 TemporaryFile cache_source;
125std::string ApplyPatchTest::new_file; 107};
126std::string ApplyPatchTest::rand_file;
127std::string ApplyPatchTest::patch_file;
128std::string ApplyPatchTest::cache_file;
129std::string ApplyPatchTest::old_sha1;
130std::string ApplyPatchTest::new_sha1;
131std::string ApplyPatchTest::bad_sha1_a;
132std::string ApplyPatchTest::bad_sha1_b;
133size_t ApplyPatchTest::old_size;
134size_t ApplyPatchTest::new_size;
135 108
136TEST_F(ApplyPatchTest, CheckModeSkip) { 109TEST_F(ApplyPatchTest, CheckModeSkip) {
137 std::vector<std::string> sha1s; 110 std::vector<std::string> sha1s;
@@ -189,43 +162,31 @@ TEST_F(ApplyPatchTest, CheckModeEmmcTarget) {
189 ASSERT_EQ(0, applypatch_check(src_file.c_str(), sha1s)); 162 ASSERT_EQ(0, applypatch_check(src_file.c_str(), sha1s));
190} 163}
191 164
192TEST_F(ApplyPatchCacheTest, CheckCacheCorruptedSingle) { 165TEST_F(ApplyPatchCacheTest, CheckCacheCorruptedSourceSingle) {
193 mangle_file(old_file); 166 TemporaryFile temp_file;
194 std::vector<std::string> sha1s = { old_sha1 }; 167 mangle_file(temp_file.path);
195 ASSERT_EQ(0, applypatch_check(&old_file[0], sha1s)); 168 std::vector<std::string> sha1s_single = { old_sha1 };
169 ASSERT_EQ(0, applypatch_check(temp_file.path, sha1s_single));
170 ASSERT_EQ(0, applypatch_check(nonexistent_file.c_str(), sha1s_single));
196} 171}
197 172
198TEST_F(ApplyPatchCacheTest, CheckCacheCorruptedMultiple) { 173TEST_F(ApplyPatchCacheTest, CheckCacheCorruptedSourceMultiple) {
199 mangle_file(old_file); 174 TemporaryFile temp_file;
200 std::vector<std::string> sha1s = { bad_sha1_a, old_sha1, bad_sha1_b }; 175 mangle_file(temp_file.path);
201 ASSERT_EQ(0, applypatch_check(&old_file[0], sha1s)); 176 std::vector<std::string> sha1s_multiple = { bad_sha1_a, old_sha1, bad_sha1_b };
177 ASSERT_EQ(0, applypatch_check(temp_file.path, sha1s_multiple));
178 ASSERT_EQ(0, applypatch_check(nonexistent_file.c_str(), sha1s_multiple));
202} 179}
203 180
204TEST_F(ApplyPatchCacheTest, CheckCacheCorruptedFailure) { 181TEST_F(ApplyPatchCacheTest, CheckCacheCorruptedSourceFailure) {
205 mangle_file(old_file); 182 TemporaryFile temp_file;
206 std::vector<std::string> sha1s = { bad_sha1_a, bad_sha1_b }; 183 mangle_file(temp_file.path);
207 ASSERT_NE(0, applypatch_check(&old_file[0], sha1s)); 184 std::vector<std::string> sha1s_failure = { bad_sha1_a, bad_sha1_b };
208} 185 ASSERT_NE(0, applypatch_check(temp_file.path, sha1s_failure));
209 186 ASSERT_NE(0, applypatch_check(nonexistent_file.c_str(), sha1s_failure));
210TEST_F(ApplyPatchCacheTest, CheckCacheMissingSingle) {
211 unlink(&old_file[0]);
212 std::vector<std::string> sha1s = { old_sha1 };
213 ASSERT_EQ(0, applypatch_check(&old_file[0], sha1s));
214}
215
216TEST_F(ApplyPatchCacheTest, CheckCacheMissingMultiple) {
217 unlink(&old_file[0]);
218 std::vector<std::string> sha1s = { bad_sha1_a, old_sha1, bad_sha1_b };
219 ASSERT_EQ(0, applypatch_check(&old_file[0], sha1s));
220}
221
222TEST_F(ApplyPatchCacheTest, CheckCacheMissingFailure) {
223 unlink(&old_file[0]);
224 std::vector<std::string> sha1s = { bad_sha1_a, bad_sha1_b };
225 ASSERT_NE(0, applypatch_check(&old_file[0], sha1s));
226} 187}
227 188
228TEST(ApplyPatchModesTest, InvalidArgs) { 189TEST_F(ApplyPatchModesTest, InvalidArgs) {
229 // At least two args (including the filename). 190 // At least two args (including the filename).
230 ASSERT_EQ(2, applypatch_modes(1, (const char* []){ "applypatch" })); 191 ASSERT_EQ(2, applypatch_modes(1, (const char* []){ "applypatch" }));
231 192
@@ -233,7 +194,7 @@ TEST(ApplyPatchModesTest, InvalidArgs) {
233 ASSERT_EQ(2, applypatch_modes(2, (const char* []){ "applypatch", "-x" })); 194 ASSERT_EQ(2, applypatch_modes(2, (const char* []){ "applypatch", "-x" }));
234} 195}
235 196
236TEST(ApplyPatchModesTest, PatchModeEmmcTarget) { 197TEST_F(ApplyPatchModesTest, PatchModeEmmcTarget) {
237 std::string boot_img = from_testdata_base("boot.img"); 198 std::string boot_img = from_testdata_base("boot.img");
238 size_t boot_img_size; 199 size_t boot_img_size;
239 std::string boot_img_sha1; 200 std::string boot_img_sha1;
@@ -303,7 +264,7 @@ TEST(ApplyPatchModesTest, PatchModeEmmcTarget) {
303 ASSERT_EQ(0, applypatch_modes(args3.size(), args3.data())); 264 ASSERT_EQ(0, applypatch_modes(args3.size(), args3.data()));
304} 265}
305 266
306TEST(ApplyPatchModesTest, PatchModeInvalidArgs) { 267TEST_F(ApplyPatchModesTest, PatchModeInvalidArgs) {
307 // Invalid bonus file. 268 // Invalid bonus file.
308 ASSERT_NE(0, applypatch_modes(3, (const char* []){ "applypatch", "-b", "/doesntexist" })); 269 ASSERT_NE(0, applypatch_modes(3, (const char* []){ "applypatch", "-b", "/doesntexist" }));
309 270
@@ -364,11 +325,11 @@ TEST(ApplyPatchModesTest, PatchModeInvalidArgs) {
364 ASSERT_NE(0, applypatch_modes(args6.size(), args6.data())); 325 ASSERT_NE(0, applypatch_modes(args6.size(), args6.data()));
365} 326}
366 327
367TEST(ApplyPatchModesTest, CheckModeInvalidArgs) { 328TEST_F(ApplyPatchModesTest, CheckModeInvalidArgs) {
368 // Insufficient args. 329 // Insufficient args.
369 ASSERT_EQ(2, applypatch_modes(2, (const char* []){ "applypatch", "-c" })); 330 ASSERT_EQ(2, applypatch_modes(2, (const char* []){ "applypatch", "-c" }));
370} 331}
371 332
372TEST(ApplyPatchModesTest, ShowLicenses) { 333TEST_F(ApplyPatchModesTest, ShowLicenses) {
373 ASSERT_EQ(0, applypatch_modes(2, (const char* []){ "applypatch", "-l" })); 334 ASSERT_EQ(0, applypatch_modes(2, (const char* []){ "applypatch", "-l" }));
374} 335}
diff --git a/tests/component/bootloader_message_test.cpp b/tests/component/bootloader_message_test.cpp
index b38bc713..6cc59a49 100644
--- a/tests/component/bootloader_message_test.cpp
+++ b/tests/component/bootloader_message_test.cpp
@@ -18,53 +18,12 @@
18#include <vector> 18#include <vector>
19 19
20#include <android-base/strings.h> 20#include <android-base/strings.h>
21#include <android-base/test_utils.h>
21#include <bootloader_message/bootloader_message.h> 22#include <bootloader_message/bootloader_message.h>
22#include <gtest/gtest.h> 23#include <gtest/gtest.h>
23 24
24class BootloaderMessageTest : public ::testing::Test { 25TEST(BootloaderMessageTest, read_and_write_bootloader_message) {
25 protected: 26 TemporaryFile temp_misc;
26 BootloaderMessageTest() : has_misc(true) {}
27
28 virtual void SetUp() override {
29 std::string err;
30 has_misc = !get_bootloader_message_blk_device(&err).empty();
31 }
32
33 virtual void TearDown() override {
34 // Clear the BCB.
35 if (has_misc) {
36 std::string err;
37 ASSERT_TRUE(clear_bootloader_message(&err)) << "Failed to clear BCB: " << err;
38 }
39 }
40
41 bool has_misc;
42};
43
44TEST_F(BootloaderMessageTest, clear_bootloader_message) {
45 if (!has_misc) {
46 GTEST_LOG_(INFO) << "Test skipped due to no /misc partition found on the device.";
47 return;
48 }
49
50 // Clear the BCB.
51 std::string err;
52 ASSERT_TRUE(clear_bootloader_message(&err)) << "Failed to clear BCB: " << err;
53
54 // Verify the content.
55 bootloader_message boot;
56 ASSERT_TRUE(read_bootloader_message(&boot, &err)) << "Failed to read BCB: " << err;
57
58 // All the bytes should be cleared.
59 ASSERT_EQ(std::string(sizeof(boot), '\0'),
60 std::string(reinterpret_cast<const char*>(&boot), sizeof(boot)));
61}
62
63TEST_F(BootloaderMessageTest, read_and_write_bootloader_message) {
64 if (!has_misc) {
65 GTEST_LOG_(INFO) << "Test skipped due to no /misc partition found on the device.";
66 return;
67 }
68 27
69 // Write the BCB. 28 // Write the BCB.
70 bootloader_message boot = {}; 29 bootloader_message boot = {};
@@ -73,90 +32,71 @@ TEST_F(BootloaderMessageTest, read_and_write_bootloader_message) {
73 strlcpy(boot.status, "status1", sizeof(boot.status)); 32 strlcpy(boot.status, "status1", sizeof(boot.status));
74 33
75 std::string err; 34 std::string err;
76 ASSERT_TRUE(write_bootloader_message(boot, &err)) << "Failed to write BCB: " << err; 35 ASSERT_TRUE(write_bootloader_message_to(boot, temp_misc.path, &err))
36 << "Failed to write BCB: " << err;
77 37
78 // Read and verify. 38 // Read and verify.
79 bootloader_message boot_verify; 39 bootloader_message boot_verify;
80 ASSERT_TRUE(read_bootloader_message(&boot_verify, &err)) << "Failed to read BCB: " << err; 40 ASSERT_TRUE(read_bootloader_message_from(&boot_verify, temp_misc.path, &err))
41 << "Failed to read BCB: " << err;
81 42
82 ASSERT_EQ(std::string(reinterpret_cast<const char*>(&boot), sizeof(boot)), 43 ASSERT_EQ(std::string(reinterpret_cast<const char*>(&boot), sizeof(boot)),
83 std::string(reinterpret_cast<const char*>(&boot_verify), sizeof(boot_verify))); 44 std::string(reinterpret_cast<const char*>(&boot_verify), sizeof(boot_verify)));
84} 45}
85 46
86TEST_F(BootloaderMessageTest, write_bootloader_message_options) { 47TEST(BootloaderMessageTest, update_bootloader_message_in_struct) {
87 if (!has_misc) {
88 GTEST_LOG_(INFO) << "Test skipped due to no /misc partition found on the device.";
89 return;
90 }
91
92 // Write the options to BCB. 48 // Write the options to BCB.
93 std::vector<std::string> options = { "option1", "option2" }; 49 std::vector<std::string> options = { "option1", "option2" };
94 std::string err;
95 ASSERT_TRUE(write_bootloader_message(options, &err)) << "Failed to write BCB: " << err;
96 50
97 // Inject some bytes into boot, which should be overwritten while reading. 51 bootloader_message boot = {};
98 bootloader_message boot; 52 // Inject some bytes into boot.
99 strlcpy(boot.recovery, "random message", sizeof(boot.recovery)); 53 strlcpy(boot.recovery, "random message", sizeof(boot.recovery));
54 strlcpy(boot.status, "status bytes", sizeof(boot.status));
55 strlcpy(boot.stage, "stage bytes", sizeof(boot.stage));
100 strlcpy(boot.reserved, "reserved bytes", sizeof(boot.reserved)); 56 strlcpy(boot.reserved, "reserved bytes", sizeof(boot.reserved));
101 57
102 ASSERT_TRUE(read_bootloader_message(&boot, &err)) << "Failed to read BCB: " << err; 58 ASSERT_TRUE(update_bootloader_message_in_struct(&boot, options));
103 59
104 // Verify that command and recovery fields should be set. 60 // Verify that command and recovery fields should be set.
105 ASSERT_EQ("boot-recovery", std::string(boot.command)); 61 ASSERT_EQ("boot-recovery", std::string(boot.command));
106 std::string expected = "recovery\n" + android::base::Join(options, "\n") + "\n"; 62 std::string expected = "recovery\n" + android::base::Join(options, "\n") + "\n";
107 ASSERT_EQ(expected, std::string(boot.recovery)); 63 ASSERT_EQ(expected, std::string(boot.recovery));
108 64
109 // The rest should be cleared. 65 // The rest should be intact.
110 ASSERT_EQ(std::string(sizeof(boot.status), '\0'), std::string(boot.status, sizeof(boot.status))); 66 ASSERT_EQ("status bytes", std::string(boot.status));
111 ASSERT_EQ(std::string(sizeof(boot.stage), '\0'), std::string(boot.stage, sizeof(boot.stage))); 67 ASSERT_EQ("stage bytes", std::string(boot.stage));
112 ASSERT_EQ(std::string(sizeof(boot.reserved), '\0'), 68 ASSERT_EQ("reserved bytes", std::string(boot.reserved));
113 std::string(boot.reserved, sizeof(boot.reserved)));
114} 69}
115 70
116TEST_F(BootloaderMessageTest, write_bootloader_message_options_empty) { 71TEST(BootloaderMessageTest, update_bootloader_message_recovery_options_empty) {
117 if (!has_misc) {
118 GTEST_LOG_(INFO) << "Test skipped due to no /misc partition found on the device.";
119 return;
120 }
121
122 // Write empty vector. 72 // Write empty vector.
123 std::vector<std::string> options; 73 std::vector<std::string> options;
124 std::string err;
125 ASSERT_TRUE(write_bootloader_message(options, &err)) << "Failed to write BCB: " << err;
126 74
127 // Read and verify. 75 // Read and verify.
128 bootloader_message boot; 76 bootloader_message boot = {};
129 ASSERT_TRUE(read_bootloader_message(&boot, &err)) << "Failed to read BCB: " << err; 77 ASSERT_TRUE(update_bootloader_message_in_struct(&boot, options));
130 78
131 // command and recovery fields should be set. 79 // command and recovery fields should be set.
132 ASSERT_EQ("boot-recovery", std::string(boot.command)); 80 ASSERT_EQ("boot-recovery", std::string(boot.command));
133 ASSERT_EQ("recovery\n", std::string(boot.recovery)); 81 ASSERT_EQ("recovery\n", std::string(boot.recovery));
134 82
135 // The rest should be cleared. 83 // The rest should be empty.
136 ASSERT_EQ(std::string(sizeof(boot.status), '\0'), std::string(boot.status, sizeof(boot.status))); 84 ASSERT_EQ(std::string(sizeof(boot.status), '\0'), std::string(boot.status, sizeof(boot.status)));
137 ASSERT_EQ(std::string(sizeof(boot.stage), '\0'), std::string(boot.stage, sizeof(boot.stage))); 85 ASSERT_EQ(std::string(sizeof(boot.stage), '\0'), std::string(boot.stage, sizeof(boot.stage)));
138 ASSERT_EQ(std::string(sizeof(boot.reserved), '\0'), 86 ASSERT_EQ(std::string(sizeof(boot.reserved), '\0'),
139 std::string(boot.reserved, sizeof(boot.reserved))); 87 std::string(boot.reserved, sizeof(boot.reserved)));
140} 88}
141 89
142TEST_F(BootloaderMessageTest, write_bootloader_message_options_long) { 90TEST(BootloaderMessageTest, update_bootloader_message_recovery_options_long) {
143 if (!has_misc) {
144 GTEST_LOG_(INFO) << "Test skipped due to no /misc partition found on the device.";
145 return;
146 }
147
148 // Write super long message. 91 // Write super long message.
149 std::vector<std::string> options; 92 std::vector<std::string> options;
150 for (int i = 0; i < 100; i++) { 93 for (int i = 0; i < 100; i++) {
151 options.push_back("option: " + std::to_string(i)); 94 options.push_back("option: " + std::to_string(i));
152 } 95 }
153 96
154 std::string err;
155 ASSERT_TRUE(write_bootloader_message(options, &err)) << "Failed to write BCB: " << err;
156
157 // Read and verify. 97 // Read and verify.
158 bootloader_message boot; 98 bootloader_message boot = {};
159 ASSERT_TRUE(read_bootloader_message(&boot, &err)) << "Failed to read BCB: " << err; 99 ASSERT_TRUE(update_bootloader_message_in_struct(&boot, options));
160 100
161 // Make sure it's long enough. 101 // Make sure it's long enough.
162 std::string expected = "recovery\n" + android::base::Join(options, "\n") + "\n"; 102 std::string expected = "recovery\n" + android::base::Join(options, "\n") + "\n";
@@ -167,40 +107,10 @@ TEST_F(BootloaderMessageTest, write_bootloader_message_options_long) {
167 ASSERT_EQ(expected.substr(0, sizeof(boot.recovery) - 1), std::string(boot.recovery)); 107 ASSERT_EQ(expected.substr(0, sizeof(boot.recovery) - 1), std::string(boot.recovery));
168 ASSERT_EQ('\0', boot.recovery[sizeof(boot.recovery) - 1]); 108 ASSERT_EQ('\0', boot.recovery[sizeof(boot.recovery) - 1]);
169 109
170 // The rest should be cleared. 110 // The rest should be empty.
171 ASSERT_EQ(std::string(sizeof(boot.status), '\0'), std::string(boot.status, sizeof(boot.status))); 111 ASSERT_EQ(std::string(sizeof(boot.status), '\0'), std::string(boot.status, sizeof(boot.status)));
172 ASSERT_EQ(std::string(sizeof(boot.stage), '\0'), std::string(boot.stage, sizeof(boot.stage))); 112 ASSERT_EQ(std::string(sizeof(boot.stage), '\0'), std::string(boot.stage, sizeof(boot.stage)));
173 ASSERT_EQ(std::string(sizeof(boot.reserved), '\0'), 113 ASSERT_EQ(std::string(sizeof(boot.reserved), '\0'),
174 std::string(boot.reserved, sizeof(boot.reserved))); 114 std::string(boot.reserved, sizeof(boot.reserved)));
175} 115}
176 116
177TEST_F(BootloaderMessageTest, update_bootloader_message) {
178 if (!has_misc) {
179 GTEST_LOG_(INFO) << "Test skipped due to no /misc partition found on the device.";
180 return;
181 }
182
183 // Inject some bytes into boot, which should be not overwritten later.
184 bootloader_message boot;
185 strlcpy(boot.recovery, "random message", sizeof(boot.recovery));
186 strlcpy(boot.reserved, "reserved bytes", sizeof(boot.reserved));
187 std::string err;
188 ASSERT_TRUE(write_bootloader_message(boot, &err)) << "Failed to write BCB: " << err;
189
190 // Update the BCB message.
191 std::vector<std::string> options = { "option1", "option2" };
192 ASSERT_TRUE(update_bootloader_message(options, &err)) << "Failed to update BCB: " << err;
193
194 bootloader_message boot_verify;
195 ASSERT_TRUE(read_bootloader_message(&boot_verify, &err)) << "Failed to read BCB: " << err;
196
197 // Verify that command and recovery fields should be set.
198 ASSERT_EQ("boot-recovery", std::string(boot_verify.command));
199 std::string expected = "recovery\n" + android::base::Join(options, "\n") + "\n";
200 ASSERT_EQ(expected, std::string(boot_verify.recovery));
201
202 // The rest should be intact.
203 ASSERT_EQ(std::string(boot.status), std::string(boot_verify.status));
204 ASSERT_EQ(std::string(boot.stage), std::string(boot_verify.stage));
205 ASSERT_EQ(std::string(boot.reserved), std::string(boot_verify.reserved));
206}
diff --git a/tests/component/uncrypt_test.cpp b/tests/component/uncrypt_test.cpp
index 3925236a..55baca2e 100644
--- a/tests/component/uncrypt_test.cpp
+++ b/tests/component/uncrypt_test.cpp
@@ -20,6 +20,7 @@
20#include <sys/un.h> 20#include <sys/un.h>
21#include <unistd.h> 21#include <unistd.h>
22 22
23#include <algorithm>
23#include <string> 24#include <string>
24 25
25#include <android-base/file.h> 26#include <android-base/file.h>
@@ -38,43 +39,49 @@ static const std::string INIT_SVC_CLEAR_BCB = "init.svc.clear-bcb";
38static const std::string INIT_SVC_UNCRYPT = "init.svc.uncrypt"; 39static const std::string INIT_SVC_UNCRYPT = "init.svc.uncrypt";
39static constexpr int SOCKET_CONNECTION_MAX_RETRY = 30; 40static constexpr int SOCKET_CONNECTION_MAX_RETRY = 30;
40 41
42static void StopService() {
43 ASSERT_TRUE(android::base::SetProperty("ctl.stop", "setup-bcb"));
44 ASSERT_TRUE(android::base::SetProperty("ctl.stop", "clear-bcb"));
45 ASSERT_TRUE(android::base::SetProperty("ctl.stop", "uncrypt"));
46
47 bool success = false;
48 for (int retry = 0; retry < SOCKET_CONNECTION_MAX_RETRY; retry++) {
49 std::string setup_bcb = android::base::GetProperty(INIT_SVC_SETUP_BCB, "");
50 std::string clear_bcb = android::base::GetProperty(INIT_SVC_CLEAR_BCB, "");
51 std::string uncrypt = android::base::GetProperty(INIT_SVC_UNCRYPT, "");
52 GTEST_LOG_(INFO) << "setup-bcb: [" << setup_bcb << "] clear-bcb: [" << clear_bcb
53 << "] uncrypt: [" << uncrypt << "]";
54 if (setup_bcb != "running" && clear_bcb != "running" && uncrypt != "running") {
55 success = true;
56 break;
57 }
58 sleep(1);
59 }
60
61 ASSERT_TRUE(success) << "uncrypt service is not available.";
62}
63
41class UncryptTest : public ::testing::Test { 64class UncryptTest : public ::testing::Test {
42 protected: 65 protected:
43 UncryptTest() : has_misc(true) {} 66 UncryptTest() : has_misc(true) {}
44 67
45 virtual void SetUp() override { 68 void SetUp() override {
46 ASSERT_TRUE(android::base::SetProperty("ctl.stop", "setup-bcb"));
47 ASSERT_TRUE(android::base::SetProperty("ctl.stop", "clear-bcb"));
48 ASSERT_TRUE(android::base::SetProperty("ctl.stop", "uncrypt"));
49
50 bool success = false;
51 for (int retry = 0; retry < SOCKET_CONNECTION_MAX_RETRY; retry++) {
52 std::string setup_bcb = android::base::GetProperty(INIT_SVC_SETUP_BCB, "");
53 std::string clear_bcb = android::base::GetProperty(INIT_SVC_CLEAR_BCB, "");
54 std::string uncrypt = android::base::GetProperty(INIT_SVC_UNCRYPT, "");
55 LOG(INFO) << "setup-bcb: [" << setup_bcb << "] clear-bcb: [" << clear_bcb << "] uncrypt: ["
56 << uncrypt << "]";
57 if (setup_bcb != "running" && clear_bcb != "running" && uncrypt != "running") {
58 success = true;
59 break;
60 }
61 sleep(1);
62 }
63
64 ASSERT_TRUE(success) << "uncrypt service is not available.";
65
66 std::string err; 69 std::string err;
67 has_misc = !get_bootloader_message_blk_device(&err).empty(); 70 has_misc = !get_bootloader_message_blk_device(&err).empty();
68 } 71 }
69 72
70 void SetupOrClearBcb(bool isSetup, const std::string& message, 73 void TearDown() override {
71 const std::string& message_in_bcb) const { 74 // Clear the BCB.
72 if (!has_misc) { 75 if (has_misc) {
73 GTEST_LOG_(INFO) << "Test skipped due to no /misc partition found on the device."; 76 std::string err;
74 return; 77 ASSERT_TRUE(clear_bootloader_message(&err)) << "Failed to clear BCB: " << err;
75 } 78 }
79 }
76 80
77 // Trigger the setup-bcb service. 81 void SetupOrClearBcb(bool isSetup, const std::string& message,
82 const std::string& message_in_bcb) const {
83 // Restart the setup-bcb service.
84 StopService();
78 ASSERT_TRUE(android::base::SetProperty("ctl.start", isSetup ? "setup-bcb" : "clear-bcb")); 85 ASSERT_TRUE(android::base::SetProperty("ctl.start", isSetup ? "setup-bcb" : "clear-bcb"));
79 86
80 // Test tends to be flaky if proceeding immediately ("Transport endpoint is not connected"). 87 // Test tends to be flaky if proceeding immediately ("Transport endpoint is not connected").
@@ -144,27 +151,49 @@ class UncryptTest : public ::testing::Test {
144 } 151 }
145 } 152 }
146 153
154 void VerifyBootloaderMessage(const std::string& expected) {
155 std::string err;
156 bootloader_message boot;
157 ASSERT_TRUE(read_bootloader_message(&boot, &err)) << "Failed to read BCB: " << err;
158
159 // Check that we have all the expected bytes.
160 ASSERT_EQ(expected, std::string(reinterpret_cast<const char*>(&boot), sizeof(boot)));
161 }
162
147 bool has_misc; 163 bool has_misc;
148}; 164};
149 165
150TEST_F(UncryptTest, setup_bcb) { 166TEST_F(UncryptTest, setup_bcb) {
167 if (!has_misc) {
168 GTEST_LOG_(INFO) << "Test skipped due to no /misc partition found on the device.";
169 return;
170 }
171
172 std::string random_data;
173 random_data.reserve(sizeof(bootloader_message));
174 generate_n(back_inserter(random_data), sizeof(bootloader_message), []() { return rand() % 128; });
175
176 bootloader_message boot;
177 memcpy(&boot, random_data.c_str(), random_data.size());
178
179 std::string err;
180 ASSERT_TRUE(write_bootloader_message(boot, &err)) << "Failed to write BCB: " << err;
181 VerifyBootloaderMessage(random_data);
182
183 ASSERT_TRUE(clear_bootloader_message(&err)) << "Failed to clear BCB: " << err;
184 VerifyBootloaderMessage(std::string(sizeof(bootloader_message), '\0'));
185
151 std::string message = "--update_message=abc value"; 186 std::string message = "--update_message=abc value";
152 std::string message_in_bcb = "recovery\n--update_message=abc value\n"; 187 std::string message_in_bcb = "recovery\n--update_message=abc value\n";
153 SetupOrClearBcb(true, message, message_in_bcb); 188 SetupOrClearBcb(true, message, message_in_bcb);
154}
155 189
156TEST_F(UncryptTest, clear_bcb) {
157 SetupOrClearBcb(false, "", ""); 190 SetupOrClearBcb(false, "", "");
158}
159 191
160TEST_F(UncryptTest, setup_bcb_wipe_ab) {
161 TemporaryFile wipe_package; 192 TemporaryFile wipe_package;
162 ASSERT_TRUE(android::base::WriteStringToFile(std::string(345, 'a'), wipe_package.path)); 193 ASSERT_TRUE(android::base::WriteStringToFile(std::string(345, 'a'), wipe_package.path));
163 194
164 // It's expected to store a wipe package in /misc, with the package size passed to recovery. 195 // It's expected to store a wipe package in /misc, with the package size passed to recovery.
165 std::string message = 196 message = "--wipe_ab\n--wipe_package="s + wipe_package.path + "\n--reason=wipePackage"s;
166 "--wipe_ab\n--wipe_package="s + wipe_package.path + "\n--reason=wipePackage"s; 197 message_in_bcb = "recovery\n--wipe_ab\n--wipe_package_size=345\n--reason=wipePackage\n";
167 std::string message_in_bcb =
168 "recovery\n--wipe_ab\n--wipe_package_size=345\n--reason=wipePackage\n";
169 SetupOrClearBcb(true, message, message_in_bcb); 198 SetupOrClearBcb(true, message, message_in_bcb);
170} 199}