[libc-commits] [libc] 7fdb50c - [libc] Add a new rule add_integration_test.

Siva Chandra Reddy via libc-commits libc-commits at lists.llvm.org
Wed Mar 23 13:57:44 PDT 2022


Author: Siva Chandra Reddy
Date: 2022-03-23T20:57:29Z
New Revision: 7fdb50c8137b0b9c7f02fe0803e368f12969b389

URL: https://github.com/llvm/llvm-project/commit/7fdb50c8137b0b9c7f02fe0803e368f12969b389
DIFF: https://github.com/llvm/llvm-project/commit/7fdb50c8137b0b9c7f02fe0803e368f12969b389.diff

LOG: [libc] Add a new rule add_integration_test.

All existing loader tests are switched to an integration test added with
the new rule. Also, the getenv test is now enabled as an integration test.

All loader tests have been moved to test/integration. Also, the simple
checker library for the previous loader tests has been moved to a
separate directory of its own.

A follow up change will perform more cleanup of the loader CMake rules
to eliminate now redundent options.

Reviewed By: lntue, michaelrj

Differential Revision: https://reviews.llvm.org/D122266

Added: 
    libc/test/integration/loader/CMakeLists.txt
    libc/test/integration/loader/linux/CMakeLists.txt
    libc/test/integration/loader/linux/args_test.cpp
    libc/test/integration/loader/linux/main_without_args.cpp
    libc/test/integration/loader/linux/main_without_envp.cpp
    libc/test/integration/loader/linux/tls_test.cpp
    libc/test/integration/src/CMakeLists.txt
    libc/test/integration/src/stdlib/CMakeLists.txt
    libc/test/integration/src/stdlib/getenv_test.cpp
    libc/utils/IntegrationTest/CMakeLists.txt
    libc/utils/IntegrationTest/test.h

Modified: 
    libc/cmake/modules/LLVMLibCTestRules.cmake
    libc/config/linux/x86_64/entrypoints.txt
    libc/loader/linux/CMakeLists.txt
    libc/test/CMakeLists.txt
    libc/test/integration/CMakeLists.txt
    libc/utils/CMakeLists.txt

Removed: 
    libc/test/loader/CMakeLists.txt
    libc/test/loader/linux/CMakeLists.txt
    libc/test/loader/linux/args_test.cpp
    libc/test/loader/linux/getenv_test.cpp
    libc/test/loader/linux/loader_test.h
    libc/test/loader/linux/main_without_args.cpp
    libc/test/loader/linux/main_without_envp.cpp
    libc/test/loader/linux/tls_test.cpp


################################################################################
diff  --git a/libc/cmake/modules/LLVMLibCTestRules.cmake b/libc/cmake/modules/LLVMLibCTestRules.cmake
index 00b14014ef8b0..edbeaaff8ac03 100644
--- a/libc/cmake/modules/LLVMLibCTestRules.cmake
+++ b/libc/cmake/modules/LLVMLibCTestRules.cmake
@@ -269,3 +269,129 @@ function(add_libc_fuzzer target_name)
   )
   add_dependencies(libc-fuzzer ${fq_target_name})
 endfunction(add_libc_fuzzer)
