diff --git a/ci/test.xsh b/ci/test.xsh index 790318a3f7..f29c125f10 100644 --- a/ci/test.xsh +++ b/ci/test.xsh @@ -17,4 +17,5 @@ src/bin/lpython --show-cpp tests/doconcurrentloop_01.py if $WIN != "1": python run_tests.py - python integration_tests/run_tests.py + cd integration_tests + ./run_tests.sh diff --git a/integration_tests/CMakeLists.txt b/integration_tests/CMakeLists.txt new file mode 100644 index 0000000000..3398fdecc9 --- /dev/null +++ b/integration_tests/CMakeLists.txt @@ -0,0 +1,156 @@ +cmake_minimum_required(VERSION 3.5 FATAL_ERROR) + +project(lpython_tests C) + +if (NOT CMAKE_BUILD_TYPE) + set(CMAKE_BUILD_TYPE Debug + CACHE STRING "Build type (Debug, Release)" FORCE) +endif () +if (NOT (CMAKE_BUILD_TYPE STREQUAL "Debug" OR + CMAKE_BUILD_TYPE STREQUAL "Release")) + message("${CMAKE_BUILD_TYPE}") + message(FATAL_ERROR "CMAKE_BUILD_TYPE must be one of: Debug, Release (current value: '${CMAKE_BUILD_TYPE}')") +endif () + +set(LPYTHON_BACKEND no CACHE STRING "Only compile the LPython subset for the given backend") + +find_path(LPYTHON_RTLIB_DIR lfortran_intrinsics.h + ${CMAKE_SOURCE_DIR}/../src/runtime/impure) +find_library(LPYTHON_RTLIB_LIBRARY lpython_runtime_static + ${CMAKE_SOURCE_DIR}/../src/runtime/) +add_library(lpython_rtlib INTERFACE IMPORTED) +set_property(TARGET lpython_rtlib PROPERTY INTERFACE_INCLUDE_DIRECTORIES + ${LPYTHON_RTLIB_DIR}) +set_property(TARGET lpython_rtlib PROPERTY INTERFACE_LINK_LIBRARIES + ${LPYTHON_RTLIB_LIBRARY}) +target_link_libraries(lpython_rtlib INTERFACE m) + +enable_testing() + +message("\n") +message("Configuration results") +message("---------------------") +message("C compiler : ${CMAKE_C_COMPILER}") +message("Build type: ${CMAKE_BUILD_TYPE}") +if (CMAKE_BUILD_TYPE STREQUAL "Debug") + message("C compiler flags : ${CMAKE_C_FLAGS_DEBUG}") +else () + message("C compiler flags : ${CMAKE_C_FLAGS_RELEASE}") +endif () +message("Installation prefix: ${CMAKE_INSTALL_PREFIX}") +message("LPYTHON_BACKEND: ${LPYTHON_BACKEND}") +message("LPYTHON_RTLIB_DIR: ${LPYTHON_RTLIB_DIR}") +message("LPYTHON_RTLIB_LIBRARY: ${LPYTHON_RTLIB_LIBRARY}") + + + +macro(RUN) + set(options FAIL) + set(oneValueArgs NAME) + set(multiValueArgs LABELS EXTRAFILES) + cmake_parse_arguments(RUN "${options}" "${oneValueArgs}" + "${multiValueArgs}" ${ARGN} ) + set(name ${RUN_NAME}) + if (NOT name) + message(FATAL_ERROR "Must specify the NAME argument") + endif() + if (LPYTHON_BACKEND) + if (${LPYTHON_BACKEND} IN_LIST RUN_LABELS) + # Test is supported by the given LPython backend + if (LPYTHON_BACKEND STREQUAL "llvm") + add_custom_command( + OUTPUT ${name}.o + COMMAND lpython -c ${name}.py -o ${name}.o + DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${name}.py + VERBATIM) + add_executable(${name} ${name}.o ${RUN_EXTRAFILES}) + set_target_properties(${name} PROPERTIES LINKER_LANGUAGE C) + target_link_libraries(${name} lpython_rtlib) + add_test(${name} ${CMAKE_CURRENT_BINARY_DIR}/${name}) + if (RUN_LABELS) + set_tests_properties(${name} PROPERTIES LABELS "${RUN_LABELS}") + endif() + if (${RUN_FAIL}) + set_tests_properties(${name} PROPERTIES WILL_FAIL TRUE) + endif() + endif() + if (LPYTHON_BACKEND STREQUAL "c") + add_custom_command( + OUTPUT ${name}.c + COMMAND lpython --show-c ${name}.py > ${name}.c + DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${name}.py + VERBATIM) + add_executable(${name} ${name}.c ${RUN_EXTRAFILES}) + set_target_properties(${name} PROPERTIES LINKER_LANGUAGE C) + target_link_libraries(${name} lpython_rtlib) + add_test(${name} ${CMAKE_CURRENT_BINARY_DIR}/${name}) + if (RUN_LABELS) + set_tests_properties(${name} PROPERTIES LABELS "${RUN_LABELS}") + endif() + if (${RUN_FAIL}) + set_tests_properties(${name} PROPERTIES WILL_FAIL TRUE) + endif() + endif() + endif() + else() + if ("cpython" IN_LIST RUN_LABELS) + # CPython test + add_test(${name} python ${CMAKE_CURRENT_BINARY_DIR}/${name}.py) + set_tests_properties(${name} PROPERTIES + ENVIRONMENT PYTHONPATH=${CMAKE_SOURCE_DIR}/../src/runtime/ltypes) + if (RUN_LABELS) + set_tests_properties(${name} PROPERTIES LABELS "${RUN_LABELS}") + endif() + if (${RUN_FAIL}) + set_tests_properties(${name} PROPERTIES WILL_FAIL TRUE) + endif() + endif() + endif() +endmacro(RUN) + + +# Test zero and non-zero exit code +RUN(NAME exit_01 LABELS cpython llvm) +RUN(NAME exit_02 FAIL LABELS cpython llvm) + +# Test all three backends +RUN(NAME print_01 LABELS cpython llvm c) + +# CPython and LLVM +RUN(NAME expr_01 LABELS cpython llvm) +RUN(NAME expr_02 LABELS cpython llvm) +RUN(NAME expr_03 LABELS cpython llvm) +RUN(NAME expr_04 LABELS cpython llvm) +RUN(NAME expr_05 LABELS cpython llvm) +RUN(NAME test_types_01 LABELS cpython llvm) +RUN(NAME test_str_01 LABELS cpython llvm) +RUN(NAME test_str_02 LABELS cpython llvm) +RUN(NAME test_list_01 LABELS cpython llvm) +RUN(NAME modules_01 LABELS cpython llvm) +RUN(NAME test_math LABELS cpython llvm) +RUN(NAME test_numpy_01 LABELS cpython llvm) +RUN(NAME test_numpy_02 LABELS cpython llvm) +RUN(NAME test_random LABELS cpython llvm) +RUN(NAME test_os LABELS cpython llvm) +RUN(NAME test_builtin LABELS cpython llvm) +RUN(NAME test_builtin_abs LABELS cpython llvm) +RUN(NAME test_builtin_bool LABELS cpython llvm) +RUN(NAME test_builtin_pow LABELS cpython llvm) +RUN(NAME test_builtin_int LABELS cpython llvm) +RUN(NAME test_builtin_len LABELS cpython llvm) +RUN(NAME test_builtin_float LABELS cpython llvm) +RUN(NAME test_builtin_str_02 LABELS cpython llvm) +RUN(NAME test_builtin_round LABELS cpython llvm) +RUN(NAME test_math1 LABELS cpython llvm) +RUN(NAME test_math_02 LABELS cpython llvm) +RUN(NAME test_c_interop_01 LABELS cpython llvm) +RUN(NAME test_generics_01 LABELS cpython llvm) +RUN(NAME test_cmath LABELS cpython llvm) +RUN(NAME test_complex LABELS cpython llvm) +RUN(NAME test_max_min LABELS cpython llvm) +RUN(NAME test_integer_bitnot LABELS cpython llvm) +RUN(NAME test_unary_minus LABELS cpython llvm) +RUN(NAME test_issue_518 LABELS cpython llvm) + +# Just CPython +RUN(NAME test_builtin_bin LABELS cpython) diff --git a/integration_tests/exit_02.py b/integration_tests/exit_02.py new file mode 100644 index 0000000000..cee5fe86b1 --- /dev/null +++ b/integration_tests/exit_02.py @@ -0,0 +1,8 @@ +from sys import exit + +def main0(): + print("Before") + exit(1) + print("After") + +main0() diff --git a/integration_tests/print_01.py b/integration_tests/print_01.py new file mode 100644 index 0000000000..f301245e24 --- /dev/null +++ b/integration_tests/print_01.py @@ -0,0 +1 @@ +print("Hello World!") diff --git a/integration_tests/run_tests.py b/integration_tests/run_tests.py deleted file mode 100755 index 8f741bade8..0000000000 --- a/integration_tests/run_tests.py +++ /dev/null @@ -1,117 +0,0 @@ -#!/usr/bin/env python - -import os -import sys - -# LPython and CPython tests -tests = [ - "exit_01.py", - "expr_01.py", - "expr_02.py", - "expr_03.py", - "expr_04.py", - "expr_05.py", - "test_types_01.py", - "test_str_01.py", - "test_str_02.py", - "test_list_01.py", - "modules_01.py", - #"modules_02.py", - "test_math.py", - "test_numpy_01.py", - "test_numpy_02.py", - "test_random.py", - "test_os.py", - "test_builtin.py", - "test_builtin_abs.py", - "test_builtin_bool.py", - "test_builtin_pow.py", - "test_builtin_int.py", - "test_builtin_len.py", - "test_builtin_float.py", - "test_builtin_str_02.py", - "test_builtin_round.py", - # "test_builtin_hex.py", - # "test_builtin_oct.py", - # "test_builtin_str.py", - "test_math1.py", - "test_math_02.py", - "test_c_interop_01.py", - "test_generics_01.py", - "test_cmath.py", - "test_complex.py", - "test_max_min.py", - "test_integer_bitnot.py", - "test_unary_minus.py", - "test_issue_518.py" - -] - -# CPython tests only -test_cpython = [ - "test_builtin_bin.py", -] - -CUR_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__))) - -def main(): - if not os.path.exists(os.path.join(CUR_DIR, 'tmp')): - os.makedirs(os.path.join(CUR_DIR, 'tmp')) - _print_msg("Compiling LPython tests...", 30) - for pyfile in tests: - basename = os.path.splitext(pyfile)[0] - cmd = os.path.join("..", "src", "bin", "lpython") + " %s -o tmp/%s" % (pyfile, basename) - msg = "Running: %s" % cmd - _print_msg(msg, 33) - os.chdir("integration_tests") - r = os.system(cmd) - os.chdir("..") - if r != 0: - msg = "Command '%s' failed." % cmd - _print_msg(msg, 31) - sys.exit(1) - - _print_msg("Running LPython and CPython tests...", 30) - python_path="src/runtime/ltypes" - for pyfile in tests: - basename = os.path.splitext(pyfile)[0] - cmd = "integration_tests/tmp/%s" % (basename) - msg = "Running: %s" % cmd - _print_msg(msg, 33) - r = os.system(cmd) - if r != 0: - msg = "Command '%s' failed." % cmd - _print_msg(msg, 31) - sys.exit(1) - cmd = "PYTHONPATH=%s python integration_tests/%s" % (python_path, - pyfile) - msg = "Running: %s" % cmd - _print_msg(msg, 33) - r = os.system(cmd) - if r != 0: - msg = "Command '%s' failed." % cmd - _print_msg(msg, 31) - sys.exit(1) - - _print_msg("Running CPython tests...", 30) - for pyfile in test_cpython: - cmd = "PYTHONPATH=%s python integration_tests/%s" % (python_path, - pyfile) - msg = "Running: %s" % cmd - _print_msg(msg, 33) - r = os.system(cmd) - if r != 0: - msg = "Command '%s' failed." % cmd - _print_msg(msg, 31) - sys.exit(1) - _print_msg("ALL TESTS PASSED", 32) - - -def _color(value): - return "\033[" + str(int(value)) + "m" - -def _print_msg(string, color_int): - print("%s%s%s" % (_color(color_int) + _color(1), string, _color(39) + _color(0))) - -if __name__ == "__main__": - main() diff --git a/integration_tests/run_tests.sh b/integration_tests/run_tests.sh new file mode 100755 index 0000000000..0fd1e38b93 --- /dev/null +++ b/integration_tests/run_tests.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +set -ex + +export PATH="$(pwd)/../src/bin:$PATH" + +cmake . +ctest + +cmake -DLPYTHON_BACKEND=llvm . +make +ctest + +cmake -DLPYTHON_BACKEND=c . +make +ctest diff --git a/integration_tests/test_os.py b/integration_tests/test_os.py index 664d5fea0a..53a489f928 100644 --- a/integration_tests/test_os.py +++ b/integration_tests/test_os.py @@ -3,7 +3,7 @@ def test(): path: str - path = "integration_tests/test_os.py" + path = "test_os.py" fd: i64 n: i64 fd = open(path, O_RDONLY)