summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/Android.bp230
-rw-r--r--tests/Android.build.prebuilt.mk30
-rw-r--r--tests/Android.mk37
-rw-r--r--tests/dirent_test.cpp12
-rw-r--r--tests/dlext_private.h4
-rw-r--r--tests/dlext_test.cpp12
-rw-r--r--tests/dlfcn_test.cpp36
-rw-r--r--tests/fortify_test.cpp10
-rw-r--r--tests/grp_pwd_test.cpp18
-rw-r--r--tests/gtest_globals.cpp5
-rw-r--r--tests/gtest_globals.h6
-rw-r--r--tests/libs/Android.bp17
-rw-r--r--tests/libs/thread_exit_cb_helper.cpp66
-rw-r--r--tests/libs/tls_properties_helper.cpp83
-rw-r--r--tests/netinet_ether_test.cpp10
-rw-r--r--tests/netinet_in_test.cpp9
-rw-r--r--tests/pty_test.cpp54
-rw-r--r--tests/sched_test.cpp4
-rw-r--r--tests/search_test.cpp28
-rw-r--r--tests/stdio_test.cpp87
-rw-r--r--tests/stdlib_test.cpp27
-rw-r--r--tests/string_test.cpp67
-rw-r--r--tests/sys_procfs_test.cpp15
-rw-r--r--tests/sys_thread_properties_test.cpp47
-rw-r--r--tests/sys_vfs_test.cpp28
-rw-r--r--tests/sys_wait_test.cpp44
-rw-r--r--tests/time_test.cpp102
-rw-r--r--tests/unistd_test.cpp31
-rw-r--r--tests/utmp_test.cpp6
29 files changed, 959 insertions, 166 deletions
diff --git a/tests/Android.bp b/tests/Android.bp
index 598865bd7..586ef344e 100644
--- a/tests/Android.bp
+++ b/tests/Android.bp
@@ -72,6 +72,217 @@ cc_defaults {
}
// -----------------------------------------------------------------------------
+// Prebuilt shared libraries for use in tests.
+// -----------------------------------------------------------------------------
+
+cc_prebuilt_test_library_shared {
+ name: "libtest_invalid-rw_load_segment",
+ strip: {
+ none: true,
+ },
+ check_elf_files: false,
+ relative_install_path: "bionic-loader-test-libs/prebuilt-elf-files",
+ arch: {
+ arm: {
+ srcs: ["prebuilt-elf-files/arm/libtest_invalid-rw_load_segment.so"],
+ },
+ arm64: {
+ srcs: ["prebuilt-elf-files/arm64/libtest_invalid-rw_load_segment.so"],
+ },
+ x86: {
+ srcs: ["prebuilt-elf-files/x86/libtest_invalid-rw_load_segment.so"],
+ },
+ x86_64: {
+ srcs: ["prebuilt-elf-files/x86_64/libtest_invalid-rw_load_segment.so"],
+ },
+ },
+}
+
+cc_prebuilt_test_library_shared {
+ name: "libtest_invalid-unaligned_shdr_offset",
+ strip: {
+ none: true,
+ },
+ check_elf_files: false,
+ relative_install_path: "bionic-loader-test-libs/prebuilt-elf-files",
+ arch: {
+ arm: {
+ srcs: ["prebuilt-elf-files/arm/libtest_invalid-unaligned_shdr_offset.so"],
+ },
+ arm64: {
+ srcs: ["prebuilt-elf-files/arm64/libtest_invalid-unaligned_shdr_offset.so"],
+ },
+ x86: {
+ srcs: ["prebuilt-elf-files/x86/libtest_invalid-unaligned_shdr_offset.so"],
+ },
+ x86_64: {
+ srcs: ["prebuilt-elf-files/x86_64/libtest_invalid-unaligned_shdr_offset.so"],
+ },
+ },
+}
+
+cc_prebuilt_test_library_shared {
+ name: "libtest_invalid-zero_shentsize",
+ strip: {
+ none: true,
+ },
+ check_elf_files: false,
+ relative_install_path: "bionic-loader-test-libs/prebuilt-elf-files",
+ arch: {
+ arm: {
+ srcs: ["prebuilt-elf-files/arm/libtest_invalid-zero_shentsize.so"],
+ },
+ arm64: {
+ srcs: ["prebuilt-elf-files/arm64/libtest_invalid-zero_shentsize.so"],
+ },
+ x86: {
+ srcs: ["prebuilt-elf-files/x86/libtest_invalid-zero_shentsize.so"],
+ },
+ x86_64: {
+ srcs: ["prebuilt-elf-files/x86_64/libtest_invalid-zero_shentsize.so"],
+ },
+ },
+}
+
+cc_prebuilt_test_library_shared {
+ name: "libtest_invalid-zero_shstrndx",
+ strip: {
+ none: true,
+ },
+ check_elf_files: false,
+ relative_install_path: "bionic-loader-test-libs/prebuilt-elf-files",
+ arch: {
+ arm: {
+ srcs: ["prebuilt-elf-files/arm/libtest_invalid-zero_shstrndx.so"],
+ },
+ arm64: {
+ srcs: ["prebuilt-elf-files/arm64/libtest_invalid-zero_shstrndx.so"],
+ },
+ x86: {
+ srcs: ["prebuilt-elf-files/x86/libtest_invalid-zero_shstrndx.so"],
+ },
+ x86_64: {
+ srcs: ["prebuilt-elf-files/x86_64/libtest_invalid-zero_shstrndx.so"],
+ },
+ },
+}
+
+cc_prebuilt_test_library_shared {
+ name: "libtest_invalid-empty_shdr_table",
+ strip: {
+ none: true,
+ },
+ check_elf_files: false,
+ relative_install_path: "bionic-loader-test-libs/prebuilt-elf-files",
+ arch: {
+ arm: {
+ srcs: ["prebuilt-elf-files/arm/libtest_invalid-empty_shdr_table.so"],
+ },
+ arm64: {
+ srcs: ["prebuilt-elf-files/arm64/libtest_invalid-empty_shdr_table.so"],
+ },
+ x86: {
+ srcs: ["prebuilt-elf-files/x86/libtest_invalid-empty_shdr_table.so"],
+ },
+ x86_64: {
+ srcs: ["prebuilt-elf-files/x86_64/libtest_invalid-empty_shdr_table.so"],
+ },
+ },
+}
+
+cc_prebuilt_test_library_shared {
+ name: "libtest_invalid-zero_shdr_table_offset",
+ strip: {
+ none: true,
+ },
+ check_elf_files: false,
+ relative_install_path: "bionic-loader-test-libs/prebuilt-elf-files",
+ arch: {
+ arm: {
+ srcs: ["prebuilt-elf-files/arm/libtest_invalid-zero_shdr_table_offset.so"],
+ },
+ arm64: {
+ srcs: ["prebuilt-elf-files/arm64/libtest_invalid-zero_shdr_table_offset.so"],
+ },
+ x86: {
+ srcs: ["prebuilt-elf-files/x86/libtest_invalid-zero_shdr_table_offset.so"],
+ },
+ x86_64: {
+ srcs: ["prebuilt-elf-files/x86_64/libtest_invalid-zero_shdr_table_offset.so"],
+ },
+ },
+}
+
+cc_prebuilt_test_library_shared {
+ name: "libtest_invalid-zero_shdr_table_content",
+ strip: {
+ none: true,
+ },
+ check_elf_files: false,
+ relative_install_path: "bionic-loader-test-libs/prebuilt-elf-files",
+ arch: {
+ arm: {
+ srcs: ["prebuilt-elf-files/arm/libtest_invalid-zero_shdr_table_content.so"],
+ },
+ arm64: {
+ srcs: ["prebuilt-elf-files/arm64/libtest_invalid-zero_shdr_table_content.so"],
+ },
+ x86: {
+ srcs: ["prebuilt-elf-files/x86/libtest_invalid-zero_shdr_table_content.so"],
+ },
+ x86_64: {
+ srcs: ["prebuilt-elf-files/x86_64/libtest_invalid-zero_shdr_table_content.so"],
+ },
+ },
+}
+
+cc_prebuilt_test_library_shared {
+ name: "libtest_invalid-textrels",
+ strip: {
+ none: true,
+ },
+ check_elf_files: false,
+ relative_install_path: "bionic-loader-test-libs/prebuilt-elf-files",
+ arch: {
+ arm: {
+ srcs: ["prebuilt-elf-files/arm/libtest_invalid-textrels.so"],
+ },
+ arm64: {
+ srcs: ["prebuilt-elf-files/arm64/libtest_invalid-textrels.so"],
+ },
+ x86: {
+ srcs: ["prebuilt-elf-files/x86/libtest_invalid-textrels.so"],
+ },
+ x86_64: {
+ srcs: ["prebuilt-elf-files/x86_64/libtest_invalid-textrels.so"],
+ },
+ },
+}
+
+cc_prebuilt_test_library_shared {
+ name: "libtest_invalid-textrels2",
+ strip: {
+ none: true,
+ },
+ check_elf_files: false,
+ relative_install_path: "bionic-loader-test-libs/prebuilt-elf-files",
+ arch: {
+ arm: {
+ srcs: ["prebuilt-elf-files/arm/libtest_invalid-textrels2.so"],
+ },
+ arm64: {
+ srcs: ["prebuilt-elf-files/arm64/libtest_invalid-textrels2.so"],
+ },
+ x86: {
+ srcs: ["prebuilt-elf-files/x86/libtest_invalid-textrels2.so"],
+ },
+ x86_64: {
+ srcs: ["prebuilt-elf-files/x86_64/libtest_invalid-textrels2.so"],
+ },
+ },
+}
+
+// -----------------------------------------------------------------------------
// All standard tests.
// -----------------------------------------------------------------------------
@@ -211,6 +422,7 @@ cc_test_library {
"sys_uio_test.cpp",
"sys_un_test.cpp",
"sys_vfs_test.cpp",
+ "sys_wait_test.cpp",
"sys_xattr_test.cpp",
"system_properties_test.cpp",
"system_properties_test2.cpp",
@@ -736,15 +948,15 @@ cc_defaults {
"libtest_with_dependency_loop",
"libtest_with_dependency",
"libtest_indirect_thread_local_dtor",
- "libtest_invalid-empty_shdr_table.so",
- "libtest_invalid-rw_load_segment.so",
- "libtest_invalid-unaligned_shdr_offset.so",
- "libtest_invalid-zero_shdr_table_content.so",
- "libtest_invalid-zero_shdr_table_offset.so",
- "libtest_invalid-zero_shentsize.so",
- "libtest_invalid-zero_shstrndx.so",
- "libtest_invalid-textrels.so",
- "libtest_invalid-textrels2.so",
+ "libtest_invalid-empty_shdr_table",
+ "libtest_invalid-rw_load_segment",
+ "libtest_invalid-unaligned_shdr_offset",
+ "libtest_invalid-zero_shdr_table_content",
+ "libtest_invalid-zero_shdr_table_offset",
+ "libtest_invalid-zero_shentsize",
+ "libtest_invalid-zero_shstrndx",
+ "libtest_invalid-textrels",
+ "libtest_invalid-textrels2",
"libtest_thread_local_dtor",
"libtest_thread_local_dtor2",
"preinit_getauxval_test_helper",
diff --git a/tests/Android.build.prebuilt.mk b/tests/Android.build.prebuilt.mk
deleted file mode 100644
index de8f5e6c5..000000000
--- a/tests/Android.build.prebuilt.mk
+++ /dev/null
@@ -1,30 +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 $(CLEAR_VARS)
-LOCAL_MULTILIB := both
-LOCAL_MODULE := $(bionic_tests_module)
-LOCAL_MODULE_PATH_32 := $($(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_DATA_NATIVE_TESTS)/bionic-loader-test-libs/prebuilt-elf-files
-LOCAL_MODULE_PATH_64 := $(TARGET_OUT_DATA_NATIVE_TESTS)/bionic-loader-test-libs/prebuilt-elf-files
-LOCAL_MODULE_CLASS := EXECUTABLES
-
-LOCAL_SRC_FILES_arm := prebuilt-elf-files/arm/$(bionic_tests_module)
-LOCAL_SRC_FILES_arm64 := prebuilt-elf-files/arm64/$(bionic_tests_module)
-LOCAL_SRC_FILES_x86 := prebuilt-elf-files/x86/$(bionic_tests_module)
-LOCAL_SRC_FILES_x86_64 := prebuilt-elf-files/x86_64/$(bionic_tests_module)
-include $(BUILD_PREBUILT)
-bionic-loader-test-libs-target: $(LOCAL_MODULE)
-.PHONY: bionic-loader-test-libs-target
diff --git a/tests/Android.mk b/tests/Android.mk
index b5571e3f6..5ad4045bd 100644
--- a/tests/Android.mk
+++ b/tests/Android.mk
@@ -16,43 +16,6 @@
LOCAL_PATH := $(call my-dir)
-# TODO(dimitry): replace with define once https://android-review.googlesource.com/247466 is reverted
-# https://github.com/google/kati/issues/83 is currently blocking it.
-
-# Move prebuilt test elf-files to $(TARGET_OUT_NATIVE_TESTS)
-bionic_tests_module := libtest_invalid-rw_load_segment.so
-include $(LOCAL_PATH)/Android.build.prebuilt.mk
-
-bionic_tests_module := libtest_invalid-unaligned_shdr_offset.so
-include $(LOCAL_PATH)/Android.build.prebuilt.mk
-
-bionic_tests_module := libtest_invalid-zero_shentsize.so
-include $(LOCAL_PATH)/Android.build.prebuilt.mk
-
-bionic_tests_module := libtest_invalid-zero_shstrndx.so
-include $(LOCAL_PATH)/Android.build.prebuilt.mk
-
-bionic_tests_module := libtest_invalid-empty_shdr_table.so
-include $(LOCAL_PATH)/Android.build.prebuilt.mk
-
-bionic_tests_module := libtest_invalid-zero_shdr_table_offset.so
-include $(LOCAL_PATH)/Android.build.prebuilt.mk
-
-bionic_tests_module := libtest_invalid-zero_shdr_table_content.so
-include $(LOCAL_PATH)/Android.build.prebuilt.mk
-
-bionic_tests_module := libtest_invalid-textrels.so
-include $(LOCAL_PATH)/Android.build.prebuilt.mk
-
-bionic_tests_module := libtest_invalid-textrels2.so
-include $(LOCAL_PATH)/Android.build.prebuilt.mk
-
-ifeq ($(HOST_OS)-$(HOST_ARCH),$(filter $(HOST_OS)-$(HOST_ARCH),linux-x86 linux-x86_64))
-build_host := true
-else
-build_host := false
-endif
-
ifeq ($(HOST_OS)-$(HOST_ARCH),$(filter $(HOST_OS)-$(HOST_ARCH),linux-x86 linux-x86_64))
# -----------------------------------------------------------------------------
diff --git a/tests/dirent_test.cpp b/tests/dirent_test.cpp
index 378aea41e..56929d138 100644
--- a/tests/dirent_test.cpp
+++ b/tests/dirent_test.cpp
@@ -113,6 +113,18 @@ TEST(dirent, scandirat_scandirat64) {
ASSERT_EQ(unsorted_name_list, unsorted_name_list_at64);
}
+static int is_version_filter(const dirent* de) {
+ return !strcmp(de->d_name, "version");
+}
+
+TEST(dirent, scandir_filter) {
+ dirent** entries;
+ errno = 0;
+ ASSERT_EQ(1, scandir("/proc", &entries, is_version_filter, nullptr));
+ ASSERT_STREQ("version", entries[0]->d_name);
+ free(entries);
+}
+
TEST(dirent, scandir_ENOENT) {
dirent** entries;
errno = 0;
diff --git a/tests/dlext_private.h b/tests/dlext_private.h
index b338ae01f..262af4c25 100644
--- a/tests/dlext_private.h
+++ b/tests/dlext_private.h
@@ -56,10 +56,10 @@ enum {
*/
ANDROID_NAMESPACE_TYPE_SHARED = 2,
- /* This flag instructs linker to enable grey-list workaround for the namespace.
+ /* This flag instructs linker to enable exempt-list workaround for the namespace.
* See http://b/26394120 for details.
*/
- ANDROID_NAMESPACE_TYPE_GREYLIST_ENABLED = 0x08000000,
+ ANDROID_NAMESPACE_TYPE_EXEMPT_LIST_ENABLED = 0x08000000,
ANDROID_NAMESPACE_TYPE_SHARED_ISOLATED = ANDROID_NAMESPACE_TYPE_SHARED |
ANDROID_NAMESPACE_TYPE_ISOLATED,
diff --git a/tests/dlext_test.cpp b/tests/dlext_test.cpp
index 4c4a1c3e8..01bf8ab51 100644
--- a/tests/dlext_test.cpp
+++ b/tests/dlext_test.cpp
@@ -1228,7 +1228,7 @@ TEST(dlext, ns_unload_between_namespaces_missing_symbol_indirect) {
dlerror());
}
-TEST(dlext, ns_greylist_enabled) {
+TEST(dlext, ns_exempt_list_enabled) {
ASSERT_TRUE(android_init_anonymous_namespace(g_core_shared_libs.c_str(), nullptr));
const std::string ns_search_path = GetTestlibRoot() + "/private_namespace_libs";
@@ -1237,7 +1237,7 @@ TEST(dlext, ns_greylist_enabled) {
android_create_namespace("namespace",
nullptr,
ns_search_path.c_str(),
- ANDROID_NAMESPACE_TYPE_ISOLATED | ANDROID_NAMESPACE_TYPE_GREYLIST_ENABLED,
+ ANDROID_NAMESPACE_TYPE_ISOLATED | ANDROID_NAMESPACE_TYPE_EXEMPT_LIST_ENABLED,
nullptr,
nullptr);
@@ -1247,26 +1247,26 @@ TEST(dlext, ns_greylist_enabled) {
extinfo.flags = ANDROID_DLEXT_USE_NAMESPACE;
extinfo.library_namespace = ns;
- // An app targeting M can open libnativehelper.so because it's on the greylist.
+ // An app targeting M can open libnativehelper.so because it's on the exempt-list.
android_set_application_target_sdk_version(23);
void* handle = android_dlopen_ext("libnativehelper.so", RTLD_NOW, &extinfo);
ASSERT_TRUE(handle != nullptr) << dlerror();
- // Check that loader did not load another copy of libdl.so while loading greylisted library.
+ // Check that loader did not load another copy of libdl.so while loading exempted library.
void* dlsym_ptr = dlsym(handle, "dlsym");
ASSERT_TRUE(dlsym_ptr != nullptr) << dlerror();
ASSERT_EQ(&dlsym, dlsym_ptr);
dlclose(handle);
- // An app targeting N no longer has the greylist.
+ // An app targeting N no longer has the exempt-list.
android_set_application_target_sdk_version(24);
handle = android_dlopen_ext("libnativehelper.so", RTLD_NOW, &extinfo);
ASSERT_TRUE(handle == nullptr);
ASSERT_STREQ("dlopen failed: library \"libnativehelper.so\" not found", dlerror());
}
-TEST(dlext, ns_greylist_disabled_by_default) {
+TEST(dlext, ns_exempt_list_disabled_by_default) {
ASSERT_TRUE(android_init_anonymous_namespace(g_core_shared_libs.c_str(), nullptr));
const std::string ns_search_path = GetTestlibRoot() + "/private_namespace_libs";
diff --git a/tests/dlfcn_test.cpp b/tests/dlfcn_test.cpp
index d7b9bae64..35e12eb4a 100644
--- a/tests/dlfcn_test.cpp
+++ b/tests/dlfcn_test.cpp
@@ -1623,9 +1623,7 @@ TEST(dlext, compat_elf_hash_and_relocation_tables) {
#endif // defined(__arm__)
TEST(dlfcn, dlopen_invalid_rw_load_segment) {
- const std::string libpath = GetTestlibRoot() +
- "/" + kPrebuiltElfDir +
- "/libtest_invalid-rw_load_segment.so";
+ const std::string libpath = GetPrebuiltElfDir() + "/libtest_invalid-rw_load_segment.so";
void* handle = dlopen(libpath.c_str(), RTLD_NOW);
ASSERT_TRUE(handle == nullptr);
std::string expected_dlerror = std::string("dlopen failed: \"") + libpath + "\": W+E load segments are not allowed";
@@ -1633,9 +1631,7 @@ TEST(dlfcn, dlopen_invalid_rw_load_segment) {
}
TEST(dlfcn, dlopen_invalid_unaligned_shdr_offset) {
- const std::string libpath = GetTestlibRoot() +
- "/" + kPrebuiltElfDir +
- "/libtest_invalid-unaligned_shdr_offset.so";
+ const std::string libpath = GetPrebuiltElfDir() + "/libtest_invalid-unaligned_shdr_offset.so";
void* handle = dlopen(libpath.c_str(), RTLD_NOW);
ASSERT_TRUE(handle == nullptr);
@@ -1644,9 +1640,7 @@ TEST(dlfcn, dlopen_invalid_unaligned_shdr_offset) {
}
TEST(dlfcn, dlopen_invalid_zero_shentsize) {
- const std::string libpath = GetTestlibRoot() +
- "/" + kPrebuiltElfDir +
- "/libtest_invalid-zero_shentsize.so";
+ const std::string libpath = GetPrebuiltElfDir() + "/libtest_invalid-zero_shentsize.so";
void* handle = dlopen(libpath.c_str(), RTLD_NOW);
ASSERT_TRUE(handle == nullptr);
@@ -1655,9 +1649,7 @@ TEST(dlfcn, dlopen_invalid_zero_shentsize) {
}
TEST(dlfcn, dlopen_invalid_zero_shstrndx) {
- const std::string libpath = GetTestlibRoot() +
- "/" + kPrebuiltElfDir +
- "/libtest_invalid-zero_shstrndx.so";
+ const std::string libpath = GetPrebuiltElfDir() + "/libtest_invalid-zero_shstrndx.so";
void* handle = dlopen(libpath.c_str(), RTLD_NOW);
ASSERT_TRUE(handle == nullptr);
@@ -1666,9 +1658,7 @@ TEST(dlfcn, dlopen_invalid_zero_shstrndx) {
}
TEST(dlfcn, dlopen_invalid_empty_shdr_table) {
- const std::string libpath = GetTestlibRoot() +
- "/" + kPrebuiltElfDir +
- "/libtest_invalid-empty_shdr_table.so";
+ const std::string libpath = GetPrebuiltElfDir() + "/libtest_invalid-empty_shdr_table.so";
void* handle = dlopen(libpath.c_str(), RTLD_NOW);
ASSERT_TRUE(handle == nullptr);
@@ -1677,9 +1667,7 @@ TEST(dlfcn, dlopen_invalid_empty_shdr_table) {
}
TEST(dlfcn, dlopen_invalid_zero_shdr_table_offset) {
- const std::string libpath = GetTestlibRoot() +
- "/" + kPrebuiltElfDir +
- "/libtest_invalid-zero_shdr_table_offset.so";
+ const std::string libpath = GetPrebuiltElfDir() + "/libtest_invalid-zero_shdr_table_offset.so";
void* handle = dlopen(libpath.c_str(), RTLD_NOW);
ASSERT_TRUE(handle == nullptr);
@@ -1688,9 +1676,7 @@ TEST(dlfcn, dlopen_invalid_zero_shdr_table_offset) {
}
TEST(dlfcn, dlopen_invalid_zero_shdr_table_content) {
- const std::string libpath = GetTestlibRoot() +
- "/" + kPrebuiltElfDir +
- "/libtest_invalid-zero_shdr_table_content.so";
+ const std::string libpath = GetPrebuiltElfDir() + "/libtest_invalid-zero_shdr_table_content.so";
void* handle = dlopen(libpath.c_str(), RTLD_NOW);
ASSERT_TRUE(handle == nullptr);
@@ -1699,9 +1685,7 @@ TEST(dlfcn, dlopen_invalid_zero_shdr_table_content) {
}
TEST(dlfcn, dlopen_invalid_textrels) {
- const std::string libpath = GetTestlibRoot() +
- "/" + kPrebuiltElfDir +
- "/libtest_invalid-textrels.so";
+ const std::string libpath = GetPrebuiltElfDir() + "/libtest_invalid-textrels.so";
void* handle = dlopen(libpath.c_str(), RTLD_NOW);
ASSERT_TRUE(handle == nullptr);
@@ -1710,9 +1694,7 @@ TEST(dlfcn, dlopen_invalid_textrels) {
}
TEST(dlfcn, dlopen_invalid_textrels2) {
- const std::string libpath = GetTestlibRoot() +
- "/" + kPrebuiltElfDir +
- "/libtest_invalid-textrels2.so";
+ const std::string libpath = GetPrebuiltElfDir() + "/libtest_invalid-textrels2.so";
void* handle = dlopen(libpath.c_str(), RTLD_NOW);
ASSERT_TRUE(handle == nullptr);
diff --git a/tests/fortify_test.cpp b/tests/fortify_test.cpp
index 6907abe9b..3ca0223b2 100644
--- a/tests/fortify_test.cpp
+++ b/tests/fortify_test.cpp
@@ -204,8 +204,9 @@ TEST_F(DEATHTEST, memchr_fortified2) {
foo myfoo;
volatile int asize = sizeof(myfoo.a) + 1;
memcpy(myfoo.a, "0123456789", sizeof(myfoo.a));
- ASSERT_FORTIFY(printf("%s", memchr(myfoo.a, 'a', asize)));
- ASSERT_FORTIFY(printf("%s", memchr(static_cast<const void*>(myfoo.a), 'a', asize)));
+ ASSERT_FORTIFY(printf("%s", static_cast<const char*>(memchr(myfoo.a, 'a', asize))));
+ ASSERT_FORTIFY(printf(
+ "%s", static_cast<const char*>(memchr(static_cast<const void*>(myfoo.a), 'a', asize))));
#else // __BIONIC__
GTEST_SKIP() << "glibc is broken";
#endif // __BIONIC__
@@ -216,8 +217,9 @@ TEST_F(DEATHTEST, memrchr_fortified2) {
foo myfoo;
volatile int asize = sizeof(myfoo.a) + 1;
memcpy(myfoo.a, "0123456789", sizeof(myfoo.a));
- ASSERT_FORTIFY(printf("%s", memrchr(myfoo.a, 'a', asize)));
- ASSERT_FORTIFY(printf("%s", memrchr(static_cast<const void*>(myfoo.a), 'a', asize)));
+ ASSERT_FORTIFY(printf("%s", static_cast<const char*>(memrchr(myfoo.a, 'a', asize))));
+ ASSERT_FORTIFY(printf(
+ "%s", static_cast<const char*>(memrchr(static_cast<const void*>(myfoo.a), 'a', asize))));
#else // __BIONIC__
GTEST_SKIP() << "glibc is broken";
#endif // __BIONIC__
diff --git a/tests/grp_pwd_test.cpp b/tests/grp_pwd_test.cpp
index 99117e45b..bf65720f9 100644
--- a/tests/grp_pwd_test.cpp
+++ b/tests/grp_pwd_test.cpp
@@ -820,6 +820,24 @@ TEST(grp, getgrent_iterate) {
#endif
}
+TEST(grp, getgrouplist) {
+#if defined(__BIONIC__)
+ // Query the number of groups.
+ int ngroups = 0;
+ ASSERT_EQ(-1, getgrouplist("root", 123, nullptr, &ngroups));
+ ASSERT_EQ(1, ngroups);
+
+ // Query the specific groups (just the one you pass in on Android).
+ ngroups = 8;
+ gid_t groups[ngroups];
+ ASSERT_EQ(1, getgrouplist("root", 123, groups, &ngroups));
+ ASSERT_EQ(1, ngroups);
+ ASSERT_EQ(123u, groups[0]);
+#else
+ GTEST_SKIP() << "bionic-only test (groups too unpredictable)";
+#endif
+}
+
#if defined(__BIONIC__)
static void TestAidNamePrefix(const std::string& file_path) {
std::string file_contents;
diff --git a/tests/gtest_globals.cpp b/tests/gtest_globals.cpp
index 4160237ab..5b5ede8d4 100644
--- a/tests/gtest_globals.cpp
+++ b/tests/gtest_globals.cpp
@@ -24,8 +24,9 @@
#include <string>
std::string GetTestlibRoot() {
- // Calculate ANDROID_DATA assuming the binary is in "$ANDROID_DATA/somedir/binary-dir/binary"
- std::string path = android::base::Dirname(android::base::GetExecutablePath()) + "/..";
+ // Typically the executable is /data/nativetest[64]/bionic-unit-tests/bionic-unit-tests, and the
+ // test libraries are in /data/nativetest[64]/bionic-loader-test-libs.
+ std::string path = android::base::GetExecutableDirectory() + "/..";
std::string out_path;
if (!android::base::Realpath(path.c_str(), &out_path)) {
diff --git a/tests/gtest_globals.h b/tests/gtest_globals.h
index b3c7b102d..1bebb7006 100644
--- a/tests/gtest_globals.h
+++ b/tests/gtest_globals.h
@@ -19,8 +19,10 @@
#include <string>
-constexpr const char* kPrebuiltElfDir = "prebuilt-elf-files";
-
std::string GetTestlibRoot();
+inline std::string GetPrebuiltElfDir() {
+ return GetTestlibRoot() + "/prebuilt-elf-files";
+}
+
#endif // _BIONIC_TESTS_GTEST_GLOBALS_H
diff --git a/tests/libs/Android.bp b/tests/libs/Android.bp
index c427282c1..ef4fddd45 100644
--- a/tests/libs/Android.bp
+++ b/tests/libs/Android.bp
@@ -79,6 +79,22 @@ cc_test_library {
shared_libs: ["libtest_elftls_shared_var"],
}
+cc_test {
+ name: "thread_exit_cb_helper.cpp",
+ defaults: ["bionic_testlib_defaults"],
+ srcs: ["thread_exit_cb_helper.cpp"],
+ cflags: ["-fno-emulated-tls"],
+}
+
+cc_test {
+ name: "tls_properties_helper",
+ defaults: ["bionic_testlib_defaults"],
+ srcs: ["tls_properties_helper.cpp"],
+ cflags: ["-fno-emulated-tls"],
+ shared_libs: ["libtest_elftls_shared_var"],
+}
+
+
cc_test_library {
name: "libtest_elftls_dynamic_filler_1",
defaults: ["bionic_testlib_defaults"],
@@ -1268,6 +1284,7 @@ cc_test_library {
name: "libtest_check_rtld_next_from_library",
defaults: ["bionic_testlib_defaults"],
srcs: ["check_rtld_next_from_library.cpp"],
+ native_coverage: false,
}
// -----------------------------------------------------------------------------
diff --git a/tests/libs/thread_exit_cb_helper.cpp b/tests/libs/thread_exit_cb_helper.cpp
new file mode 100644
index 000000000..8ec1398f1
--- /dev/null
+++ b/tests/libs/thread_exit_cb_helper.cpp
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+// Prevent tests from being compiled with glibc because thread_properties.h
+// only exists in Bionic.
+#if defined(__BIONIC__)
+
+#include <stdio.h>
+#include <sys/thread_properties.h>
+
+// Helper binary for testing thread_exit_cb registration.
+
+void exit_cb_1() {
+ printf("exit_cb_1 called ");
+}
+
+void exit_cb_2() {
+ printf("exit_cb_2 called ");
+}
+
+void exit_cb_3() {
+ printf("exit_cb_3 called");
+}
+
+void test_register_thread_exit_cb() {
+ // Register the exit-cb in reverse order (3,2,1)
+ // so that they'd be called in 1,2,3 order.
+ __libc_register_thread_exit_callback(&exit_cb_3);
+ __libc_register_thread_exit_callback(&exit_cb_2);
+ __libc_register_thread_exit_callback(&exit_cb_1);
+}
+
+int main() {
+ test_register_thread_exit_cb();
+ return 0;
+}
+#else
+int main() {
+ return 0;
+}
+#endif // __BIONIC__
diff --git a/tests/libs/tls_properties_helper.cpp b/tests/libs/tls_properties_helper.cpp
new file mode 100644
index 000000000..3f8d11885
--- /dev/null
+++ b/tests/libs/tls_properties_helper.cpp
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+// Prevent tests from being compiled with glibc because thread_properties.h
+// only exists in Bionic.
+#if defined(__BIONIC__)
+
+#include <sys/thread_properties.h>
+
+#include <assert.h>
+#include <dlfcn.h>
+#include <stdio.h>
+#include <unistd.h> // for gettid
+
+// Helper binary to use TLS-related functions in thread_properties
+
+// Tests __get_static_tls_bound.
+thread_local int local_var;
+void test_static_tls_bounds() {
+ local_var = 123;
+ void* start_addr = nullptr;
+ void* end_addr = nullptr;
+
+ __libc_get_static_tls_bounds(reinterpret_cast<void**>(&start_addr),
+ reinterpret_cast<void**>(&end_addr));
+ assert(start_addr != nullptr);
+ assert(end_addr != nullptr);
+
+ assert(&local_var >= start_addr && &local_var < end_addr);
+
+ printf("done_get_static_tls_bounds\n");
+}
+
+// Tests iterate_dynamic tls chunks.
+// Export a var from the shared so.
+__thread char large_tls_var[4 * 1024 * 1024];
+void test_iter_tls() {
+ void* lib = dlopen("libtest_elftls_dynamic.so", RTLD_LOCAL | RTLD_NOW);
+
+ int i = 0;
+ auto cb = [&](void* dtls_begin, void* dtls_end, size_t dso_id, void* arg) {
+ printf("iterate_cb i = %d\n", i++);
+ };
+ __libc_iterate_dynamic_tls(gettid(), cb, nullptr);
+ printf("done_iterate_dynamic_tls\n");
+}
+
+int main() {
+ test_static_tls_bounds();
+ test_iter_tls();
+ return 0;
+}
+
+#else
+int main() {
+ return 0;
+}
+#endif // __BIONIC__
diff --git a/tests/netinet_ether_test.cpp b/tests/netinet_ether_test.cpp
index faa3db47f..af020ec93 100644
--- a/tests/netinet_ether_test.cpp
+++ b/tests/netinet_ether_test.cpp
@@ -34,7 +34,7 @@ TEST(netinet_ether, ether_aton__ether_ntoa) {
TEST(netinet_ether, ether_aton_r__ether_ntoa_r) {
ether_addr addr;
memset(&addr, 0, sizeof(addr));
- ether_addr* a = ether_aton_r("12:34:56:78:9a:bc", &addr);
+ ether_addr* a = ether_aton_r("12:34:56:78:9a:Bc", &addr);
ASSERT_EQ(&addr, a);
ASSERT_EQ(0x12, addr.ether_addr_octet[0]);
ASSERT_EQ(0x34, addr.ether_addr_octet[1]);
@@ -49,3 +49,11 @@ TEST(netinet_ether, ether_aton_r__ether_ntoa_r) {
ASSERT_EQ(buf, p);
ASSERT_STREQ("12:34:56:78:9a:bc", buf);
}
+
+TEST(netinet_ether, ether_aton_r_failures) {
+ ether_addr addr;
+ ASSERT_TRUE(ether_aton_r("12:34:56:78:9a;bc", &addr) == nullptr);
+ ASSERT_TRUE(ether_aton_r("12:34:56:78:9a:bc ", &addr) == nullptr);
+ ASSERT_TRUE(ether_aton_r("g2:34:56:78:9a:bc ", &addr) == nullptr);
+ ASSERT_TRUE(ether_aton_r("1G:34:56:78:9a:bc ", &addr) == nullptr);
+}
diff --git a/tests/netinet_in_test.cpp b/tests/netinet_in_test.cpp
index 260608210..437e18022 100644
--- a/tests/netinet_in_test.cpp
+++ b/tests/netinet_in_test.cpp
@@ -31,8 +31,15 @@ static constexpr uint32_t be32 = 0x78563412;
static constexpr uint64_t be64 = 0xf0debc9a78563412;
TEST(netinet_in, bindresvport) {
- // This isn't something we can usually test, so just check the symbol's there.
+ // This isn't something we can usually test (because you need to be root),
+ // so just check the symbol's there.
ASSERT_EQ(-1, bindresvport(-1, nullptr));
+
+ // Only AF_INET is supported.
+ sockaddr_in sin = {.sin_family = AF_INET6};
+ errno = 0;
+ ASSERT_EQ(-1, bindresvport(-1, &sin));
+ ASSERT_EQ(EPFNOSUPPORT, errno);
}
TEST(netinet_in, in6addr_any) {
diff --git a/tests/pty_test.cpp b/tests/pty_test.cpp
index 29f86f16a..d5d8994be 100644
--- a/tests/pty_test.cpp
+++ b/tests/pty_test.cpp
@@ -28,34 +28,34 @@
#include "utils.h"
TEST(pty, openpty) {
- int master, slave;
+ int pty, tty;
char name[32];
struct winsize w = { 123, 456, 9999, 999 };
- ASSERT_EQ(0, openpty(&master, &slave, name, nullptr, &w));
- ASSERT_NE(-1, master);
- ASSERT_NE(-1, slave);
- ASSERT_NE(master, slave);
+ ASSERT_EQ(0, openpty(&pty, &tty, name, nullptr, &w));
+ ASSERT_NE(-1, pty);
+ ASSERT_NE(-1, tty);
+ ASSERT_NE(pty, tty);
char tty_name[32];
- ASSERT_EQ(0, ttyname_r(slave, tty_name, sizeof(tty_name)));
+ ASSERT_EQ(0, ttyname_r(tty, tty_name, sizeof(tty_name)));
ASSERT_STREQ(tty_name, name);
struct winsize w_actual;
- ASSERT_EQ(0, ioctl(slave, TIOCGWINSZ, &w_actual));
+ ASSERT_EQ(0, ioctl(tty, TIOCGWINSZ, &w_actual));
ASSERT_EQ(w_actual.ws_row, w.ws_row);
ASSERT_EQ(w_actual.ws_col, w.ws_col);
ASSERT_EQ(w_actual.ws_xpixel, w.ws_xpixel);
ASSERT_EQ(w_actual.ws_ypixel, w.ws_ypixel);
- close(master);
- close(slave);
+ close(pty);
+ close(tty);
}
TEST(pty, forkpty) {
pid_t sid = getsid(0);
- int master;
- pid_t pid = forkpty(&master, nullptr, nullptr, nullptr);
+ int pty;
+ pid_t pid = forkpty(&pty, nullptr, nullptr, nullptr);
ASSERT_NE(-1, pid);
if (pid == 0) {
@@ -68,12 +68,12 @@ TEST(pty, forkpty) {
AssertChildExited(pid, 0);
- close(master);
+ close(pty);
}
struct PtyReader_28979140_Arg {
int main_cpu_id;
- int slave_fd;
+ int fd;
uint32_t data_count;
bool finished;
std::atomic<bool> matched;
@@ -90,7 +90,7 @@ static void PtyReader_28979140(PtyReader_28979140_Arg* arg) {
while (counter <= arg->data_count) {
char buf[4096]; // Use big buffer to read to hit the bug more easily.
size_t to_read = std::min(sizeof(buf), (arg->data_count + 1 - counter) * sizeof(uint32_t));
- ASSERT_TRUE(android::base::ReadFully(arg->slave_fd, buf, to_read));
+ ASSERT_TRUE(android::base::ReadFully(arg->fd, buf, to_read));
size_t num_of_value = to_read / sizeof(uint32_t);
uint32_t* p = reinterpret_cast<uint32_t*>(buf);
while (num_of_value-- > 0) {
@@ -99,7 +99,7 @@ static void PtyReader_28979140(PtyReader_28979140_Arg* arg) {
}
}
}
- close(arg->slave_fd);
+ close(arg->fd);
arg->finished = true;
}
@@ -114,16 +114,16 @@ TEST(pty, bug_28979140) {
constexpr uint32_t TEST_DATA_COUNT = 2000000;
// 1. Open raw pty.
- int master;
- int slave;
- ASSERT_EQ(0, openpty(&master, &slave, nullptr, nullptr, nullptr));
+ int pty;
+ int tty;
+ ASSERT_EQ(0, openpty(&pty, &tty, nullptr, nullptr, nullptr));
termios tattr;
- ASSERT_EQ(0, tcgetattr(slave, &tattr));
+ ASSERT_EQ(0, tcgetattr(tty, &tattr));
cfmakeraw(&tattr);
- ASSERT_EQ(0, tcsetattr(slave, TCSADRAIN, &tattr));
+ ASSERT_EQ(0, tcsetattr(tty, TCSADRAIN, &tattr));
- // 2. Make master thread and slave thread running on different cpus:
- // master thread uses first available cpu, and slave thread uses other cpus.
+ // 2. Make two threads running on different cpus:
+ // pty thread uses first available cpu, and tty thread uses other cpus.
PtyReader_28979140_Arg arg;
arg.main_cpu_id = -1;
for (int i = 0; i < CPU_SETSIZE; i++) {
@@ -134,9 +134,9 @@ TEST(pty, bug_28979140) {
}
ASSERT_GE(arg.main_cpu_id, 0);
- // 3. Create thread for slave reader.
+ // 3. Create thread for tty reader.
pthread_t thread;
- arg.slave_fd = slave;
+ arg.fd = tty;
arg.data_count = TEST_DATA_COUNT;
arg.matched = true;
ASSERT_EQ(0, pthread_create(&thread, nullptr,
@@ -147,7 +147,7 @@ TEST(pty, bug_28979140) {
CPU_SET(arg.main_cpu_id, &cpus);
ASSERT_EQ(0, sched_setaffinity(0, sizeof(cpu_set_t), &cpus));
- // 4. Send data to slave.
+ // 4. Send data to tty reader.
// Send a bunch of data at a time, so it is easier to catch the bug that some data isn't seen
// by the reader thread on another cpu.
uint32_t counter_buf[100];
@@ -156,11 +156,11 @@ TEST(pty, bug_28979140) {
for (size_t i = 0; i < sizeof(counter_buf) / sizeof(counter_buf[0]); ++i) {
counter_buf[i] = counter++;
}
- ASSERT_TRUE(android::base::WriteFully(master, &counter_buf, sizeof(counter_buf)));
+ ASSERT_TRUE(android::base::WriteFully(pty, &counter_buf, sizeof(counter_buf)));
ASSERT_TRUE(arg.matched) << "failed at count = " << counter;
}
ASSERT_EQ(0, pthread_join(thread, nullptr));
ASSERT_TRUE(arg.finished);
ASSERT_TRUE(arg.matched);
- close(master);
+ close(pty);
}
diff --git a/tests/sched_test.cpp b/tests/sched_test.cpp
index 9309a7ff5..03e8062d8 100644
--- a/tests/sched_test.cpp
+++ b/tests/sched_test.cpp
@@ -301,3 +301,7 @@ TEST(sched, sched_getscheduler_sched_setscheduler) {
// don't behave as POSIX specifies. http://b/26203902.
ASSERT_EQ(0, sched_setscheduler(getpid(), original_policy, &p));
}
+
+TEST(sched, sched_getaffinity_failure) {
+ ASSERT_EQ(-1, sched_getaffinity(getpid(), 0, nullptr));
+}
diff --git a/tests/search_test.cpp b/tests/search_test.cpp
index 1509199c9..8b8359d50 100644
--- a/tests/search_test.cpp
+++ b/tests/search_test.cpp
@@ -114,6 +114,11 @@ TEST(search, tfind_tsearch_twalk_tdestroy) {
ASSERT_EQ(3U, g_free_calls);
}
+TEST(search, tdestroy_null) {
+ // It's okay to pass a null node, and your callback will not be called.
+ tdestroy(nullptr, nullptr);
+}
+
struct pod_node {
explicit pod_node(int i) : i(i) {}
int i;
@@ -285,3 +290,26 @@ TEST(search, hcreate_r_hsearch_r_hdestroy_r) {
AssertEntry(e, "a", "B");
hdestroy_r(&h2);
}
+
+TEST(search, hsearch_resizing) {
+ ASSERT_NE(0, hcreate(1));
+
+ std::vector<char*> entries;
+ // Add enough entries to ensure that we've had to resize.
+ for (char ch = ' '; ch <= '~'; ++ch) {
+ char* p;
+ asprintf(&p, "%c", ch);
+ ENTRY e;
+ e.data = e.key = p;
+ ASSERT_TRUE(hsearch(e, ENTER) != nullptr);
+ entries.push_back(p);
+ }
+
+ // Check they're all there.
+ for (auto& p : entries) {
+ ENTRY* e = hsearch(ENTRY{.key = p, .data = nullptr}, FIND);
+ AssertEntry(e, p, p);
+ }
+
+ for (auto& p : entries) free(p);
+}
diff --git a/tests/stdio_test.cpp b/tests/stdio_test.cpp
index f6eca05f4..c21c3b8b6 100644
--- a/tests/stdio_test.cpp
+++ b/tests/stdio_test.cpp
@@ -371,6 +371,11 @@ TEST(STDIO_TEST, snprintf_n) {
#endif
}
+TEST(STDIO_TEST, snprintf_measure) {
+ char buf[16];
+ ASSERT_EQ(11, snprintf(buf, 0, "Hello %s", "world"));
+}
+
TEST(STDIO_TEST, snprintf_smoke) {
char buf[BUFSIZ];
@@ -1155,7 +1160,6 @@ TEST(STDIO_TEST, sscanf_mc) {
free(p1);
}
-
TEST(STDIO_TEST, sscanf_mlc) {
// This is so useless that clang doesn't even believe it exists...
#pragma clang diagnostic push
@@ -1189,7 +1193,6 @@ TEST(STDIO_TEST, sscanf_mlc) {
#pragma clang diagnostic pop
}
-
TEST(STDIO_TEST, sscanf_ms) {
CheckScanfM(sscanf, "hello", "%ms", 1, "hello");
CheckScanfM(sscanf, "hello", "%4ms", 1, "hell");
@@ -2533,6 +2536,16 @@ TEST(STDIO_TEST, puts) {
eth.Run([&]() { exit(puts("a b c")); }, 0, "a b c\n");
}
+TEST(STDIO_TEST, putchar) {
+ ExecTestHelper eth;
+ eth.Run([&]() { exit(putchar('A')); }, 65, "A");
+}
+
+TEST(STDIO_TEST, putchar_unlocked) {
+ ExecTestHelper eth;
+ eth.Run([&]() { exit(putchar('B')); }, 66, "B");
+}
+
TEST(STDIO_TEST, unlocked) {
TemporaryFile tf;
@@ -2733,3 +2746,73 @@ TEST(STDIO_TEST, renameat2_flags) {
ASSERT_NE(0, RENAME_WHITEOUT);
#endif
}
+
+TEST(STDIO_TEST, fdopen_failures) {
+ FILE* fp;
+ int fd = open("/proc/version", O_RDONLY);
+ ASSERT_TRUE(fd != -1);
+
+ // Nonsense mode.
+ errno = 0;
+ fp = fdopen(fd, "nonsense");
+ ASSERT_TRUE(fp == nullptr);
+ ASSERT_EQ(EINVAL, errno);
+
+ // Mode that isn't a subset of the fd's actual mode.
+ errno = 0;
+ fp = fdopen(fd, "w");
+ ASSERT_TRUE(fp == nullptr);
+ ASSERT_EQ(EINVAL, errno);
+
+ // Can't set append on the underlying fd.
+ errno = 0;
+ fp = fdopen(fd, "a");
+ ASSERT_TRUE(fp == nullptr);
+ ASSERT_EQ(EINVAL, errno);
+
+ // Bad fd.
+ errno = 0;
+ fp = fdopen(-1, "re");
+ ASSERT_TRUE(fp == nullptr);
+ ASSERT_EQ(EBADF, errno);
+
+ close(fd);
+}
+
+TEST(STDIO_TEST, fmemopen_invalid_mode) {
+ errno = 0;
+ FILE* fp = fmemopen(nullptr, 16, "nonsense");
+ ASSERT_TRUE(fp == nullptr);
+ ASSERT_EQ(EINVAL, errno);
+}
+
+TEST(STDIO_TEST, fopen_invalid_mode) {
+ errno = 0;
+ FILE* fp = fopen("/proc/version", "nonsense");
+ ASSERT_TRUE(fp == nullptr);
+ ASSERT_EQ(EINVAL, errno);
+}
+
+TEST(STDIO_TEST, freopen_invalid_mode) {
+ FILE* fp = fopen("/proc/version", "re");
+ ASSERT_TRUE(fp != nullptr);
+
+ errno = 0;
+ fp = freopen("/proc/version", "nonsense", fp);
+ ASSERT_TRUE(fp == nullptr);
+ ASSERT_EQ(EINVAL, errno);
+}
+
+TEST(STDIO_TEST, asprintf_smoke) {
+ char* p = nullptr;
+ ASSERT_EQ(11, asprintf(&p, "hello %s", "world"));
+ ASSERT_STREQ("hello world", p);
+ free(p);
+}
+
+TEST(STDIO_TEST, fopen_ENOENT) {
+ errno = 0;
+ FILE* fp = fopen("/proc/does-not-exist", "re");
+ ASSERT_TRUE(fp == nullptr);
+ ASSERT_EQ(ENOENT, errno);
+}
diff --git a/tests/stdlib_test.cpp b/tests/stdlib_test.cpp
index 3f1ec866d..c7b2ad89a 100644
--- a/tests/stdlib_test.cpp
+++ b/tests/stdlib_test.cpp
@@ -800,10 +800,25 @@ static void CheckStrToInt(T fn(const char* s, char** end, int base)) {
ASSERT_EQ(T(0), fn("123", &end_p, 37));
ASSERT_EQ(EINVAL, errno);
+ // Both leading + or - are always allowed (even for the strtou* family).
+ ASSERT_EQ(T(-123), fn("-123", &end_p, 10));
+ ASSERT_EQ(T(123), fn("+123", &end_p, 10));
+
// If we see "0x" *not* followed by a hex digit, we shouldn't swallow the 'x'.
ASSERT_EQ(T(0), fn("0xy", &end_p, 16));
ASSERT_EQ('x', *end_p);
+ // Hexadecimal (both the 0x and the digits) is case-insensitive.
+ ASSERT_EQ(T(0xab), fn("0xab", &end_p, 0));
+ ASSERT_EQ(T(0xab), fn("0Xab", &end_p, 0));
+ ASSERT_EQ(T(0xab), fn("0xAB", &end_p, 0));
+ ASSERT_EQ(T(0xab), fn("0XAB", &end_p, 0));
+ ASSERT_EQ(T(0xab), fn("0xAb", &end_p, 0));
+ ASSERT_EQ(T(0xab), fn("0XAb", &end_p, 0));
+
+ // Octal lives! (Sadly.)
+ ASSERT_EQ(T(0666), fn("0666", &end_p, 0));
+
if (std::numeric_limits<T>::is_signed) {
// Minimum (such as -128).
std::string min{std::to_string(std::numeric_limits<T>::min())};
@@ -878,6 +893,18 @@ TEST(stdlib, strtoumax_smoke) {
CheckStrToInt(strtoumax);
}
+TEST(stdlib, atoi) {
+ // Implemented using strtol in bionic, so extensive testing unnecessary.
+ ASSERT_EQ(123, atoi("123four"));
+ ASSERT_EQ(0, atoi("hello"));
+}
+
+TEST(stdlib, atol) {
+ // Implemented using strtol in bionic, so extensive testing unnecessary.
+ ASSERT_EQ(123L, atol("123four"));
+ ASSERT_EQ(0L, atol("hello"));
+}
+
TEST(stdlib, abs) {
ASSERT_EQ(INT_MAX, abs(-INT_MAX));
ASSERT_EQ(INT_MAX, abs(INT_MAX));
diff --git a/tests/string_test.cpp b/tests/string_test.cpp
index 0ed0598f6..22be85241 100644
--- a/tests/string_test.cpp
+++ b/tests/string_test.cpp
@@ -64,6 +64,11 @@ TEST(STRING_TEST, strerror) {
ASSERT_STREQ("Unknown error 134", strerror(EHWPOISON + 1));
}
+TEST(STRING_TEST, strerror_l) {
+ // bionic just forwards to strerror(3).
+ ASSERT_STREQ("Success", strerror_l(0, LC_GLOBAL_LOCALE));
+}
+
#if defined(__BIONIC__)
static void* ConcurrentStrErrorFn(void*) {
bool equal = (strcmp("Unknown error 2002", strerror(2002)) == 0);
@@ -1538,13 +1543,31 @@ TEST(STRING_TEST, memmem_strstr_empty_needle) {
}
TEST(STRING_TEST, memmem_smoke) {
- const char haystack[] = "big\0daddy\0giant\0haystacks";
- ASSERT_EQ(haystack, memmem(haystack, sizeof(haystack), "", 0));
- ASSERT_EQ(haystack + 3, memmem(haystack, sizeof(haystack), "", 1));
+ const char haystack[] = "big\0daddy/giant\0haystacks!";
+
+ // The current memmem() implementation has special cases for needles of
+ // lengths 0, 1, 2, 3, and 4, plus a long needle case. We test matches at the
+ // beginning, middle, and end of the haystack.
+
+ ASSERT_EQ(haystack + 0, memmem(haystack, sizeof(haystack), "", 0));
+
ASSERT_EQ(haystack + 0, memmem(haystack, sizeof(haystack), "b", 1));
- ASSERT_EQ(haystack + 1, memmem(haystack, sizeof(haystack), "i", 1));
- ASSERT_EQ(haystack + 4, memmem(haystack, sizeof(haystack), "da", 2));
- ASSERT_EQ(haystack + 8, memmem(haystack, sizeof(haystack), "y\0g", 3));
+ ASSERT_EQ(haystack + 0, memmem(haystack, sizeof(haystack), "bi", 2));
+ ASSERT_EQ(haystack + 0, memmem(haystack, sizeof(haystack), "big", 3));
+ ASSERT_EQ(haystack + 0, memmem(haystack, sizeof(haystack), "big\0", 4));
+ ASSERT_EQ(haystack + 0, memmem(haystack, sizeof(haystack), "big\0d", 5));
+
+ ASSERT_EQ(haystack + 2, memmem(haystack, sizeof(haystack), "g", 1));
+ ASSERT_EQ(haystack + 10, memmem(haystack, sizeof(haystack), "gi", 2));
+ ASSERT_EQ(haystack + 10, memmem(haystack, sizeof(haystack), "gia", 3));
+ ASSERT_EQ(haystack + 10, memmem(haystack, sizeof(haystack), "gian", 4));
+ ASSERT_EQ(haystack + 10, memmem(haystack, sizeof(haystack), "giant", 5));
+
+ ASSERT_EQ(haystack + 25, memmem(haystack, sizeof(haystack), "!", 1));
+ ASSERT_EQ(haystack + 24, memmem(haystack, sizeof(haystack), "s!", 2));
+ ASSERT_EQ(haystack + 23, memmem(haystack, sizeof(haystack), "ks!", 3));
+ ASSERT_EQ(haystack + 22, memmem(haystack, sizeof(haystack), "cks!", 4));
+ ASSERT_EQ(haystack + 21, memmem(haystack, sizeof(haystack), "acks!", 5));
}
TEST(STRING_TEST, strstr_smoke) {
@@ -1589,16 +1612,44 @@ TEST(STRING_TEST, strcoll_smoke) {
ASSERT_TRUE(strcoll("aac", "aab") > 0);
}
+TEST(STRING_TEST, strcoll_l_smoke) {
+ // bionic just forwards to strcoll(3).
+ ASSERT_TRUE(strcoll_l("aab", "aac", LC_GLOBAL_LOCALE) < 0);
+ ASSERT_TRUE(strcoll_l("aab", "aab", LC_GLOBAL_LOCALE) == 0);
+ ASSERT_TRUE(strcoll_l("aac", "aab", LC_GLOBAL_LOCALE) > 0);
+}
+
TEST(STRING_TEST, strxfrm_smoke) {
const char* src1 = "aab";
char dst1[16] = {};
- ASSERT_GT(strxfrm(dst1, src1, sizeof(dst1)), 0U);
+ // Dry run.
+ ASSERT_EQ(strxfrm(dst1, src1, 0), 3U);
+ ASSERT_STREQ(dst1, "");
+ // Really do it.
+ ASSERT_EQ(strxfrm(dst1, src1, sizeof(dst1)), 3U);
+
const char* src2 = "aac";
char dst2[16] = {};
- ASSERT_GT(strxfrm(dst2, src2, sizeof(dst2)), 0U);
+ // Dry run.
+ ASSERT_EQ(strxfrm(dst2, src2, 0), 3U);
+ ASSERT_STREQ(dst2, "");
+ // Really do it.
+ ASSERT_EQ(strxfrm(dst2, src2, sizeof(dst2)), 3U);
+
+ // The "transform" of two different strings should cause different outputs.
ASSERT_TRUE(strcmp(dst1, dst2) < 0);
}
+TEST(STRING_TEST, strxfrm_l_smoke) {
+ // bionic just forwards to strxfrm(3), so this is a subset of the
+ // strxfrm test.
+ const char* src1 = "aab";
+ char dst1[16] = {};
+ ASSERT_EQ(strxfrm_l(dst1, src1, 0, LC_GLOBAL_LOCALE), 3U);
+ ASSERT_STREQ(dst1, "");
+ ASSERT_EQ(strxfrm_l(dst1, src1, sizeof(dst1), LC_GLOBAL_LOCALE), 3U);
+}
+
TEST(STRING_TEST, memccpy_smoke) {
char dst[32];
diff --git a/tests/sys_procfs_test.cpp b/tests/sys_procfs_test.cpp
index 8054869eb..5e0a0b024 100644
--- a/tests/sys_procfs_test.cpp
+++ b/tests/sys_procfs_test.cpp
@@ -18,7 +18,7 @@
#include <sys/procfs.h>
-TEST(sys_procfs, smoke) {
+TEST(sys_procfs, types) {
elf_greg_t reg;
memset(&reg, 0, sizeof(reg));
@@ -37,3 +37,16 @@ TEST(sys_procfs, smoke) {
static_assert(sizeof(prgregset_t) == sizeof(elf_gregset_t), "");
static_assert(sizeof(prfpregset_t) == sizeof(elf_fpregset_t), "");
}
+
+TEST(sys_procfs, constants) {
+ // NGREG != ELF_NGREG (https://github.com/android/ndk/issues/1347)
+ static_assert(sizeof(gregset_t) / sizeof(greg_t) == NGREG);
+
+#if defined(__arm__)
+ static_assert(sizeof(user_regs) / sizeof(elf_greg_t) == ELF_NGREG);
+#elif defined(__aarch64__)
+ static_assert(sizeof(user_pt_regs) / sizeof(elf_greg_t) == ELF_NGREG);
+#else
+ static_assert(sizeof(user_regs_struct) / sizeof(elf_greg_t) == ELF_NGREG);
+#endif
+}
diff --git a/tests/sys_thread_properties_test.cpp b/tests/sys_thread_properties_test.cpp
new file mode 100644
index 000000000..cf1a6ba63
--- /dev/null
+++ b/tests/sys_thread_properties_test.cpp
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <gtest/gtest.h>
+
+#include "gtest_globals.h"
+#include "utils.h"
+
+TEST(thread_properties_test, iterate_dts) {
+#if defined(__BIONIC__)
+ const char expected_out[] =
+ "got test_static_tls_bounds\niterate_cb i = 0\ndone_iterate_dynamic_tls\n";
+ std::string helper = GetTestLibRoot() + "tls_properties_helper/tls_properties_helper";
+ chmod(helper.c_str(), 0755); // TODO: "x" lost in CTS, b/34945607
+
+ ExecTestHelper eth;
+ eth.SetArgs({helper.c_str(), nullptr});
+ eth.Run([&]() { execve(helper.c_str(), eth.GetArgs(), eth.GetEnv()); }, 0, expected_out);
+#endif
+}
+
+TEST(thread_properties_test, thread_exit_cb) {
+#if defined(__BIONIC__)
+ // tests/libs/thread_exit_cb_helper.cpp
+ const char expected_out[] = "exit_cb_1 called exit_cb_2 called exit_cb_3 called";
+ std::string helper = GetTestLibRoot() + "thread_exit_cb_helper/thread_exit_cb_helper";
+ chmod(helper.c_str(), 0755); // TODO: "x" lost in CTS, b/34945607
+
+ ExecTestHelper eth;
+ eth.SetArgs({helper.c_str(), nullptr});
+ eth.Run([&]() { execve(helper.c_str(), eth.GetArgs(), eth.GetEnv()); }, 0, expected_out);
+
+#endif
+}
diff --git a/tests/sys_vfs_test.cpp b/tests/sys_vfs_test.cpp
index a521967bf..f82f50546 100644
--- a/tests/sys_vfs_test.cpp
+++ b/tests/sys_vfs_test.cpp
@@ -44,12 +44,26 @@ TEST(sys_vfs, statfs) {
Check(sb);
}
+TEST(sys_vfs, statfs_failure) {
+ struct statfs sb;
+ errno = 0;
+ ASSERT_EQ(-1, statfs("/does-not-exist", &sb));
+ ASSERT_EQ(ENOENT, errno);
+}
+
TEST(sys_vfs, statfs64) {
struct statfs64 sb;
ASSERT_EQ(0, statfs64("/proc", &sb));
Check(sb);
}
+TEST(sys_vfs, statfs64_failure) {
+ struct statfs64 sb;
+ errno = 0;
+ ASSERT_EQ(-1, statfs64("/does-not-exist", &sb));
+ ASSERT_EQ(ENOENT, errno);
+}
+
TEST(sys_vfs, fstatfs) {
struct statfs sb;
int fd = open("/proc", O_RDONLY);
@@ -58,6 +72,13 @@ TEST(sys_vfs, fstatfs) {
Check(sb);
}
+TEST(sys_vfs, fstatfs_failure) {
+ struct statfs sb;
+ errno = 0;
+ ASSERT_EQ(-1, fstatfs(-1, &sb));
+ ASSERT_EQ(EBADF, errno);
+}
+
TEST(sys_vfs, fstatfs64) {
struct statfs64 sb;
int fd = open("/proc", O_RDONLY);
@@ -65,3 +86,10 @@ TEST(sys_vfs, fstatfs64) {
close(fd);
Check(sb);
}
+
+TEST(sys_vfs, fstatfs64_failure) {
+ struct statfs sb;
+ errno = 0;
+ ASSERT_EQ(-1, fstatfs(-1, &sb));
+ ASSERT_EQ(EBADF, errno);
+}
diff --git a/tests/sys_wait_test.cpp b/tests/sys_wait_test.cpp
new file mode 100644
index 000000000..c0069721d
--- /dev/null
+++ b/tests/sys_wait_test.cpp
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <gtest/gtest.h>
+
+#include <sys/wait.h>
+
+TEST(sys_wait, waitid) {
+ pid_t pid = fork();
+ ASSERT_NE(pid, -1);
+
+ if (pid == 0) _exit(66);
+
+ siginfo_t si = {};
+ ASSERT_EQ(0, waitid(P_PID, pid, &si, WEXITED));
+ ASSERT_EQ(pid, si.si_pid);
+ ASSERT_EQ(66, si.si_status);
+ ASSERT_EQ(CLD_EXITED, si.si_code);
+}
diff --git a/tests/time_test.cpp b/tests/time_test.cpp
index 74d691dc9..b1de0a446 100644
--- a/tests/time_test.cpp
+++ b/tests/time_test.cpp
@@ -142,7 +142,7 @@ TEST(time, mktime_10310929) {
t.tm_mday = 10;
#if !defined(__LP64__)
- // 32-bit bionic stupidly had a signed 32-bit time_t.
+ // 32-bit bionic has a signed 32-bit time_t.
ASSERT_EQ(-1, mktime(&t));
ASSERT_EQ(EOVERFLOW, errno);
#else
@@ -363,6 +363,105 @@ TEST(time, strptime_V_G_g) {
EXPECT_TRUE(memcmp(&tm, &zero, sizeof(tm)) == 0);
}
+TEST(time, strptime_Z) {
+#if defined(__BIONIC__)
+ // glibc doesn't handle %Z at all.
+ // The BSDs only handle hard-coded "GMT" and "UTC", plus whatever two strings
+ // are in the global `tzname` (which correspond to the current $TZ).
+ struct tm tm;
+ setenv("TZ", "Europe/Berlin", 1);
+
+ // "GMT" always works.
+ tm = {};
+ ASSERT_EQ('\0', *strptime("GMT", "%Z", &tm));
+ EXPECT_STREQ("GMT", tm.tm_zone);
+ EXPECT_EQ(0, tm.tm_isdst);
+ EXPECT_EQ(0, tm.tm_gmtoff);
+
+ // As does "UTC".
+ tm = {};
+ ASSERT_EQ('\0', *strptime("UTC", "%Z", &tm));
+ EXPECT_STREQ("UTC", tm.tm_zone);
+ EXPECT_EQ(0, tm.tm_isdst);
+ EXPECT_EQ(0, tm.tm_gmtoff);
+
+ // Europe/Berlin is known as "CET" when there's no DST.
+ tm = {};
+ ASSERT_EQ('\0', *strptime("CET", "%Z", &tm));
+ EXPECT_STREQ("CET", tm.tm_zone);
+ EXPECT_EQ(0, tm.tm_isdst);
+ EXPECT_EQ(3600, tm.tm_gmtoff);
+
+ // Europe/Berlin is known as "CEST" when there's no DST.
+ tm = {};
+ ASSERT_EQ('\0', *strptime("CEST", "%Z", &tm));
+ EXPECT_STREQ("CEST", tm.tm_zone);
+ EXPECT_EQ(1, tm.tm_isdst);
+ EXPECT_EQ(3600, tm.tm_gmtoff);
+
+ // And as long as we're in Europe/Berlin, those are the only time zone
+ // abbreviations that are recognized.
+ tm = {};
+ ASSERT_TRUE(strptime("PDT", "%Z", &tm) == nullptr);
+#endif
+}
+
+TEST(time, strptime_z) {
+ struct tm tm;
+ setenv("TZ", "Europe/Berlin", 1);
+
+ // "UT" is what RFC822 called UTC.
+ tm = {};
+ ASSERT_EQ('\0', *strptime("UT", "%z", &tm));
+ EXPECT_STREQ("UTC", tm.tm_zone);
+ EXPECT_EQ(0, tm.tm_isdst);
+ EXPECT_EQ(0, tm.tm_gmtoff);
+ // "GMT" is RFC822's other name for UTC.
+ tm = {};
+ ASSERT_EQ('\0', *strptime("GMT", "%z", &tm));
+ EXPECT_STREQ("UTC", tm.tm_zone);
+ EXPECT_EQ(0, tm.tm_isdst);
+ EXPECT_EQ(0, tm.tm_gmtoff);
+
+ // "Z" ("Zulu") is a synonym for UTC.
+ tm = {};
+ ASSERT_EQ('\0', *strptime("Z", "%z", &tm));
+ EXPECT_STREQ("UTC", tm.tm_zone);
+ EXPECT_EQ(0, tm.tm_isdst);
+ EXPECT_EQ(0, tm.tm_gmtoff);
+
+ // "PST"/"PDT" and the other common US zone abbreviations are all supported.
+ tm = {};
+ ASSERT_EQ('\0', *strptime("PST", "%z", &tm));
+ EXPECT_STREQ("PST", tm.tm_zone);
+ EXPECT_EQ(0, tm.tm_isdst);
+ EXPECT_EQ(-28800, tm.tm_gmtoff);
+ tm = {};
+ ASSERT_EQ('\0', *strptime("PDT", "%z", &tm));
+ EXPECT_STREQ("PDT", tm.tm_zone);
+ EXPECT_EQ(1, tm.tm_isdst);
+ EXPECT_EQ(-25200, tm.tm_gmtoff);
+
+ // +-hh
+ tm = {};
+ ASSERT_EQ('\0', *strptime("+01", "%z", &tm));
+ EXPECT_EQ(3600, tm.tm_gmtoff);
+ EXPECT_TRUE(tm.tm_zone == nullptr);
+ EXPECT_EQ(0, tm.tm_isdst);
+ // +-hhmm
+ tm = {};
+ ASSERT_EQ('\0', *strptime("+0130", "%z", &tm));
+ EXPECT_EQ(5400, tm.tm_gmtoff);
+ EXPECT_TRUE(tm.tm_zone == nullptr);
+ EXPECT_EQ(0, tm.tm_isdst);
+ // +-hh:mm
+ tm = {};
+ ASSERT_EQ('\0', *strptime("+01:30", "%z", &tm));
+ EXPECT_EQ(5400, tm.tm_gmtoff);
+ EXPECT_TRUE(tm.tm_zone == nullptr);
+ EXPECT_EQ(0, tm.tm_isdst);
+}
+
void SetTime(timer_t t, time_t value_s, time_t value_ns, time_t interval_s, time_t interval_ns) {
itimerspec ts;
ts.it_value.tv_sec = value_s;
@@ -1008,4 +1107,5 @@ TEST(time, timespec_get) {
TEST(time, difftime) {
ASSERT_EQ(1.0, difftime(1, 0));
+ ASSERT_EQ(-1.0, difftime(0, 1));
}
diff --git a/tests/unistd_test.cpp b/tests/unistd_test.cpp
index 6b2856169..43d50f888 100644
--- a/tests/unistd_test.cpp
+++ b/tests/unistd_test.cpp
@@ -1350,6 +1350,11 @@ TEST(UNISTD_TEST, execve_failure) {
ASSERT_EQ(EACCES, errno);
}
+static void append_llvm_cov_env_var(std::string& env_str) {
+ if (getenv("LLVM_PROFILE_FILE") != nullptr)
+ env_str.append("__LLVM_PROFILE_RT_INIT_ONCE=__LLVM_PROFILE_RT_INIT_ONCE\n");
+}
+
TEST(UNISTD_TEST, execve_args) {
// int execve(const char* path, char* argv[], char* envp[]);
@@ -1361,7 +1366,12 @@ TEST(UNISTD_TEST, execve_args) {
// Test environment variable setting too.
eth.SetArgs({"printenv", nullptr});
eth.SetEnv({"A=B", nullptr});
- eth.Run([&]() { execve(BIN_DIR "printenv", eth.GetArgs(), eth.GetEnv()); }, 0, "A=B\n");
+
+ std::string expected_output("A=B\n");
+ append_llvm_cov_env_var(expected_output);
+
+ eth.Run([&]() { execve(BIN_DIR "printenv", eth.GetArgs(), eth.GetEnv()); }, 0,
+ expected_output.c_str());
}
TEST(UNISTD_TEST, execl_failure) {
@@ -1386,8 +1396,13 @@ TEST(UNISTD_TEST, execle_failure) {
TEST(UNISTD_TEST, execle) {
ExecTestHelper eth;
eth.SetEnv({"A=B", nullptr});
+
+ std::string expected_output("A=B\n");
+ append_llvm_cov_env_var(expected_output);
+
// int execle(const char* path, const char* arg, ..., char* envp[]);
- eth.Run([&]() { execle(BIN_DIR "printenv", "printenv", nullptr, eth.GetEnv()); }, 0, "A=B\n");
+ eth.Run([&]() { execle(BIN_DIR "printenv", "printenv", nullptr, eth.GetEnv()); }, 0,
+ expected_output.c_str());
}
TEST(UNISTD_TEST, execv_failure) {
@@ -1450,7 +1465,11 @@ TEST(UNISTD_TEST, execvpe) {
// Test environment variable setting too.
eth.SetArgs({"printenv", nullptr});
eth.SetEnv({"A=B", nullptr});
- eth.Run([&]() { execvpe("printenv", eth.GetArgs(), eth.GetEnv()); }, 0, "A=B\n");
+
+ std::string expected_output("A=B\n");
+ append_llvm_cov_env_var(expected_output);
+
+ eth.Run([&]() { execvpe("printenv", eth.GetArgs(), eth.GetEnv()); }, 0, expected_output.c_str());
}
TEST(UNISTD_TEST, execvpe_ENOEXEC) {
@@ -1538,7 +1557,11 @@ TEST(UNISTD_TEST, fexecve_args) {
ASSERT_NE(-1, printenv_fd);
eth.SetArgs({"printenv", nullptr});
eth.SetEnv({"A=B", nullptr});
- eth.Run([&]() { fexecve(printenv_fd, eth.GetArgs(), eth.GetEnv()); }, 0, "A=B\n");
+
+ std::string expected_output("A=B\n");
+ append_llvm_cov_env_var(expected_output);
+
+ eth.Run([&]() { fexecve(printenv_fd, eth.GetArgs(), eth.GetEnv()); }, 0, expected_output.c_str());
close(printenv_fd);
}
diff --git a/tests/utmp_test.cpp b/tests/utmp_test.cpp
index 0fa55c74b..6d0d6f127 100644
--- a/tests/utmp_test.cpp
+++ b/tests/utmp_test.cpp
@@ -24,8 +24,10 @@ TEST(utmp, login_tty) {
ASSERT_EQ(-1, login_tty(-1));
}
-TEST(utmp, setutent_getutent_endutent) {
+TEST(utmp, smoke) {
+ ASSERT_EQ(-1, utmpname("hello"));
setutent();
- getutent();
+ ASSERT_EQ(NULL, getutent());
endutent();
+ ASSERT_EQ(NULL, pututline(NULL));
}