aboutsummaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
authorTianjie Xu2017-10-25 15:16:54 -0500
committerTianjie Xu2017-11-03 16:09:11 -0500
commita88cc5440ed79a0927f57bbd03377ff3ce04a760 (patch)
tree493507d15c2ec159ee74a3e21a0cee91bee58d28 /tests
parent43f194c8bc383fdda40505813db98c9f7860417b (diff)
downloadplatform-bootable-recovery-a88cc5440ed79a0927f57bbd03377ff3ce04a760.tar.gz
platform-bootable-recovery-a88cc5440ed79a0927f57bbd03377ff3ce04a760.tar.xz
platform-bootable-recovery-a88cc5440ed79a0927f57bbd03377ff3ce04a760.zip
Switch to bionic gtest in bootable/recovery
We encountered segfaults in Imgdiff host tests due to the failure to reset states of getopt. The problem can be solved by switching to use bionic's gtest where a new process is forked for each test. Also modify the recovery_component_test to make sure it runs in parallel. Changes include: 1. Merge the writes to misc partition into one single test. 2. Change the hard coded location "/cache/saved.file" into a configurable variable. Bug: 67849209 Test: recovery tests pass Change-Id: I165d313f32b83393fb7922c5078636ac40b50bc2
Diffstat (limited to 'tests')
-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
4 files changed, 142 insertions, 238 deletions
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}