summaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/Android.mk52
-rw-r--r--tests/common/test_constants.h25
-rw-r--r--tests/component/applypatch_test.cpp392
-rw-r--r--tests/component/verifier_test.cpp178
-rw-r--r--tests/testdata/alter-footer.zipbin0 -> 4009 bytes
-rw-r--r--tests/testdata/alter-metadata.zipbin0 -> 4009 bytes
-rw-r--r--tests/testdata/fake-eocd.zipbin0 -> 4313 bytes
-rw-r--r--tests/testdata/jarsigned.zipbin0 -> 2271 bytes
-rw-r--r--tests/testdata/new.filebin0 -> 1388877 bytes
-rw-r--r--tests/testdata/old.filebin0 -> 1348051 bytes
-rw-r--r--tests/testdata/otasigned.zipbin0 -> 4009 bytes
-rw-r--r--tests/testdata/otasigned_ecdsa_sha256.zipbin0 -> 3085 bytes
-rw-r--r--tests/testdata/otasigned_f4.zipbin0 -> 5195 bytes
-rw-r--r--tests/testdata/otasigned_f4_sha256.zipbin0 -> 5319 bytes
-rw-r--r--tests/testdata/otasigned_sha256.zipbin0 -> 5326 bytes
-rw-r--r--tests/testdata/patch.bsdiffbin0 -> 57476 bytes
-rw-r--r--tests/testdata/random.zipbin0 -> 1024 bytes
-rw-r--r--tests/testdata/test_f4.pk8bin0 -> 1217 bytes
-rw-r--r--tests/testdata/test_f4.x509.pem25
-rw-r--r--tests/testdata/test_f4_sha256.x509.pem25
-rw-r--r--tests/testdata/test_key_e3.txt1
-rw-r--r--tests/testdata/test_key_ec.txt1
-rw-r--r--tests/testdata/test_key_f4.txt1
-rw-r--r--tests/testdata/testkey.pk8bin0 -> 1217 bytes
-rw-r--r--tests/testdata/testkey.x509.pem27
-rw-r--r--tests/testdata/testkey_ecdsa.pk8bin0 -> 138 bytes
-rw-r--r--tests/testdata/testkey_ecdsa.x509.pem10
-rw-r--r--tests/testdata/testkey_sha256.x509.pem27
-rw-r--r--tests/testdata/unsigned.zipbin0 -> 376 bytes
-rw-r--r--tests/unit/asn1_decoder_test.cpp (renamed from tests/asn1_decoder_test.cpp)0
-rw-r--r--tests/unit/locale_test.cpp29
-rw-r--r--tests/unit/recovery_test.cpp92
32 files changed, 881 insertions, 4 deletions
diff --git a/tests/Android.mk b/tests/Android.mk
index 02a272a24..a66991b21 100644
--- a/tests/Android.mk
+++ b/tests/Android.mk
@@ -16,10 +16,54 @@
LOCAL_PATH := $(call my-dir)
+# Unit tests
include $(CLEAR_VARS)
+LOCAL_CLANG := true
+LOCAL_MODULE := recovery_unit_test
LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
-LOCAL_STATIC_LIBRARIES := libverifier
-LOCAL_SRC_FILES := asn1_decoder_test.cpp
-LOCAL_MODULE := asn1_decoder_test
-LOCAL_C_INCLUDES := $(LOCAL_PATH)/..
+LOCAL_STATIC_LIBRARIES := \
+ libverifier \
+ libminui
+
+LOCAL_SRC_FILES := unit/asn1_decoder_test.cpp
+LOCAL_SRC_FILES += unit/recovery_test.cpp
+LOCAL_SRC_FILES += unit/locale_test.cpp
+LOCAL_C_INCLUDES := bootable/recovery
+LOCAL_SHARED_LIBRARIES := liblog
+include $(BUILD_NATIVE_TEST)
+
+# Component tests
+include $(CLEAR_VARS)
+LOCAL_CLANG := true
+LOCAL_CFLAGS += -Wno-unused-parameter
+LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
+LOCAL_MODULE := recovery_component_test
+LOCAL_C_INCLUDES := bootable/recovery
+LOCAL_SRC_FILES := \
+ component/verifier_test.cpp \
+ component/applypatch_test.cpp
+LOCAL_FORCE_STATIC_EXECUTABLE := true
+LOCAL_STATIC_LIBRARIES := \
+ libapplypatch \
+ libotafault \
+ libmtdutils \
+ libbase \
+ libverifier \
+ libcrypto_static \
+ libminui \
+ libminzip \
+ libcutils \
+ libbz \
+ libz \
+ libc
+
+testdata_out_path := $(TARGET_OUT_DATA_NATIVE_TESTS)/recovery
+testdata_files := $(call find-subdir-files, testdata/*)
+
+GEN := $(addprefix $(testdata_out_path)/, $(testdata_files))
+$(GEN): PRIVATE_PATH := $(LOCAL_PATH)
+$(GEN): PRIVATE_CUSTOM_TOOL = cp $< $@
+$(GEN): $(testdata_out_path)/% : $(LOCAL_PATH)/%
+ $(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
include $(BUILD_NATIVE_TEST)
diff --git a/tests/common/test_constants.h b/tests/common/test_constants.h
new file mode 100644
index 000000000..3490f6805
--- /dev/null
+++ b/tests/common/test_constants.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agree to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef _OTA_TEST_CONSTANTS_H
+#define _OTA_TEST_CONSTANTS_H
+
+#if defined(__LP64__)
+#define NATIVE_TEST_PATH "/nativetest64"
+#else
+#define NATIVE_TEST_PATH "/nativetest"
+#endif
+
+#endif
diff --git a/tests/component/applypatch_test.cpp b/tests/component/applypatch_test.cpp
new file mode 100644
index 000000000..b44ddd17c
--- /dev/null
+++ b/tests/component/applypatch_test.cpp
@@ -0,0 +1,392 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agree to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <fcntl.h>
+#include <gtest/gtest.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+#include <sys/statvfs.h>
+#include <sys/types.h>
+#include <time.h>
+
+#include <string>
+
+#include <android-base/file.h>
+#include <android-base/stringprintf.h>
+#include <android-base/test_utils.h>
+
+#include "applypatch/applypatch.h"
+#include "common/test_constants.h"
+#include "openssl/sha.h"
+#include "print_sha1.h"
+
+static const std::string DATA_PATH = getenv("ANDROID_DATA");
+static const std::string TESTDATA_PATH = "/recovery/testdata";
+static const std::string WORK_FS = "/data";
+
+static std::string sha1sum(const std::string& fname) {
+ uint8_t digest[SHA_DIGEST_LENGTH];
+ std::string data;
+ android::base::ReadFileToString(fname, &data);
+
+ SHA1((const uint8_t*)data.c_str(), data.size(), digest);
+ return print_sha1(digest);
+}
+
+static void mangle_file(const std::string& fname) {
+ FILE* fh = fopen(&fname[0], "w");
+ int r;
+ for (int i=0; i < 1024; i++) {
+ r = rand();
+ fwrite(&r, sizeof(short), 1, fh);
+ }
+ fclose(fh);
+}
+
+static bool file_cmp(std::string& f1, std::string& f2) {
+ std::string c1;
+ std::string c2;
+ android::base::ReadFileToString(f1, &c1);
+ android::base::ReadFileToString(f2, &c2);
+ return c1 == c2;
+}
+
+static std::string from_testdata_base(const std::string fname) {
+ return android::base::StringPrintf("%s%s%s/%s",
+ &DATA_PATH[0],
+ &NATIVE_TEST_PATH[0],
+ &TESTDATA_PATH[0],
+ &fname[0]);
+}
+
+class ApplyPatchTest : public ::testing::Test {
+ public:
+ static void SetUpTestCase() {
+ // set up files
+ old_file = from_testdata_base("old.file");
+ new_file = from_testdata_base("new.file");
+ patch_file = from_testdata_base("patch.bsdiff");
+ rand_file = "/cache/applypatch_test_rand.file";
+ cache_file = "/cache/saved.file";
+
+ // write stuff to rand_file
+ android::base::WriteStringToFile("hello", rand_file);
+
+ // set up SHA constants
+ old_sha1 = sha1sum(old_file);
+ new_sha1 = sha1sum(new_file);
+ srand(time(NULL));
+ bad_sha1_a = android::base::StringPrintf("%040x", rand());
+ bad_sha1_b = android::base::StringPrintf("%040x", rand());
+
+ struct stat st;
+ stat(&new_file[0], &st);
+ new_size = st.st_size;
+ }
+
+ static std::string old_file;
+ static std::string new_file;
+ static std::string rand_file;
+ static std::string cache_file;
+ static std::string patch_file;
+
+ static std::string old_sha1;
+ static std::string new_sha1;
+ static std::string bad_sha1_a;
+ static std::string bad_sha1_b;
+
+ static size_t new_size;
+};
+
+std::string ApplyPatchTest::old_file;
+std::string ApplyPatchTest::new_file;
+
+static void cp(std::string src, std::string tgt) {
+ std::string cmd = android::base::StringPrintf("cp %s %s",
+ &src[0],
+ &tgt[0]);
+ system(&cmd[0]);
+}
+
+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 {
+ public:
+ virtual void SetUp() {
+ backup_old();
+ }
+
+ virtual void TearDown() {
+ restore_old();
+ }
+};
+
+class ApplyPatchFullTest : public ApplyPatchCacheTest {
+ public:
+ static void SetUpTestCase() {
+ ApplyPatchTest::SetUpTestCase();
+ unsigned long free_kb = FreeSpaceForFile(&WORK_FS[0]);
+ ASSERT_GE(free_kb * 1024, new_size * 3 / 2);
+ output_f = new TemporaryFile();
+ output_loc = std::string(output_f->path);
+
+ struct FileContents fc;
+
+ ASSERT_EQ(0, LoadFileContents(&rand_file[0], &fc));
+ Value* patch1 = new Value();
+ patch1->type = VAL_BLOB;
+ patch1->size = fc.data.size();
+ patch1->data = static_cast<char*>(malloc(fc.data.size()));
+ memcpy(patch1->data, fc.data.data(), fc.data.size());
+ patches.push_back(patch1);
+
+ ASSERT_EQ(0, LoadFileContents(&patch_file[0], &fc));
+ Value* patch2 = new Value();
+ patch2->type = VAL_BLOB;
+ patch2->size = fc.st.st_size;
+ patch2->data = static_cast<char*>(malloc(fc.data.size()));
+ memcpy(patch2->data, fc.data.data(), fc.data.size());
+ patches.push_back(patch2);
+ }
+ static void TearDownTestCase() {
+ delete output_f;
+ for (auto it = patches.begin(); it != patches.end(); ++it) {
+ free((*it)->data);
+ delete *it;
+ }
+ patches.clear();
+ }
+
+ static std::vector<Value*> patches;
+ static TemporaryFile* output_f;
+ static std::string output_loc;
+};
+
+class ApplyPatchDoubleCacheTest : public ApplyPatchFullTest {
+ public:
+ virtual void SetUp() {
+ ApplyPatchCacheTest::SetUp();
+ cp(cache_file, "/cache/reallysaved.file");
+ }
+
+ virtual void TearDown() {
+ cp("/cache/reallysaved.file", cache_file);
+ ApplyPatchCacheTest::TearDown();
+ }
+};
+
+std::string ApplyPatchTest::rand_file;
+std::string ApplyPatchTest::patch_file;
+std::string ApplyPatchTest::cache_file;
+std::string ApplyPatchTest::old_sha1;
+std::string ApplyPatchTest::new_sha1;
+std::string ApplyPatchTest::bad_sha1_a;
+std::string ApplyPatchTest::bad_sha1_b;
+
+size_t ApplyPatchTest::new_size;
+
+std::vector<Value*> ApplyPatchFullTest::patches;
+TemporaryFile* ApplyPatchFullTest::output_f;
+std::string ApplyPatchFullTest::output_loc;
+
+TEST_F(ApplyPatchTest, CheckModeSingle) {
+ char* s = &old_sha1[0];
+ ASSERT_EQ(0, applypatch_check(&old_file[0], 1, &s));
+}
+
+TEST_F(ApplyPatchTest, CheckModeMultiple) {
+ char* argv[3] = {
+ &bad_sha1_a[0],
+ &old_sha1[0],
+ &bad_sha1_b[0]
+ };
+ ASSERT_EQ(0, applypatch_check(&old_file[0], 3, argv));
+}
+
+TEST_F(ApplyPatchTest, CheckModeFailure) {
+ char* argv[2] = {
+ &bad_sha1_a[0],
+ &bad_sha1_b[0]
+ };
+ ASSERT_NE(0, applypatch_check(&old_file[0], 2, argv));
+}
+
+TEST_F(ApplyPatchCacheTest, CheckCacheCorruptedSingle) {
+ mangle_file(old_file);
+ char* s = &old_sha1[0];
+ ASSERT_EQ(0, applypatch_check(&old_file[0], 1, &s));
+}
+
+TEST_F(ApplyPatchCacheTest, CheckCacheCorruptedMultiple) {
+ mangle_file(old_file);
+ char* argv[3] = {
+ &bad_sha1_a[0],
+ &old_sha1[0],
+ &bad_sha1_b[0]
+ };
+ ASSERT_EQ(0, applypatch_check(&old_file[0], 3, argv));
+}
+
+TEST_F(ApplyPatchCacheTest, CheckCacheCorruptedFailure) {
+ mangle_file(old_file);
+ char* argv[2] = {
+ &bad_sha1_a[0],
+ &bad_sha1_b[0]
+ };
+ ASSERT_NE(0, applypatch_check(&old_file[0], 2, argv));
+}
+
+TEST_F(ApplyPatchCacheTest, CheckCacheMissingSingle) {
+ unlink(&old_file[0]);
+ char* s = &old_sha1[0];
+ ASSERT_EQ(0, applypatch_check(&old_file[0], 1, &s));
+}
+
+TEST_F(ApplyPatchCacheTest, CheckCacheMissingMultiple) {
+ unlink(&old_file[0]);
+ char* argv[3] = {
+ &bad_sha1_a[0],
+ &old_sha1[0],
+ &bad_sha1_b[0]
+ };
+ ASSERT_EQ(0, applypatch_check(&old_file[0], 3, argv));
+}
+
+TEST_F(ApplyPatchCacheTest, CheckCacheMissingFailure) {
+ unlink(&old_file[0]);
+ char* argv[2] = {
+ &bad_sha1_a[0],
+ &bad_sha1_b[0]
+ };
+ ASSERT_NE(0, applypatch_check(&old_file[0], 2, argv));
+}
+
+TEST_F(ApplyPatchFullTest, ApplyInPlace) {
+ std::vector<char*> sha1s;
+ sha1s.push_back(&bad_sha1_a[0]);
+ sha1s.push_back(&old_sha1[0]);
+
+ int ap_result = applypatch(&old_file[0],
+ "-",
+ &new_sha1[0],
+ new_size,
+ 2,
+ sha1s.data(),
+ patches.data(),
+ nullptr);
+ ASSERT_EQ(0, ap_result);
+ ASSERT_TRUE(file_cmp(old_file, new_file));
+ // reapply, applypatch is idempotent so it should succeed
+ ap_result = applypatch(&old_file[0],
+ "-",
+ &new_sha1[0],
+ new_size,
+ 2,
+ sha1s.data(),
+ patches.data(),
+ nullptr);
+ ASSERT_EQ(0, ap_result);
+ ASSERT_TRUE(file_cmp(old_file, new_file));
+}
+
+TEST_F(ApplyPatchFullTest, ApplyInNewLocation) {
+ std::vector<char*> sha1s;
+ sha1s.push_back(&bad_sha1_a[0]);
+ sha1s.push_back(&old_sha1[0]);
+ int ap_result = applypatch(&old_file[0],
+ &output_loc[0],
+ &new_sha1[0],
+ new_size,
+ 2,
+ sha1s.data(),
+ patches.data(),
+ nullptr);
+ ASSERT_EQ(0, ap_result);
+ ASSERT_TRUE(file_cmp(output_loc, new_file));
+ ap_result = applypatch(&old_file[0],
+ &output_loc[0],
+ &new_sha1[0],
+ new_size,
+ 2,
+ sha1s.data(),
+ patches.data(),
+ nullptr);
+ ASSERT_EQ(0, ap_result);
+ ASSERT_TRUE(file_cmp(output_loc, new_file));
+}
+
+TEST_F(ApplyPatchFullTest, ApplyCorruptedInNewLocation) {
+ mangle_file(old_file);
+ std::vector<char*> sha1s;
+ sha1s.push_back(&bad_sha1_a[0]);
+ sha1s.push_back(&old_sha1[0]);
+ int ap_result = applypatch(&old_file[0],
+ &output_loc[0],
+ &new_sha1[0],
+ new_size,
+ 2,
+ sha1s.data(),
+ patches.data(),
+ nullptr);
+ ASSERT_EQ(0, ap_result);
+ ASSERT_TRUE(file_cmp(output_loc, new_file));
+ ap_result = applypatch(&old_file[0],
+ &output_loc[0],
+ &new_sha1[0],
+ new_size,
+ 2,
+ sha1s.data(),
+ patches.data(),
+ nullptr);
+ ASSERT_EQ(0, ap_result);
+ ASSERT_TRUE(file_cmp(output_loc, new_file));
+}
+
+TEST_F(ApplyPatchDoubleCacheTest, ApplyDoubleCorruptedInNewLocation) {
+ mangle_file(old_file);
+ mangle_file(cache_file);
+
+ std::vector<char*> sha1s;
+ sha1s.push_back(&bad_sha1_a[0]);
+ sha1s.push_back(&old_sha1[0]);
+ int ap_result = applypatch(&old_file[0],
+ &output_loc[0],
+ &new_sha1[0],
+ new_size,
+ 2,
+ sha1s.data(),
+ patches.data(),
+ nullptr);
+ ASSERT_NE(0, ap_result);
+ ASSERT_FALSE(file_cmp(output_loc, new_file));
+ ap_result = applypatch(&old_file[0],
+ &output_loc[0],
+ &new_sha1[0],
+ new_size,
+ 2,
+ sha1s.data(),
+ patches.data(),
+ nullptr);
+ ASSERT_NE(0, ap_result);
+ ASSERT_FALSE(file_cmp(output_loc, new_file));
+}
diff --git a/tests/component/verifier_test.cpp b/tests/component/verifier_test.cpp
new file mode 100644
index 000000000..780ff2816
--- /dev/null
+++ b/tests/component/verifier_test.cpp
@@ -0,0 +1,178 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agree to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <gtest/gtest.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include <openssl/sha.h>
+
+#include <android-base/stringprintf.h>
+
+#include "common.h"
+#include "common/test_constants.h"
+#include "minzip/SysUtil.h"
+#include "ui.h"
+#include "verifier.h"
+
+static const char* DATA_PATH = getenv("ANDROID_DATA");
+static const char* TESTDATA_PATH = "/recovery/testdata/";
+
+RecoveryUI* ui = NULL;
+
+class MockUI : public RecoveryUI {
+ void Init() { }
+ void SetStage(int, int) { }
+ void SetLocale(const char*) { }
+ void SetBackground(Icon icon) { }
+ void SetSystemUpdateText(bool security_update) { }
+
+ void SetProgressType(ProgressType determinate) { }
+ void ShowProgress(float portion, float seconds) { }
+ void SetProgress(float fraction) { }
+
+ void ShowText(bool visible) { }
+ bool IsTextVisible() { return false; }
+ bool WasTextEverVisible() { return false; }
+ void Print(const char* fmt, ...) {
+ va_list ap;
+ va_start(ap, fmt);
+ vfprintf(stderr, fmt, ap);
+ va_end(ap);
+ }
+ void PrintOnScreenOnly(const char* fmt, ...) {
+ va_list ap;
+ va_start(ap, fmt);
+ vfprintf(stderr, fmt, ap);
+ va_end(ap);
+ }
+ void ShowFile(const char*) { }
+
+ void StartMenu(const char* const * headers, const char* const * items,
+ int initial_selection) { }
+ int SelectMenu(int sel) { return 0; }
+ void EndMenu() { }
+};
+
+void
+ui_print(const char* format, ...) {
+ va_list ap;
+ va_start(ap, format);
+ vfprintf(stdout, format, ap);
+ va_end(ap);
+}
+
+class VerifierTest : public testing::TestWithParam<std::vector<std::string>> {
+ public:
+ MemMapping memmap;
+ std::vector<Certificate> certs;
+
+ virtual void SetUp() {
+ std::vector<std::string> args = GetParam();
+ std::string package =
+ android::base::StringPrintf("%s%s%s%s", DATA_PATH, NATIVE_TEST_PATH,
+ TESTDATA_PATH, args[0].c_str());
+ if (sysMapFile(package.c_str(), &memmap) != 0) {
+ FAIL() << "Failed to mmap " << package << ": " << strerror(errno)
+ << "\n";
+ }
+
+ for (auto it = ++(args.cbegin()); it != args.cend(); ++it) {
+ if (it->substr(it->length() - 3, it->length()) == "256") {
+ if (certs.empty()) {
+ FAIL() << "May only specify -sha256 after key type\n";
+ }
+ certs.back().hash_len = SHA256_DIGEST_LENGTH;
+ } else {
+ std::string public_key_file = android::base::StringPrintf(
+ "%s%s%stest_key_%s.txt", DATA_PATH, NATIVE_TEST_PATH,
+ TESTDATA_PATH, it->c_str());
+ ASSERT_TRUE(load_keys(public_key_file.c_str(), certs));
+ certs.back().hash_len = SHA_DIGEST_LENGTH;
+ }
+ }
+ if (certs.empty()) {
+ std::string public_key_file = android::base::StringPrintf(
+ "%s%s%stest_key_e3.txt", DATA_PATH, NATIVE_TEST_PATH,
+ TESTDATA_PATH);
+ ASSERT_TRUE(load_keys(public_key_file.c_str(), certs));
+ certs.back().hash_len = SHA_DIGEST_LENGTH;
+ }
+ }
+
+ static void SetUpTestCase() {
+ ui = new MockUI();
+ }
+};
+
+class VerifierSuccessTest : public VerifierTest {
+};
+
+class VerifierFailureTest : public VerifierTest {
+};
+
+TEST_P(VerifierSuccessTest, VerifySucceed) {
+ ASSERT_EQ(verify_file(memmap.addr, memmap.length, certs), VERIFY_SUCCESS);
+}
+
+TEST_P(VerifierFailureTest, VerifyFailure) {
+ ASSERT_EQ(verify_file(memmap.addr, memmap.length, certs), VERIFY_FAILURE);
+}
+
+INSTANTIATE_TEST_CASE_P(SingleKeySuccess, VerifierSuccessTest,
+ ::testing::Values(
+ std::vector<std::string>({"otasigned.zip", "e3"}),
+ std::vector<std::string>({"otasigned_f4.zip", "f4"}),
+ std::vector<std::string>({"otasigned_sha256.zip", "e3", "sha256"}),
+ std::vector<std::string>({"otasigned_f4_sha256.zip", "f4", "sha256"}),
+ std::vector<std::string>({"otasigned_ecdsa_sha256.zip", "ec", "sha256"})));
+
+INSTANTIATE_TEST_CASE_P(MultiKeySuccess, VerifierSuccessTest,
+ ::testing::Values(
+ std::vector<std::string>({"otasigned.zip", "f4", "e3"}),
+ std::vector<std::string>({"otasigned_f4.zip", "ec", "f4"}),
+ std::vector<std::string>({"otasigned_sha256.zip", "ec", "e3", "e3", "sha256"}),
+ std::vector<std::string>({"otasigned_f4_sha256.zip", "ec", "sha256", "e3", "f4", "sha256"}),
+ std::vector<std::string>({"otasigned_ecdsa_sha256.zip", "f4", "sha256", "e3", "ec", "sha256"})));
+
+INSTANTIATE_TEST_CASE_P(WrongKey, VerifierFailureTest,
+ ::testing::Values(
+ std::vector<std::string>({"otasigned.zip", "f4"}),
+ std::vector<std::string>({"otasigned_f4.zip", "e3"}),
+ std::vector<std::string>({"otasigned_ecdsa_sha256.zip", "e3", "sha256"})));
+
+INSTANTIATE_TEST_CASE_P(WrongHash, VerifierFailureTest,
+ ::testing::Values(
+ std::vector<std::string>({"otasigned.zip", "e3", "sha256"}),
+ std::vector<std::string>({"otasigned_f4.zip", "f4", "sha256"}),
+ std::vector<std::string>({"otasigned_sha256.zip"}),
+ std::vector<std::string>({"otasigned_f4_sha256.zip", "f4"}),
+ std::vector<std::string>({"otasigned_ecdsa_sha256.zip"})));
+
+INSTANTIATE_TEST_CASE_P(BadPackage, VerifierFailureTest,
+ ::testing::Values(
+ std::vector<std::string>({"random.zip"}),
+ std::vector<std::string>({"fake-eocd.zip"}),
+ std::vector<std::string>({"alter-metadata.zip"}),
+ std::vector<std::string>({"alter-footer.zip"})));
diff --git a/tests/testdata/alter-footer.zip b/tests/testdata/alter-footer.zip
new file mode 100644
index 000000000..f497ec000
--- /dev/null
+++ b/tests/testdata/alter-footer.zip
Binary files differ
diff --git a/tests/testdata/alter-metadata.zip b/tests/testdata/alter-metadata.zip
new file mode 100644
index 000000000..1c71fbc49
--- /dev/null
+++ b/tests/testdata/alter-metadata.zip
Binary files differ
diff --git a/tests/testdata/fake-eocd.zip b/tests/testdata/fake-eocd.zip
new file mode 100644
index 000000000..15dc0a946
--- /dev/null
+++ b/tests/testdata/fake-eocd.zip
Binary files differ
diff --git a/tests/testdata/jarsigned.zip b/tests/testdata/jarsigned.zip
new file mode 100644
index 000000000..8b1ef8bdd
--- /dev/null
+++ b/tests/testdata/jarsigned.zip
Binary files differ
diff --git a/tests/testdata/new.file b/tests/testdata/new.file
new file mode 100644
index 000000000..cdeb8fd50
--- /dev/null
+++ b/tests/testdata/new.file
Binary files differ
diff --git a/tests/testdata/old.file b/tests/testdata/old.file
new file mode 100644
index 000000000..166c8732e
--- /dev/null
+++ b/tests/testdata/old.file
Binary files differ
diff --git a/tests/testdata/otasigned.zip b/tests/testdata/otasigned.zip
new file mode 100644
index 000000000..a6bc53e41
--- /dev/null
+++ b/tests/testdata/otasigned.zip
Binary files differ
diff --git a/tests/testdata/otasigned_ecdsa_sha256.zip b/tests/testdata/otasigned_ecdsa_sha256.zip
new file mode 100644
index 000000000..999fcdd0f
--- /dev/null
+++ b/tests/testdata/otasigned_ecdsa_sha256.zip
Binary files differ
diff --git a/tests/testdata/otasigned_f4.zip b/tests/testdata/otasigned_f4.zip
new file mode 100644
index 000000000..dd1e4dd40
--- /dev/null
+++ b/tests/testdata/otasigned_f4.zip
Binary files differ
diff --git a/tests/testdata/otasigned_f4_sha256.zip b/tests/testdata/otasigned_f4_sha256.zip
new file mode 100644
index 000000000..3af408c40
--- /dev/null
+++ b/tests/testdata/otasigned_f4_sha256.zip
Binary files differ
diff --git a/tests/testdata/otasigned_sha256.zip b/tests/testdata/otasigned_sha256.zip
new file mode 100644
index 000000000..0ed4409b3
--- /dev/null
+++ b/tests/testdata/otasigned_sha256.zip
Binary files differ
diff --git a/tests/testdata/patch.bsdiff b/tests/testdata/patch.bsdiff
new file mode 100644
index 000000000..b78d38573
--- /dev/null
+++ b/tests/testdata/patch.bsdiff
Binary files differ
diff --git a/tests/testdata/random.zip b/tests/testdata/random.zip
new file mode 100644
index 000000000..18c0b3b9f
--- /dev/null
+++ b/tests/testdata/random.zip
Binary files differ
diff --git a/tests/testdata/test_f4.pk8 b/tests/testdata/test_f4.pk8
new file mode 100644
index 000000000..3052613c5
--- /dev/null
+++ b/tests/testdata/test_f4.pk8
Binary files differ
diff --git a/tests/testdata/test_f4.x509.pem b/tests/testdata/test_f4.x509.pem
new file mode 100644
index 000000000..814abcf99
--- /dev/null
+++ b/tests/testdata/test_f4.x509.pem
@@ -0,0 +1,25 @@
+-----BEGIN CERTIFICATE-----
+MIIENjCCAx6gAwIBAgIJAKhkCO1dDYMaMA0GCSqGSIb3DQEBBQUAMG8xCzAJBgNV
+BAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1Nb3VudGFpbiBW
+aWV3MQ8wDQYDVQQKEwZHb29nbGUxEDAOBgNVBAsTB0FuZHJvaWQxEDAOBgNVBAMT
+B1Rlc3QxMjMwHhcNMTIwNzI1MTg1NzAzWhcNMzkxMjExMTg1NzAzWjBvMQswCQYD
+VQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNTW91bnRhaW4g
+VmlldzEPMA0GA1UEChMGR29vZ2xlMRAwDgYDVQQLEwdBbmRyb2lkMRAwDgYDVQQD
+EwdUZXN0MTIzMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAu8WwMN9x
+4Mz7YgkG2qy9g8/kl5ZoYrUM0ApHhaITAcL7RXLZaNipCf0w/YjYTQgj+75MK30x
+TsnPeWNOEwA62gkHrZyyWfxBRO6kBYuIuI4roGDBJOmKQ1OEaDeIRKu7q5V8v3Cs
+0wQDAQWTbhpxBZr9UYFgJUg8XWBfPrGJLVwsoiy4xrMhoTlNZKHfwOMMqVtSHkZX
+qydYrcIzyjh+TO0e/xSNQ8MMRRbtqWgCHN6Rzhog3IHZu0RaPoukariopjXM/s0V
+gTm3rHDHCOpna2pNblyiFlvbkoCs769mtNmx/yrDShO30jg/xaG8RypKDvTChzOT
+oWW/XQ5VEXjbHwIDAQABo4HUMIHRMB0GA1UdDgQWBBRlT2dEZJY1tmUM8mZ0xnhS
+GdD9TTCBoQYDVR0jBIGZMIGWgBRlT2dEZJY1tmUM8mZ0xnhSGdD9TaFzpHEwbzEL
+MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDU1vdW50
+YWluIFZpZXcxDzANBgNVBAoTBkdvb2dsZTEQMA4GA1UECxMHQW5kcm9pZDEQMA4G
+A1UEAxMHVGVzdDEyM4IJAKhkCO1dDYMaMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcN
+AQEFBQADggEBAHqnXHtE+h3hvGmHh24GT51vGAYLc68WUUtCVlMIU85zQ757wlxZ
+BmRypZ1i9hSqnXj5n+mETV5rFX3g2gvdAPVHkRycuDa2aUdZSE8cW4Z6qYFx6SaD
+e+3SyXokpUquW64RuHJrf/yd/FnGjneBe3Qpm2reuzGWNH90qZGdbsfNaCm5kx2L
+X+ZNHM3CcGMLaphY5++sM0JxSEcju5EK33ZYgLf4YdlbyMp8LDFVNd7ff0SFi9fF
+0ZlAsJWoS3QmVCj2744BFdsCu7UHpnYpG6X3MT4SHAawdOaT5zSuaCl2xx6H0O7t
+w/Fvbl/KVD1ZmLHgBKjDMNSh0OB9mSsDWpw=
+-----END CERTIFICATE-----
diff --git a/tests/testdata/test_f4_sha256.x509.pem b/tests/testdata/test_f4_sha256.x509.pem
new file mode 100644
index 000000000..9d5376b45
--- /dev/null
+++ b/tests/testdata/test_f4_sha256.x509.pem
@@ -0,0 +1,25 @@
+-----BEGIN CERTIFICATE-----
+MIIENjCCAx6gAwIBAgIJAKhkCO1dDYMaMA0GCSqGSIb3DQEBCwUAMG8xCzAJBgNV
+BAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1Nb3VudGFpbiBW
+aWV3MQ8wDQYDVQQKEwZHb29nbGUxEDAOBgNVBAsTB0FuZHJvaWQxEDAOBgNVBAMT
+B1Rlc3QxMjMwHhcNMTMwNDEwMTcyMzUyWhcNMTMwNTEwMTcyMzUyWjBvMQswCQYD
+VQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNTW91bnRhaW4g
+VmlldzEPMA0GA1UEChMGR29vZ2xlMRAwDgYDVQQLEwdBbmRyb2lkMRAwDgYDVQQD
+EwdUZXN0MTIzMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAu8WwMN9x
+4Mz7YgkG2qy9g8/kl5ZoYrUM0ApHhaITAcL7RXLZaNipCf0w/YjYTQgj+75MK30x
+TsnPeWNOEwA62gkHrZyyWfxBRO6kBYuIuI4roGDBJOmKQ1OEaDeIRKu7q5V8v3Cs
+0wQDAQWTbhpxBZr9UYFgJUg8XWBfPrGJLVwsoiy4xrMhoTlNZKHfwOMMqVtSHkZX
+qydYrcIzyjh+TO0e/xSNQ8MMRRbtqWgCHN6Rzhog3IHZu0RaPoukariopjXM/s0V
+gTm3rHDHCOpna2pNblyiFlvbkoCs769mtNmx/yrDShO30jg/xaG8RypKDvTChzOT
+oWW/XQ5VEXjbHwIDAQABo4HUMIHRMB0GA1UdDgQWBBRlT2dEZJY1tmUM8mZ0xnhS
+GdD9TTCBoQYDVR0jBIGZMIGWgBRlT2dEZJY1tmUM8mZ0xnhSGdD9TaFzpHEwbzEL
+MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDU1vdW50
+YWluIFZpZXcxDzANBgNVBAoTBkdvb2dsZTEQMA4GA1UECxMHQW5kcm9pZDEQMA4G
+A1UEAxMHVGVzdDEyM4IJAKhkCO1dDYMaMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcN
+AQELBQADggEBAKWWQ9S0V9wWjrMJe8exj1gklwD1Ysi0vi+h2tfixahelrpsNkWi
+EFjoUSHEkW9ThLmtui646uAlwSiWtSn1XkGGmIJ3s+gmAFUcMc0CaK0dgoq/M9zn
+fQ0Vkzc1tK4MLsf+CbPDywPycb6+T3dBkerbWn9GUpjGl1ANWlciXZZ3657m61sL
+HhwUOBxbZZ6sYP4ed2SVCf45GgMyJ0VoUg5yI2JzPAgOkGfeEIPVXE1M94edJY4G
+8eHYvXovJZwXvKFI+ZyS0KBPx8cpfw89RB9qmkxqNBIm8qWb3qBiuBEIPj+NF/7w
+sC/Fv8NNXkVquy0xa0qdyJBABzWE18zGcXs=
+-----END CERTIFICATE-----
diff --git a/tests/testdata/test_key_e3.txt b/tests/testdata/test_key_e3.txt
new file mode 100644
index 000000000..53f5297bd
--- /dev/null
+++ b/tests/testdata/test_key_e3.txt
@@ -0,0 +1 @@
+{64,0xc926ad21,{1795090719,2141396315,950055447,2581568430,4268923165,1920809988,546586521,3498997798,1776797858,3740060814,1805317999,1429410244,129622599,1422441418,1783893377,1222374759,2563319927,323993566,28517732,609753416,1826472888,215237850,4261642700,4049082591,3228462402,774857746,154822455,2497198897,2758199418,3019015328,2794777644,87251430,2534927978,120774784,571297800,3695899472,2479925187,3811625450,3401832990,2394869647,3267246207,950095497,555058928,414729973,1136544882,3044590084,465547824,4058146728,2731796054,1689838846,3890756939,1048029507,895090649,247140249,178744550,3547885223,3165179243,109881576,3944604415,1044303212,3772373029,2985150306,3737520932,3599964420},{3437017481,3784475129,2800224972,3086222688,251333580,2131931323,512774938,325948880,2657486437,2102694287,3820568226,792812816,1026422502,2053275343,2800889200,3113586810,165549746,4273519969,4065247892,1902789247,772932719,3941848426,3652744109,216871947,3164400649,1942378755,3996765851,1055777370,964047799,629391717,2232744317,3910558992,191868569,2758883837,3682816752,2997714732,2702529250,3570700455,3776873832,3924067546,3555689545,2758825434,1323144535,61311905,1997411085,376844204,213777604,4077323584,9135381,1625809335,2804742137,2952293945,1117190829,4237312782,1825108855,3013147971,1111251351,2568837572,1684324211,2520978805,367251975,810756730,2353784344,1175080310}}
diff --git a/tests/testdata/test_key_ec.txt b/tests/testdata/test_key_ec.txt
new file mode 100644
index 000000000..72b4395d9
--- /dev/null
+++ b/tests/testdata/test_key_ec.txt
@@ -0,0 +1 @@
+v5 {32,{36,250,86,214,202,22,20,147,198,120,2,28,76,190,78,23,106,35,24,96,86,22,186,69,132,93,192,232,0,213,14,103},{222,154,23,13,125,130,22,76,146,185,140,159,138,255,105,143,32,16,27,72,175,145,141,121,233,184,77,24,217,141,132,181}}
diff --git a/tests/testdata/test_key_f4.txt b/tests/testdata/test_key_f4.txt
new file mode 100644
index 000000000..54ddbbad1
--- /dev/null
+++ b/tests/testdata/test_key_f4.txt
@@ -0,0 +1 @@
+v2 {64,0xc9bd1f21,{293133087,3210546773,865313125,250921607,3158780490,943703457,1242806226,2986289859,2942743769,2457906415,2719374299,1783459420,149579627,3081531591,3440738617,2788543742,2758457512,1146764939,3699497403,2446203424,1744968926,1159130537,2370028300,3978231572,3392699980,1487782451,1180150567,2841334302,3753960204,961373345,3333628321,748825784,2978557276,1566596926,1613056060,2600292737,1847226629,50398611,1890374404,2878700735,2286201787,1401186359,619285059,731930817,2340993166,1156490245,2992241729,151498140,318782170,3480838990,2100383433,4223552555,3628927011,4247846280,1759029513,4215632601,2719154626,3490334597,1751299340,3487864726,3668753795,4217506054,3748782284,3150295088},{1772626313,445326068,3477676155,1758201194,2986784722,491035581,3922936562,702212696,2979856666,3324974564,2488428922,3056318590,1626954946,664714029,398585816,3964097931,3356701905,2298377729,2040082097,3025491477,539143308,3348777868,2995302452,3602465520,212480763,2691021393,1307177300,704008044,2031136606,1054106474,3838318865,2441343869,1477566916,700949900,2534790355,3353533667,336163563,4106790558,2701448228,1571536379,1103842411,3623110423,1635278839,1577828979,910322800,715583630,138128831,1017877531,2289162787,447994798,1897243165,4121561445,4150719842,2131821093,2262395396,3305771534,980753571,3256525190,3128121808,1072869975,3507939515,4229109952,118381341,2209831334}}
diff --git a/tests/testdata/testkey.pk8 b/tests/testdata/testkey.pk8
new file mode 100644
index 000000000..586c1bd5c
--- /dev/null
+++ b/tests/testdata/testkey.pk8
Binary files differ
diff --git a/tests/testdata/testkey.x509.pem b/tests/testdata/testkey.x509.pem
new file mode 100644
index 000000000..e242d83e2
--- /dev/null
+++ b/tests/testdata/testkey.x509.pem
@@ -0,0 +1,27 @@
+-----BEGIN CERTIFICATE-----
+MIIEqDCCA5CgAwIBAgIJAJNurL4H8gHfMA0GCSqGSIb3DQEBBQUAMIGUMQswCQYD
+VQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNTW91bnRhaW4g
+VmlldzEQMA4GA1UEChMHQW5kcm9pZDEQMA4GA1UECxMHQW5kcm9pZDEQMA4GA1UE
+AxMHQW5kcm9pZDEiMCAGCSqGSIb3DQEJARYTYW5kcm9pZEBhbmRyb2lkLmNvbTAe
+Fw0wODAyMjkwMTMzNDZaFw0zNTA3MTcwMTMzNDZaMIGUMQswCQYDVQQGEwJVUzET
+MBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzEQMA4G
+A1UEChMHQW5kcm9pZDEQMA4GA1UECxMHQW5kcm9pZDEQMA4GA1UEAxMHQW5kcm9p
+ZDEiMCAGCSqGSIb3DQEJARYTYW5kcm9pZEBhbmRyb2lkLmNvbTCCASAwDQYJKoZI
+hvcNAQEBBQADggENADCCAQgCggEBANaTGQTexgskse3HYuDZ2CU+Ps1s6x3i/waM
+qOi8qM1r03hupwqnbOYOuw+ZNVn/2T53qUPn6D1LZLjk/qLT5lbx4meoG7+yMLV4
+wgRDvkxyGLhG9SEVhvA4oU6Jwr44f46+z4/Kw9oe4zDJ6pPQp8PcSvNQIg1QCAcy
+4ICXF+5qBTNZ5qaU7Cyz8oSgpGbIepTYOzEJOmc3Li9kEsBubULxWBjf/gOBzAzU
+RNps3cO4JFgZSAGzJWQTT7/emMkod0jb9WdqVA2BVMi7yge54kdVMxHEa5r3b97s
+zI5p58ii0I54JiCUP5lyfTwE/nKZHZnfm644oLIXf6MdW2r+6R8CAQOjgfwwgfkw
+HQYDVR0OBBYEFEhZAFY9JyxGrhGGBaR0GawJyowRMIHJBgNVHSMEgcEwgb6AFEhZ
+AFY9JyxGrhGGBaR0GawJyowRoYGapIGXMIGUMQswCQYDVQQGEwJVUzETMBEGA1UE
+CBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzEQMA4GA1UEChMH
+QW5kcm9pZDEQMA4GA1UECxMHQW5kcm9pZDEQMA4GA1UEAxMHQW5kcm9pZDEiMCAG
+CSqGSIb3DQEJARYTYW5kcm9pZEBhbmRyb2lkLmNvbYIJAJNurL4H8gHfMAwGA1Ud
+EwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAHqvlozrUMRBBVEY0NqrrwFbinZa
+J6cVosK0TyIUFf/azgMJWr+kLfcHCHJsIGnlw27drgQAvilFLAhLwn62oX6snb4Y
+LCBOsVMR9FXYJLZW2+TcIkCRLXWG/oiVHQGo/rWuWkJgU134NDEFJCJGjDbiLCpe
++ZTWHdcwauTJ9pUbo8EvHRkU3cYfGmLaLfgn9gP+pWA7LFQNvXwBnDa6sppCccEX
+31I828XzgXpJ4O+mDL1/dBd+ek8ZPUP0IgdyZm5MTYPhvVqGCHzzTy3sIeJFymwr
+sBbmg2OAUNLEMO6nwmocSdN2ClirfxqCzJOLSDE4QyS9BAH6EhY6UFcOaE0=
+-----END CERTIFICATE-----
diff --git a/tests/testdata/testkey_ecdsa.pk8 b/tests/testdata/testkey_ecdsa.pk8
new file mode 100644
index 000000000..9a521c8cf
--- /dev/null
+++ b/tests/testdata/testkey_ecdsa.pk8
Binary files differ
diff --git a/tests/testdata/testkey_ecdsa.x509.pem b/tests/testdata/testkey_ecdsa.x509.pem
new file mode 100644
index 000000000..b12283645
--- /dev/null
+++ b/tests/testdata/testkey_ecdsa.x509.pem
@@ -0,0 +1,10 @@
+-----BEGIN CERTIFICATE-----
+MIIBezCCASACCQC4g5wurPSmtzAKBggqhkjOPQQDAjBFMQswCQYDVQQGEwJBVTET
+MBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0cyBQ
+dHkgTHRkMB4XDTEzMTAwODIxMTAxM1oXDTE0MTAwODIxMTAxM1owRTELMAkGA1UE
+BhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdp
+ZGdpdHMgUHR5IEx0ZDBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABGcO1QDowF2E
+RboWVmAYI2oXTr5MHAJ4xpMUFsrWVvoktYSN2RhNuOl5jZGvSBsQII9p/4qfjLmS
+TBaCfQ0Xmt4wCgYIKoZIzj0EAwIDSQAwRgIhAIJjWmZAwngc2VcHUhYp2oSLoCQ+
+P+7AtbAn5242AqfOAiEAghO0t6jTKs0LUhLJrQwbOkHyZMVdZaG2vcwV9y9H5Qc=
+-----END CERTIFICATE-----
diff --git a/tests/testdata/testkey_sha256.x509.pem b/tests/testdata/testkey_sha256.x509.pem
new file mode 100644
index 000000000..002ce8968
--- /dev/null
+++ b/tests/testdata/testkey_sha256.x509.pem
@@ -0,0 +1,27 @@
+-----BEGIN CERTIFICATE-----
+MIIEqDCCA5CgAwIBAgIJAJNurL4H8gHfMA0GCSqGSIb3DQEBCwUAMIGUMQswCQYD
+VQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNTW91bnRhaW4g
+VmlldzEQMA4GA1UEChMHQW5kcm9pZDEQMA4GA1UECxMHQW5kcm9pZDEQMA4GA1UE
+AxMHQW5kcm9pZDEiMCAGCSqGSIb3DQEJARYTYW5kcm9pZEBhbmRyb2lkLmNvbTAe
+Fw0xMzA0MTAxODA1MzZaFw0xMzA1MTAxODA1MzZaMIGUMQswCQYDVQQGEwJVUzET
+MBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzEQMA4G
+A1UEChMHQW5kcm9pZDEQMA4GA1UECxMHQW5kcm9pZDEQMA4GA1UEAxMHQW5kcm9p
+ZDEiMCAGCSqGSIb3DQEJARYTYW5kcm9pZEBhbmRyb2lkLmNvbTCCASAwDQYJKoZI
+hvcNAQEBBQADggENADCCAQgCggEBANaTGQTexgskse3HYuDZ2CU+Ps1s6x3i/waM
+qOi8qM1r03hupwqnbOYOuw+ZNVn/2T53qUPn6D1LZLjk/qLT5lbx4meoG7+yMLV4
+wgRDvkxyGLhG9SEVhvA4oU6Jwr44f46+z4/Kw9oe4zDJ6pPQp8PcSvNQIg1QCAcy
+4ICXF+5qBTNZ5qaU7Cyz8oSgpGbIepTYOzEJOmc3Li9kEsBubULxWBjf/gOBzAzU
+RNps3cO4JFgZSAGzJWQTT7/emMkod0jb9WdqVA2BVMi7yge54kdVMxHEa5r3b97s
+zI5p58ii0I54JiCUP5lyfTwE/nKZHZnfm644oLIXf6MdW2r+6R8CAQOjgfwwgfkw
+HQYDVR0OBBYEFEhZAFY9JyxGrhGGBaR0GawJyowRMIHJBgNVHSMEgcEwgb6AFEhZ
+AFY9JyxGrhGGBaR0GawJyowRoYGapIGXMIGUMQswCQYDVQQGEwJVUzETMBEGA1UE
+CBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzEQMA4GA1UEChMH
+QW5kcm9pZDEQMA4GA1UECxMHQW5kcm9pZDEQMA4GA1UEAxMHQW5kcm9pZDEiMCAG
+CSqGSIb3DQEJARYTYW5kcm9pZEBhbmRyb2lkLmNvbYIJAJNurL4H8gHfMAwGA1Ud
+EwQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAKRVj9hOaozH1W8Wb4CNj7sCWixh
+UMMZJXkxUtvUVHZGefp6MdtYiD/ZM7YRwZphm9aNhkykbHJdZ3lPzeL2csCa+sDQ
+8sIzGu0/aD6p4zgIKQZmz0mZHqPGbHoLWOmA9EexRCFZ7vO/kO56ZbyhfFz2DI3S
+Yez65CabErOFhNX6WukSPbV3zfsHRDD5JUStb/ko6t99HXsvIO0Ax9poj60PpCC1
+SiFzHZUY9mOnUfJFs+3NWCwKtP9nho3mZ3pJ1i+SeF6JiqbE3KHl4CDBeVGcu3CK
+fiUZ8e8iXVN471Cgc5GD6Ud1pS7ifNZJsKhbETQ63KmvHCLRPi4NmP67uDE=
+-----END CERTIFICATE-----
diff --git a/tests/testdata/unsigned.zip b/tests/testdata/unsigned.zip
new file mode 100644
index 000000000..24e3eadac
--- /dev/null
+++ b/tests/testdata/unsigned.zip
Binary files differ
diff --git a/tests/asn1_decoder_test.cpp b/tests/unit/asn1_decoder_test.cpp
index af96d87d2..af96d87d2 100644
--- a/tests/asn1_decoder_test.cpp
+++ b/tests/unit/asn1_decoder_test.cpp
diff --git a/tests/unit/locale_test.cpp b/tests/unit/locale_test.cpp
new file mode 100644
index 000000000..0e515f8c1
--- /dev/null
+++ b/tests/unit/locale_test.cpp
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <gtest/gtest.h>
+
+#include "minui/minui.h"
+
+TEST(LocaleTest, Misc) {
+ EXPECT_TRUE(matches_locale("zh_CN", "zh_CN_#Hans"));
+ EXPECT_TRUE(matches_locale("zh", "zh_CN_#Hans"));
+ EXPECT_FALSE(matches_locale("zh_HK", "zh_CN_#Hans"));
+ EXPECT_TRUE(matches_locale("en_GB", "en_GB"));
+ EXPECT_TRUE(matches_locale("en", "en_GB"));
+ EXPECT_FALSE(matches_locale("en_GB", "en"));
+ EXPECT_FALSE(matches_locale("en_GB", "en_US"));
+}
diff --git a/tests/unit/recovery_test.cpp b/tests/unit/recovery_test.cpp
new file mode 100644
index 000000000..f397f258e
--- /dev/null
+++ b/tests/unit/recovery_test.cpp
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <fcntl.h>
+#include <string.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <android/log.h>
+#include <gtest/gtest.h>
+#include <log/logger.h>
+#include <private/android_logger.h>
+
+static const char myFilename[] = "/data/misc/recovery/inject.txt";
+static const char myContent[] = "Hello World\nWelcome to my recovery\n";
+
+// Failure is expected on systems that do not deliver either the
+// recovery-persist or recovery-refresh executables. Tests also require
+// a reboot sequence of test to truly verify.
+
+static ssize_t __pmsg_fn(log_id_t logId, char prio, const char *filename,
+ const char *buf, size_t len, void *arg) {
+ EXPECT_EQ(LOG_ID_SYSTEM, logId);
+ EXPECT_EQ(ANDROID_LOG_INFO, prio);
+ EXPECT_EQ(0, NULL == strstr(myFilename,filename));
+ EXPECT_EQ(0, strcmp(myContent, buf));
+ EXPECT_EQ(sizeof(myContent), len);
+ EXPECT_EQ(0, NULL != arg);
+ return len;
+}
+
+// recovery.refresh - May fail. Requires recovery.inject, two reboots,
+// then expect success after second reboot.
+TEST(recovery, refresh) {
+ EXPECT_EQ(0, access("/system/bin/recovery-refresh", F_OK));
+
+ ssize_t ret = __android_log_pmsg_file_read(
+ LOG_ID_SYSTEM, ANDROID_LOG_INFO, "recovery/", __pmsg_fn, NULL);
+ if (ret == -ENOENT) {
+ EXPECT_LT(0, __android_log_pmsg_file_write(
+ LOG_ID_SYSTEM, ANDROID_LOG_INFO,
+ myFilename, myContent, sizeof(myContent)));
+ fprintf(stderr, "injected test data, "
+ "requires two intervening reboots "
+ "to check for replication\n");
+ }
+ EXPECT_EQ((ssize_t)sizeof(myContent), ret);
+}
+
+// recovery.persist - Requires recovery.inject, then a reboot, then
+// expect success after for this test on that boot.
+TEST(recovery, persist) {
+ EXPECT_EQ(0, access("/system/bin/recovery-persist", F_OK));
+
+ ssize_t ret = __android_log_pmsg_file_read(
+ LOG_ID_SYSTEM, ANDROID_LOG_INFO, "recovery/", __pmsg_fn, NULL);
+ if (ret == -ENOENT) {
+ EXPECT_LT(0, __android_log_pmsg_file_write(
+ LOG_ID_SYSTEM, ANDROID_LOG_INFO,
+ myFilename, myContent, sizeof(myContent)));
+ fprintf(stderr, "injected test data, "
+ "requires intervening reboot "
+ "to check for storage\n");
+ }
+
+ int fd = open(myFilename, O_RDONLY);
+ EXPECT_LE(0, fd);
+
+ char buf[sizeof(myContent) + 32];
+ ret = read(fd, buf, sizeof(buf));
+ close(fd);
+ EXPECT_EQ(ret, (ssize_t)sizeof(myContent));
+ EXPECT_EQ(0, strcmp(myContent, buf));
+ if (fd >= 0) {
+ fprintf(stderr, "Removing persistent test data, "
+ "check if reconstructed on reboot\n");
+ }
+ EXPECT_EQ(0, unlink(myFilename));
+}