+
+# Rule to add an integration test. An integration test is like a unit test
+# but does not use the system libc. Not even the loader from the system libc
+# is linked to the final executable. The final exe is fully statically linked.
+# The libc that the final exe links to consists of only the object files of
+# the DEPENDS targets.
+# 
+# Usage:
+#   add_integration_test(
+#     <target name>
+#     SUITE <the suite to which the test should belong>
+#     SRCS <src1.cpp> [src2.cpp ...]
+#     HDRS [hdr1.cpp ...]
+#     LOADER <fully qualified loader target name>
+#     DEPENDS <list of entrypoint or other object targets>
+#     ARGS <list of command line arguments to be passed to the test>
+#     ENV <list of environment variables to set before running the test>
+#   )
+#
+# The loader target should provide a property named LOADER_OBJECT which is
+# the full path to the object file produces when the loader is built.
+#
+# The DEPENDS list can be empty. If not empty, it should be a list of
+# targets added with add_entrypoint_object or add_object_library.
+function(add_integration_test test_name)
+  cmake_parse_arguments(
+    "INTEGRATION_TEST"
+    "" # No optional arguments
+    "SUITE;LOADER" # Single value arguments
+    "SRCS;HDRS;DEPENDS;ARGS;ENV" # Multi-value arguments
+    ${ARGN}
+  )
+  get_fq_target_name(${test_name} fq_target_name)
+
+  if(NOT INTEGRATION_TEST_SUITE)
+    message(FATAL_ERROR "SUITE not specified for ${fq_target_name}")
+  endif()
+  if(NOT INTEGRATION_TEST_LOADER)
+    message(FATAL_ERROR "The LOADER to link to the integration test is missing.")
+  endif()
+  if(NOT INTEGRATION_TEST_SRCS)
+    message(FATAL_ERROR "The SRCS list for add_integration_test is missing.")
+  endif()
+
+  get_fq_target_name(${test_name}.libc fq_libc_target_name)
+
+  get_fq_deps_list(fq_deps_list ${INTEGRATION_TEST_DEPENDS})
+  # Add memory functions to which compilers can emit calls.
+  list(APPEND fq_deps_list
+          libc.src.string.bcmp
+          libc.src.string.bzero
+          libc.src.string.memcmp
+          libc.src.string.memcpy
+          libc.src.string.memset)
+  list(REMOVE_DUPLICATES fq_deps_list)
+  # TODO: Instead of gathering internal object files from entrypoints,
+  # collect the object files with public names of entrypoints.
+  get_object_files_for_test(
+      link_object_files skipped_entrypoints_list ${fq_deps_list})
+  if(skipped_entrypoints_list)
+    message(STATUS "Skipping ${fq_target_name} as it has skipped deps.")
+    return()
+  endif()
+
+  # Create a sysroot structure
+  set(sysroot ${CMAKE_CURRENT_BINARY_DIR}/${test_name}/sysroot)
+  file(MAKE_DIRECTORY ${sysroot})
+  file(MAKE_DIRECTORY ${sysroot}/include)
+  set(sysroot_lib ${sysroot}/lib)
+  file(MAKE_DIRECTORY ${sysroot_lib})
+  # Add dummy crti.o, crtn.o, libm.a and libc++.a
+  file(TOUCH ${sysroot_lib}/crti.o)
+  file(TOUCH ${sysroot_lib}/crtn.o)
+  file(TOUCH ${sysroot_lib}/libm.a)
+  file(TOUCH ${sysroot_lib}/libc++.a)
+  # Copy the loader object
+  get_target_property(loader_object_file ${INTEGRATION_TEST_LOADER} LOADER_OBJECT)
+  if(NOT loader_object_file)
+    message(FATAL_ERROR "Missing LOADER_OBJECT property of ${INTEGRATION_TEST_LOADER}.")
+  endif()
+  set(loader_dst ${sysroot_lib}/${LIBC_TARGET_ARCHITECTURE}-linux-gnu/crt1.o)
+  add_custom_command(
+    OUTPUT ${loader_dst}
+    COMMAND cmake -E copy ${loader_object_file} ${loader_dst}
+    DEPENDS ${INTEGRATION_TEST_LOADER}
+  )
+  add_custom_target(
+    ${fq_target_name}.__copy_loader__
+    DEPENDS ${loader_dst}
+  )
+
+  add_library(
+    ${fq_libc_target_name}
+    STATIC
+    ${link_object_files}
+  )
+  set_target_properties(${fq_libc_target_name} PROPERTIES ARCHIVE_OUTPUT_NAME c)
+  set_target_properties(${fq_libc_target_name} PROPERTIES ARCHIVE_OUTPUT_DIRECTORY ${sysroot_lib})
+
+  add_executable(
+    ${fq_target_name}
+    EXCLUDE_FROM_ALL
+    ${INTEGRATION_TEST_SRCS}
+    ${INTEGRATION_TEST_HDRS}
+  )
+  target_include_directories(
+    ${fq_target_name}
+    PRIVATE
+      ${LIBC_SOURCE_DIR}
+      ${LIBC_BUILD_DIR}
+      ${LIBC_BUILD_DIR}/include
+  )
+  target_link_options(${fq_target_name} PRIVATE --sysroot=${sysroot} -static -stdlib=libc++)
+  add_dependencies(${fq_target_name}
+                   ${fq_target_name}.__copy_loader__
+                   ${fq_libc_target_name}
+                   libc.utils.IntegrationTest.test)
+
+  add_custom_command(
+    TARGET ${fq_target_name}
+    POST_BUILD
+    COMMAND ${INTEGRATION_TEST_ENV} $<TARGET_FILE:${fq_target_name}> ${INTEGRATION_TEST_ARGS}
+  )
+
+  add_dependencies(${INTEGRATION_TEST_SUITE} ${fq_target_name})
+endfunction(add_integration_test)

