Merge "Switch to bionic gtest in bootable/recovery"
This commit is contained in:
@@ -42,6 +42,8 @@
|
|||||||
#include "otafault/ota_io.h"
|
#include "otafault/ota_io.h"
|
||||||
#include "otautil/print_sha1.h"
|
#include "otautil/print_sha1.h"
|
||||||
|
|
||||||
|
std::string cache_temp_source = "/cache/saved.file";
|
||||||
|
|
||||||
static int LoadPartitionContents(const std::string& filename, FileContents* file);
|
static int LoadPartitionContents(const std::string& filename, FileContents* file);
|
||||||
static size_t FileSink(const unsigned char* data, size_t len, int fd);
|
static size_t FileSink(const unsigned char* data, size_t len, int fd);
|
||||||
static int GenerateTarget(const FileContents& source_file, const std::unique_ptr<Value>& patch,
|
static 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
|
|||||||
(!patch_sha1_str.empty() && FindMatchingPatch(file.sha1, patch_sha1_str) < 0)) {
|
(!patch_sha1_str.empty() && FindMatchingPatch(file.sha1, patch_sha1_str) < 0)) {
|
||||||
printf("file \"%s\" doesn't have any of expected sha1 sums; checking cache\n", filename);
|
printf("file \"%s\" doesn't have any of expected sha1 sums; checking cache\n", filename);
|
||||||
|
|
||||||
// If the source file is missing or corrupted, it might be because
|
// If the source file is missing or corrupted, it might be because we were killed in the middle
|
||||||
// we were killed in the middle of patching it. A copy of it
|
// of patching it. A copy of it should have been made in cache_temp_source. If that file
|
||||||
// should have been made in CACHE_TEMP_SOURCE. If that file
|
// exists and matches the sha1 we're looking for, the check still passes.
|
||||||
// exists and matches the sha1 we're looking for, the check still
|
if (LoadFileContents(cache_temp_source.c_str(), &file) != 0) {
|
||||||
// passes.
|
|
||||||
if (LoadFileContents(CACHE_TEMP_SOURCE, &file) != 0) {
|
|
||||||
printf("failed to load cache file\n");
|
printf("failed to load cache file\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -539,7 +539,7 @@ int applypatch(const char* source_filename, const char* target_filename,
|
|||||||
printf("source file is bad; trying copy\n");
|
printf("source file is bad; trying copy\n");
|
||||||
|
|
||||||
FileContents copy_file;
|
FileContents copy_file;
|
||||||
if (LoadFileContents(CACHE_TEMP_SOURCE, ©_file) < 0) {
|
if (LoadFileContents(cache_temp_source.c_str(), ©_file) < 0) {
|
||||||
printf("failed to read copy file\n");
|
printf("failed to read copy file\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -634,7 +634,7 @@ static int GenerateTarget(const FileContents& source_file, const std::unique_ptr
|
|||||||
printf("not enough free space on /cache\n");
|
printf("not enough free space on /cache\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if (SaveFileContents(CACHE_TEMP_SOURCE, &source_file) < 0) {
|
if (SaveFileContents(cache_temp_source.c_str(), &source_file) < 0) {
|
||||||
printf("failed to back up source file\n");
|
printf("failed to back up source file\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -680,7 +680,7 @@ static int GenerateTarget(const FileContents& source_file, const std::unique_ptr
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Delete the backup copy of the source.
|
// Delete the backup copy of the source.
|
||||||
unlink(CACHE_TEMP_SOURCE);
|
unlink(cache_temp_source.c_str());
|
||||||
|
|
||||||
// Success!
|
// Success!
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -90,10 +90,9 @@ static std::set<std::string> FindExpendableFiles() {
|
|||||||
while ((de = readdir(d.get())) != 0) {
|
while ((de = readdir(d.get())) != 0) {
|
||||||
std::string path = std::string(dirs[i]) + "/" + de->d_name;
|
std::string path = std::string(dirs[i]) + "/" + de->d_name;
|
||||||
|
|
||||||
// We can't delete CACHE_TEMP_SOURCE; if it's there we might have
|
// We can't delete cache_temp_source; if it's there we might have restarted during
|
||||||
// restarted during installation and could be depending on it to
|
// installation and could be depending on it to be there.
|
||||||
// be there.
|
if (path == cache_temp_source) {
|
||||||
if (path == CACHE_TEMP_SOURCE) {
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -36,12 +36,11 @@ struct FileContents {
|
|||||||
struct stat st;
|
struct stat st;
|
||||||
};
|
};
|
||||||
|
|
||||||
// When there isn't enough room on the target filesystem to hold the
|
// When there isn't enough room on the target filesystem to hold the patched version of the file,
|
||||||
// patched version of the file, we copy the original here and delete
|
// we copy the original here and delete it to free up space. If the expected source file doesn't
|
||||||
// it to free up space. If the expected source file doesn't exist, or
|
// exist, or is corrupted, we look to see if the cached file contains the bits we want and use it as
|
||||||
// is corrupted, we look to see if this file contains the bits we want
|
// the source instead. The default location for the cached source is "/cache/saved.file".
|
||||||
// and use it as the source instead.
|
extern std::string cache_temp_source;
|
||||||
#define CACHE_TEMP_SOURCE "/cache/saved.file"
|
|
||||||
|
|
||||||
using SinkFn = std::function<size_t(const unsigned char*, size_t)>;
|
using SinkFn = std::function<size_t(const unsigned char*, size_t)>;
|
||||||
|
|
||||||
|
|||||||
@@ -159,14 +159,8 @@ bool clear_bootloader_message(std::string* err) {
|
|||||||
|
|
||||||
bool write_bootloader_message(const std::vector<std::string>& options, std::string* err) {
|
bool write_bootloader_message(const std::vector<std::string>& options, std::string* err) {
|
||||||
bootloader_message boot = {};
|
bootloader_message boot = {};
|
||||||
strlcpy(boot.command, "boot-recovery", sizeof(boot.command));
|
update_bootloader_message_in_struct(&boot, options);
|
||||||
strlcpy(boot.recovery, "recovery\n", sizeof(boot.recovery));
|
|
||||||
for (const auto& s : options) {
|
|
||||||
strlcat(boot.recovery, s.c_str(), sizeof(boot.recovery));
|
|
||||||
if (s.back() != '\n') {
|
|
||||||
strlcat(boot.recovery, "\n", sizeof(boot.recovery));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return write_bootloader_message(boot, err);
|
return write_bootloader_message(boot, err);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -175,20 +169,27 @@ bool update_bootloader_message(const std::vector<std::string>& options, std::str
|
|||||||
if (!read_bootloader_message(&boot, err)) {
|
if (!read_bootloader_message(&boot, err)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
update_bootloader_message_in_struct(&boot, options);
|
||||||
|
|
||||||
// Zero out the entire fields.
|
return write_bootloader_message(boot, err);
|
||||||
memset(boot.command, 0, sizeof(boot.command));
|
}
|
||||||
memset(boot.recovery, 0, sizeof(boot.recovery));
|
|
||||||
|
|
||||||
strlcpy(boot.command, "boot-recovery", sizeof(boot.command));
|
bool update_bootloader_message_in_struct(bootloader_message* boot,
|
||||||
strlcpy(boot.recovery, "recovery\n", sizeof(boot.recovery));
|
const std::vector<std::string>& options) {
|
||||||
|
if (!boot) return false;
|
||||||
|
// Replace the command & recovery fields.
|
||||||
|
memset(boot->command, 0, sizeof(boot->command));
|
||||||
|
memset(boot->recovery, 0, sizeof(boot->recovery));
|
||||||
|
|
||||||
|
strlcpy(boot->command, "boot-recovery", sizeof(boot->command));
|
||||||
|
strlcpy(boot->recovery, "recovery\n", sizeof(boot->recovery));
|
||||||
for (const auto& s : options) {
|
for (const auto& s : options) {
|
||||||
strlcat(boot.recovery, s.c_str(), sizeof(boot.recovery));
|
strlcat(boot->recovery, s.c_str(), sizeof(boot->recovery));
|
||||||
if (s.back() != '\n') {
|
if (s.back() != '\n') {
|
||||||
strlcat(boot.recovery, "\n", sizeof(boot.recovery));
|
strlcat(boot->recovery, "\n", sizeof(boot->recovery));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return write_bootloader_message(boot, err);
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool write_reboot_bootloader(std::string* err) {
|
bool write_reboot_bootloader(std::string* err) {
|
||||||
|
|||||||
@@ -207,6 +207,11 @@ bool write_bootloader_message(const std::vector<std::string>& options, std::stri
|
|||||||
// only update the command and recovery fields.
|
// only update the command and recovery fields.
|
||||||
bool update_bootloader_message(const std::vector<std::string>& options, std::string* err);
|
bool update_bootloader_message(const std::vector<std::string>& options, std::string* err);
|
||||||
|
|
||||||
|
// Update bootloader message (boots into recovery with the |options|) in |boot|. Will only update
|
||||||
|
// the command and recovery fields.
|
||||||
|
bool update_bootloader_message_in_struct(bootloader_message* boot,
|
||||||
|
const std::vector<std::string>& options);
|
||||||
|
|
||||||
// Clear BCB.
|
// Clear BCB.
|
||||||
bool clear_bootloader_message(std::string* err);
|
bool clear_bootloader_message(std::string* err);
|
||||||
|
|
||||||
|
|||||||
@@ -46,7 +46,12 @@ LOCAL_COMPATIBILITY_SUITE := device-tests
|
|||||||
LOCAL_SRC_FILES := fuse_adb_provider_test.cpp
|
LOCAL_SRC_FILES := fuse_adb_provider_test.cpp
|
||||||
LOCAL_CFLAGS := $(minadbd_cflags)
|
LOCAL_CFLAGS := $(minadbd_cflags)
|
||||||
LOCAL_C_INCLUDES := $(LOCAL_PATH) system/core/adb
|
LOCAL_C_INCLUDES := $(LOCAL_PATH) system/core/adb
|
||||||
LOCAL_STATIC_LIBRARIES := libminadbd
|
LOCAL_STATIC_LIBRARIES := \
|
||||||
LOCAL_SHARED_LIBRARIES := liblog libbase libcutils
|
libBionicGtestMain \
|
||||||
|
libminadbd
|
||||||
|
LOCAL_SHARED_LIBRARIES := \
|
||||||
|
liblog \
|
||||||
|
libbase \
|
||||||
|
libcutils
|
||||||
|
|
||||||
include $(BUILD_NATIVE_TEST)
|
include $(BUILD_NATIVE_TEST)
|
||||||
|
|||||||
@@ -30,7 +30,8 @@ LOCAL_STATIC_LIBRARIES := \
|
|||||||
libutils \
|
libutils \
|
||||||
libz \
|
libz \
|
||||||
libselinux \
|
libselinux \
|
||||||
libbase
|
libbase \
|
||||||
|
libBionicGtestMain
|
||||||
|
|
||||||
LOCAL_SRC_FILES := \
|
LOCAL_SRC_FILES := \
|
||||||
unit/asn1_decoder_test.cpp \
|
unit/asn1_decoder_test.cpp \
|
||||||
@@ -50,7 +51,8 @@ LOCAL_CFLAGS := -Wall -Werror
|
|||||||
LOCAL_MODULE := recovery_manual_test
|
LOCAL_MODULE := recovery_manual_test
|
||||||
LOCAL_STATIC_LIBRARIES := \
|
LOCAL_STATIC_LIBRARIES := \
|
||||||
libminui \
|
libminui \
|
||||||
libbase
|
libbase \
|
||||||
|
libBionicGtestMain
|
||||||
|
|
||||||
LOCAL_SRC_FILES := manual/recovery_test.cpp
|
LOCAL_SRC_FILES := manual/recovery_test.cpp
|
||||||
LOCAL_SHARED_LIBRARIES := \
|
LOCAL_SHARED_LIBRARIES := \
|
||||||
@@ -163,6 +165,7 @@ LOCAL_STATIC_LIBRARIES := \
|
|||||||
libsquashfs_utils \
|
libsquashfs_utils \
|
||||||
libcutils \
|
libcutils \
|
||||||
libbrotli \
|
libbrotli \
|
||||||
|
libBionicGtestMain \
|
||||||
$(tune2fs_static_libraries)
|
$(tune2fs_static_libraries)
|
||||||
|
|
||||||
testdata_files := $(call find-subdir-files, testdata/*)
|
testdata_files := $(call find-subdir-files, testdata/*)
|
||||||
@@ -212,7 +215,8 @@ LOCAL_STATIC_LIBRARIES := \
|
|||||||
libbz \
|
libbz \
|
||||||
libdivsufsort64 \
|
libdivsufsort64 \
|
||||||
libdivsufsort \
|
libdivsufsort \
|
||||||
libz
|
libz \
|
||||||
|
libBionicGtestMain
|
||||||
LOCAL_SHARED_LIBRARIES := \
|
LOCAL_SHARED_LIBRARIES := \
|
||||||
liblog
|
liblog
|
||||||
include $(BUILD_HOST_NATIVE_TEST)
|
include $(BUILD_HOST_NATIVE_TEST)
|
||||||
|
|||||||
@@ -53,8 +53,7 @@ static void sha1sum(const std::string& fname, std::string* sha1, size_t* fsize =
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void mangle_file(const std::string& fname) {
|
static void mangle_file(const std::string& fname) {
|
||||||
std::string content;
|
std::string content(1024, '\0');
|
||||||
content.reserve(1024);
|
|
||||||
for (size_t i = 0; i < 1024; i++) {
|
for (size_t i = 0; i < 1024; i++) {
|
||||||
content[i] = rand() % 256;
|
content[i] = rand() % 256;
|
||||||
}
|
}
|
||||||
@@ -63,16 +62,11 @@ static void mangle_file(const std::string& fname) {
|
|||||||
|
|
||||||
class ApplyPatchTest : public ::testing::Test {
|
class ApplyPatchTest : public ::testing::Test {
|
||||||
public:
|
public:
|
||||||
static void SetUpTestCase() {
|
virtual void SetUp() override {
|
||||||
// set up files
|
// set up files
|
||||||
old_file = from_testdata_base("old.file");
|
old_file = from_testdata_base("old.file");
|
||||||
new_file = from_testdata_base("new.file");
|
new_file = from_testdata_base("new.file");
|
||||||
patch_file = from_testdata_base("patch.bsdiff");
|
nonexistent_file = from_testdata_base("nonexistent.file");
|
||||||
rand_file = "/cache/applypatch_test_rand.file";
|
|
||||||
cache_file = "/cache/saved.file";
|
|
||||||
|
|
||||||
// write stuff to rand_file
|
|
||||||
ASSERT_TRUE(android::base::WriteStringToFile("hello", rand_file));
|
|
||||||
|
|
||||||
// set up SHA constants
|
// set up SHA constants
|
||||||
sha1sum(old_file, &old_sha1, &old_size);
|
sha1sum(old_file, &old_sha1, &old_size);
|
||||||
@@ -82,56 +76,35 @@ class ApplyPatchTest : public ::testing::Test {
|
|||||||
bad_sha1_b = android::base::StringPrintf("%040x", rand());
|
bad_sha1_b = android::base::StringPrintf("%040x", rand());
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string old_file;
|
std::string old_file;
|
||||||
static std::string new_file;
|
std::string new_file;
|
||||||
static std::string rand_file;
|
std::string nonexistent_file;
|
||||||
static std::string cache_file;
|
|
||||||
static std::string patch_file;
|
|
||||||
|
|
||||||
static std::string old_sha1;
|
std::string old_sha1;
|
||||||
static std::string new_sha1;
|
std::string new_sha1;
|
||||||
static std::string bad_sha1_a;
|
std::string bad_sha1_a;
|
||||||
static std::string bad_sha1_b;
|
std::string bad_sha1_b;
|
||||||
|
|
||||||
static size_t old_size;
|
size_t old_size;
|
||||||
static size_t new_size;
|
size_t new_size;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void cp(const std::string& src, const std::string& tgt) {
|
|
||||||
std::string cmd = "cp " + src + " " + tgt;
|
|
||||||
system(cmd.c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
static void backup_old() {
|
|
||||||
cp(ApplyPatchTest::old_file, ApplyPatchTest::cache_file);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void restore_old() {
|
|
||||||
cp(ApplyPatchTest::cache_file, ApplyPatchTest::old_file);
|
|
||||||
}
|
|
||||||
|
|
||||||
class ApplyPatchCacheTest : public ApplyPatchTest {
|
class ApplyPatchCacheTest : public ApplyPatchTest {
|
||||||
public:
|
protected:
|
||||||
virtual void SetUp() {
|
void SetUp() override {
|
||||||
backup_old();
|
ApplyPatchTest::SetUp();
|
||||||
}
|
cache_temp_source = old_file;
|
||||||
|
|
||||||
virtual void TearDown() {
|
|
||||||
restore_old();
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
std::string ApplyPatchTest::old_file;
|
class ApplyPatchModesTest : public ::testing::Test {
|
||||||
std::string ApplyPatchTest::new_file;
|
protected:
|
||||||
std::string ApplyPatchTest::rand_file;
|
void SetUp() override {
|
||||||
std::string ApplyPatchTest::patch_file;
|
cache_temp_source = cache_source.path;
|
||||||
std::string ApplyPatchTest::cache_file;
|
}
|
||||||
std::string ApplyPatchTest::old_sha1;
|
|
||||||
std::string ApplyPatchTest::new_sha1;
|
TemporaryFile cache_source;
|
||||||
std::string ApplyPatchTest::bad_sha1_a;
|
};
|
||||||
std::string ApplyPatchTest::bad_sha1_b;
|
|
||||||
size_t ApplyPatchTest::old_size;
|
|
||||||
size_t ApplyPatchTest::new_size;
|
|
||||||
|
|
||||||
TEST_F(ApplyPatchTest, CheckModeSkip) {
|
TEST_F(ApplyPatchTest, CheckModeSkip) {
|
||||||
std::vector<std::string> sha1s;
|
std::vector<std::string> sha1s;
|
||||||
@@ -189,43 +162,31 @@ TEST_F(ApplyPatchTest, CheckModeEmmcTarget) {
|
|||||||
ASSERT_EQ(0, applypatch_check(src_file.c_str(), sha1s));
|
ASSERT_EQ(0, applypatch_check(src_file.c_str(), sha1s));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ApplyPatchCacheTest, CheckCacheCorruptedSingle) {
|
TEST_F(ApplyPatchCacheTest, CheckCacheCorruptedSourceSingle) {
|
||||||
mangle_file(old_file);
|
TemporaryFile temp_file;
|
||||||
std::vector<std::string> sha1s = { old_sha1 };
|
mangle_file(temp_file.path);
|
||||||
ASSERT_EQ(0, applypatch_check(&old_file[0], sha1s));
|
std::vector<std::string> sha1s_single = { old_sha1 };
|
||||||
|
ASSERT_EQ(0, applypatch_check(temp_file.path, sha1s_single));
|
||||||
|
ASSERT_EQ(0, applypatch_check(nonexistent_file.c_str(), sha1s_single));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ApplyPatchCacheTest, CheckCacheCorruptedMultiple) {
|
TEST_F(ApplyPatchCacheTest, CheckCacheCorruptedSourceMultiple) {
|
||||||
mangle_file(old_file);
|
TemporaryFile temp_file;
|
||||||
std::vector<std::string> sha1s = { bad_sha1_a, old_sha1, bad_sha1_b };
|
mangle_file(temp_file.path);
|
||||||
ASSERT_EQ(0, applypatch_check(&old_file[0], sha1s));
|
std::vector<std::string> sha1s_multiple = { bad_sha1_a, old_sha1, bad_sha1_b };
|
||||||
|
ASSERT_EQ(0, applypatch_check(temp_file.path, sha1s_multiple));
|
||||||
|
ASSERT_EQ(0, applypatch_check(nonexistent_file.c_str(), sha1s_multiple));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ApplyPatchCacheTest, CheckCacheCorruptedFailure) {
|
TEST_F(ApplyPatchCacheTest, CheckCacheCorruptedSourceFailure) {
|
||||||
mangle_file(old_file);
|
TemporaryFile temp_file;
|
||||||
std::vector<std::string> sha1s = { bad_sha1_a, bad_sha1_b };
|
mangle_file(temp_file.path);
|
||||||
ASSERT_NE(0, applypatch_check(&old_file[0], sha1s));
|
std::vector<std::string> sha1s_failure = { bad_sha1_a, bad_sha1_b };
|
||||||
|
ASSERT_NE(0, applypatch_check(temp_file.path, sha1s_failure));
|
||||||
|
ASSERT_NE(0, applypatch_check(nonexistent_file.c_str(), sha1s_failure));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ApplyPatchCacheTest, CheckCacheMissingSingle) {
|
TEST_F(ApplyPatchModesTest, InvalidArgs) {
|
||||||
unlink(&old_file[0]);
|
|
||||||
std::vector<std::string> sha1s = { old_sha1 };
|
|
||||||
ASSERT_EQ(0, applypatch_check(&old_file[0], sha1s));
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(ApplyPatchCacheTest, CheckCacheMissingMultiple) {
|
|
||||||
unlink(&old_file[0]);
|
|
||||||
std::vector<std::string> sha1s = { bad_sha1_a, old_sha1, bad_sha1_b };
|
|
||||||
ASSERT_EQ(0, applypatch_check(&old_file[0], sha1s));
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(ApplyPatchCacheTest, CheckCacheMissingFailure) {
|
|
||||||
unlink(&old_file[0]);
|
|
||||||
std::vector<std::string> sha1s = { bad_sha1_a, bad_sha1_b };
|
|
||||||
ASSERT_NE(0, applypatch_check(&old_file[0], sha1s));
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(ApplyPatchModesTest, InvalidArgs) {
|
|
||||||
// At least two args (including the filename).
|
// At least two args (including the filename).
|
||||||
ASSERT_EQ(2, applypatch_modes(1, (const char* []){ "applypatch" }));
|
ASSERT_EQ(2, applypatch_modes(1, (const char* []){ "applypatch" }));
|
||||||
|
|
||||||
@@ -233,7 +194,7 @@ TEST(ApplyPatchModesTest, InvalidArgs) {
|
|||||||
ASSERT_EQ(2, applypatch_modes(2, (const char* []){ "applypatch", "-x" }));
|
ASSERT_EQ(2, applypatch_modes(2, (const char* []){ "applypatch", "-x" }));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(ApplyPatchModesTest, PatchModeEmmcTarget) {
|
TEST_F(ApplyPatchModesTest, PatchModeEmmcTarget) {
|
||||||
std::string boot_img = from_testdata_base("boot.img");
|
std::string boot_img = from_testdata_base("boot.img");
|
||||||
size_t boot_img_size;
|
size_t boot_img_size;
|
||||||
std::string boot_img_sha1;
|
std::string boot_img_sha1;
|
||||||
@@ -303,7 +264,7 @@ TEST(ApplyPatchModesTest, PatchModeEmmcTarget) {
|
|||||||
ASSERT_EQ(0, applypatch_modes(args3.size(), args3.data()));
|
ASSERT_EQ(0, applypatch_modes(args3.size(), args3.data()));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(ApplyPatchModesTest, PatchModeInvalidArgs) {
|
TEST_F(ApplyPatchModesTest, PatchModeInvalidArgs) {
|
||||||
// Invalid bonus file.
|
// Invalid bonus file.
|
||||||
ASSERT_NE(0, applypatch_modes(3, (const char* []){ "applypatch", "-b", "/doesntexist" }));
|
ASSERT_NE(0, applypatch_modes(3, (const char* []){ "applypatch", "-b", "/doesntexist" }));
|
||||||
|
|
||||||
@@ -364,11 +325,11 @@ TEST(ApplyPatchModesTest, PatchModeInvalidArgs) {
|
|||||||
ASSERT_NE(0, applypatch_modes(args6.size(), args6.data()));
|
ASSERT_NE(0, applypatch_modes(args6.size(), args6.data()));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(ApplyPatchModesTest, CheckModeInvalidArgs) {
|
TEST_F(ApplyPatchModesTest, CheckModeInvalidArgs) {
|
||||||
// Insufficient args.
|
// Insufficient args.
|
||||||
ASSERT_EQ(2, applypatch_modes(2, (const char* []){ "applypatch", "-c" }));
|
ASSERT_EQ(2, applypatch_modes(2, (const char* []){ "applypatch", "-c" }));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(ApplyPatchModesTest, ShowLicenses) {
|
TEST_F(ApplyPatchModesTest, ShowLicenses) {
|
||||||
ASSERT_EQ(0, applypatch_modes(2, (const char* []){ "applypatch", "-l" }));
|
ASSERT_EQ(0, applypatch_modes(2, (const char* []){ "applypatch", "-l" }));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,53 +18,12 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include <android-base/strings.h>
|
#include <android-base/strings.h>
|
||||||
|
#include <android-base/test_utils.h>
|
||||||
#include <bootloader_message/bootloader_message.h>
|
#include <bootloader_message/bootloader_message.h>
|
||||||
#include <gtest/gtest.h>
|
#include <gtest/gtest.h>
|
||||||
|
|
||||||
class BootloaderMessageTest : public ::testing::Test {
|
TEST(BootloaderMessageTest, read_and_write_bootloader_message) {
|
||||||
protected:
|
TemporaryFile temp_misc;
|
||||||
BootloaderMessageTest() : has_misc(true) {}
|
|
||||||
|
|
||||||
virtual void SetUp() override {
|
|
||||||
std::string err;
|
|
||||||
has_misc = !get_bootloader_message_blk_device(&err).empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void TearDown() override {
|
|
||||||
// Clear the BCB.
|
|
||||||
if (has_misc) {
|
|
||||||
std::string err;
|
|
||||||
ASSERT_TRUE(clear_bootloader_message(&err)) << "Failed to clear BCB: " << err;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool has_misc;
|
|
||||||
};
|
|
||||||
|
|
||||||
TEST_F(BootloaderMessageTest, clear_bootloader_message) {
|
|
||||||
if (!has_misc) {
|
|
||||||
GTEST_LOG_(INFO) << "Test skipped due to no /misc partition found on the device.";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Clear the BCB.
|
|
||||||
std::string err;
|
|
||||||
ASSERT_TRUE(clear_bootloader_message(&err)) << "Failed to clear BCB: " << err;
|
|
||||||
|
|
||||||
// Verify the content.
|
|
||||||
bootloader_message boot;
|
|
||||||
ASSERT_TRUE(read_bootloader_message(&boot, &err)) << "Failed to read BCB: " << err;
|
|
||||||
|
|
||||||
// All the bytes should be cleared.
|
|
||||||
ASSERT_EQ(std::string(sizeof(boot), '\0'),
|
|
||||||
std::string(reinterpret_cast<const char*>(&boot), sizeof(boot)));
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(BootloaderMessageTest, read_and_write_bootloader_message) {
|
|
||||||
if (!has_misc) {
|
|
||||||
GTEST_LOG_(INFO) << "Test skipped due to no /misc partition found on the device.";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Write the BCB.
|
// Write the BCB.
|
||||||
bootloader_message boot = {};
|
bootloader_message boot = {};
|
||||||
@@ -73,90 +32,71 @@ TEST_F(BootloaderMessageTest, read_and_write_bootloader_message) {
|
|||||||
strlcpy(boot.status, "status1", sizeof(boot.status));
|
strlcpy(boot.status, "status1", sizeof(boot.status));
|
||||||
|
|
||||||
std::string err;
|
std::string err;
|
||||||
ASSERT_TRUE(write_bootloader_message(boot, &err)) << "Failed to write BCB: " << err;
|
ASSERT_TRUE(write_bootloader_message_to(boot, temp_misc.path, &err))
|
||||||
|
<< "Failed to write BCB: " << err;
|
||||||
|
|
||||||
// Read and verify.
|
// Read and verify.
|
||||||
bootloader_message boot_verify;
|
bootloader_message boot_verify;
|
||||||
ASSERT_TRUE(read_bootloader_message(&boot_verify, &err)) << "Failed to read BCB: " << err;
|
ASSERT_TRUE(read_bootloader_message_from(&boot_verify, temp_misc.path, &err))
|
||||||
|
<< "Failed to read BCB: " << err;
|
||||||
|
|
||||||
ASSERT_EQ(std::string(reinterpret_cast<const char*>(&boot), sizeof(boot)),
|
ASSERT_EQ(std::string(reinterpret_cast<const char*>(&boot), sizeof(boot)),
|
||||||
std::string(reinterpret_cast<const char*>(&boot_verify), sizeof(boot_verify)));
|
std::string(reinterpret_cast<const char*>(&boot_verify), sizeof(boot_verify)));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(BootloaderMessageTest, write_bootloader_message_options) {
|
TEST(BootloaderMessageTest, update_bootloader_message_in_struct) {
|
||||||
if (!has_misc) {
|
|
||||||
GTEST_LOG_(INFO) << "Test skipped due to no /misc partition found on the device.";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Write the options to BCB.
|
// Write the options to BCB.
|
||||||
std::vector<std::string> options = { "option1", "option2" };
|
std::vector<std::string> options = { "option1", "option2" };
|
||||||
std::string err;
|
|
||||||
ASSERT_TRUE(write_bootloader_message(options, &err)) << "Failed to write BCB: " << err;
|
|
||||||
|
|
||||||
// Inject some bytes into boot, which should be overwritten while reading.
|
bootloader_message boot = {};
|
||||||
bootloader_message boot;
|
// Inject some bytes into boot.
|
||||||
strlcpy(boot.recovery, "random message", sizeof(boot.recovery));
|
strlcpy(boot.recovery, "random message", sizeof(boot.recovery));
|
||||||
|
strlcpy(boot.status, "status bytes", sizeof(boot.status));
|
||||||
|
strlcpy(boot.stage, "stage bytes", sizeof(boot.stage));
|
||||||
strlcpy(boot.reserved, "reserved bytes", sizeof(boot.reserved));
|
strlcpy(boot.reserved, "reserved bytes", sizeof(boot.reserved));
|
||||||
|
|
||||||
ASSERT_TRUE(read_bootloader_message(&boot, &err)) << "Failed to read BCB: " << err;
|
ASSERT_TRUE(update_bootloader_message_in_struct(&boot, options));
|
||||||
|
|
||||||
// Verify that command and recovery fields should be set.
|
// Verify that command and recovery fields should be set.
|
||||||
ASSERT_EQ("boot-recovery", std::string(boot.command));
|
ASSERT_EQ("boot-recovery", std::string(boot.command));
|
||||||
std::string expected = "recovery\n" + android::base::Join(options, "\n") + "\n";
|
std::string expected = "recovery\n" + android::base::Join(options, "\n") + "\n";
|
||||||
ASSERT_EQ(expected, std::string(boot.recovery));
|
ASSERT_EQ(expected, std::string(boot.recovery));
|
||||||
|
|
||||||
// The rest should be cleared.
|
// The rest should be intact.
|
||||||
ASSERT_EQ(std::string(sizeof(boot.status), '\0'), std::string(boot.status, sizeof(boot.status)));
|
ASSERT_EQ("status bytes", std::string(boot.status));
|
||||||
ASSERT_EQ(std::string(sizeof(boot.stage), '\0'), std::string(boot.stage, sizeof(boot.stage)));
|
ASSERT_EQ("stage bytes", std::string(boot.stage));
|
||||||
ASSERT_EQ(std::string(sizeof(boot.reserved), '\0'),
|
ASSERT_EQ("reserved bytes", std::string(boot.reserved));
|
||||||
std::string(boot.reserved, sizeof(boot.reserved)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(BootloaderMessageTest, write_bootloader_message_options_empty) {
|
TEST(BootloaderMessageTest, update_bootloader_message_recovery_options_empty) {
|
||||||
if (!has_misc) {
|
|
||||||
GTEST_LOG_(INFO) << "Test skipped due to no /misc partition found on the device.";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Write empty vector.
|
// Write empty vector.
|
||||||
std::vector<std::string> options;
|
std::vector<std::string> options;
|
||||||
std::string err;
|
|
||||||
ASSERT_TRUE(write_bootloader_message(options, &err)) << "Failed to write BCB: " << err;
|
|
||||||
|
|
||||||
// Read and verify.
|
// Read and verify.
|
||||||
bootloader_message boot;
|
bootloader_message boot = {};
|
||||||
ASSERT_TRUE(read_bootloader_message(&boot, &err)) << "Failed to read BCB: " << err;
|
ASSERT_TRUE(update_bootloader_message_in_struct(&boot, options));
|
||||||
|
|
||||||
// command and recovery fields should be set.
|
// command and recovery fields should be set.
|
||||||
ASSERT_EQ("boot-recovery", std::string(boot.command));
|
ASSERT_EQ("boot-recovery", std::string(boot.command));
|
||||||
ASSERT_EQ("recovery\n", std::string(boot.recovery));
|
ASSERT_EQ("recovery\n", std::string(boot.recovery));
|
||||||
|
|
||||||
// The rest should be cleared.
|
// The rest should be empty.
|
||||||
ASSERT_EQ(std::string(sizeof(boot.status), '\0'), std::string(boot.status, sizeof(boot.status)));
|
ASSERT_EQ(std::string(sizeof(boot.status), '\0'), std::string(boot.status, sizeof(boot.status)));
|
||||||
ASSERT_EQ(std::string(sizeof(boot.stage), '\0'), std::string(boot.stage, sizeof(boot.stage)));
|
ASSERT_EQ(std::string(sizeof(boot.stage), '\0'), std::string(boot.stage, sizeof(boot.stage)));
|
||||||
ASSERT_EQ(std::string(sizeof(boot.reserved), '\0'),
|
ASSERT_EQ(std::string(sizeof(boot.reserved), '\0'),
|
||||||
std::string(boot.reserved, sizeof(boot.reserved)));
|
std::string(boot.reserved, sizeof(boot.reserved)));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(BootloaderMessageTest, write_bootloader_message_options_long) {
|
TEST(BootloaderMessageTest, update_bootloader_message_recovery_options_long) {
|
||||||
if (!has_misc) {
|
|
||||||
GTEST_LOG_(INFO) << "Test skipped due to no /misc partition found on the device.";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Write super long message.
|
// Write super long message.
|
||||||
std::vector<std::string> options;
|
std::vector<std::string> options;
|
||||||
for (int i = 0; i < 100; i++) {
|
for (int i = 0; i < 100; i++) {
|
||||||
options.push_back("option: " + std::to_string(i));
|
options.push_back("option: " + std::to_string(i));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string err;
|
|
||||||
ASSERT_TRUE(write_bootloader_message(options, &err)) << "Failed to write BCB: " << err;
|
|
||||||
|
|
||||||
// Read and verify.
|
// Read and verify.
|
||||||
bootloader_message boot;
|
bootloader_message boot = {};
|
||||||
ASSERT_TRUE(read_bootloader_message(&boot, &err)) << "Failed to read BCB: " << err;
|
ASSERT_TRUE(update_bootloader_message_in_struct(&boot, options));
|
||||||
|
|
||||||
// Make sure it's long enough.
|
// Make sure it's long enough.
|
||||||
std::string expected = "recovery\n" + android::base::Join(options, "\n") + "\n";
|
std::string expected = "recovery\n" + android::base::Join(options, "\n") + "\n";
|
||||||
@@ -167,40 +107,10 @@ TEST_F(BootloaderMessageTest, write_bootloader_message_options_long) {
|
|||||||
ASSERT_EQ(expected.substr(0, sizeof(boot.recovery) - 1), std::string(boot.recovery));
|
ASSERT_EQ(expected.substr(0, sizeof(boot.recovery) - 1), std::string(boot.recovery));
|
||||||
ASSERT_EQ('\0', boot.recovery[sizeof(boot.recovery) - 1]);
|
ASSERT_EQ('\0', boot.recovery[sizeof(boot.recovery) - 1]);
|
||||||
|
|
||||||
// The rest should be cleared.
|
// The rest should be empty.
|
||||||
ASSERT_EQ(std::string(sizeof(boot.status), '\0'), std::string(boot.status, sizeof(boot.status)));
|
ASSERT_EQ(std::string(sizeof(boot.status), '\0'), std::string(boot.status, sizeof(boot.status)));
|
||||||
ASSERT_EQ(std::string(sizeof(boot.stage), '\0'), std::string(boot.stage, sizeof(boot.stage)));
|
ASSERT_EQ(std::string(sizeof(boot.stage), '\0'), std::string(boot.stage, sizeof(boot.stage)));
|
||||||
ASSERT_EQ(std::string(sizeof(boot.reserved), '\0'),
|
ASSERT_EQ(std::string(sizeof(boot.reserved), '\0'),
|
||||||
std::string(boot.reserved, sizeof(boot.reserved)));
|
std::string(boot.reserved, sizeof(boot.reserved)));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(BootloaderMessageTest, update_bootloader_message) {
|
|
||||||
if (!has_misc) {
|
|
||||||
GTEST_LOG_(INFO) << "Test skipped due to no /misc partition found on the device.";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Inject some bytes into boot, which should be not overwritten later.
|
|
||||||
bootloader_message boot;
|
|
||||||
strlcpy(boot.recovery, "random message", sizeof(boot.recovery));
|
|
||||||
strlcpy(boot.reserved, "reserved bytes", sizeof(boot.reserved));
|
|
||||||
std::string err;
|
|
||||||
ASSERT_TRUE(write_bootloader_message(boot, &err)) << "Failed to write BCB: " << err;
|
|
||||||
|
|
||||||
// Update the BCB message.
|
|
||||||
std::vector<std::string> options = { "option1", "option2" };
|
|
||||||
ASSERT_TRUE(update_bootloader_message(options, &err)) << "Failed to update BCB: " << err;
|
|
||||||
|
|
||||||
bootloader_message boot_verify;
|
|
||||||
ASSERT_TRUE(read_bootloader_message(&boot_verify, &err)) << "Failed to read BCB: " << err;
|
|
||||||
|
|
||||||
// Verify that command and recovery fields should be set.
|
|
||||||
ASSERT_EQ("boot-recovery", std::string(boot_verify.command));
|
|
||||||
std::string expected = "recovery\n" + android::base::Join(options, "\n") + "\n";
|
|
||||||
ASSERT_EQ(expected, std::string(boot_verify.recovery));
|
|
||||||
|
|
||||||
// The rest should be intact.
|
|
||||||
ASSERT_EQ(std::string(boot.status), std::string(boot_verify.status));
|
|
||||||
ASSERT_EQ(std::string(boot.stage), std::string(boot_verify.stage));
|
|
||||||
ASSERT_EQ(std::string(boot.reserved), std::string(boot_verify.reserved));
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -20,6 +20,7 @@
|
|||||||
#include <sys/un.h>
|
#include <sys/un.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include <android-base/file.h>
|
#include <android-base/file.h>
|
||||||
@@ -38,43 +39,49 @@ static const std::string INIT_SVC_CLEAR_BCB = "init.svc.clear-bcb";
|
|||||||
static const std::string INIT_SVC_UNCRYPT = "init.svc.uncrypt";
|
static const std::string INIT_SVC_UNCRYPT = "init.svc.uncrypt";
|
||||||
static constexpr int SOCKET_CONNECTION_MAX_RETRY = 30;
|
static constexpr int SOCKET_CONNECTION_MAX_RETRY = 30;
|
||||||
|
|
||||||
|
static void StopService() {
|
||||||
|
ASSERT_TRUE(android::base::SetProperty("ctl.stop", "setup-bcb"));
|
||||||
|
ASSERT_TRUE(android::base::SetProperty("ctl.stop", "clear-bcb"));
|
||||||
|
ASSERT_TRUE(android::base::SetProperty("ctl.stop", "uncrypt"));
|
||||||
|
|
||||||
|
bool success = false;
|
||||||
|
for (int retry = 0; retry < SOCKET_CONNECTION_MAX_RETRY; retry++) {
|
||||||
|
std::string setup_bcb = android::base::GetProperty(INIT_SVC_SETUP_BCB, "");
|
||||||
|
std::string clear_bcb = android::base::GetProperty(INIT_SVC_CLEAR_BCB, "");
|
||||||
|
std::string uncrypt = android::base::GetProperty(INIT_SVC_UNCRYPT, "");
|
||||||
|
GTEST_LOG_(INFO) << "setup-bcb: [" << setup_bcb << "] clear-bcb: [" << clear_bcb
|
||||||
|
<< "] uncrypt: [" << uncrypt << "]";
|
||||||
|
if (setup_bcb != "running" && clear_bcb != "running" && uncrypt != "running") {
|
||||||
|
success = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
sleep(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
ASSERT_TRUE(success) << "uncrypt service is not available.";
|
||||||
|
}
|
||||||
|
|
||||||
class UncryptTest : public ::testing::Test {
|
class UncryptTest : public ::testing::Test {
|
||||||
protected:
|
protected:
|
||||||
UncryptTest() : has_misc(true) {}
|
UncryptTest() : has_misc(true) {}
|
||||||
|
|
||||||
virtual void SetUp() override {
|
void SetUp() override {
|
||||||
ASSERT_TRUE(android::base::SetProperty("ctl.stop", "setup-bcb"));
|
|
||||||
ASSERT_TRUE(android::base::SetProperty("ctl.stop", "clear-bcb"));
|
|
||||||
ASSERT_TRUE(android::base::SetProperty("ctl.stop", "uncrypt"));
|
|
||||||
|
|
||||||
bool success = false;
|
|
||||||
for (int retry = 0; retry < SOCKET_CONNECTION_MAX_RETRY; retry++) {
|
|
||||||
std::string setup_bcb = android::base::GetProperty(INIT_SVC_SETUP_BCB, "");
|
|
||||||
std::string clear_bcb = android::base::GetProperty(INIT_SVC_CLEAR_BCB, "");
|
|
||||||
std::string uncrypt = android::base::GetProperty(INIT_SVC_UNCRYPT, "");
|
|
||||||
LOG(INFO) << "setup-bcb: [" << setup_bcb << "] clear-bcb: [" << clear_bcb << "] uncrypt: ["
|
|
||||||
<< uncrypt << "]";
|
|
||||||
if (setup_bcb != "running" && clear_bcb != "running" && uncrypt != "running") {
|
|
||||||
success = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
sleep(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
ASSERT_TRUE(success) << "uncrypt service is not available.";
|
|
||||||
|
|
||||||
std::string err;
|
std::string err;
|
||||||
has_misc = !get_bootloader_message_blk_device(&err).empty();
|
has_misc = !get_bootloader_message_blk_device(&err).empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TearDown() override {
|
||||||
|
// Clear the BCB.
|
||||||
|
if (has_misc) {
|
||||||
|
std::string err;
|
||||||
|
ASSERT_TRUE(clear_bootloader_message(&err)) << "Failed to clear BCB: " << err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void SetupOrClearBcb(bool isSetup, const std::string& message,
|
void SetupOrClearBcb(bool isSetup, const std::string& message,
|
||||||
const std::string& message_in_bcb) const {
|
const std::string& message_in_bcb) const {
|
||||||
if (!has_misc) {
|
// Restart the setup-bcb service.
|
||||||
GTEST_LOG_(INFO) << "Test skipped due to no /misc partition found on the device.";
|
StopService();
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Trigger the setup-bcb service.
|
|
||||||
ASSERT_TRUE(android::base::SetProperty("ctl.start", isSetup ? "setup-bcb" : "clear-bcb"));
|
ASSERT_TRUE(android::base::SetProperty("ctl.start", isSetup ? "setup-bcb" : "clear-bcb"));
|
||||||
|
|
||||||
// Test tends to be flaky if proceeding immediately ("Transport endpoint is not connected").
|
// Test tends to be flaky if proceeding immediately ("Transport endpoint is not connected").
|
||||||
@@ -144,27 +151,49 @@ class UncryptTest : public ::testing::Test {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VerifyBootloaderMessage(const std::string& expected) {
|
||||||
|
std::string err;
|
||||||
|
bootloader_message boot;
|
||||||
|
ASSERT_TRUE(read_bootloader_message(&boot, &err)) << "Failed to read BCB: " << err;
|
||||||
|
|
||||||
|
// Check that we have all the expected bytes.
|
||||||
|
ASSERT_EQ(expected, std::string(reinterpret_cast<const char*>(&boot), sizeof(boot)));
|
||||||
|
}
|
||||||
|
|
||||||
bool has_misc;
|
bool has_misc;
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST_F(UncryptTest, setup_bcb) {
|
TEST_F(UncryptTest, setup_bcb) {
|
||||||
|
if (!has_misc) {
|
||||||
|
GTEST_LOG_(INFO) << "Test skipped due to no /misc partition found on the device.";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string random_data;
|
||||||
|
random_data.reserve(sizeof(bootloader_message));
|
||||||
|
generate_n(back_inserter(random_data), sizeof(bootloader_message), []() { return rand() % 128; });
|
||||||
|
|
||||||
|
bootloader_message boot;
|
||||||
|
memcpy(&boot, random_data.c_str(), random_data.size());
|
||||||
|
|
||||||
|
std::string err;
|
||||||
|
ASSERT_TRUE(write_bootloader_message(boot, &err)) << "Failed to write BCB: " << err;
|
||||||
|
VerifyBootloaderMessage(random_data);
|
||||||
|
|
||||||
|
ASSERT_TRUE(clear_bootloader_message(&err)) << "Failed to clear BCB: " << err;
|
||||||
|
VerifyBootloaderMessage(std::string(sizeof(bootloader_message), '\0'));
|
||||||
|
|
||||||
std::string message = "--update_message=abc value";
|
std::string message = "--update_message=abc value";
|
||||||
std::string message_in_bcb = "recovery\n--update_message=abc value\n";
|
std::string message_in_bcb = "recovery\n--update_message=abc value\n";
|
||||||
SetupOrClearBcb(true, message, message_in_bcb);
|
SetupOrClearBcb(true, message, message_in_bcb);
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(UncryptTest, clear_bcb) {
|
|
||||||
SetupOrClearBcb(false, "", "");
|
SetupOrClearBcb(false, "", "");
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(UncryptTest, setup_bcb_wipe_ab) {
|
|
||||||
TemporaryFile wipe_package;
|
TemporaryFile wipe_package;
|
||||||
ASSERT_TRUE(android::base::WriteStringToFile(std::string(345, 'a'), wipe_package.path));
|
ASSERT_TRUE(android::base::WriteStringToFile(std::string(345, 'a'), wipe_package.path));
|
||||||
|
|
||||||
// It's expected to store a wipe package in /misc, with the package size passed to recovery.
|
// It's expected to store a wipe package in /misc, with the package size passed to recovery.
|
||||||
std::string message =
|
message = "--wipe_ab\n--wipe_package="s + wipe_package.path + "\n--reason=wipePackage"s;
|
||||||
"--wipe_ab\n--wipe_package="s + wipe_package.path + "\n--reason=wipePackage"s;
|
message_in_bcb = "recovery\n--wipe_ab\n--wipe_package_size=345\n--reason=wipePackage\n";
|
||||||
std::string message_in_bcb =
|
|
||||||
"recovery\n--wipe_ab\n--wipe_package_size=345\n--reason=wipePackage\n";
|
|
||||||
SetupOrClearBcb(true, message, message_in_bcb);
|
SetupOrClearBcb(true, message, message_in_bcb);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user