Skip to content

Commit a5587de

Browse files
authored
Merge pull request #20 from Shaikh-Ubaid/integration_tests
Support Integration tests
2 parents 2cc6adb + f5b6917 commit a5587de

File tree

13 files changed

+332
-20
lines changed

13 files changed

+332
-20
lines changed

.github/workflows/CI.yml

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -55,18 +55,6 @@ jobs:
5555
run: |
5656
which clang
5757
58-
lc examples/expr2.c --backend c --extra-arg="-Isrc/runtime/include" --
59-
60-
lc examples/expr2.c --backend wasm --extra-arg="-Isrc/runtime/include" --
61-
62-
lc examples/expr2.c --backend llvm --extra-arg="-Isrc/runtime/include" --
63-
64-
lc tests/array_01.cpp --backend=llvm --extra-arg="-Isrc/runtime/include" --
65-
66-
lc tests/array_02.cpp --backend=llvm --extra-arg="-Isrc/runtime/include" --
67-
68-
lc tests/array_02.cpp --backend=llvm --extra-arg="-Isrc/runtime/include" --
69-
7058
lc tests/array_03.cpp --backend=llvm --extra-arg="-I$CONDA_PREFIX/include" --
7159
7260
# Test generating object files
@@ -77,3 +65,10 @@ jobs:
7765
# Test including iostream and span headers
7866
lc tests/span_01.cpp --ast-dump --ast-dump-file="tests/span_01.ast" --extra-arg="-std=c++20" --
7967
cat tests/span_01.ast
68+
69+
- name: Test3 (Linux / macOS)
70+
shell: bash -l -e {0}
71+
if: contains(matrix.os, 'ubuntu') || contains(matrix.os, 'macos')
72+
run: |
73+
./integration_tests/run_tests.py -b gcc llvm wasm c
74+
./integration_tests/run_tests.py -b gcc llvm wasm c -f

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ fa
3131
fa2
3232
*/bin/lc
3333
*vscode*
34+
integration_tests/test-*
3435

3536
## Byte-compiled / optimized / DLL files
3637
__pycache__/

cmake/UserOverride.cmake

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# This overrides the default CMake Debug and Release compiler options.
2+
# The user can still specify different options by setting the
3+
# CMAKE_CXX_FLAGS_[RELEASE,DEBUG] variables (on the command line or in the
4+
# CMakeList.txt). This files serves as better CMake defaults and should only be
5+
# modified if the default values are to be changed. Project specific compiler
6+
# flags should be set in the CMakeList.txt by setting the CMAKE_CXX_FLAGS_*
7+
# variables.
8+
9+
if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
10+
# g++
11+
set(common "-Wall -Wextra")
12+
set(CMAKE_CXX_FLAGS_RELEASE_INIT "${common} -O3 -funroll-loops -DNDEBUG")
13+
set(CMAKE_CXX_FLAGS_DEBUG_INIT "${common} -g -ggdb")
14+
elseif (CMAKE_CXX_COMPILER_ID STREQUAL "Intel")
15+
# icpc
16+
set(common "-Wall")
17+
set(CMAKE_CXX_FLAGS_RELEASE_INIT "${common} -xHOST -O3")
18+
set(CMAKE_CXX_FLAGS_DEBUG_INIT "${common} -g -O0")
19+
elseif (CMAKE_CXX_COMPILER_ID MATCHES Clang)
20+
# clang
21+
set(common "-Wall -Wextra")
22+
set(CMAKE_CXX_FLAGS_RELEASE_INIT "${common} -O3 -funroll-loops -DNDEBUG")
23+
set(CMAKE_CXX_FLAGS_DEBUG_INIT "${common} -g -ggdb")
24+
elseif (CMAKE_CXX_COMPILER_ID STREQUAL "PGI")
25+
# pgcpp
26+
endif ()

integration_tests/CMakeLists.txt