diff  --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index fc64dbf68b452..7ae253ab187f9 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -226,6 +226,7 @@ if(LLVM_LIBC_FULL_BUILD)
     # libc.src.stdlib.abort
     libc.src.stdlib.atexit
     libc.src.stdlib.exit
+    libc.src.stdlib.getenv
 
     # signal.h entrypoints
     # TODO: Enable signal.h entrypoints after fixing signal.h

diff  --git a/libc/loader/linux/CMakeLists.txt b/libc/loader/linux/CMakeLists.txt
index 4b8b0d9e98fa3..1454abd9fabad 100644
--- a/libc/loader/linux/CMakeLists.txt
+++ b/libc/loader/linux/CMakeLists.txt
@@ -19,11 +19,12 @@ function(add_loader_object name)
 
     add_custom_target(${fq_target_name})
     add_dependencies(${fq_target_name} ${fq_dep_name})
-    get_target_property(dep_objfile ${fq_dep_name} OBJECT_FILES)
+    get_target_property(loader_object ${fq_dep_name} LOADER_OBJECT)
     set_target_properties(
       ${fq_target_name}
       PROPERTIES
         "TARGET_TYPE" "${OBJECT_LIBRARY_TARGET_TYPE}"
+        "LOADER_OBJECT" "${loader_object}"
         "OBJECT_FILES" ""
         "DEPS" "${fq_dep_name}"
     )
@@ -51,6 +52,7 @@ function(add_loader_object name)
     ${fq_target_name}
     PROPERTIES
       "TARGET_TYPE" "${OBJECT_LIBRARY_TARGET_TYPE}"
+      "LOADER_OBJECT" "${objfile}"
       "OBJECT_FILES" ""
       "DEPS" "${fq_target_name}.__objects__"
   )

diff  --git a/libc/test/CMakeLists.txt b/libc/test/CMakeLists.txt
index 850d69345d29d..181d5cc336ecf 100644
--- a/libc/test/CMakeLists.txt
+++ b/libc/test/CMakeLists.txt
@@ -19,4 +19,3 @@ if(NOT LLVM_LIBC_FULL_BUILD)
 endif()
 
 add_subdirectory(integration)
-add_subdirectory(loader)

diff  --git a/libc/test/integration/CMakeLists.txt b/libc/test/integration/CMakeLists.txt
index 13f53e836542f..336cf4fb23534 100644
--- a/libc/test/integration/CMakeLists.txt
+++ b/libc/test/integration/CMakeLists.txt
@@ -1 +1,5 @@
+add_custom_target(libc-integration-tests)
+
+add_subdirectory(loader)
 add_subdirectory(scudo)
+add_subdirectory(src)

