Skip to content

Commit 321227a

Browse files
committed
Replace test_not.cpp by test_not.py so that it can be tested under emulation
1 parent b6645ef commit 321227a

File tree

5 files changed

+105
-41
lines changed

5 files changed

+105
-41
lines changed

CMakeLists.txt

+6
Original file line numberDiff line numberDiff line change
@@ -319,6 +319,12 @@ if (TEST_SUITE_USER_MODE_EMULATION)
319319
set(FPCMP fpcmp)
320320
endif()
321321

322+
# Shortcut for the path to the not executable
323+
set(NOT_TOOL not)
324+
if (TEST_SUITE_USER_MODE_EMULATION AND TEST_SUITE_RUN_UNDER)
325+
set(NOT_TOOL not-spawning-emulator)
326+
endif()
327+
322328
add_subdirectory(litsupport)
323329

324330
option(TEST_SUITE_COLLECT_COMPILE_TIME

Fortran/gfortran/CMakeLists.txt

-8
Original file line numberDiff line numberDiff line change
@@ -716,14 +716,6 @@ function(gfortran_add_execute_test expect_error main others fflags ldflags)
716716
gfortran_make_working_dir("${target}" working_dir)
717717
get_filename_component(working_dir_name "${working_dir}" NAME)
718718

719-
# When running in an emulator, use the version of 'not' that will
720-
# spawn the subprocess under that emulator as well.
721-
if(TEST_SUITE_USER_MODE_EMULATION AND TEST_SUITE_RUN_UNDER)
722-
set(NOT_TOOL "not-spawning-emulator")
723-
else()
724-
set(NOT_TOOL "not")
725-
endif()
726-
727719
llvm_test_executable_no_test(${target} ${main} ${others})
728720
if (expect_error)
729721
llvm_test_run(

tools/test/CMakeLists.txt

+11-26
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,3 @@
1-
# Copy these files to the build directory so that the tests can be run even
2-
# without the source directory.
3-
configure_file(test_not.py test_not.py
4-
COPYONLY)
5-
61
llvm_test_executable_no_test(ret1 ret1.c)
72
add_dependencies(ret1 not)
83
llvm_test_run(EXECUTABLE "$<TARGET_FILE:not>" "$<TARGET_FILE:ret1>")
@@ -13,25 +8,15 @@ add_dependencies(ret0 not)
138
llvm_test_run(EXECUTABLE "$<TARGET_FILE:not>" "$<TARGET_FILE:not>" "$<TARGET_FILE:ret0>")
149
llvm_add_test_for_target(ret0)
1510

16-
if(TEST_SUITE_USER_MODE_EMULATION AND TEST_SUITE_RUN_UNDER)
17-
# Check that expected crashes are handled correctly under user-mode emulation.
18-
llvm_test_executable_no_test(abrt abort.c)
19-
add_dependencies(abrt not-spawning-emulator)
20-
llvm_test_run(EXECUTABLE "$<TARGET_FILE:not-spawning-emulator>" "--crash" "$<TARGET_FILE:abrt>")
21-
llvm_add_test_for_target(abrt)
22-
else()
23-
# Check that expected crashes are handled correctly.
24-
llvm_test_executable_no_test(abrt abort.c)
25-
add_dependencies(abrt not)
26-
llvm_test_run(EXECUTABLE "$<TARGET_FILE:not>" "--crash" "$<TARGET_FILE:abrt>")
27-
llvm_add_test_for_target(abrt)
11+
# Check that expected crashes are handled correctly under user-mode emulation.
12+
llvm_test_executable_no_test(abrt abort.c)
13+
add_dependencies(abrt ${NOT_TOOL})
14+
llvm_test_run(EXECUTABLE "$<TARGET_FILE:${NOT_TOOL}>" "--crash" "$<TARGET_FILE:abrt>")
15+
llvm_add_test_for_target(abrt)
2816

29-
# Check that not passes environment variables to the called executable.
30-
# This test is disabled in case of user-mode emulation because it would otherwise run the
31-
# host python interpreter under the target emulator.
32-
find_package(Python COMPONENTS Interpreter)
33-
llvm_test_executable_no_test(check_env check_env.c)
34-
add_dependencies(check_env not)
35-
llvm_test_run(EXECUTABLE ${Python_EXECUTABLE} "%b/test/test_not.py" "$<TARGET_FILE:not>" "$<TARGET_FILE:check_env>")
36-
llvm_add_test_For_target(check_env)
37-
endif()
17+
# Check that not passes environment variables to the called executable.
18+
llvm_test_executable_no_test(test_not test_not.cpp)
19+
llvm_test_executable_no_test(check_env check_env.c)
20+
add_dependencies(check_env not test_not)
21+
llvm_test_run(EXECUTABLE ${Python_EXECUTABLE} "$<TARGET_FILE:test_not>" "$<TARGET_FILE:${NOT_TOOL}>" "$<TARGET_FILE:check_env>")
22+
llvm_add_test_For_target(check_env)

tools/test/test_not.cpp

+88
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
//===- test_not.cpp - Test for enviroment variables in the not tool -------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#include <cstdlib>
10+
#include <iostream>
11+
#include <sstream>
12+
13+
#ifdef _WIN32
14+
#define WIN32_LEAN_AND_MEAN
15+
#define NOMINMAX
16+
#include <windows.h>
17+
#endif
18+
19+
#if defined(__unix__) || defined(__APPLE__)
20+
#include <spawn.h>
21+
#include <sys/wait.h>
22+
#endif
23+
24+
int main(int argc, char *const *argv) {
25+
++argv;
26+
--argc;
27+
if (argc == 0)
28+
return EXIT_FAILURE;
29+
30+
#ifdef _WIN32
31+
SetEnvironmentVariableA("SET_IN_PARENT", "something");
32+
#else
33+
setenv("SET_IN_PARENT", "something", 0);
34+
#endif
35+
36+
int result;
37+
38+
#if defined(__unix__) || defined(__APPLE__)
39+
pid_t pid;
40+
extern char **environ;
41+
if (posix_spawn(&pid, argv[0], NULL, NULL, argv, environ))
42+
return EXIT_FAILURE;
43+
if (waitpid(pid, &result, WUNTRACED | WCONTINUED) == -1)
44+
return EXIT_FAILURE;
45+
#else
46+
std::stringstream ss;
47+
ss << argv[0];
48+
for (int i = 1; i < argc; ++i)
49+
ss << " " << argv[i];
50+
std::string cmd = ss.str();
51+
result = std::system(cmd.c_str());
52+
#endif
53+
54+
int retcode = 0;
55+
int signal = 0;
56+
57+
#ifdef _WIN32
58+
// Handle abort() in msvcrt -- It has exit code as 3. abort(), aka
59+
// unreachable, should be recognized as a crash. However, some binaries use
60+
// exit code 3 on non-crash failure paths, so only do this if we expect a
61+
// crash.
62+
if (errno) {
63+
// If the command interpreter was not found, errno will be set and 0 will
64+
// be returned. It is unlikely that this will happen in our use case, but
65+
// check anyway.
66+
retcode = 1;
67+
signal = 1;
68+
} else {
69+
// On Windows, result is the exit code, except for the special case above.
70+
retcode = result;
71+
signal = 0;
72+
}
73+
#elif defined(WIFEXITED) && defined(WEXITSTATUS) && defined(WIFSIGNALED) && \
74+
defined(WTERMSIG)
75+
// On POSIX systems and Solaris, result is a composite value of the exit code
76+
// and, potentially, the signal that caused termination of the command.
77+
if (WIFEXITED(result))
78+
retcode = WEXITSTATUS(result);
79+
if (WIFSIGNALED(result))
80+
signal = WTERMSIG(result);
81+
#else
82+
#error "Unsupported system"
83+
#endif
84+
85+
if (!signal && retcode == EXIT_SUCCESS)
86+
return EXIT_SUCCESS;
87+
return EXIT_FAILURE;
88+
}

tools/test/test_not.py

-7
This file was deleted.

0 commit comments

Comments
 (0)