Lines changed: 183 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,183 @@
1+
cmake_minimum_required(VERSION 3.10 FATAL_ERROR)
2+
3+
project(lc C CXX)
4+
5+
if (NOT CMAKE_BUILD_TYPE)
6+
set(CMAKE_BUILD_TYPE Debug
7+
CACHE STRING "Build type (Debug, Release)" FORCE)
8+
endif ()
9+
if (NOT (CMAKE_BUILD_TYPE STREQUAL "Debug" OR
10+
CMAKE_BUILD_TYPE STREQUAL "Release"))
11+
message("${CMAKE_BUILD_TYPE}")
12+
message(FATAL_ERROR "CMAKE_BUILD_TYPE must be one of: Debug, Release (current value: '${CMAKE_BUILD_TYPE}')")
13+
endif ()
14+
15+
find_program(LC NAMES lc)
16+
17+
set(LC_RTL_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../src/runtime)
18+
set(LC_RTL_HEADER_DIR ${LC_RTL_DIR}/impure)
19+
20+
find_path(LC_RTLIB_DIR lfortran_intrinsics.h
21+
HINTS ${LC_RTL_HEADER_DIR})
22+
find_library(LC_RTLIB_LIBRARY lc_runtime_static
23+
HINTS ${LC_RTL_DIR})
24+
add_library(lc_runtime INTERFACE IMPORTED)
25+
set_property(TARGET lc_runtime PROPERTY INTERFACE_INCLUDE_DIRECTORIES
26+
${LC_RTLIB_DIR})
27+
set_property(TARGET lc_runtime PROPERTY INTERFACE_LINK_LIBRARIES
28+
${LC_RTLIB_LIBRARY})
29+
target_link_libraries(lc_runtime INTERFACE m)
30+
31+
set(LC_BACKEND no CACHE STRING "Only compile the LC subset for the given backend")
32+
set(FAST no CACHE BOOL "Run supported tests with --fast")
33+
34+
enable_testing()
35+
36+
message("\n")
37+
message("Configuration results")
38+
message("---------------------")
39+
message("Fortran compiler: ${CMAKE_Fortran_COMPILER}")
40+
message("C compiler : ${CMAKE_C_COMPILER}")
41+
message("Build type: ${CMAKE_BUILD_TYPE}")
42+
if (CMAKE_BUILD_TYPE STREQUAL "Debug")
43+
message("Fortran compiler flags: ${CMAKE_Fortran_FLAGS_DEBUG}")
44+
message("C compiler flags : ${CMAKE_C_FLAGS_DEBUG}")
45+
else ()
46+
message("Fortran compiler flags: ${CMAKE_Fortran_FLAGS_RELEASE}")
47+
message("C compiler flags : ${CMAKE_C_FLAGS_RELEASE}")
48+
endif ()
49+
message("Installation prefix: ${CMAKE_INSTALL_PREFIX}")
50+
message("LC_BACKEND: ${LC_BACKEND}")
51+
message("FAST: ${FAST}")
52+
53+
54+
macro(RUN_UTIL RUN_FAIL RUN_NAME RUN_FILE_NAME RUN_LABELS RUN_EXTRAFILES RUN_EXTRA_ARGS RUN_COPY_TO_BIN RUN_GCC_ARGS)
55+
set(fail ${${RUN_FAIL}})
56+
set(name ${${RUN_NAME}})
57+
set(file_name ${${RUN_FILE_NAME}})
58+
set(labels ${${RUN_LABELS}})
59+
set(extra_files ${${RUN_EXTRAFILES}})
60+
set(extra_args ${${RUN_EXTRA_ARGS}})
61+
set(copy_to_bin ${${RUN_COPY_TO_BIN}})
62+
set(gcc_args ${${RUN_GCC_ARGS}})
63+
64+
if (NOT name)
65+
message(FATAL_ERROR "Must specify the NAME argument")
66+
endif()
67+
68+
if (LC_BACKEND)
69+
if (${LC_BACKEND} IN_LIST labels)
70+
# Test is supported by the given LC backend
71+
set(ADD_TEST ON)
72+
else()
73+
# Test is not supported by the given LC backend
74+
set(ADD_TEST OFF)
75+
endif()
76+
else()
77+
# GCC
78+
if ("gcc" IN_LIST labels)
79+
set(ADD_TEST ON)
80+
else()
81+
set(ADD_TEST OFF)
82+
endif()
83+
endif()
84+
85+
if (ADD_TEST)
86+
if ((LC_BACKEND STREQUAL "llvm") OR (LC_BACKEND STREQUAL "cpp") OR (LC_BACKEND STREQUAL "x86")
87+
OR (LC_BACKEND STREQUAL "c") OR (LC_BACKEND STREQUAL "fortran"))
88+
add_custom_command(
89+
OUTPUT ${name}.o
90+
COMMAND ${LC} -c ${extra_args} ${CMAKE_CURRENT_SOURCE_DIR}/${file_name} -o ${name}.o --extra-arg -I${CMAKE_CURRENT_SOURCE_DIR}/../src/runtime/include --
91+
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${file_name}
92+
VERBATIM)
93+
add_executable(${name} ${name}.o ${extra_files})
94+
set_target_properties(${name} PROPERTIES LINKER_LANGUAGE C)
95+
target_link_libraries(${name} lc_runtime)
96+
add_test(${name} ${CURRENT_BINARY_DIR}/${name})
97+
elseif (LC_BACKEND STREQUAL "wasm")
98+
# wasm test
99+
execute_process(COMMAND ${LC} ${extra_args} --backend=wasm ${CMAKE_CURRENT_SOURCE_DIR}/${file_name} -o ${name}
100+
--extra-arg -I${CMAKE_CURRENT_SOURCE_DIR}/../src/runtime/include --)
101+
find_program(WASM_EXEC_RUNTIME node)
102+
execute_process(COMMAND "${WASM_EXEC_RUNTIME}" --version
103+
OUTPUT_VARIABLE WASM_EXEC_VERSION
104+
OUTPUT_STRIP_TRAILING_WHITESPACE)
105+
106+
string(REGEX REPLACE "v([0-9]+)\\.([0-9]+)\\.([0-9]+)" "\\1" NODE_MAJOR_VERSION "${WASM_EXEC_VERSION}")
107+
108+
if (NODE_MAJOR_VERSION LESS 16)
109+
message(STATUS "${WASM_EXEC_RUNTIME} version: ${WASM_EXEC_VERSION}")
110+
set(WASM_EXEC_FLAGS "--experimental-wasm-bigint")
111+
endif()
112+
set(WASM_EXEC_FLAGS ${WASM_EXEC_FLAGS} "--experimental-wasi-unstable-preview1")
113+
add_test(${name} ${WASM_EXEC_RUNTIME} ${WASM_EXEC_FLAGS} ${CURRENT_BINARY_DIR}/${name}.js)
114+
else ()
115+
add_executable(${name} ${file_name} ${extra_files})
116+
target_compile_options(${name} PUBLIC ${gcc_args})
117+
add_test(${name} ${CURRENT_BINARY_DIR}/${name})
118+
endif()
119+
120+
if (labels)
121+
set_tests_properties(${name} PROPERTIES LABELS "${labels}")
122+
endif()
123+
124+
if (fail)
125+
set_tests_properties(${name} PROPERTIES WILL_FAIL TRUE)
126+
endif()
127+
128+
if (copy_to_bin)
129+
file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/${copy_to_bin} DESTINATION ${CURRENT_BINARY_DIR})
130+
endif()
131+
endif()
132+
endmacro(RUN_UTIL)
133+
134+
macro(RUN)
135+
set(options FAIL NOFAST)
136+
set(oneValueArgs NAME INCLUDE_PATH COPY_TO_BIN)
137+
set(multiValueArgs LABELS EXTRAFILES EXTRA_ARGS GCC_ARGS)
138+
cmake_parse_arguments(RUN "${options}" "${oneValueArgs}"
139+
"${multiValueArgs}" ${ARGN} )
140+
141+
foreach(b ${RUN_LABELS})
142+
if (NOT (b MATCHES "^(llvm|llvm2|llvm_rtlib|gcc|c|cpp|x86|wasm|gfortran|llvmImplicit|llvmStackArray|fortran|c_nopragma|llvm_nopragma)$"))
143+
message(FATAL_ERROR "Unsupported backend: ${b}")
144+
endif()
145+
endforeach()
146+
147+
set(RUN_FILE_NAME ${RUN_NAME})
148+
149+
if (RUN_INCLUDE_PATH)
150+
# Only one include path supported for now
151+
# Later add support for multiple include paths by looping over and appending to extra args
152+
set(RUN_EXTRA_ARGS ${RUN_EXTRA_ARGS} -I${CMAKE_CURRENT_SOURCE_DIR}/${RUN_INCLUDE_PATH})
153+
set(RUN_GCC_ARGS ${RUN_GCC_ARGS} -I${CMAKE_CURRENT_SOURCE_DIR}/${RUN_INCLUDE_PATH})
154+
endif()
155+
156+
if (NOT FAST)
157+
RUN_UTIL(RUN_FAIL RUN_NAME RUN_FILE_NAME RUN_LABELS RUN_EXTRAFILES RUN_EXTRA_ARGS RUN_COPY_TO_BIN RUN_GCC_ARGS)
158+
endif()
159+
160+
if ((FAST) AND (NOT RUN_NOFAST))
161+
set(RUN_EXTRA_ARGS ${RUN_EXTRA_ARGS} --fast)
162+
set(RUN_NAME "${RUN_NAME}_FAST")
163+
list(REMOVE_ITEM RUN_LABELS gfortran) # remove gfortran from --fast test
164+
RUN_UTIL(RUN_FAIL RUN_NAME RUN_FILE_NAME RUN_LABELS RUN_EXTRAFILES RUN_EXTRA_ARGS RUN_COPY_TO_BIN RUN_GCC_ARGS)
165+
endif()
166+
endmacro(RUN)
167+
168+
# The supported test labels are:
169+
#
170+
# gcc --- compile with Gcc
171+
# fortran --- convert to Fortran code and compile with GFortran
172+
# llvm --- compile with LC, only generate binary code at the very end
173+
# llvm2 --- compile with LC, generate object files
174+
# llvm_rtlib --- compile with LC loading ASR runtime library, generate object files
175+
# cpp --- compile to C++, compile C++ to binary
176+
# x86 --- compile to x86 binary directly
177+
# wasm --- compile to WASM binary directly
178+
179+
RUN(NAME expr1.c LABELS gcc c wasm llvm NOFAST)
180+
181+
# arrays
182+
RUN(NAME array_01.cpp LABELS gcc llvm NOFAST)
183+
RUN(NAME array_02.cpp LABELS gcc llvm NOFAST)
File renamed without changes.
File renamed without changes.