diff  --git a/libc/test/loader/CMakeLists.txt b/libc/test/integration/loader/CMakeLists.txt
similarity index 97%
rename from libc/test/loader/CMakeLists.txt
rename to libc/test/integration/loader/CMakeLists.txt
index 5123bed8aaa91..49f7eb71a99f9 100644
--- a/libc/test/loader/CMakeLists.txt
+++ b/libc/test/integration/loader/CMakeLists.txt
@@ -1,5 +1,3 @@
-add_custom_target(libc_loader_tests)
-
 # A rule to add loader tests. When we have a complete loader, we should
 # be able to use the add_libc_unittest rule or an extension of it. But,
 # while the loader is getting built, we need to use a special rule like

diff  --git a/libc/test/integration/loader/linux/CMakeLists.txt b/libc/test/integration/loader/linux/CMakeLists.txt
new file mode 100644
index 0000000000000..564046372064f
--- /dev/null
+++ b/libc/test/integration/loader/linux/CMakeLists.txt
@@ -0,0 +1,57 @@
+if(NOT (EXISTS ${LIBC_SOURCE_DIR}/loader/linux/${LIBC_TARGET_ARCHITECTURE}))
+  message("Skipping loader integration tests for target architecture ${LIBC_TARGET_ARCHITECTURE}.")
+  return()
+endif()
+
+add_custom_target(libc-loader-tests)
+add_dependencies(libc-integration-tests libc-loader-tests)
+
+add_integration_test(
+  loader_args_test
+  SUITE libc-loader-tests
+  LOADER
+    libc.loader.linux.crt1
+  SRCS
+    args_test.cpp
+  ARGS
+    1 2 3
+  ENV
+    FRANCE=Paris
+    GERMANY=Berlin
+)
+
+add_integration_test(
+  loader_no_envp_test
+  SUITE libc-loader-tests
+  LOADER
+    libc.loader.linux.crt1
+  SRCS
+    main_without_envp.cpp
+)
+
+add_integration_test(
+  loader_no_args_test
+  SUITE libc-loader-tests
+  LOADER
+    libc.loader.linux.crt1
+  SRCS
+    main_without_args.cpp
+)
+
+if(NOT (${LIBC_TARGET_ARCHITECTURE} STREQUAL "x86_64"))
+  return()
+endif()
+
+add_integration_test(
+  loader_tls_test
+  SUITE libc-loader-tests
+  LOADER
+    libc.loader.linux.crt1
+  SRCS
+    tls_test.cpp
+  DEPENDS
+    libc.include.errno
+    libc.include.sys_mman
+    libc.src.errno.errno
+    libc.src.sys.mman.mmap
+)

