diff options
Diffstat (limited to 'tests')
-rw-r--r-- | tests/Android.mk | 58 | ||||
-rw-r--r-- | tests/component/applypatch_test.cpp | 139 | ||||
-rw-r--r-- | tests/component/edify_test.cpp | 169 | ||||
-rw-r--r-- | tests/component/updater_test.cpp | 99 | ||||
-rw-r--r-- | tests/component/verifier_test.cpp | 89 | ||||
-rw-r--r-- | tests/testdata/otasigned_v1.zip (renamed from tests/testdata/otasigned.zip) | bin | 4009 -> 4009 bytes | |||
-rw-r--r-- | tests/testdata/otasigned_v2.zip (renamed from tests/testdata/otasigned_f4.zip) | bin | 5195 -> 5195 bytes | |||
-rw-r--r-- | tests/testdata/otasigned_v3.zip (renamed from tests/testdata/otasigned_sha256.zip) | bin | 5326 -> 5326 bytes | |||
-rw-r--r-- | tests/testdata/otasigned_v4.zip (renamed from tests/testdata/otasigned_f4_sha256.zip) | bin | 5319 -> 5319 bytes | |||
-rw-r--r-- | tests/testdata/otasigned_v5.zip (renamed from tests/testdata/otasigned_ecdsa_sha256.zip) | bin | 3085 -> 3085 bytes | |||
-rw-r--r-- | tests/testdata/testkey_v1.pk8 (renamed from tests/testdata/testkey.pk8) | bin | 1217 -> 1217 bytes | |||
-rw-r--r-- | tests/testdata/testkey_v1.txt (renamed from tests/testdata/test_key_e3.txt) | 0 | ||||
-rw-r--r-- | tests/testdata/testkey_v1.x509.pem (renamed from tests/testdata/testkey.x509.pem) | 0 | ||||
-rw-r--r-- | tests/testdata/testkey_v2.pk8 (renamed from tests/testdata/test_f4.pk8) | bin | 1217 -> 1217 bytes | |||
-rw-r--r-- | tests/testdata/testkey_v2.txt (renamed from tests/testdata/test_key_f4.txt) | 0 | ||||
-rw-r--r-- | tests/testdata/testkey_v2.x509.pem (renamed from tests/testdata/test_f4.x509.pem) | 0 | ||||
l--------- | tests/testdata/testkey_v3.pk8 | 1 | ||||
-rw-r--r-- | tests/testdata/testkey_v3.txt | 1 | ||||
-rw-r--r-- | tests/testdata/testkey_v3.x509.pem (renamed from tests/testdata/testkey_sha256.x509.pem) | 0 | ||||
l--------- | tests/testdata/testkey_v4.pk8 | 1 | ||||
-rw-r--r-- | tests/testdata/testkey_v4.txt | 1 | ||||
-rw-r--r-- | tests/testdata/testkey_v4.x509.pem (renamed from tests/testdata/test_f4_sha256.x509.pem) | 0 | ||||
-rw-r--r-- | tests/testdata/testkey_v5.pk8 (renamed from tests/testdata/testkey_ecdsa.pk8) | bin | 138 -> 138 bytes | |||
-rw-r--r-- | tests/testdata/testkey_v5.txt (renamed from tests/testdata/test_key_ec.txt) | 0 | ||||
-rw-r--r-- | tests/testdata/testkey_v5.x509.pem (renamed from tests/testdata/testkey_ecdsa.x509.pem) | 0 | ||||
-rw-r--r-- | tests/testdata/ziptest_dummy-update.zip | bin | 0 -> 1090065 bytes | |||
-rw-r--r-- | tests/testdata/ziptest_valid.zip | bin | 0 -> 758 bytes | |||
-rw-r--r-- | tests/unit/recovery_test.cpp | 1 | ||||
-rw-r--r-- | tests/unit/zip_test.cpp | 93 |
29 files changed, 516 insertions, 136 deletions
diff --git a/tests/Android.mk b/tests/Android.mk index a66991b21..3d05386b0 100644 --- a/tests/Android.mk +++ b/tests/Android.mk @@ -19,15 +19,23 @@ LOCAL_PATH := $(call my-dir) # Unit tests include $(CLEAR_VARS) LOCAL_CLANG := true +LOCAL_CFLAGS := -Werror LOCAL_MODULE := recovery_unit_test LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk LOCAL_STATIC_LIBRARIES := \ libverifier \ - libminui + libminui \ + libotautil \ + libziparchive \ + libutils \ + libz \ + libselinux \ + libbase LOCAL_SRC_FILES := unit/asn1_decoder_test.cpp LOCAL_SRC_FILES += unit/recovery_test.cpp LOCAL_SRC_FILES += unit/locale_test.cpp +LOCAL_SRC_FILES += unit/zip_test.cpp LOCAL_C_INCLUDES := bootable/recovery LOCAL_SHARED_LIBRARIES := liblog include $(BUILD_NATIVE_TEST) @@ -35,35 +43,65 @@ include $(BUILD_NATIVE_TEST) # Component tests include $(CLEAR_VARS) LOCAL_CLANG := true -LOCAL_CFLAGS += -Wno-unused-parameter +LOCAL_CFLAGS += -Wno-unused-parameter -Werror 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 + component/applypatch_test.cpp \ + component/edify_test.cpp \ + component/updater_test.cpp \ + component/verifier_test.cpp LOCAL_FORCE_STATIC_EXECUTABLE := true + +tune2fs_static_libraries := \ + libext2_com_err \ + libext2_blkid \ + libext2_quota \ + libext2_uuid_static \ + libext2_e2p \ + libext2fs + LOCAL_STATIC_LIBRARIES := \ libapplypatch \ + libedify \ libotafault \ - libmtdutils \ - libbase \ + libupdater \ libverifier \ - libcrypto_static \ libminui \ - libminzip \ + libotautil \ + libmounts \ + liblog \ + libselinux \ + libext4_utils_static \ + libsparse_static \ + libcrypto_utils \ + libcrypto \ libcutils \ libbz \ libz \ - libc + libbase \ + libtune2fs \ + $(tune2fs_static_libraries) -testdata_out_path := $(TARGET_OUT_DATA_NATIVE_TESTS)/recovery testdata_files := $(call find-subdir-files, testdata/*) +testdata_out_path := $(TARGET_OUT_DATA_NATIVE_TESTS)/recovery 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) + +ifdef TARGET_2ND_ARCH +testdata_out_path_2nd_arch := $($(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_DATA_NATIVE_TESTS)/recovery +GEN_2ND_ARCH := $(addprefix $(testdata_out_path_2nd_arch)/, $(testdata_files)) +$(GEN_2ND_ARCH): PRIVATE_PATH := $(LOCAL_PATH) +$(GEN_2ND_ARCH): PRIVATE_CUSTOM_TOOL = cp $< $@ +$(GEN_2ND_ARCH): $(testdata_out_path_2nd_arch)/% : $(LOCAL_PATH)/% + $(transform-generated-source) +LOCAL_GENERATED_SOURCES += $(GEN_2ND_ARCH) +endif # TARGET_2ND_ARCH + include $(BUILD_NATIVE_TEST) diff --git a/tests/component/applypatch_test.cpp b/tests/component/applypatch_test.cpp index b44ddd17c..908a9f5f5 100644 --- a/tests/component/applypatch_test.cpp +++ b/tests/component/applypatch_test.cpp @@ -65,7 +65,7 @@ static bool file_cmp(std::string& f1, std::string& f2) { return c1 == c2; } -static std::string from_testdata_base(const std::string fname) { +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], @@ -153,25 +153,16 @@ class ApplyPatchFullTest : public ApplyPatchCacheTest { 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()); + Value* patch1 = new Value(VAL_BLOB, std::string(fc.data.begin(), fc.data.end())); 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()); + Value* patch2 = new Value(VAL_BLOB, std::string(fc.data.begin(), fc.data.end())); 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(); @@ -209,89 +200,93 @@ std::vector<Value*> ApplyPatchFullTest::patches; TemporaryFile* ApplyPatchFullTest::output_f; std::string ApplyPatchFullTest::output_loc; +TEST_F(ApplyPatchTest, CheckModeSkip) { + std::vector<std::string> sha1s; + ASSERT_EQ(0, applypatch_check(&old_file[0], sha1s)); +} + TEST_F(ApplyPatchTest, CheckModeSingle) { - char* s = &old_sha1[0]; - ASSERT_EQ(0, applypatch_check(&old_file[0], 1, &s)); + std::vector<std::string> sha1s = { old_sha1 }; + ASSERT_EQ(0, applypatch_check(&old_file[0], sha1s)); } TEST_F(ApplyPatchTest, CheckModeMultiple) { - char* argv[3] = { - &bad_sha1_a[0], - &old_sha1[0], - &bad_sha1_b[0] + std::vector<std::string> sha1s = { + bad_sha1_a, + old_sha1, + bad_sha1_b }; - ASSERT_EQ(0, applypatch_check(&old_file[0], 3, argv)); + ASSERT_EQ(0, applypatch_check(&old_file[0], sha1s)); } TEST_F(ApplyPatchTest, CheckModeFailure) { - char* argv[2] = { - &bad_sha1_a[0], - &bad_sha1_b[0] + std::vector<std::string> sha1s = { + bad_sha1_a, + bad_sha1_b }; - ASSERT_NE(0, applypatch_check(&old_file[0], 2, argv)); + ASSERT_NE(0, applypatch_check(&old_file[0], sha1s)); } TEST_F(ApplyPatchCacheTest, CheckCacheCorruptedSingle) { mangle_file(old_file); - char* s = &old_sha1[0]; - ASSERT_EQ(0, applypatch_check(&old_file[0], 1, &s)); + std::vector<std::string> sha1s = { old_sha1 }; + ASSERT_EQ(0, applypatch_check(&old_file[0], sha1s)); } TEST_F(ApplyPatchCacheTest, CheckCacheCorruptedMultiple) { mangle_file(old_file); - char* argv[3] = { - &bad_sha1_a[0], - &old_sha1[0], - &bad_sha1_b[0] + std::vector<std::string> sha1s = { + bad_sha1_a, + old_sha1, + bad_sha1_b }; - ASSERT_EQ(0, applypatch_check(&old_file[0], 3, argv)); + ASSERT_EQ(0, applypatch_check(&old_file[0], sha1s)); } TEST_F(ApplyPatchCacheTest, CheckCacheCorruptedFailure) { mangle_file(old_file); - char* argv[2] = { - &bad_sha1_a[0], - &bad_sha1_b[0] + std::vector<std::string> sha1s = { + bad_sha1_a, + bad_sha1_b }; - ASSERT_NE(0, applypatch_check(&old_file[0], 2, argv)); + ASSERT_NE(0, applypatch_check(&old_file[0], sha1s)); } TEST_F(ApplyPatchCacheTest, CheckCacheMissingSingle) { unlink(&old_file[0]); - char* s = &old_sha1[0]; - ASSERT_EQ(0, applypatch_check(&old_file[0], 1, &s)); + std::vector<std::string> sha1s = { old_sha1 }; + ASSERT_EQ(0, applypatch_check(&old_file[0], sha1s)); } TEST_F(ApplyPatchCacheTest, CheckCacheMissingMultiple) { unlink(&old_file[0]); - char* argv[3] = { - &bad_sha1_a[0], - &old_sha1[0], - &bad_sha1_b[0] + std::vector<std::string> sha1s = { + bad_sha1_a, + old_sha1, + bad_sha1_b }; - ASSERT_EQ(0, applypatch_check(&old_file[0], 3, argv)); + ASSERT_EQ(0, applypatch_check(&old_file[0], sha1s)); } TEST_F(ApplyPatchCacheTest, CheckCacheMissingFailure) { unlink(&old_file[0]); - char* argv[2] = { - &bad_sha1_a[0], - &bad_sha1_b[0] + std::vector<std::string> sha1s = { + bad_sha1_a, + bad_sha1_b }; - ASSERT_NE(0, applypatch_check(&old_file[0], 2, argv)); + ASSERT_NE(0, applypatch_check(&old_file[0], sha1s)); } TEST_F(ApplyPatchFullTest, ApplyInPlace) { - std::vector<char*> sha1s; - sha1s.push_back(&bad_sha1_a[0]); - sha1s.push_back(&old_sha1[0]); - + std::vector<std::string> sha1s = { + bad_sha1_a, + old_sha1 + }; int ap_result = applypatch(&old_file[0], "-", &new_sha1[0], new_size, - 2, - sha1s.data(), + sha1s, patches.data(), nullptr); ASSERT_EQ(0, ap_result); @@ -301,8 +296,7 @@ TEST_F(ApplyPatchFullTest, ApplyInPlace) { "-", &new_sha1[0], new_size, - 2, - sha1s.data(), + sha1s, patches.data(), nullptr); ASSERT_EQ(0, ap_result); @@ -310,15 +304,15 @@ TEST_F(ApplyPatchFullTest, ApplyInPlace) { } TEST_F(ApplyPatchFullTest, ApplyInNewLocation) { - std::vector<char*> sha1s; - sha1s.push_back(&bad_sha1_a[0]); - sha1s.push_back(&old_sha1[0]); + std::vector<std::string> sha1s = { + bad_sha1_a, + old_sha1 + }; int ap_result = applypatch(&old_file[0], &output_loc[0], &new_sha1[0], new_size, - 2, - sha1s.data(), + sha1s, patches.data(), nullptr); ASSERT_EQ(0, ap_result); @@ -327,8 +321,7 @@ TEST_F(ApplyPatchFullTest, ApplyInNewLocation) { &output_loc[0], &new_sha1[0], new_size, - 2, - sha1s.data(), + sha1s, patches.data(), nullptr); ASSERT_EQ(0, ap_result); @@ -337,15 +330,15 @@ TEST_F(ApplyPatchFullTest, ApplyInNewLocation) { 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]); + std::vector<std::string> sha1s = { + bad_sha1_a, + old_sha1 + }; int ap_result = applypatch(&old_file[0], &output_loc[0], &new_sha1[0], new_size, - 2, - sha1s.data(), + sha1s, patches.data(), nullptr); ASSERT_EQ(0, ap_result); @@ -354,8 +347,7 @@ TEST_F(ApplyPatchFullTest, ApplyCorruptedInNewLocation) { &output_loc[0], &new_sha1[0], new_size, - 2, - sha1s.data(), + sha1s, patches.data(), nullptr); ASSERT_EQ(0, ap_result); @@ -366,15 +358,15 @@ 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]); + std::vector<std::string> sha1s = { + bad_sha1_a, + old_sha1 + }; int ap_result = applypatch(&old_file[0], &output_loc[0], &new_sha1[0], new_size, - 2, - sha1s.data(), + sha1s, patches.data(), nullptr); ASSERT_NE(0, ap_result); @@ -383,8 +375,7 @@ TEST_F(ApplyPatchDoubleCacheTest, ApplyDoubleCorruptedInNewLocation) { &output_loc[0], &new_sha1[0], new_size, - 2, - sha1s.data(), + sha1s, patches.data(), nullptr); ASSERT_NE(0, ap_result); diff --git a/tests/component/edify_test.cpp b/tests/component/edify_test.cpp new file mode 100644 index 000000000..287e40cc6 --- /dev/null +++ b/tests/component/edify_test.cpp @@ -0,0 +1,169 @@ +/* + * 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 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 <string> + +#include <gtest/gtest.h> + +#include "edify/expr.h" + +static void expect(const char* expr_str, const char* expected) { + Expr* e; + int error_count = 0; + EXPECT_EQ(0, parse_string(expr_str, &e, &error_count)); + EXPECT_EQ(0, error_count); + + State state(expr_str, nullptr); + + std::string result; + bool status = Evaluate(&state, e, &result); + + if (expected == nullptr) { + EXPECT_FALSE(status); + } else { + EXPECT_STREQ(expected, result.c_str()); + } + +} + +class EdifyTest : public ::testing::Test { + protected: + virtual void SetUp() { + RegisterBuiltins(); + } +}; + +TEST_F(EdifyTest, parsing) { + expect("a", "a"); + expect("\"a\"", "a"); + expect("\"\\x61\"", "a"); + expect("# this is a comment\n" + " a\n" + " \n", + "a"); +} + +TEST_F(EdifyTest, sequence) { + // sequence operator + expect("a; b; c", "c"); +} + +TEST_F(EdifyTest, concat) { + // string concat operator + expect("a + b", "ab"); + expect("a + \n \"b\"", "ab"); + expect("a + b +\nc\n", "abc"); + + // string concat function + expect("concat(a, b)", "ab"); + expect("concat(a,\n \"b\")", "ab"); + expect("concat(a + b,\nc,\"d\")", "abcd"); + expect("\"concat\"(a + b,\nc,\"d\")", "abcd"); +} + +TEST_F(EdifyTest, logical) { + // logical and + expect("a && b", "b"); + expect("a && \"\"", ""); + expect("\"\" && b", ""); + expect("\"\" && \"\"", ""); + expect("\"\" && abort()", ""); // test short-circuiting + expect("t && abort()", nullptr); + + // logical or + expect("a || b", "a"); + expect("a || \"\"", "a"); + expect("\"\" || b", "b"); + expect("\"\" || \"\"", ""); + expect("a || abort()", "a"); // test short-circuiting + expect("\"\" || abort()", NULL); + + // logical not + expect("!a", ""); + expect("! \"\"", "t"); + expect("!!a", "t"); +} + +TEST_F(EdifyTest, precedence) { + // precedence + expect("\"\" == \"\" && b", "b"); + expect("a + b == ab", "t"); + expect("ab == a + b", "t"); + expect("a + (b == ab)", "a"); + expect("(ab == a) + b", "b"); +} + +TEST_F(EdifyTest, substring) { + // substring function + expect("is_substring(cad, abracadabra)", "t"); + expect("is_substring(abrac, abracadabra)", "t"); + expect("is_substring(dabra, abracadabra)", "t"); + expect("is_substring(cad, abracxadabra)", ""); + expect("is_substring(abrac, axbracadabra)", ""); + expect("is_substring(dabra, abracadabrxa)", ""); +} + +TEST_F(EdifyTest, ifelse) { + // ifelse function + expect("ifelse(t, yes, no)", "yes"); + expect("ifelse(!t, yes, no)", "no"); + expect("ifelse(t, yes, abort())", "yes"); + expect("ifelse(!t, abort(), no)", "no"); +} + +TEST_F(EdifyTest, if_statement) { + // if "statements" + expect("if t then yes else no endif", "yes"); + expect("if \"\" then yes else no endif", "no"); + expect("if \"\" then yes endif", ""); + expect("if \"\"; t then yes endif", "yes"); +} + +TEST_F(EdifyTest, comparison) { + // numeric comparisons + expect("less_than_int(3, 14)", "t"); + expect("less_than_int(14, 3)", ""); + expect("less_than_int(x, 3)", ""); + expect("less_than_int(3, x)", ""); + expect("greater_than_int(3, 14)", ""); + expect("greater_than_int(14, 3)", "t"); + expect("greater_than_int(x, 3)", ""); + expect("greater_than_int(3, x)", ""); +} + +TEST_F(EdifyTest, big_string) { + // big string + expect(std::string(8192, 's').c_str(), std::string(8192, 's').c_str()); +} + +TEST_F(EdifyTest, unknown_function) { + // unknown function + const char* script1 = "unknown_function()"; + Expr* expr; + int error_count = 0; + EXPECT_EQ(1, parse_string(script1, &expr, &error_count)); + EXPECT_EQ(1, error_count); + + const char* script2 = "abc; unknown_function()"; + error_count = 0; + EXPECT_EQ(1, parse_string(script2, &expr, &error_count)); + EXPECT_EQ(1, error_count); + + const char* script3 = "unknown_function1() || yes"; + error_count = 0; + EXPECT_EQ(1, parse_string(script3, &expr, &error_count)); + EXPECT_EQ(1, error_count); +} diff --git a/tests/component/updater_test.cpp b/tests/component/updater_test.cpp new file mode 100644 index 000000000..a859f11c1 --- /dev/null +++ b/tests/component/updater_test.cpp @@ -0,0 +1,99 @@ +/* + * 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 <string> + +#include <android-base/properties.h> +#include <gtest/gtest.h> + +#include "edify/expr.h" +#include "error_code.h" +#include "updater/install.h" + +struct selabel_handle *sehandle = nullptr; + +static void expect(const char* expected, const char* expr_str, CauseCode cause_code) { + Expr* e; + int error_count; + EXPECT_EQ(parse_string(expr_str, &e, &error_count), 0); + + State state(expr_str, nullptr); + + std::string result; + bool status = Evaluate(&state, e, &result); + + if (expected == nullptr) { + EXPECT_FALSE(status); + } else { + EXPECT_STREQ(expected, result.c_str()); + } + + // Error code is set in updater/updater.cpp only, by parsing State.errmsg. + EXPECT_EQ(kNoError, state.error_code); + + // Cause code should always be available. + EXPECT_EQ(cause_code, state.cause_code); + +} + +class UpdaterTest : public ::testing::Test { + protected: + virtual void SetUp() { + RegisterBuiltins(); + RegisterInstallFunctions(); + } +}; + +TEST_F(UpdaterTest, getprop) { + expect(android::base::GetProperty("ro.product.device", "").c_str(), + "getprop(\"ro.product.device\")", + kNoCause); + + expect(android::base::GetProperty("ro.build.fingerprint", "").c_str(), + "getprop(\"ro.build.fingerprint\")", + kNoCause); + + // getprop() accepts only one parameter. + expect(nullptr, "getprop()", kArgsParsingFailure); + expect(nullptr, "getprop(\"arg1\", \"arg2\")", kArgsParsingFailure); +} + +TEST_F(UpdaterTest, sha1_check) { + // sha1_check(data) returns the SHA-1 of the data. + expect("81fe8bfe87576c3ecb22426f8e57847382917acf", "sha1_check(\"abcd\")", kNoCause); + expect("da39a3ee5e6b4b0d3255bfef95601890afd80709", "sha1_check(\"\")", kNoCause); + + // sha1_check(data, sha1_hex, [sha1_hex, ...]) returns the matched SHA-1. + expect("81fe8bfe87576c3ecb22426f8e57847382917acf", + "sha1_check(\"abcd\", \"81fe8bfe87576c3ecb22426f8e57847382917acf\")", + kNoCause); + + expect("81fe8bfe87576c3ecb22426f8e57847382917acf", + "sha1_check(\"abcd\", \"wrong_sha1\", \"81fe8bfe87576c3ecb22426f8e57847382917acf\")", + kNoCause); + + // Or "" if there's no match. + expect("", + "sha1_check(\"abcd\", \"wrong_sha1\")", + kNoCause); + + expect("", + "sha1_check(\"abcd\", \"wrong_sha1\", \"wrong_sha2\")", + kNoCause); + + // sha1_check() expects at least one argument. + expect(nullptr, "sha1_check()", kArgsParsingFailure); +} diff --git a/tests/component/verifier_test.cpp b/tests/component/verifier_test.cpp index 780ff2816..7f9a71408 100644 --- a/tests/component/verifier_test.cpp +++ b/tests/component/verifier_test.cpp @@ -29,10 +29,11 @@ #include <openssl/sha.h> #include <android-base/stringprintf.h> +#include <ziparchive/zip_archive.h> #include "common.h" #include "common/test_constants.h" -#include "minzip/SysUtil.h" +#include "otautil/SysUtil.h" #include "ui.h" #include "verifier.h" @@ -45,14 +46,14 @@ class MockUI : public RecoveryUI { void Init() { } void SetStage(int, int) { } void SetLocale(const char*) { } - void SetBackground(Icon icon) { } - void SetSystemUpdateText(bool security_update) { } + void SetBackground(Icon /*icon*/) { } + void SetSystemUpdateText(bool /*security_update*/) { } - void SetProgressType(ProgressType determinate) { } - void ShowProgress(float portion, float seconds) { } - void SetProgress(float fraction) { } + void SetProgressType(ProgressType /*determinate*/) { } + void ShowProgress(float /*portion*/, float /*seconds*/) { } + void SetProgress(float /*fraction*/) { } - void ShowText(bool visible) { } + void ShowText(bool /*visible*/) { } bool IsTextVisible() { return false; } bool WasTextEverVisible() { return false; } void Print(const char* fmt, ...) { @@ -69,9 +70,10 @@ class MockUI : public RecoveryUI { } void ShowFile(const char*) { } - void StartMenu(const char* const * headers, const char* const * items, - int initial_selection) { } - int SelectMenu(int sel) { return 0; } + void StartMenu(const char* const* /*headers*/, + const char* const* /*items*/, + int /*initial_selection*/) { } + int SelectMenu(int /*sel*/) { return 0; } void EndMenu() { } }; @@ -94,30 +96,14 @@ class VerifierTest : public testing::TestWithParam<std::vector<std::string>> { 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"; + 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); + "%s%s%stestkey_%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; } } @@ -142,37 +128,38 @@ TEST_P(VerifierFailureTest, VerifyFailure) { 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"}))); + std::vector<std::string>({"otasigned_v1.zip", "v1"}), + std::vector<std::string>({"otasigned_v2.zip", "v2"}), + std::vector<std::string>({"otasigned_v3.zip", "v3"}), + std::vector<std::string>({"otasigned_v4.zip", "v4"}), + std::vector<std::string>({"otasigned_v5.zip", "v5"}))); 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"}))); + std::vector<std::string>({"otasigned_v1.zip", "v1", "v2"}), + std::vector<std::string>({"otasigned_v2.zip", "v5", "v2"}), + std::vector<std::string>({"otasigned_v3.zip", "v5", "v1", "v3"}), + std::vector<std::string>({"otasigned_v4.zip", "v5", "v1", "v4"}), + std::vector<std::string>({"otasigned_v5.zip", "v4", "v1", "v5"}))); 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"}))); + std::vector<std::string>({"otasigned_v1.zip", "v2"}), + std::vector<std::string>({"otasigned_v2.zip", "v1"}), + std::vector<std::string>({"otasigned_v3.zip", "v5"}), + std::vector<std::string>({"otasigned_v4.zip", "v5"}), + std::vector<std::string>({"otasigned_v5.zip", "v3"}))); 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"}))); + std::vector<std::string>({"otasigned_v1.zip", "v3"}), + std::vector<std::string>({"otasigned_v2.zip", "v4"}), + std::vector<std::string>({"otasigned_v3.zip", "v1"}), + std::vector<std::string>({"otasigned_v4.zip", "v2"}))); 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"}))); + std::vector<std::string>({"random.zip", "v1"}), + std::vector<std::string>({"fake-eocd.zip", "v1"}), + std::vector<std::string>({"alter-metadata.zip", "v1"}), + std::vector<std::string>({"alter-footer.zip", "v1"}))); diff --git a/tests/testdata/otasigned.zip b/tests/testdata/otasigned_v1.zip Binary files differindex a6bc53e41..a6bc53e41 100644 --- a/tests/testdata/otasigned.zip +++ b/tests/testdata/otasigned_v1.zip diff --git a/tests/testdata/otasigned_f4.zip b/tests/testdata/otasigned_v2.zip Binary files differindex dd1e4dd40..dd1e4dd40 100644 --- a/tests/testdata/otasigned_f4.zip +++ b/tests/testdata/otasigned_v2.zip diff --git a/tests/testdata/otasigned_sha256.zip b/tests/testdata/otasigned_v3.zip Binary files differindex 0ed4409b3..0ed4409b3 100644 --- a/tests/testdata/otasigned_sha256.zip +++ b/tests/testdata/otasigned_v3.zip diff --git a/tests/testdata/otasigned_f4_sha256.zip b/tests/testdata/otasigned_v4.zip Binary files differindex 3af408c40..3af408c40 100644 --- a/tests/testdata/otasigned_f4_sha256.zip +++ b/tests/testdata/otasigned_v4.zip diff --git a/tests/testdata/otasigned_ecdsa_sha256.zip b/tests/testdata/otasigned_v5.zip Binary files differindex 999fcdd0f..999fcdd0f 100644 --- a/tests/testdata/otasigned_ecdsa_sha256.zip +++ b/tests/testdata/otasigned_v5.zip diff --git a/tests/testdata/testkey.pk8 b/tests/testdata/testkey_v1.pk8 Binary files differindex 586c1bd5c..586c1bd5c 100644 --- a/tests/testdata/testkey.pk8 +++ b/tests/testdata/testkey_v1.pk8 diff --git a/tests/testdata/test_key_e3.txt b/tests/testdata/testkey_v1.txt index 53f5297bd..53f5297bd 100644 --- a/tests/testdata/test_key_e3.txt +++ b/tests/testdata/testkey_v1.txt diff --git a/tests/testdata/testkey.x509.pem b/tests/testdata/testkey_v1.x509.pem index e242d83e2..e242d83e2 100644 --- a/tests/testdata/testkey.x509.pem +++ b/tests/testdata/testkey_v1.x509.pem diff --git a/tests/testdata/test_f4.pk8 b/tests/testdata/testkey_v2.pk8 Binary files differindex 3052613c5..3052613c5 100644 --- a/tests/testdata/test_f4.pk8 +++ b/tests/testdata/testkey_v2.pk8 diff --git a/tests/testdata/test_key_f4.txt b/tests/testdata/testkey_v2.txt index 54ddbbad1..54ddbbad1 100644 --- a/tests/testdata/test_key_f4.txt +++ b/tests/testdata/testkey_v2.txt diff --git a/tests/testdata/test_f4.x509.pem b/tests/testdata/testkey_v2.x509.pem index 814abcf99..814abcf99 100644 --- a/tests/testdata/test_f4.x509.pem +++ b/tests/testdata/testkey_v2.x509.pem diff --git a/tests/testdata/testkey_v3.pk8 b/tests/testdata/testkey_v3.pk8 new file mode 120000 index 000000000..18ecf9815 --- /dev/null +++ b/tests/testdata/testkey_v3.pk8 @@ -0,0 +1 @@ +testkey_v1.pk8
\ No newline at end of file diff --git a/tests/testdata/testkey_v3.txt b/tests/testdata/testkey_v3.txt new file mode 100644 index 000000000..3208571a5 --- /dev/null +++ b/tests/testdata/testkey_v3.txt @@ -0,0 +1 @@ +v3 {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/testkey_sha256.x509.pem b/tests/testdata/testkey_v3.x509.pem index 002ce8968..002ce8968 100644 --- a/tests/testdata/testkey_sha256.x509.pem +++ b/tests/testdata/testkey_v3.x509.pem diff --git a/tests/testdata/testkey_v4.pk8 b/tests/testdata/testkey_v4.pk8 new file mode 120000 index 000000000..683b9a3f1 --- /dev/null +++ b/tests/testdata/testkey_v4.pk8 @@ -0,0 +1 @@ +testkey_v2.pk8
\ No newline at end of file diff --git a/tests/testdata/testkey_v4.txt b/tests/testdata/testkey_v4.txt new file mode 100644 index 000000000..532cbd51a --- /dev/null +++ b/tests/testdata/testkey_v4.txt @@ -0,0 +1 @@ +v4 {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/test_f4_sha256.x509.pem b/tests/testdata/testkey_v4.x509.pem index 9d5376b45..9d5376b45 100644 --- a/tests/testdata/test_f4_sha256.x509.pem +++ b/tests/testdata/testkey_v4.x509.pem diff --git a/tests/testdata/testkey_ecdsa.pk8 b/tests/testdata/testkey_v5.pk8 Binary files differindex 9a521c8cf..9a521c8cf 100644 --- a/tests/testdata/testkey_ecdsa.pk8 +++ b/tests/testdata/testkey_v5.pk8 diff --git a/tests/testdata/test_key_ec.txt b/tests/testdata/testkey_v5.txt index 72b4395d9..72b4395d9 100644 --- a/tests/testdata/test_key_ec.txt +++ b/tests/testdata/testkey_v5.txt diff --git a/tests/testdata/testkey_ecdsa.x509.pem b/tests/testdata/testkey_v5.x509.pem index b12283645..b12283645 100644 --- a/tests/testdata/testkey_ecdsa.x509.pem +++ b/tests/testdata/testkey_v5.x509.pem diff --git a/tests/testdata/ziptest_dummy-update.zip b/tests/testdata/ziptest_dummy-update.zip Binary files differnew file mode 100644 index 000000000..6976bf155 --- /dev/null +++ b/tests/testdata/ziptest_dummy-update.zip diff --git a/tests/testdata/ziptest_valid.zip b/tests/testdata/ziptest_valid.zip Binary files differnew file mode 100644 index 000000000..9e7cb7800 --- /dev/null +++ b/tests/testdata/ziptest_valid.zip diff --git a/tests/unit/recovery_test.cpp b/tests/unit/recovery_test.cpp index f397f258e..28b845fb9 100644 --- a/tests/unit/recovery_test.cpp +++ b/tests/unit/recovery_test.cpp @@ -21,7 +21,6 @@ #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"; diff --git a/tests/unit/zip_test.cpp b/tests/unit/zip_test.cpp new file mode 100644 index 000000000..b617446b8 --- /dev/null +++ b/tests/unit/zip_test.cpp @@ -0,0 +1,93 @@ +/* + * 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 <errno.h> +#include <fcntl.h> +#include <pthread.h> +#include <unistd.h> + +#include <memory> +#include <vector> + +#include <android-base/file.h> +#include <android-base/stringprintf.h> +#include <android-base/unique_fd.h> +#include <android-base/test_utils.h> +#include <gtest/gtest.h> +#include <otautil/SysUtil.h> +#include <otautil/ZipUtil.h> +#include <ziparchive/zip_archive.h> + +static const std::string DATA_PATH(getenv("ANDROID_DATA")); +static const std::string TESTDATA_PATH("/recovery/testdata/"); + +static const std::vector<uint8_t> kATxtContents { + 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', + 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', + '\n' +}; + +static const std::vector<uint8_t> kBTxtContents { + 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', + '\n' +}; + +TEST(otazip, ExtractPackageRecursive) { + TemporaryDir td; + ASSERT_NE(td.path, nullptr); + ZipArchiveHandle handle; + std::string zip_path = DATA_PATH + TESTDATA_PATH + "/ziptest_valid.zip"; + ASSERT_EQ(0, OpenArchive(zip_path.c_str(), &handle)); + // Extract the whole package into a temp directory. + ExtractPackageRecursive(handle, "", td.path, nullptr, nullptr); + // Make sure all the files are extracted correctly. + std::string path(td.path); + android::base::unique_fd fd(open((path + "/a.txt").c_str(), O_RDONLY)); + ASSERT_NE(fd, -1); + std::vector<uint8_t> read_data; + read_data.resize(kATxtContents.size()); + // The content of the file is the same as expected. + ASSERT_TRUE(android::base::ReadFully(fd.get(), read_data.data(), read_data.size())); + ASSERT_EQ(0, memcmp(read_data.data(), kATxtContents.data(), kATxtContents.size())); + + fd.reset(open((path + "/b.txt").c_str(), O_RDONLY)); + ASSERT_NE(fd, -1); + fd.reset(open((path + "/b/c.txt").c_str(), O_RDONLY)); + ASSERT_NE(fd, -1); + fd.reset(open((path + "/b/d.txt").c_str(), O_RDONLY)); + ASSERT_NE(fd, -1); + read_data.resize(kBTxtContents.size()); + ASSERT_TRUE(android::base::ReadFully(fd.get(), read_data.data(), read_data.size())); + ASSERT_EQ(0, memcmp(read_data.data(), kBTxtContents.data(), kBTxtContents.size())); +} + +TEST(otazip, OpenFromMemory) { + MemMapping map; + std::string zip_path = DATA_PATH + TESTDATA_PATH + "/ziptest_dummy-update.zip"; + ASSERT_EQ(0, sysMapFile(zip_path.c_str(), &map)); + // Map an update package into memory and open the archive from there. + ZipArchiveHandle handle; + ASSERT_EQ(0, OpenArchiveFromMemory(map.addr, map.length, zip_path.c_str(), &handle)); + static constexpr const char* BINARY_PATH = "META-INF/com/google/android/update-binary"; + ZipString binary_path(BINARY_PATH); + ZipEntry binary_entry; + // Make sure the package opens correctly and its entry can be read. + ASSERT_EQ(0, FindEntry(handle, binary_path, &binary_entry)); + TemporaryFile tmp_binary; + ASSERT_NE(-1, tmp_binary.fd); + ASSERT_EQ(0, ExtractEntryToFile(handle, &binary_entry, tmp_binary.fd)); +} + |