integration_tests/expr1.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#include <stdio.h>
2+
3+
int main() {
4+
int x;
5+
x = (2+3)*5;
6+
printf("%d\n", x);
7+
return 0;
8+
}

integration_tests/run_tests.py

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
#!/usr/bin/env python
2+
3+
import argparse
4+
import subprocess as sp
5+
import os
6+
7+
# Initialization
8+
NO_OF_THREADS = 8 # default no of threads is 8
9+
SUPPORTED_BACKENDS = ['llvm', 'llvm2', 'llvm_rtlib', 'c', 'cpp', 'x86', 'wasm',
10+
'gcc', 'llvmImplicit', 'llvmStackArray', 'fortran',
11+
'c_nopragma', 'llvm_nopragma']
12+
BASE_DIR = os.path.dirname(os.path.realpath(__file__))
13+
LC_PATH = f"{BASE_DIR}/../src/bin:$PATH"
14+
15+
fast_tests = "no"
16+
17+
def run_cmd(cmd, cwd=None):
18+
print(f"+ {cmd}")
19+
process = sp.run(cmd, shell=True, cwd=cwd)
20+
if process.returncode != 0:
21+
print("Command failed.")
22+
exit(1)
23+
24+
def run_test(backend):
25+
run_cmd(f"mkdir {BASE_DIR}/test-{backend}")
26+
cwd=f"{BASE_DIR}/test-{backend}"
27+
common=f" -DCURRENT_BINARY_DIR={BASE_DIR}/test-{backend} -S {BASE_DIR} -B {BASE_DIR}/test-{backend}"
28+
if backend == "gcc":
29+
run_cmd(f"cmake" + common,
30+
cwd=cwd)
31+
else:
32+
run_cmd(f"cmake -DLC_BACKEND={backend} -DFAST={fast_tests}" + common,
33+
cwd=cwd)
34+
run_cmd(f"make -j{NO_OF_THREADS}", cwd=cwd)
35+
run_cmd(f"ctest -j{NO_OF_THREADS} --output-on-failure", cwd=cwd)
36+
37+
38+
def test_backend(backend):
39+
if backend not in SUPPORTED_BACKENDS:
40+
print(f"Unsupported Backend: {backend}\n")
41+
return
42+
run_test(backend)
43+
44+
def check_module_names():
45+
from glob import glob
46+
import re
47+
mod = re.compile("(module|MODULE) (\w+)")
48+
files = glob("*.f90")
49+
module_names = []
50+
file_names = []
51+
for file in files:
52+
f = open(file).read()
53+
s = mod.search(f)
54+
if s:
55+
module_names.append(s.group(2))
56+
file_names.append(file)
57+
for i in range(len(module_names)):
58+
name = module_names[i]
59+
if name in module_names[i+1:]:
60+
print("FAIL: Found a duplicate module name")
61+
print("Name:", name)
62+
print("Filename:", file_names[i])
63+
raise Exception("Duplicate module names")
64+
print("OK: All module names are unique")
65+
66+
def get_args():
67+
parser = argparse.ArgumentParser(description="LFortran Integration Test Suite")
68+
parser.add_argument("-j", "-n", "--no_of_threads", type=int,
69+
help="Parallel testing on given number of threads")
70+
parser.add_argument("-b", "--backends", nargs="*", default=["llvm"], type=str,
71+
help="Test the requested backends (%s)" % \
72+
", ".join(SUPPORTED_BACKENDS))
73+
parser.add_argument("-f", "--fast", action='store_true',
74+
help="Run supported tests with --fast")
75+
parser.add_argument("-m", action='store_true',
76+
help="Check that all module names are unique")
77+
return parser.parse_args()
78+
79+
def main():
80+
args = get_args()
81+
82+
if args.m:
83+
check_module_names()
84+
return
85+
86+
# Setup
87+
global NO_OF_THREADS, fast_tests
88+
os.environ["PATH"] += os.pathsep + LC_PATH
89+
# delete previously created directories (if any)
90+
for backend in SUPPORTED_BACKENDS:
91+
run_cmd(f"rm -rf {BASE_DIR}/test-{backend}")
92+
93+
NO_OF_THREADS = args.no_of_threads or NO_OF_THREADS
94+
fast_tests = "yes" if args.fast else "no"
95+
for backend in args.backends:
96+
test_backend(backend)
97+
98+
if __name__ == "__main__":
99+
main()