diff  --git a/libc/test/loader/linux/args_test.cpp b/libc/test/integration/loader/linux/args_test.cpp
similarity index 96%
rename from libc/test/loader/linux/args_test.cpp
rename to libc/test/integration/loader/linux/args_test.cpp
index 77ce75610f80c..24d19cbf420a8 100644
--- a/libc/test/loader/linux/args_test.cpp
+++ b/libc/test/integration/loader/linux/args_test.cpp
@@ -6,7 +6,7 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "loader_test.h"
+#include "utils/IntegrationTest/test.h"
 
 static bool my_streq(const char *lhs, const char *rhs) {
   const char *l, *r;

diff  --git a/libc/test/loader/linux/main_without_args.cpp b/libc/test/integration/loader/linux/main_without_args.cpp
similarity index 100%
rename from libc/test/loader/linux/main_without_args.cpp
rename to libc/test/integration/loader/linux/main_without_args.cpp

diff  --git a/libc/test/loader/linux/main_without_envp.cpp b/libc/test/integration/loader/linux/main_without_envp.cpp
similarity index 100%
rename from libc/test/loader/linux/main_without_envp.cpp
rename to libc/test/integration/loader/linux/main_without_envp.cpp

diff  --git a/libc/test/loader/linux/tls_test.cpp b/libc/test/integration/loader/linux/tls_test.cpp
similarity index 96%
rename from libc/test/loader/linux/tls_test.cpp
rename to libc/test/integration/loader/linux/tls_test.cpp
index 7d71db4a5baff..8cd408f491dea 100644
--- a/libc/test/loader/linux/tls_test.cpp
+++ b/libc/test/integration/loader/linux/tls_test.cpp
@@ -6,13 +6,12 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "loader_test.h"
-
 #include "include/errno.h"
 #include "include/sys/mman.h"
 
 #include "src/errno/llvmlibc_errno.h"
 #include "src/sys/mman/mmap.h"
+#include "utils/IntegrationTest/test.h"
 
 constexpr int threadLocalDataSize = 101;
 _Thread_local int a[threadLocalDataSize] = {123};

diff  --git a/libc/test/integration/src/CMakeLists.txt b/libc/test/integration/src/CMakeLists.txt
new file mode 100644
index 0000000000000..641755c0f39e8
--- /dev/null
+++ b/libc/test/integration/src/CMakeLists.txt
@@ -0,0 +1 @@
+add_subdirectory(stdlib)

diff  --git a/libc/test/integration/src/stdlib/CMakeLists.txt b/libc/test/integration/src/stdlib/CMakeLists.txt
new file mode 100644
index 0000000000000..01f5f6a4f1b02
--- /dev/null
+++ b/libc/test/integration/src/stdlib/CMakeLists.txt
@@ -0,0 +1,18 @@
+add_custom_target(stdlib-integration-tests)
+add_dependencies(libc-integration-tests stdlib-integration-tests)
+
+add_integration_test(
+  getenv_test
+  SUITE
+    stdlib-integration-tests
+  SRCS
+    getenv_test.cpp
+  LOADER
+    libc.loader.linux.crt1
+  DEPENDS
+    libc.src.stdlib.getenv
+  ENV
+    FRANCE=Paris
+    GERMANY=Berlin
+)
+

diff  --git a/libc/test/loader/linux/getenv_test.cpp b/libc/test/integration/src/stdlib/getenv_test.cpp
similarity index 97%
rename from libc/test/loader/linux/getenv_test.cpp
rename to libc/test/integration/src/stdlib/getenv_test.cpp
index 0a627a7847a66..a4b3ff53572ec 100644
--- a/libc/test/loader/linux/getenv_test.cpp
+++ b/libc/test/integration/src/stdlib/getenv_test.cpp
@@ -6,9 +6,10 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "loader_test.h"
 #include "src/stdlib/getenv.h"
 
+#include "utils/IntegrationTest/test.h"
+
 static bool my_streq(const char *lhs, const char *rhs) {
   if (lhs == rhs)
     return true;

diff  --git a/libc/test/loader/linux/CMakeLists.txt b/libc/test/loader/linux/CMakeLists.txt
deleted file mode 100644
index e9db6451aa57d..0000000000000
--- a/libc/test/loader/linux/CMakeLists.txt
+++ /dev/null
@@ -1,75 +0,0 @@
-if(NOT (EXISTS ${LIBC_SOURCE_DIR}/loader/linux/${LIBC_TARGET_ARCHITECTURE}))
-  message("Skipping loader tests for target architecture ${LIBC_TARGET_ARCHITECTURE}.")
-  return()
-endif()
-
-add_header_library(
-  loader_test
-  HDRS
-    loader_test.h
-  DEPENDS
-    libc.src.__support.OSUtil.osutil
-)
-
-add_loader_test(
-  loader_args_test
-  SRC
-    args_test.cpp
-  DEPENDS
-    .loader_test
-    libc.loader.linux.crt1
-  ARGS
-    1 2 3
-  ENV
-    FRANCE=Paris
-    GERMANY=Berlin
-)
-
-add_loader_test(
-  loader_no_envp_test
-  SRC
-    main_without_envp.cpp
-  DEPENDS
-    .loader_test
-    libc.loader.linux.crt1
-)
-
-add_loader_test(
-  loader_no_args_test
-  SRC
-    main_without_args.cpp
-  DEPENDS
-    .loader_test
-    libc.loader.linux.crt1
-)
-
-# TODO: Disableing this test temporarily.
-# add_loader_test(
-#   getenv_test
-#   SRC
-#     getenv_test.cpp
-#   DEPENDS
-#     .loader_test
-#     libc.loader.linux.crt1
-#     libc.src.stdlib.getenv
-#   ENV
-#     FRANCE=Paris
-#     GERMANY=Berlin
-# )
-
-if(NOT (${LIBC_TARGET_ARCHITECTURE} STREQUAL "x86_64"))
-  return()
-endif()
-
-add_loader_test(
-  loader_tls_test
-  SRC
-    tls_test.cpp
-  DEPENDS
-    .loader_test
-    libc.include.errno
-    libc.include.sys_mman
-    libc.loader.linux.crt1
-    libc.src.errno.errno
-    libc.src.sys.mman.mmap
-)

diff  --git a/libc/utils/CMakeLists.txt b/libc/utils/CMakeLists.txt
index df79da3204990..80da547924c14 100644
--- a/libc/utils/CMakeLists.txt
+++ b/libc/utils/CMakeLists.txt
@@ -3,5 +3,6 @@ add_subdirectory(testutils)
 add_subdirectory(UnitTest)
 
 if(LLVM_LIBC_FULL_BUILD)
+  add_subdirectory(IntegrationTest)
   add_subdirectory(tools)
 endif()

diff  --git a/libc/utils/IntegrationTest/CMakeLists.txt b/libc/utils/IntegrationTest/CMakeLists.txt
new file mode 100644
index 0000000000000..3866bbe929c7d
--- /dev/null
+++ b/libc/utils/IntegrationTest/CMakeLists.txt
@@ -0,0 +1,7 @@
+add_header_library(
+  test
+  HDRS
+    test.h
+  DEPENDS
+    libc.src.__support.OSUtil.osutil
+)

diff  --git a/libc/test/loader/linux/loader_test.h b/libc/utils/IntegrationTest/test.h
similarity index 88%
rename from libc/test/loader/linux/loader_test.h
rename to libc/utils/IntegrationTest/test.h
index fe00210fc5c3f..97fa10e0524b9 100644
--- a/libc/test/loader/linux/loader_test.h
+++ b/libc/utils/IntegrationTest/test.h
@@ -1,4 +1,4 @@
-//===-- Simple checkers for loader tests ------------------------*- C++ -*-===//
+//===-- Simple checkers for integrations tests ------------------*- C++ -*-===//
 //
 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 // See https://llvm.org/LICENSE.txt for license information.
@@ -6,8 +6,8 @@
 //
 //===----------------------------------------------------------------------===//
 
-#ifndef LLVM_LIBC_TEST_LOADER_LINUX_LOADER_TEST_H
-#define LLVM_LIBC_TEST_LOADER_LINUX_LOADER_TEST_H
+#ifndef LLVM_LIBC_UTILS_INTEGRATION_TEST_TEST_H
+#define LLVM_LIBC_UTILS_INTEGRATION_TEST_TEST_H
 
 #include "src/__support/OSUtil/io.h"
 #include "src/__support/OSUtil/quick_exit.h"
@@ -34,4 +34,4 @@
 #define EXPECT_FALSE(val) __CHECK_NE(__FILE__, __LINE__, val, false)
 #define ASSERT_FALSE(val) __CHECK_NE(__FILE__, __LINE__, val, true)
 
-#endif // LLVM_LIBC_TEST_LOADER_LINUX_LOADER_TEST_H
+#endif // LLVM_LIBC_UTILS_INTEGRATION_TEST_TEST_H


        


More information about the libc-commits mailing list