From a4f701af93a5a739f34823cde0c493dfbc63537a Mon Sep 17 00:00:00 2001 From: Mark Salyzyn Date: Wed, 9 Mar 2016 14:58:16 -0800 Subject: recovery: use __android_log_pmsg_file_write for log files - Add call to __android_log_pmsg_file_write for recovery logging. - Add call to refresh pmsg if we reboot back into recovery and then allow overwrite of those logs. - Add a new one-time executable recovery-refresh that refreshes pmsg in post-fs phase of init. We rely on pmsg eventually scrolling off to age the content after recovery-persist has done its job. - Add a new one-time executable recovery-persist that transfers from pmsg to /data/misc/recovery/ directory if /cache is not mounted in post-fs-data phase of init. - Build and appropriately trigger the above two as required if BOARD_CACHEIMAGE_PARTITION_SIZE is undefined. - Add some simple unit tests NB: Test failure is expected on systems that do not deliver either the recovery-persist or recovery-refresh executables, e.g. systems with /cache. Tests also require a timely reboot sequence of test to truly verify, tests provide guidance on stderr to direct. Bug: 27176738 Change-Id: I17bb95980234984f6b2087fd5941b0a3126b706b --- tests/unit/recovery_test.cpp | 92 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) create mode 100644 tests/unit/recovery_test.cpp (limited to 'tests/unit') 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 +#include +#include +#include + +#include +#include +#include +#include + +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)); +} -- cgit v1.2.3 From fee79a4532e9ef27b9dae4b02f2d06fa932e8c95 Mon Sep 17 00:00:00 2001 From: Mark Salyzyn Date: Tue, 4 Oct 2016 08:58:24 -0700 Subject: recovery: drop log/logger.h private/android_logger.h contains all we need. Test: compile Bug: 26552300 Bug: 31289077 Bug: 31456426 Change-Id: I6714d730372dc81f784e7f9dfee8a33848643a5d --- tests/unit/recovery_test.cpp | 1 - 1 file changed, 1 deletion(-) (limited to 'tests/unit') 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 #include -#include #include static const char myFilename[] = "/data/misc/recovery/inject.txt"; -- cgit v1.2.3 From 8cf5c8f60f51049278b08ae4cbc31df397b651fd Mon Sep 17 00:00:00 2001 From: Tianjie Xu Date: Thu, 8 Sep 2016 20:10:11 -0700 Subject: Replace minzip with libziparchive Clean up the duplicated codes that handle the zip files in bootable/recovery; and rename the library of the remaining utility functions to libotautil. Test: Update package installed successfully on angler. Bug: 19472796 Change-Id: Iea8962fcf3004473cb0322b6bb3a9ea3ca7f679e --- tests/unit/zip_test.cpp | 93 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 tests/unit/zip_test.cpp (limited to 'tests/unit') 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 +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +static const std::string DATA_PATH(getenv("ANDROID_DATA")); +static const std::string TESTDATA_PATH("/recovery/testdata/"); + +static const std::vector kATxtContents { + 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', + 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', + '\n' +}; + +static const std::vector 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 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)); +} + -- cgit v1.2.3 From 0dfb7536bb3b923bc4378002ecc0da871c6de01f Mon Sep 17 00:00:00 2001 From: Tao Bao Date: Fri, 4 Nov 2016 15:15:52 -0700 Subject: tests: Fix unit/zip_test.cpp. It's accidentally broken when refactoring the testdata path. Also clean up the testcase a bit by simplying the file reading. Test: recovery_unit_test passes. Change-Id: I592a1cf5a4eb9a7a5f4eecbc6426baeedeb02781 --- tests/unit/zip_test.cpp | 109 ++++++++++++++++++++++-------------------------- 1 file changed, 50 insertions(+), 59 deletions(-) (limited to 'tests/unit') diff --git a/tests/unit/zip_test.cpp b/tests/unit/zip_test.cpp index b617446b8..49729467d 100644 --- a/tests/unit/zip_test.cpp +++ b/tests/unit/zip_test.cpp @@ -16,78 +16,69 @@ #include #include -#include #include #include #include #include -#include -#include #include #include #include #include #include -static const std::string DATA_PATH(getenv("ANDROID_DATA")); -static const std::string TESTDATA_PATH("/recovery/testdata/"); - -static const std::vector kATxtContents { - 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', - 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', - '\n' -}; - -static const std::vector 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 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())); +#include "common/test_constants.h" + +static const std::string kATxtContents("abcdefghabcdefgh\n"); +static const std::string kBTxtContents("abcdefgh\n"); + +TEST(ZipTest, ExtractPackageRecursive) { + std::string zip_path = from_testdata_base("ziptest_valid.zip"); + ZipArchiveHandle handle; + ASSERT_EQ(0, OpenArchive(zip_path.c_str(), &handle)); + + // Extract the whole package into a temp directory. + TemporaryDir td; + ASSERT_NE(nullptr, td.path); + ExtractPackageRecursive(handle, "", td.path, nullptr, nullptr); + + // Make sure all the files are extracted correctly. + std::string path(td.path); + ASSERT_EQ(0, access((path + "/a.txt").c_str(), O_RDONLY)); + ASSERT_EQ(0, access((path + "/b.txt").c_str(), O_RDONLY)); + ASSERT_EQ(0, access((path + "/b/c.txt").c_str(), O_RDONLY)); + ASSERT_EQ(0, access((path + "/b/d.txt").c_str(), O_RDONLY)); + + // The content of the file is the same as expected. + std::string content1; + ASSERT_TRUE(android::base::ReadFileToString(path + "/a.txt", &content1)); + ASSERT_EQ(kATxtContents, content1); + + std::string content2; + ASSERT_TRUE(android::base::ReadFileToString(path + "/b/d.txt", &content2)); + ASSERT_EQ(kBTxtContents, content2); } -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)); +TEST(ZipTest, OpenFromMemory) { + MemMapping map; + std::string zip_path = from_testdata_base("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)); + + sysReleaseMap(&map); } -- cgit v1.2.3 From c3292f3fcbb3cd608cc19b7459751fa5bb64ab84 Mon Sep 17 00:00:00 2001 From: Tao Bao Date: Fri, 4 Nov 2016 10:52:13 -0700 Subject: otautil: Clean up SysUtil.cpp. Add unit testcases for sysMapFile(). Test: recovery_unit_test passes. Test: Build and use the new recovery image to sideload a package. Test: Build and use the new recovery image to install an update. Change-Id: I77d8f1ea151ab513865d992c256ba93a1fcb51a4 --- tests/unit/sysutil_test.cpp | 140 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 140 insertions(+) create mode 100644 tests/unit/sysutil_test.cpp (limited to 'tests/unit') diff --git a/tests/unit/sysutil_test.cpp b/tests/unit/sysutil_test.cpp new file mode 100644 index 000000000..f4699664b --- /dev/null +++ b/tests/unit/sysutil_test.cpp @@ -0,0 +1,140 @@ +/* + * Copyright 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 + +#include + +#include +#include + +#include "otautil/SysUtil.h" + +TEST(SysUtilTest, InvalidArgs) { + MemMapping mapping; + + // Invalid argument. + ASSERT_EQ(-1, sysMapFile(nullptr, &mapping)); + ASSERT_EQ(-1, sysMapFile("/somefile", nullptr)); +} + +TEST(SysUtilTest, sysMapFileRegularFile) { + TemporaryFile temp_file1; + std::string content = "abc"; + ASSERT_TRUE(android::base::WriteStringToFile(content, temp_file1.path)); + + // sysMapFile() should map the file to one range. + MemMapping mapping; + ASSERT_EQ(0, sysMapFile(temp_file1.path, &mapping)); + ASSERT_NE(nullptr, mapping.addr); + ASSERT_EQ(content.size(), mapping.length); + ASSERT_EQ(1U, mapping.ranges.size()); + + sysReleaseMap(&mapping); + ASSERT_EQ(0U, mapping.ranges.size()); +} + +TEST(SysUtilTest, sysMapFileBlockMap) { + // Create a file that has 10 blocks. + TemporaryFile package; + std::string content; + constexpr size_t file_size = 4096 * 10; + content.reserve(file_size); + ASSERT_TRUE(android::base::WriteStringToFile(content, package.path)); + + TemporaryFile block_map_file; + std::string filename = std::string("@") + block_map_file.path; + MemMapping mapping; + + // One range. + std::string block_map_content = std::string(package.path) + "\n40960 4096\n1\n0 10\n"; + ASSERT_TRUE(android::base::WriteStringToFile(block_map_content, block_map_file.path)); + + ASSERT_EQ(0, sysMapFile(filename.c_str(), &mapping)); + ASSERT_EQ(file_size, mapping.length); + ASSERT_EQ(1U, mapping.ranges.size()); + + // It's okay to not have the trailing '\n'. + block_map_content = std::string(package.path) + "\n40960 4096\n1\n0 10"; + ASSERT_TRUE(android::base::WriteStringToFile(block_map_content, block_map_file.path)); + + ASSERT_EQ(0, sysMapFile(filename.c_str(), &mapping)); + ASSERT_EQ(file_size, mapping.length); + ASSERT_EQ(1U, mapping.ranges.size()); + + // Or having multiple trailing '\n's. + block_map_content = std::string(package.path) + "\n40960 4096\n1\n0 10\n\n\n"; + ASSERT_TRUE(android::base::WriteStringToFile(block_map_content, block_map_file.path)); + + ASSERT_EQ(0, sysMapFile(filename.c_str(), &mapping)); + ASSERT_EQ(file_size, mapping.length); + ASSERT_EQ(1U, mapping.ranges.size()); + + // Multiple ranges. + block_map_content = std::string(package.path) + "\n40960 4096\n3\n0 3\n3 5\n5 10\n"; + ASSERT_TRUE(android::base::WriteStringToFile(block_map_content, block_map_file.path)); + + ASSERT_EQ(0, sysMapFile(filename.c_str(), &mapping)); + ASSERT_EQ(file_size, mapping.length); + ASSERT_EQ(3U, mapping.ranges.size()); + + sysReleaseMap(&mapping); + ASSERT_EQ(0U, mapping.ranges.size()); +} + +TEST(SysUtilTest, sysMapFileBlockMapInvalidBlockMap) { + MemMapping mapping; + TemporaryFile temp_file; + std::string filename = std::string("@") + temp_file.path; + + // Block map file is too short. + ASSERT_TRUE(android::base::WriteStringToFile("/somefile\n", temp_file.path)); + ASSERT_EQ(-1, sysMapFile(filename.c_str(), &mapping)); + + ASSERT_TRUE(android::base::WriteStringToFile("/somefile\n4096 4096\n0\n", temp_file.path)); + ASSERT_EQ(-1, sysMapFile(filename.c_str(), &mapping)); + + // Block map file has unexpected number of lines. + ASSERT_TRUE(android::base::WriteStringToFile("/somefile\n4096 4096\n1\n", temp_file.path)); + ASSERT_EQ(-1, sysMapFile(filename.c_str(), &mapping)); + + ASSERT_TRUE(android::base::WriteStringToFile("/somefile\n4096 4096\n2\n0 1\n", temp_file.path)); + ASSERT_EQ(-1, sysMapFile(filename.c_str(), &mapping)); + + // Invalid size/blksize/range_count. + ASSERT_TRUE(android::base::WriteStringToFile("/somefile\nabc 4096\n1\n0 1\n", temp_file.path)); + ASSERT_EQ(-1, sysMapFile(filename.c_str(), &mapping)); + + ASSERT_TRUE(android::base::WriteStringToFile("/somefile\n4096 4096\n\n0 1\n", temp_file.path)); + ASSERT_EQ(-1, sysMapFile(filename.c_str(), &mapping)); + + // size/blksize/range_count don't match. + ASSERT_TRUE(android::base::WriteStringToFile("/somefile\n0 4096\n1\n0 1\n", temp_file.path)); + ASSERT_EQ(-1, sysMapFile(filename.c_str(), &mapping)); + + ASSERT_TRUE(android::base::WriteStringToFile("/somefile\n4096 0\n1\n0 1\n", temp_file.path)); + ASSERT_EQ(-1, sysMapFile(filename.c_str(), &mapping)); + + ASSERT_TRUE(android::base::WriteStringToFile("/somefile\n4096 4096\n0\n0 1\n", temp_file.path)); + ASSERT_EQ(-1, sysMapFile(filename.c_str(), &mapping)); + + // Invalid block dev path. + ASSERT_TRUE(android::base::WriteStringToFile("/doesntexist\n4096 4096\n1\n0 1\n", temp_file.path)); + ASSERT_EQ(-1, sysMapFile(filename.c_str(), &mapping)); + + sysReleaseMap(&mapping); + ASSERT_EQ(0U, mapping.ranges.size()); +} -- cgit v1.2.3 From 5d8b53b248ac56cb8280d2d2d653f12c43a26abd Mon Sep 17 00:00:00 2001 From: Tianjie Xu Date: Mon, 7 Nov 2016 14:45:59 -0800 Subject: Move recovery_test.cpp out of unit test Move recovery-refresh/persist tests out because these tests need special steps to run. Also switch the constants to std::string. Test: recovery_manual_test passed on an A/B device Change-Id: I60b3ec6f094044945c3aafc1fae540896a6ddea6 --- tests/unit/recovery_test.cpp | 91 -------------------------------------------- 1 file changed, 91 deletions(-) delete mode 100644 tests/unit/recovery_test.cpp (limited to 'tests/unit') diff --git a/tests/unit/recovery_test.cpp b/tests/unit/recovery_test.cpp deleted file mode 100644 index 28b845fb9..000000000 --- a/tests/unit/recovery_test.cpp +++ /dev/null @@ -1,91 +0,0 @@ -/* - * 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 -#include -#include -#include - -#include -#include -#include - -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)); -} -- cgit v1.2.3 From ef0eb3b01b66fbbc97908667a3dd1e02d710cbb7 Mon Sep 17 00:00:00 2001 From: Tao Bao Date: Mon, 14 Nov 2016 21:29:52 -0800 Subject: updater: Fix the wrong return value for package_extract_file(). 'bool success = ExtractEntryToFile()' gives opposite result. Fix the issue and add testcases. Change the one-argument version of package_extract_file() to explicitly abort for non-existent zip entry. Note that this is NOT changing the behavior. Prior to this CL, it aborts from Evaluate() function, by giving a general cause code. Now it returns kPackageExtractFileFailure. BUg: 32903624 Test: recovery_component_test works. Change-Id: I7a273e9c0d9aaaf8c472b2c778f7b8d90362c24f --- tests/unit/zip_test.cpp | 3 --- 1 file changed, 3 deletions(-) (limited to 'tests/unit') diff --git a/tests/unit/zip_test.cpp b/tests/unit/zip_test.cpp index 49729467d..ef0ee4c1d 100644 --- a/tests/unit/zip_test.cpp +++ b/tests/unit/zip_test.cpp @@ -30,9 +30,6 @@ #include "common/test_constants.h" -static const std::string kATxtContents("abcdefghabcdefgh\n"); -static const std::string kBTxtContents("abcdefgh\n"); - TEST(ZipTest, ExtractPackageRecursive) { std::string zip_path = from_testdata_base("ziptest_valid.zip"); ZipArchiveHandle handle; -- cgit v1.2.3 From a3ece96f9f87e7219350498486975c5b8deccd83 Mon Sep 17 00:00:00 2001 From: Tao Bao Date: Wed, 21 Dec 2016 18:44:20 -0800 Subject: tests: Replace the O_RDONLY in access(2). Although O_RDONLY gives the same value as F_OK (0), it's not the right friend of access(2). Also clean up the temporary files from ZipTest (TemporaryDir doesn't like non-empty directory). Test: recovery_unit_test passes and has no leftover. Change-Id: I66b90e43c0954c89ce08b36b9e2b4e84183b28f5 --- tests/unit/zip_test.cpp | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) (limited to 'tests/unit') diff --git a/tests/unit/zip_test.cpp b/tests/unit/zip_test.cpp index ef0ee4c1d..4a1a49b97 100644 --- a/tests/unit/zip_test.cpp +++ b/tests/unit/zip_test.cpp @@ -15,7 +15,6 @@ */ #include -#include #include #include @@ -42,10 +41,10 @@ TEST(ZipTest, ExtractPackageRecursive) { // Make sure all the files are extracted correctly. std::string path(td.path); - ASSERT_EQ(0, access((path + "/a.txt").c_str(), O_RDONLY)); - ASSERT_EQ(0, access((path + "/b.txt").c_str(), O_RDONLY)); - ASSERT_EQ(0, access((path + "/b/c.txt").c_str(), O_RDONLY)); - ASSERT_EQ(0, access((path + "/b/d.txt").c_str(), O_RDONLY)); + ASSERT_EQ(0, access((path + "/a.txt").c_str(), F_OK)); + ASSERT_EQ(0, access((path + "/b.txt").c_str(), F_OK)); + ASSERT_EQ(0, access((path + "/b/c.txt").c_str(), F_OK)); + ASSERT_EQ(0, access((path + "/b/d.txt").c_str(), F_OK)); // The content of the file is the same as expected. std::string content1; @@ -54,7 +53,16 @@ TEST(ZipTest, ExtractPackageRecursive) { std::string content2; ASSERT_TRUE(android::base::ReadFileToString(path + "/b/d.txt", &content2)); - ASSERT_EQ(kBTxtContents, content2); + ASSERT_EQ(kDTxtContents, content2); + + CloseArchive(handle); + + // Clean up. + ASSERT_EQ(0, unlink((path + "/a.txt").c_str())); + ASSERT_EQ(0, unlink((path + "/b.txt").c_str())); + ASSERT_EQ(0, unlink((path + "/b/c.txt").c_str())); + ASSERT_EQ(0, unlink((path + "/b/d.txt").c_str())); + ASSERT_EQ(0, rmdir((path + "/b").c_str())); } TEST(ZipTest, OpenFromMemory) { @@ -76,6 +84,7 @@ TEST(ZipTest, OpenFromMemory) { ASSERT_NE(-1, tmp_binary.fd); ASSERT_EQ(0, ExtractEntryToFile(handle, &binary_entry, tmp_binary.fd)); + CloseArchive(handle); sysReleaseMap(&map); } -- cgit v1.2.3 From e7e7b46666f27135783bcd45252655d9cf2edd33 Mon Sep 17 00:00:00 2001 From: Tao Bao Date: Wed, 21 Dec 2016 17:58:42 -0800 Subject: tests: Add testcase for ZipUtil. Test: recovery_unit_test passes. Change-Id: I8ad364e88aaee31579ed7206aad8e5620518d797 --- tests/unit/ziputil_test.cpp | 191 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 191 insertions(+) create mode 100644 tests/unit/ziputil_test.cpp (limited to 'tests/unit') diff --git a/tests/unit/ziputil_test.cpp b/tests/unit/ziputil_test.cpp new file mode 100644 index 000000000..14e541690 --- /dev/null +++ b/tests/unit/ziputil_test.cpp @@ -0,0 +1,191 @@ +/* + * Copyright 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 +#include +#include + +#include + +#include +#include +#include +#include +#include + +#include "common/test_constants.h" + +TEST(ZipUtilTest, invalid_args) { + std::string zip_path = from_testdata_base("ziptest_valid.zip"); + ZipArchiveHandle handle; + ASSERT_EQ(0, OpenArchive(zip_path.c_str(), &handle)); + + // zip_path must be a relative path. + ASSERT_FALSE(ExtractPackageRecursive(handle, "/a/b", "/tmp", nullptr, nullptr)); + + // dest_path must be an absolute path. + ASSERT_FALSE(ExtractPackageRecursive(handle, "a/b", "tmp", nullptr, nullptr)); + ASSERT_FALSE(ExtractPackageRecursive(handle, "a/b", "", nullptr, nullptr)); + + CloseArchive(handle); +} + +TEST(ZipUtilTest, extract_all) { + std::string zip_path = from_testdata_base("ziptest_valid.zip"); + ZipArchiveHandle handle; + ASSERT_EQ(0, OpenArchive(zip_path.c_str(), &handle)); + + // Extract the whole package into a temp directory. + TemporaryDir td; + ExtractPackageRecursive(handle, "", td.path, nullptr, nullptr); + + // Make sure all the files are extracted correctly. + std::string path(td.path); + ASSERT_EQ(0, access((path + "/a.txt").c_str(), F_OK)); + ASSERT_EQ(0, access((path + "/b.txt").c_str(), F_OK)); + ASSERT_EQ(0, access((path + "/b/c.txt").c_str(), F_OK)); + ASSERT_EQ(0, access((path + "/b/d.txt").c_str(), F_OK)); + + // The content of the file is the same as expected. + std::string content1; + ASSERT_TRUE(android::base::ReadFileToString(path + "/a.txt", &content1)); + ASSERT_EQ(kATxtContents, content1); + + std::string content2; + ASSERT_TRUE(android::base::ReadFileToString(path + "/b/d.txt", &content2)); + ASSERT_EQ(kDTxtContents, content2); + + // Clean up the temp files under td. + ASSERT_EQ(0, unlink((path + "/a.txt").c_str())); + ASSERT_EQ(0, unlink((path + "/b.txt").c_str())); + ASSERT_EQ(0, unlink((path + "/b/c.txt").c_str())); + ASSERT_EQ(0, unlink((path + "/b/d.txt").c_str())); + ASSERT_EQ(0, rmdir((path + "/b").c_str())); + + CloseArchive(handle); +} + +TEST(ZipUtilTest, extract_prefix_with_slash) { + std::string zip_path = from_testdata_base("ziptest_valid.zip"); + ZipArchiveHandle handle; + ASSERT_EQ(0, OpenArchive(zip_path.c_str(), &handle)); + + // Extract all the entries starting with "b/". + TemporaryDir td; + ExtractPackageRecursive(handle, "b/", td.path, nullptr, nullptr); + + // Make sure all the files with "b/" prefix are extracted correctly. + std::string path(td.path); + ASSERT_EQ(0, access((path + "/c.txt").c_str(), F_OK)); + ASSERT_EQ(0, access((path + "/d.txt").c_str(), F_OK)); + + // And the rest are not extracted. + ASSERT_EQ(-1, access((path + "/a.txt").c_str(), F_OK)); + ASSERT_EQ(ENOENT, errno); + ASSERT_EQ(-1, access((path + "/b.txt").c_str(), F_OK)); + ASSERT_EQ(ENOENT, errno); + + // The content of the file is the same as expected. + std::string content1; + ASSERT_TRUE(android::base::ReadFileToString(path + "/c.txt", &content1)); + ASSERT_EQ(kCTxtContents, content1); + + std::string content2; + ASSERT_TRUE(android::base::ReadFileToString(path + "/d.txt", &content2)); + ASSERT_EQ(kDTxtContents, content2); + + // Clean up the temp files under td. + ASSERT_EQ(0, unlink((path + "/c.txt").c_str())); + ASSERT_EQ(0, unlink((path + "/d.txt").c_str())); + + CloseArchive(handle); +} + +TEST(ZipUtilTest, extract_prefix_without_slash) { + std::string zip_path = from_testdata_base("ziptest_valid.zip"); + ZipArchiveHandle handle; + ASSERT_EQ(0, OpenArchive(zip_path.c_str(), &handle)); + + // Extract all the file entries starting with "b/". + TemporaryDir td; + ExtractPackageRecursive(handle, "b", td.path, nullptr, nullptr); + + // Make sure all the files with "b/" prefix are extracted correctly. + std::string path(td.path); + ASSERT_EQ(0, access((path + "/c.txt").c_str(), F_OK)); + ASSERT_EQ(0, access((path + "/d.txt").c_str(), F_OK)); + + // And the rest are not extracted. + ASSERT_EQ(-1, access((path + "/a.txt").c_str(), F_OK)); + ASSERT_EQ(ENOENT, errno); + ASSERT_EQ(-1, access((path + "/b.txt").c_str(), F_OK)); + ASSERT_EQ(ENOENT, errno); + + // The content of the file is the same as expected. + std::string content1; + ASSERT_TRUE(android::base::ReadFileToString(path + "/c.txt", &content1)); + ASSERT_EQ(kCTxtContents, content1); + + std::string content2; + ASSERT_TRUE(android::base::ReadFileToString(path + "/d.txt", &content2)); + ASSERT_EQ(kDTxtContents, content2); + + // Clean up the temp files under td. + ASSERT_EQ(0, unlink((path + "/c.txt").c_str())); + ASSERT_EQ(0, unlink((path + "/d.txt").c_str())); + + CloseArchive(handle); +} + +TEST(ZipUtilTest, set_timestamp) { + std::string zip_path = from_testdata_base("ziptest_valid.zip"); + ZipArchiveHandle handle; + ASSERT_EQ(0, OpenArchive(zip_path.c_str(), &handle)); + + // Set the timestamp to 8/1/2008. + constexpr struct utimbuf timestamp = { 1217592000, 1217592000 }; + + // Extract all the entries starting with "b/". + TemporaryDir td; + ExtractPackageRecursive(handle, "b", td.path, ×tamp, nullptr); + + // Make sure all the files with "b/" prefix are extracted correctly. + std::string path(td.path); + std::string file_c = path + "/c.txt"; + std::string file_d = path + "/d.txt"; + ASSERT_EQ(0, access(file_c.c_str(), F_OK)); + ASSERT_EQ(0, access(file_d.c_str(), F_OK)); + + // Verify the timestamp. + timespec time; + time.tv_sec = 1217592000; + time.tv_nsec = 0; + + struct stat sb; + ASSERT_EQ(0, stat(file_c.c_str(), &sb)) << strerror(errno); + ASSERT_EQ(time.tv_sec, static_cast(sb.st_atime)); + ASSERT_EQ(time.tv_sec, static_cast(sb.st_mtime)); + + ASSERT_EQ(0, stat(file_d.c_str(), &sb)) << strerror(errno); + ASSERT_EQ(time.tv_sec, static_cast(sb.st_atime)); + ASSERT_EQ(time.tv_sec, static_cast(sb.st_mtime)); + + // Clean up the temp files under td. + ASSERT_EQ(0, unlink(file_c.c_str())); + ASSERT_EQ(0, unlink(file_d.c_str())); + + CloseArchive(handle); +} -- cgit v1.2.3 From f19295c5dc7cefff2bb26b5bcbab5a76a16cffe3 Mon Sep 17 00:00:00 2001 From: Tao Bao Date: Thu, 22 Dec 2016 09:28:03 -0800 Subject: tests: Add test coverage for DirUtil. Test: recovery_unit_test passes. Change-Id: I764c56404c7ccdd57ae5486c946fbc9ac6ae7bc9 --- tests/unit/dirutil_test.cpp | 150 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 150 insertions(+) create mode 100644 tests/unit/dirutil_test.cpp (limited to 'tests/unit') diff --git a/tests/unit/dirutil_test.cpp b/tests/unit/dirutil_test.cpp new file mode 100644 index 000000000..5e2ae4fb5 --- /dev/null +++ b/tests/unit/dirutil_test.cpp @@ -0,0 +1,150 @@ +/* + * Copyright 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 +#include +#include + +#include + +#include +#include +#include + +TEST(DirUtilTest, create_invalid) { + // Requesting to create an empty dir is invalid. + ASSERT_EQ(-1, dirCreateHierarchy("", 0755, nullptr, false, nullptr)); + ASSERT_EQ(ENOENT, errno); + + // Requesting to strip the name with no slash present. + ASSERT_EQ(-1, dirCreateHierarchy("abc", 0755, nullptr, true, nullptr)); + ASSERT_EQ(ENOENT, errno); + + // Creating a dir that already exists. + TemporaryDir td; + ASSERT_EQ(0, dirCreateHierarchy(td.path, 0755, nullptr, false, nullptr)); + + // "///" is a valid dir. + ASSERT_EQ(0, dirCreateHierarchy("///", 0755, nullptr, false, nullptr)); + + // Request to create a dir, but a file with the same name already exists. + TemporaryFile tf; + ASSERT_EQ(-1, dirCreateHierarchy(tf.path, 0755, nullptr, false, nullptr)); + ASSERT_EQ(ENOTDIR, errno); +} + +TEST(DirUtilTest, create_smoke) { + TemporaryDir td; + std::string prefix(td.path); + std::string path = prefix + "/a/b"; + constexpr mode_t mode = 0755; + ASSERT_EQ(0, dirCreateHierarchy(path.c_str(), mode, nullptr, false, nullptr)); + + // Verify. + struct stat sb; + ASSERT_EQ(0, stat(path.c_str(), &sb)) << strerror(errno); + ASSERT_TRUE(S_ISDIR(sb.st_mode)); + constexpr mode_t mask = S_IRWXU | S_IRWXG | S_IRWXO; + ASSERT_EQ(mode, sb.st_mode & mask); + + // Clean up. + ASSERT_EQ(0, rmdir((prefix + "/a/b").c_str())); + ASSERT_EQ(0, rmdir((prefix + "/a").c_str())); +} + +TEST(DirUtilTest, create_strip_filename) { + TemporaryDir td; + std::string prefix(td.path); + std::string path = prefix + "/a/b"; + ASSERT_EQ(0, dirCreateHierarchy(path.c_str(), 0755, nullptr, true, nullptr)); + + // Verify that "../a" exists but not "../a/b". + struct stat sb; + ASSERT_EQ(0, stat((prefix + "/a").c_str(), &sb)) << strerror(errno); + ASSERT_TRUE(S_ISDIR(sb.st_mode)); + + ASSERT_EQ(-1, stat(path.c_str(), &sb)); + ASSERT_EQ(ENOENT, errno); + + // Clean up. + ASSERT_EQ(0, rmdir((prefix + "/a").c_str())); +} + +TEST(DirUtilTest, create_mode_and_timestamp) { + TemporaryDir td; + std::string prefix(td.path); + std::string path = prefix + "/a/b"; + // Set the timestamp to 8/1/2008. + constexpr struct utimbuf timestamp = { 1217592000, 1217592000 }; + constexpr mode_t mode = 0751; + ASSERT_EQ(0, dirCreateHierarchy(path.c_str(), mode, ×tamp, false, nullptr)); + + // Verify the mode and timestamp for "../a/b". + struct stat sb; + ASSERT_EQ(0, stat(path.c_str(), &sb)) << strerror(errno); + ASSERT_TRUE(S_ISDIR(sb.st_mode)); + constexpr mode_t mask = S_IRWXU | S_IRWXG | S_IRWXO; + ASSERT_EQ(mode, sb.st_mode & mask); + + timespec time; + time.tv_sec = 1217592000; + time.tv_nsec = 0; + + ASSERT_EQ(time.tv_sec, static_cast(sb.st_atime)); + ASSERT_EQ(time.tv_sec, static_cast(sb.st_mtime)); + + // Verify the mode for "../a". Note that the timestamp for intermediate directories (e.g. "../a") + // may not be 'timestamp' according to the current implementation. + ASSERT_EQ(0, stat((prefix + "/a").c_str(), &sb)) << strerror(errno); + ASSERT_TRUE(S_ISDIR(sb.st_mode)); + ASSERT_EQ(mode, sb.st_mode & mask); + + // Clean up. + ASSERT_EQ(0, rmdir((prefix + "/a/b").c_str())); + ASSERT_EQ(0, rmdir((prefix + "/a").c_str())); +} + +TEST(DirUtilTest, unlink_invalid) { + // File doesn't exist. + ASSERT_EQ(-1, dirUnlinkHierarchy("doesntexist")); + + // Nonexistent directory. + TemporaryDir td; + std::string path(td.path); + ASSERT_EQ(-1, dirUnlinkHierarchy((path + "/a").c_str())); + ASSERT_EQ(ENOENT, errno); +} + +TEST(DirUtilTest, unlink_smoke) { + // Unlink a file. + TemporaryFile tf; + ASSERT_EQ(0, dirUnlinkHierarchy(tf.path)); + ASSERT_EQ(-1, access(tf.path, F_OK)); + + TemporaryDir td; + std::string path(td.path); + constexpr mode_t mode = 0700; + ASSERT_EQ(0, mkdir((path + "/a").c_str(), mode)); + ASSERT_EQ(0, mkdir((path + "/a/b").c_str(), mode)); + ASSERT_EQ(0, mkdir((path + "/a/b/c").c_str(), mode)); + ASSERT_EQ(0, mkdir((path + "/a/d").c_str(), mode)); + + // Remove "../a" recursively. + ASSERT_EQ(0, dirUnlinkHierarchy((path + "/a").c_str())); + + // Verify it's gone. + ASSERT_EQ(-1, access((path + "/a").c_str(), F_OK)); +} -- cgit v1.2.3 From d17a6885253da909e376ba5ca5084f5281f3557c Mon Sep 17 00:00:00 2001 From: Tianjie Xu Date: Mon, 9 Jan 2017 11:18:29 -0800 Subject: Add checkers and tests for empty locale in PNG file match_locale() will return false for empty locale string in the PNG file. Also add a manual test to validate if a PNG file is qualified to use under recovery. Bug: 34054052 Test: recovery_manual_test catches invalid PNG files successfully & Locale_test passed Change-Id: Id7e2136e1d8abf20da15825aa7901effbced8b03 --- tests/unit/locale_test.cpp | 3 +++ 1 file changed, 3 insertions(+) (limited to 'tests/unit') diff --git a/tests/unit/locale_test.cpp b/tests/unit/locale_test.cpp index 0e515f8c1..f73235005 100644 --- a/tests/unit/locale_test.cpp +++ b/tests/unit/locale_test.cpp @@ -26,4 +26,7 @@ TEST(LocaleTest, Misc) { EXPECT_TRUE(matches_locale("en", "en_GB")); EXPECT_FALSE(matches_locale("en_GB", "en")); EXPECT_FALSE(matches_locale("en_GB", "en_US")); + EXPECT_FALSE(matches_locale("en_US", "")); + // Empty locale prefix in the PNG file will match the input locale. + EXPECT_TRUE(matches_locale("", "en_US")); } -- cgit v1.2.3 From 76fdb2419bfec0e747db2530379484a3dc571f34 Mon Sep 17 00:00:00 2001 From: Tao Bao Date: Mon, 20 Mar 2017 17:09:13 -0700 Subject: verify_file: Add constness to a few addresses. We should not touch any data while verifying packages (or parsing the in-memory ASN.1 structures). Test: mmma bootable/recovery Test: recovery_component_test passes. Test: recovery_unit_test passes. Change-Id: Ie990662c6451ec066a1807b3081c9296afbdb0bf --- tests/unit/asn1_decoder_test.cpp | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) (limited to 'tests/unit') diff --git a/tests/unit/asn1_decoder_test.cpp b/tests/unit/asn1_decoder_test.cpp index af96d87d2..997639d8a 100644 --- a/tests/unit/asn1_decoder_test.cpp +++ b/tests/unit/asn1_decoder_test.cpp @@ -39,7 +39,7 @@ TEST_F(Asn1DecoderTest, Empty_Failure) { EXPECT_EQ(NULL, asn1_set_get(ctx)); EXPECT_FALSE(asn1_sequence_next(ctx)); - uint8_t* junk; + const uint8_t* junk; size_t length; EXPECT_FALSE(asn1_oid_get(ctx, &junk, &length)); EXPECT_FALSE(asn1_octet_string_get(ctx, &junk, &length)); @@ -68,7 +68,7 @@ TEST_F(Asn1DecoderTest, ConstructedGet_TooSmallForChild_Failure) { asn1_context_t* ptr = asn1_constructed_get(ctx); ASSERT_NE((asn1_context_t*)NULL, ptr); EXPECT_EQ(5, asn1_constructed_type(ptr)); - uint8_t* oid; + const uint8_t* oid; size_t length; EXPECT_FALSE(asn1_oid_get(ptr, &oid, &length)); asn1_context_free(ptr); @@ -81,7 +81,7 @@ TEST_F(Asn1DecoderTest, ConstructedGet_Success) { asn1_context_t* ptr = asn1_constructed_get(ctx); ASSERT_NE((asn1_context_t*)NULL, ptr); EXPECT_EQ(5, asn1_constructed_type(ptr)); - uint8_t* oid; + const uint8_t* oid; size_t length; ASSERT_TRUE(asn1_oid_get(ptr, &oid, &length)); EXPECT_EQ(1U, length); @@ -103,7 +103,7 @@ TEST_F(Asn1DecoderTest, ConstructedSkipAll_Success) { 0x06, 0x01, 0xA5, }; asn1_context_t* ctx = asn1_context_new(data, sizeof(data)); ASSERT_TRUE(asn1_constructed_skip_all(ctx)); - uint8_t* oid; + const uint8_t* oid; size_t length; ASSERT_TRUE(asn1_oid_get(ctx, &oid, &length)); EXPECT_EQ(1U, length); @@ -123,7 +123,7 @@ TEST_F(Asn1DecoderTest, SequenceGet_TooSmallForChild_Failure) { asn1_context_t* ctx = asn1_context_new(data, sizeof(data)); asn1_context_t* ptr = asn1_sequence_get(ctx); ASSERT_NE((asn1_context_t*)NULL, ptr); - uint8_t* oid; + const uint8_t* oid; size_t length; EXPECT_FALSE(asn1_oid_get(ptr, &oid, &length)); asn1_context_free(ptr); @@ -135,7 +135,7 @@ TEST_F(Asn1DecoderTest, SequenceGet_Success) { asn1_context_t* ctx = asn1_context_new(data, sizeof(data)); asn1_context_t* ptr = asn1_sequence_get(ctx); ASSERT_NE((asn1_context_t*)NULL, ptr); - uint8_t* oid; + const uint8_t* oid; size_t length; ASSERT_TRUE(asn1_oid_get(ptr, &oid, &length)); EXPECT_EQ(1U, length); @@ -156,7 +156,7 @@ TEST_F(Asn1DecoderTest, SetGet_TooSmallForChild_Failure) { asn1_context_t* ctx = asn1_context_new(data, sizeof(data)); asn1_context_t* ptr = asn1_set_get(ctx); ASSERT_NE((asn1_context_t*)NULL, ptr); - uint8_t* oid; + const uint8_t* oid; size_t length; EXPECT_FALSE(asn1_oid_get(ptr, &oid, &length)); asn1_context_free(ptr); @@ -168,7 +168,7 @@ TEST_F(Asn1DecoderTest, SetGet_Success) { asn1_context_t* ctx = asn1_context_new(data, sizeof(data)); asn1_context_t* ptr = asn1_set_get(ctx); ASSERT_NE((asn1_context_t*)NULL, ptr); - uint8_t* oid; + const uint8_t* oid; size_t length; ASSERT_TRUE(asn1_oid_get(ptr, &oid, &length)); EXPECT_EQ(1U, length); @@ -180,7 +180,7 @@ TEST_F(Asn1DecoderTest, SetGet_Success) { TEST_F(Asn1DecoderTest, OidGet_LengthZero_Failure) { uint8_t data[] = { 0x06, 0x00, 0x01, }; asn1_context_t* ctx = asn1_context_new(data, sizeof(data)); - uint8_t* oid; + const uint8_t* oid; size_t length; EXPECT_FALSE(asn1_oid_get(ctx, &oid, &length)); asn1_context_free(ctx); @@ -189,7 +189,7 @@ TEST_F(Asn1DecoderTest, OidGet_LengthZero_Failure) { TEST_F(Asn1DecoderTest, OidGet_TooSmall_Failure) { uint8_t data[] = { 0x06, 0x01, }; asn1_context_t* ctx = asn1_context_new(data, sizeof(data)); - uint8_t* oid; + const uint8_t* oid; size_t length; EXPECT_FALSE(asn1_oid_get(ctx, &oid, &length)); asn1_context_free(ctx); @@ -198,7 +198,7 @@ TEST_F(Asn1DecoderTest, OidGet_TooSmall_Failure) { TEST_F(Asn1DecoderTest, OidGet_Success) { uint8_t data[] = { 0x06, 0x01, 0x99, }; asn1_context_t* ctx = asn1_context_new(data, sizeof(data)); - uint8_t* oid; + const uint8_t* oid; size_t length; ASSERT_TRUE(asn1_oid_get(ctx, &oid, &length)); EXPECT_EQ(1U, length); @@ -209,7 +209,7 @@ TEST_F(Asn1DecoderTest, OidGet_Success) { TEST_F(Asn1DecoderTest, OctetStringGet_LengthZero_Failure) { uint8_t data[] = { 0x04, 0x00, 0x55, }; asn1_context_t* ctx = asn1_context_new(data, sizeof(data)); - uint8_t* string; + const uint8_t* string; size_t length; ASSERT_FALSE(asn1_octet_string_get(ctx, &string, &length)); asn1_context_free(ctx); @@ -218,7 +218,7 @@ TEST_F(Asn1DecoderTest, OctetStringGet_LengthZero_Failure) { TEST_F(Asn1DecoderTest, OctetStringGet_TooSmall_Failure) { uint8_t data[] = { 0x04, 0x01, }; asn1_context_t* ctx = asn1_context_new(data, sizeof(data)); - uint8_t* string; + const uint8_t* string; size_t length; ASSERT_FALSE(asn1_octet_string_get(ctx, &string, &length)); asn1_context_free(ctx); @@ -227,7 +227,7 @@ TEST_F(Asn1DecoderTest, OctetStringGet_TooSmall_Failure) { TEST_F(Asn1DecoderTest, OctetStringGet_Success) { uint8_t data[] = { 0x04, 0x01, 0xAA, }; asn1_context_t* ctx = asn1_context_new(data, sizeof(data)); - uint8_t* string; + const uint8_t* string; size_t length; ASSERT_TRUE(asn1_octet_string_get(ctx, &string, &length)); EXPECT_EQ(1U, length); -- cgit v1.2.3 From 861c53c6c55db4cf6cb76d35f92804cabf1cd444 Mon Sep 17 00:00:00 2001 From: Tao Bao Date: Mon, 20 Mar 2017 17:09:13 -0700 Subject: Refactor asn1_decoder functions into a class. Test: mmma bootable/recovery Test: recovery_unit_test passes. Test: recovery_component_test passes. Change-Id: If0bf25993158eaebeedff55ba4f4dd0f6e5f937d --- tests/unit/asn1_decoder_test.cpp | 397 ++++++++++++++++++--------------------- 1 file changed, 180 insertions(+), 217 deletions(-) (limited to 'tests/unit') diff --git a/tests/unit/asn1_decoder_test.cpp b/tests/unit/asn1_decoder_test.cpp index 997639d8a..b334a655b 100644 --- a/tests/unit/asn1_decoder_test.cpp +++ b/tests/unit/asn1_decoder_test.cpp @@ -14,225 +14,188 @@ * limitations under the License. */ -#define LOG_TAG "asn1_decoder_test" +#include + +#include -#include #include -#include -#include #include "asn1_decoder.h" -namespace android { - -class Asn1DecoderTest : public testing::Test { -}; - -TEST_F(Asn1DecoderTest, Empty_Failure) { - uint8_t empty[] = { }; - asn1_context_t* ctx = asn1_context_new(empty, sizeof(empty)); - - EXPECT_EQ(NULL, asn1_constructed_get(ctx)); - EXPECT_FALSE(asn1_constructed_skip_all(ctx)); - EXPECT_EQ(0, asn1_constructed_type(ctx)); - EXPECT_EQ(NULL, asn1_sequence_get(ctx)); - EXPECT_EQ(NULL, asn1_set_get(ctx)); - EXPECT_FALSE(asn1_sequence_next(ctx)); - - const uint8_t* junk; - size_t length; - EXPECT_FALSE(asn1_oid_get(ctx, &junk, &length)); - EXPECT_FALSE(asn1_octet_string_get(ctx, &junk, &length)); - - asn1_context_free(ctx); -} - -TEST_F(Asn1DecoderTest, ConstructedGet_TruncatedLength_Failure) { - uint8_t truncated[] = { 0xA0, 0x82, }; - asn1_context_t* ctx = asn1_context_new(truncated, sizeof(truncated)); - EXPECT_EQ(NULL, asn1_constructed_get(ctx)); - asn1_context_free(ctx); -} - -TEST_F(Asn1DecoderTest, ConstructedGet_LengthTooBig_Failure) { - uint8_t truncated[] = { 0xA0, 0x8a, 0xA5, 0x5A, 0xA5, 0x5A, - 0xA5, 0x5A, 0xA5, 0x5A, 0xA5, 0x5A, }; - asn1_context_t* ctx = asn1_context_new(truncated, sizeof(truncated)); - EXPECT_EQ(NULL, asn1_constructed_get(ctx)); - asn1_context_free(ctx); -} - -TEST_F(Asn1DecoderTest, ConstructedGet_TooSmallForChild_Failure) { - uint8_t data[] = { 0xA5, 0x02, 0x06, 0x01, 0x01, }; - asn1_context_t* ctx = asn1_context_new(data, sizeof(data)); - asn1_context_t* ptr = asn1_constructed_get(ctx); - ASSERT_NE((asn1_context_t*)NULL, ptr); - EXPECT_EQ(5, asn1_constructed_type(ptr)); - const uint8_t* oid; - size_t length; - EXPECT_FALSE(asn1_oid_get(ptr, &oid, &length)); - asn1_context_free(ptr); - asn1_context_free(ctx); -} - -TEST_F(Asn1DecoderTest, ConstructedGet_Success) { - uint8_t data[] = { 0xA5, 0x03, 0x06, 0x01, 0x01, }; - asn1_context_t* ctx = asn1_context_new(data, sizeof(data)); - asn1_context_t* ptr = asn1_constructed_get(ctx); - ASSERT_NE((asn1_context_t*)NULL, ptr); - EXPECT_EQ(5, asn1_constructed_type(ptr)); - const uint8_t* oid; - size_t length; - ASSERT_TRUE(asn1_oid_get(ptr, &oid, &length)); - EXPECT_EQ(1U, length); - EXPECT_EQ(0x01U, *oid); - asn1_context_free(ptr); - asn1_context_free(ctx); -} - -TEST_F(Asn1DecoderTest, ConstructedSkipAll_TruncatedLength_Failure) { - uint8_t truncated[] = { 0xA2, 0x82, }; - asn1_context_t* ctx = asn1_context_new(truncated, sizeof(truncated)); - EXPECT_FALSE(asn1_constructed_skip_all(ctx)); - asn1_context_free(ctx); -} - -TEST_F(Asn1DecoderTest, ConstructedSkipAll_Success) { - uint8_t data[] = { 0xA0, 0x03, 0x02, 0x01, 0x01, - 0xA1, 0x03, 0x02, 0x01, 0x01, - 0x06, 0x01, 0xA5, }; - asn1_context_t* ctx = asn1_context_new(data, sizeof(data)); - ASSERT_TRUE(asn1_constructed_skip_all(ctx)); - const uint8_t* oid; - size_t length; - ASSERT_TRUE(asn1_oid_get(ctx, &oid, &length)); - EXPECT_EQ(1U, length); - EXPECT_EQ(0xA5U, *oid); - asn1_context_free(ctx); -} - -TEST_F(Asn1DecoderTest, SequenceGet_TruncatedLength_Failure) { - uint8_t truncated[] = { 0x30, 0x82, }; - asn1_context_t* ctx = asn1_context_new(truncated, sizeof(truncated)); - EXPECT_EQ(NULL, asn1_sequence_get(ctx)); - asn1_context_free(ctx); -} - -TEST_F(Asn1DecoderTest, SequenceGet_TooSmallForChild_Failure) { - uint8_t data[] = { 0x30, 0x02, 0x06, 0x01, 0x01, }; - asn1_context_t* ctx = asn1_context_new(data, sizeof(data)); - asn1_context_t* ptr = asn1_sequence_get(ctx); - ASSERT_NE((asn1_context_t*)NULL, ptr); - const uint8_t* oid; - size_t length; - EXPECT_FALSE(asn1_oid_get(ptr, &oid, &length)); - asn1_context_free(ptr); - asn1_context_free(ctx); -} - -TEST_F(Asn1DecoderTest, SequenceGet_Success) { - uint8_t data[] = { 0x30, 0x03, 0x06, 0x01, 0x01, }; - asn1_context_t* ctx = asn1_context_new(data, sizeof(data)); - asn1_context_t* ptr = asn1_sequence_get(ctx); - ASSERT_NE((asn1_context_t*)NULL, ptr); - const uint8_t* oid; - size_t length; - ASSERT_TRUE(asn1_oid_get(ptr, &oid, &length)); - EXPECT_EQ(1U, length); - EXPECT_EQ(0x01U, *oid); - asn1_context_free(ptr); - asn1_context_free(ctx); -} - -TEST_F(Asn1DecoderTest, SetGet_TruncatedLength_Failure) { - uint8_t truncated[] = { 0x31, 0x82, }; - asn1_context_t* ctx = asn1_context_new(truncated, sizeof(truncated)); - EXPECT_EQ(NULL, asn1_set_get(ctx)); - asn1_context_free(ctx); -} - -TEST_F(Asn1DecoderTest, SetGet_TooSmallForChild_Failure) { - uint8_t data[] = { 0x31, 0x02, 0x06, 0x01, 0x01, }; - asn1_context_t* ctx = asn1_context_new(data, sizeof(data)); - asn1_context_t* ptr = asn1_set_get(ctx); - ASSERT_NE((asn1_context_t*)NULL, ptr); - const uint8_t* oid; - size_t length; - EXPECT_FALSE(asn1_oid_get(ptr, &oid, &length)); - asn1_context_free(ptr); - asn1_context_free(ctx); -} - -TEST_F(Asn1DecoderTest, SetGet_Success) { - uint8_t data[] = { 0x31, 0x03, 0x06, 0x01, 0xBA, }; - asn1_context_t* ctx = asn1_context_new(data, sizeof(data)); - asn1_context_t* ptr = asn1_set_get(ctx); - ASSERT_NE((asn1_context_t*)NULL, ptr); - const uint8_t* oid; - size_t length; - ASSERT_TRUE(asn1_oid_get(ptr, &oid, &length)); - EXPECT_EQ(1U, length); - EXPECT_EQ(0xBAU, *oid); - asn1_context_free(ptr); - asn1_context_free(ctx); -} - -TEST_F(Asn1DecoderTest, OidGet_LengthZero_Failure) { - uint8_t data[] = { 0x06, 0x00, 0x01, }; - asn1_context_t* ctx = asn1_context_new(data, sizeof(data)); - const uint8_t* oid; - size_t length; - EXPECT_FALSE(asn1_oid_get(ctx, &oid, &length)); - asn1_context_free(ctx); -} - -TEST_F(Asn1DecoderTest, OidGet_TooSmall_Failure) { - uint8_t data[] = { 0x06, 0x01, }; - asn1_context_t* ctx = asn1_context_new(data, sizeof(data)); - const uint8_t* oid; - size_t length; - EXPECT_FALSE(asn1_oid_get(ctx, &oid, &length)); - asn1_context_free(ctx); -} - -TEST_F(Asn1DecoderTest, OidGet_Success) { - uint8_t data[] = { 0x06, 0x01, 0x99, }; - asn1_context_t* ctx = asn1_context_new(data, sizeof(data)); - const uint8_t* oid; - size_t length; - ASSERT_TRUE(asn1_oid_get(ctx, &oid, &length)); - EXPECT_EQ(1U, length); - EXPECT_EQ(0x99U, *oid); - asn1_context_free(ctx); -} - -TEST_F(Asn1DecoderTest, OctetStringGet_LengthZero_Failure) { - uint8_t data[] = { 0x04, 0x00, 0x55, }; - asn1_context_t* ctx = asn1_context_new(data, sizeof(data)); - const uint8_t* string; - size_t length; - ASSERT_FALSE(asn1_octet_string_get(ctx, &string, &length)); - asn1_context_free(ctx); -} - -TEST_F(Asn1DecoderTest, OctetStringGet_TooSmall_Failure) { - uint8_t data[] = { 0x04, 0x01, }; - asn1_context_t* ctx = asn1_context_new(data, sizeof(data)); - const uint8_t* string; - size_t length; - ASSERT_FALSE(asn1_octet_string_get(ctx, &string, &length)); - asn1_context_free(ctx); -} - -TEST_F(Asn1DecoderTest, OctetStringGet_Success) { - uint8_t data[] = { 0x04, 0x01, 0xAA, }; - asn1_context_t* ctx = asn1_context_new(data, sizeof(data)); - const uint8_t* string; - size_t length; - ASSERT_TRUE(asn1_octet_string_get(ctx, &string, &length)); - EXPECT_EQ(1U, length); - EXPECT_EQ(0xAAU, *string); - asn1_context_free(ctx); -} - -} // namespace android +TEST(Asn1DecoderTest, Empty_Failure) { + uint8_t empty[] = {}; + asn1_context ctx(empty, sizeof(empty)); + + ASSERT_EQ(nullptr, ctx.asn1_constructed_get()); + ASSERT_FALSE(ctx.asn1_constructed_skip_all()); + ASSERT_EQ(0, ctx.asn1_constructed_type()); + ASSERT_EQ(nullptr, ctx.asn1_sequence_get()); + ASSERT_EQ(nullptr, ctx.asn1_set_get()); + ASSERT_FALSE(ctx.asn1_sequence_next()); + + const uint8_t* junk; + size_t length; + ASSERT_FALSE(ctx.asn1_oid_get(&junk, &length)); + ASSERT_FALSE(ctx.asn1_octet_string_get(&junk, &length)); +} + +TEST(Asn1DecoderTest, ConstructedGet_TruncatedLength_Failure) { + uint8_t truncated[] = { 0xA0, 0x82 }; + asn1_context ctx(truncated, sizeof(truncated)); + ASSERT_EQ(nullptr, ctx.asn1_constructed_get()); +} + +TEST(Asn1DecoderTest, ConstructedGet_LengthTooBig_Failure) { + uint8_t truncated[] = { 0xA0, 0x8a, 0xA5, 0x5A, 0xA5, 0x5A, 0xA5, 0x5A, 0xA5, 0x5A, 0xA5, 0x5A }; + asn1_context ctx(truncated, sizeof(truncated)); + ASSERT_EQ(nullptr, ctx.asn1_constructed_get()); +} + +TEST(Asn1DecoderTest, ConstructedGet_TooSmallForChild_Failure) { + uint8_t data[] = { 0xA5, 0x02, 0x06, 0x01, 0x01 }; + asn1_context ctx(data, sizeof(data)); + std::unique_ptr ptr(ctx.asn1_constructed_get()); + ASSERT_NE(nullptr, ptr); + ASSERT_EQ(5, ptr->asn1_constructed_type()); + const uint8_t* oid; + size_t length; + ASSERT_FALSE(ptr->asn1_oid_get(&oid, &length)); +} + +TEST(Asn1DecoderTest, ConstructedGet_Success) { + uint8_t data[] = { 0xA5, 0x03, 0x06, 0x01, 0x01 }; + asn1_context ctx(data, sizeof(data)); + std::unique_ptr ptr(ctx.asn1_constructed_get()); + ASSERT_NE(nullptr, ptr); + ASSERT_EQ(5, ptr->asn1_constructed_type()); + const uint8_t* oid; + size_t length; + ASSERT_TRUE(ptr->asn1_oid_get(&oid, &length)); + ASSERT_EQ(1U, length); + ASSERT_EQ(0x01U, *oid); +} + +TEST(Asn1DecoderTest, ConstructedSkipAll_TruncatedLength_Failure) { + uint8_t truncated[] = { 0xA2, 0x82 }; + asn1_context ctx(truncated, sizeof(truncated)); + ASSERT_FALSE(ctx.asn1_constructed_skip_all()); +} + +TEST(Asn1DecoderTest, ConstructedSkipAll_Success) { + uint8_t data[] = { 0xA0, 0x03, 0x02, 0x01, 0x01, 0xA1, 0x03, 0x02, 0x01, 0x01, 0x06, 0x01, 0xA5 }; + asn1_context ctx(data, sizeof(data)); + ASSERT_TRUE(ctx.asn1_constructed_skip_all()); + const uint8_t* oid; + size_t length; + ASSERT_TRUE(ctx.asn1_oid_get(&oid, &length)); + ASSERT_EQ(1U, length); + ASSERT_EQ(0xA5U, *oid); +} + +TEST(Asn1DecoderTest, SequenceGet_TruncatedLength_Failure) { + uint8_t truncated[] = { 0x30, 0x82 }; + asn1_context ctx(truncated, sizeof(truncated)); + ASSERT_EQ(nullptr, ctx.asn1_sequence_get()); +} + +TEST(Asn1DecoderTest, SequenceGet_TooSmallForChild_Failure) { + uint8_t data[] = { 0x30, 0x02, 0x06, 0x01, 0x01 }; + asn1_context ctx(data, sizeof(data)); + std::unique_ptr ptr(ctx.asn1_sequence_get()); + ASSERT_NE(nullptr, ptr); + const uint8_t* oid; + size_t length; + ASSERT_FALSE(ptr->asn1_oid_get(&oid, &length)); +} + +TEST(Asn1DecoderTest, SequenceGet_Success) { + uint8_t data[] = { 0x30, 0x03, 0x06, 0x01, 0x01 }; + asn1_context ctx(data, sizeof(data)); + std::unique_ptr ptr(ctx.asn1_sequence_get()); + ASSERT_NE(nullptr, ptr); + const uint8_t* oid; + size_t length; + ASSERT_TRUE(ptr->asn1_oid_get(&oid, &length)); + ASSERT_EQ(1U, length); + ASSERT_EQ(0x01U, *oid); +} + +TEST(Asn1DecoderTest, SetGet_TruncatedLength_Failure) { + uint8_t truncated[] = { 0x31, 0x82 }; + asn1_context ctx(truncated, sizeof(truncated)); + ASSERT_EQ(nullptr, ctx.asn1_set_get()); +} + +TEST(Asn1DecoderTest, SetGet_TooSmallForChild_Failure) { + uint8_t data[] = { 0x31, 0x02, 0x06, 0x01, 0x01 }; + asn1_context ctx(data, sizeof(data)); + std::unique_ptr ptr(ctx.asn1_set_get()); + ASSERT_NE(nullptr, ptr); + const uint8_t* oid; + size_t length; + ASSERT_FALSE(ptr->asn1_oid_get(&oid, &length)); +} + +TEST(Asn1DecoderTest, SetGet_Success) { + uint8_t data[] = { 0x31, 0x03, 0x06, 0x01, 0xBA }; + asn1_context ctx(data, sizeof(data)); + std::unique_ptr ptr(ctx.asn1_set_get()); + ASSERT_NE(nullptr, ptr); + const uint8_t* oid; + size_t length; + ASSERT_TRUE(ptr->asn1_oid_get(&oid, &length)); + ASSERT_EQ(1U, length); + ASSERT_EQ(0xBAU, *oid); +} + +TEST(Asn1DecoderTest, OidGet_LengthZero_Failure) { + uint8_t data[] = { 0x06, 0x00, 0x01 }; + asn1_context ctx(data, sizeof(data)); + const uint8_t* oid; + size_t length; + ASSERT_FALSE(ctx.asn1_oid_get(&oid, &length)); +} + +TEST(Asn1DecoderTest, OidGet_TooSmall_Failure) { + uint8_t data[] = { 0x06, 0x01 }; + asn1_context ctx(data, sizeof(data)); + const uint8_t* oid; + size_t length; + ASSERT_FALSE(ctx.asn1_oid_get(&oid, &length)); +} + +TEST(Asn1DecoderTest, OidGet_Success) { + uint8_t data[] = { 0x06, 0x01, 0x99 }; + asn1_context ctx(data, sizeof(data)); + const uint8_t* oid; + size_t length; + ASSERT_TRUE(ctx.asn1_oid_get(&oid, &length)); + ASSERT_EQ(1U, length); + ASSERT_EQ(0x99U, *oid); +} + +TEST(Asn1DecoderTest, OctetStringGet_LengthZero_Failure) { + uint8_t data[] = { 0x04, 0x00, 0x55 }; + asn1_context ctx(data, sizeof(data)); + const uint8_t* string; + size_t length; + ASSERT_FALSE(ctx.asn1_octet_string_get(&string, &length)); +} + +TEST(Asn1DecoderTest, OctetStringGet_TooSmall_Failure) { + uint8_t data[] = { 0x04, 0x01 }; + asn1_context ctx(data, sizeof(data)); + const uint8_t* string; + size_t length; + ASSERT_FALSE(ctx.asn1_octet_string_get(&string, &length)); +} + +TEST(Asn1DecoderTest, OctetStringGet_Success) { + uint8_t data[] = { 0x04, 0x01, 0xAA }; + asn1_context ctx(data, sizeof(data)); + const uint8_t* string; + size_t length; + ASSERT_TRUE(ctx.asn1_octet_string_get(&string, &length)); + ASSERT_EQ(1U, length); + ASSERT_EQ(0xAAU, *string); +} -- cgit v1.2.3 From 0a599567ce79a80d8d511505d34fa810b11e034e Mon Sep 17 00:00:00 2001 From: Tianjie Xu Date: Tue, 28 Mar 2017 20:11:15 +0000 Subject: Merge "Add the missing sr-Latn into png files and rename the png locale header" am: 713d915636 am: dc235b5ab9 am: 5ec12126f0 Change-Id: Ia6b861c91958d3be23a4a7456d6d5d8e4a1607c8 (cherry picked from commit 9166f66eee883d6d6cc280a6c355e5528bb4a3f0) --- tests/unit/locale_test.cpp | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) (limited to 'tests/unit') diff --git a/tests/unit/locale_test.cpp b/tests/unit/locale_test.cpp index f73235005..cdaba0e8b 100644 --- a/tests/unit/locale_test.cpp +++ b/tests/unit/locale_test.cpp @@ -19,14 +19,15 @@ #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")); - EXPECT_FALSE(matches_locale("en_US", "")); - // Empty locale prefix in the PNG file will match the input locale. - EXPECT_TRUE(matches_locale("", "en_US")); + EXPECT_TRUE(matches_locale("zh-CN", "zh-Hans-CN")); + EXPECT_TRUE(matches_locale("zh", "zh-Hans-CN")); + EXPECT_FALSE(matches_locale("zh-HK", "zh-Hans-CN")); + 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")); + EXPECT_FALSE(matches_locale("en-US", "")); + // Empty locale prefix in the PNG file will match the input locale. + EXPECT_TRUE(matches_locale("", "en-US")); + EXPECT_TRUE(matches_locale("sr-Latn", "sr-Latn-BA")); } -- cgit v1.2.3