tests/reference/asr-array_01-bf5ef80.json renamed to tests/reference/asr-array_01-9c6ecba.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
{
2-
"basename": "asr-array_01-bf5ef80",
2+
"basename": "asr-array_01-9c6ecba",
33
"cmd": "lc --asr-dump --no-color {infile} -o {outfile} -extra-arg=\"-Isrc/runtime/include\"",
4-
"infile": "tests/array_01.cpp",
4+
"infile": "tests/../integration_tests/array_01.cpp",
55
"infile_hash": "deb860e61919d1bd2fbc7abeeed41124193f4284de0838d4ba94fa09",
66
"outfile": null,
77
"outfile_hash": null,
8-
"stdout": "asr-array_01-bf5ef80.stdout",
8+
"stdout": "asr-array_01-9c6ecba.stdout",
99
"stdout_hash": "141c00a55703c54d1d113b441b052bd1ac7dfc8cc1fb73b243532bfd",
1010
"stderr": null,
1111
"stderr_hash": null,

tests/reference/asr-array_02-0507073.json renamed to tests/reference/asr-array_02-e00d30a.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
{
2-
"basename": "asr-array_02-0507073",
2+
"basename": "asr-array_02-e00d30a",
33
"cmd": "lc --asr-dump --no-color {infile} -o {outfile} -extra-arg=\"-Isrc/runtime/include\"",
4-
"infile": "tests/array_02.cpp",
4+
"infile": "tests/../integration_tests/array_02.cpp",
55
"infile_hash": "cb968d294be0d86c0f49b3364b7a3aa45b53edcc59349301d5f298ed",
66
"outfile": null,
77
"outfile_hash": null,
8-
"stdout": "asr-array_02-0507073.stdout",
8+
"stdout": "asr-array_02-e00d30a.stdout",
99
"stdout_hash": "330d65993b5445881264552aaa9b7415b7be4a04a3ec05f5b8ae3d92",
1010
"stderr": null,
1111
"stderr_hash": null,

0 commit comments

Comments
 (0)