Skip to content

Add testing module to allow better structuring of test suites #494

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 25 commits into from
Nov 7, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
ead119d
Add testing module to allow better structuring of test suites
awvwgk Aug 21, 2021
4b7720b
Rewrite stdlib math tests
awvwgk Aug 22, 2021
703239e
Rewrite tests for stdlib_bitset_64
awvwgk Aug 22, 2021
8427418
Moved test mean
jvdp1 Aug 23, 2021
8f79e5b
Rewrite test fir stdlib_bitset_large
awvwgk Aug 24, 2021
7d4b0f7
Rewrite linear algebra tests
awvwgk Aug 24, 2021
e92bc71
Rewrite testsuite for optval
awvwgk Aug 24, 2021
056d992
Rewrite string testsuites
awvwgk Aug 24, 2021
2889964
Add test_mean_f03 + update makefile
jvdp1 Aug 26, 2021
adc86dd
Rewrite test_median.fypp
jvdp1 Aug 26, 2021
33b4df2
Rewrite tests for quadrature modules
awvwgk Aug 26, 2021
71dc8c5
Rewrite rawmoment tests
awvwgk Aug 26, 2021
0945d7b
Rewrite variance tests
awvwgk Aug 27, 2021
9d54d58
Port stdlib_io tests to test-drive
milancurcic Sep 3, 2021
58b8467
Use portable formats in savetxt and loadtxt
milancurcic Sep 4, 2021
984aa30
Port test_distribution_PRNG to test-drive
milancurcic Oct 2, 2021
3c21d51
Port test_sorting to test-drive
milancurcic Oct 2, 2021
ff9168a
Port test_varn to test-drive
milancurcic Oct 3, 2021
548b8a2
Port test_moment to test-drive
milancurcic Oct 3, 2021
1e29bdb
Port test_sleep to test-drive
milancurcic Oct 4, 2021
a7c4c8d
Resolve conflicts with the main branch
milancurcic Nov 5, 2021
2d007f1
Rename test_distribution_PRNG -> test_random
milancurcic Nov 5, 2021
0c85f24
Ignore missing source files when rm-ing for fpm deployment
milancurcic Nov 5, 2021
fdcfbd9
Use test-drive directly instead of vendoring it
awvwgk Nov 6, 2021
d2e0fe3
Increase threshold for sleep test
awvwgk Nov 6, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions ci/fpm-deployment.sh
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ include=(
prune=(
"$destdir/test/test_always_fail.f90"
"$destdir/test/test_always_skip.f90"
"$destdir/test/test_mean_f03.f90"
"$destdir/src/common.f90"
"$destdir/src/f18estop.f90"
)
Expand All @@ -43,7 +42,7 @@ find src/tests -name "*.dat" -exec cp {} "$destdir/" \;
# Include additional files
cp "${include[@]}" "$destdir/"

# Source file workarounds for fpm
# Source file workarounds for fpm; ignore missing files
rm "${prune[@]}"

# List stdlib-fpm package contents
Expand Down
3 changes: 3 additions & 0 deletions ci/fpm.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,6 @@ license = "MIT"
author = "stdlib contributors"
maintainer = "@fortran-lang/stdlib"
copyright = "2019-2021 stdlib contributors"

[dev-dependencies]
test-drive.git = "https://github.com/fortran-lang/test-drive"
3 changes: 3 additions & 0 deletions config/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ if(NOT DEFINED CMAKE_INSTALL_MODULEDIR)
)
endif()

list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
set(CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH}" PARENT_SCOPE)

# Export a pkg-config file
configure_file(
"${CMAKE_CURRENT_SOURCE_DIR}/template.pc"
Expand Down
178 changes: 178 additions & 0 deletions config/cmake/Findtest-drive.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
# SPDX-Identifier: MIT

#[[.rst:
Find test-drive
---------------

Makes the test-drive project available.

Imported Targets
^^^^^^^^^^^^^^^^

This module provides the following imported target, if found:

``test-drive::test-drive``
The test-drive library


Result Variables
^^^^^^^^^^^^^^^^

This module will define the following variables:

``TEST_DRIVE_FOUND``
True if the test-drive library is available

``TEST_DRIVE_SOURCE_DIR``
Path to the source directory of the test-drive project,
only set if the project is included as source.

``TEST_DRIVE_BINARY_DIR``
Path to the binary directory of the test-drive project,
only set if the project is included as source.

Cache variables
^^^^^^^^^^^^^^^

The following cache variables may be set to influence the library detection:

``TEST_DRIVE_FIND_METHOD``
Methods to find or make the project available. Available methods are
- ``cmake``: Try to find via CMake config file
- ``pkgconf``: Try to find via pkg-config file
- ``subproject``: Use source in subprojects directory
- ``fetch``: Fetch the source from upstream

``TEST_DRIVE_DIR``
Used for searching the CMake config file

``TEST_DRIVE_SUBPROJECT``
Directory to find the test-drive subproject, relative to the project root

#]]

set(_lib "test-drive")
set(_pkg "TEST_DRIVE")
set(_url "https://github.com/fortran-lang/test-drive")

if(NOT DEFINED "${_pkg}_FIND_METHOD")
if(DEFINED "${PROJECT_NAME}-dependency-method")
set("${_pkg}_FIND_METHOD" "${${PROJECT_NAME}-dependency-method}")
else()
set("${_pkg}_FIND_METHOD" "cmake" "pkgconf" "subproject" "fetch")
endif()
set("_${_pkg}_FIND_METHOD")
endif()

foreach(method ${${_pkg}_FIND_METHOD})
if(TARGET "${_lib}::${_lib}")
break()
endif()

if("${method}" STREQUAL "cmake")
message(STATUS "${_lib}: Find installed package")
if(DEFINED "${_pkg}_DIR")
set("_${_pkg}_DIR")
set("${_lib}_DIR" "${_pkg}_DIR")
endif()
find_package("${_lib}" CONFIG QUIET)
if("${_lib}_FOUND")
message(STATUS "${_lib}: Found installed package")
break()
endif()
endif()

if("${method}" STREQUAL "pkgconf")
find_package(PkgConfig QUIET)
pkg_check_modules("${_pkg}" QUIET "${_lib}")
if("${_pkg}_FOUND")
message(STATUS "Found ${_lib} via pkg-config")

add_library("${_lib}::${_lib}" INTERFACE IMPORTED)
target_link_libraries(
"${_lib}::${_lib}"
INTERFACE
"${${_pkg}_LINK_LIBRARIES}"
)
target_include_directories(
"${_lib}::${_lib}"
INTERFACE
"${${_pkg}_INCLUDE_DIRS}"
)

break()
endif()
endif()

if("${method}" STREQUAL "subproject")
if(NOT DEFINED "${_pkg}_SUBPROJECT")
set("_${_pkg}_SUBPROJECT")
set("${_pkg}_SUBPROJECT" "subprojects/${_lib}")
endif()
set("${_pkg}_SOURCE_DIR" "${PROJECT_SOURCE_DIR}/${${_pkg}_SUBPROJECT}")
set("${_pkg}_BINARY_DIR" "${PROJECT_BINARY_DIR}/${${_pkg}_SUBPROJECT}")
if(EXISTS "${${_pkg}_SOURCE_DIR}/CMakeLists.txt")
message(STATUS "Include ${_lib} from ${${_pkg}_SUBPROJECT}")
add_subdirectory(
"${${_pkg}_SOURCE_DIR}"
"${${_pkg}_BINARY_DIR}"
)

add_library("${_lib}::${_lib}" INTERFACE IMPORTED)
target_link_libraries("${_lib}::${_lib}" INTERFACE "${_lib}")

# We need the module directory in the subproject before we finish the configure stage
if(NOT EXISTS "${${_pkg}_BINARY_DIR}/include")
make_directory("${${_pkg}_BINARY_DIR}/include")
endif()

break()
endif()
endif()

if("${method}" STREQUAL "fetch")
message(STATUS "Retrieving ${_lib} from ${_url}")
include(FetchContent)
FetchContent_Declare(
"${_lib}"
GIT_REPOSITORY "${_url}"
GIT_TAG "HEAD"
)
FetchContent_MakeAvailable("${_lib}")

add_library("${_lib}::${_lib}" INTERFACE IMPORTED)
target_link_libraries("${_lib}::${_lib}" INTERFACE "${_lib}")

# We need the module directory in the subproject before we finish the configure stage
FetchContent_GetProperties("${_lib}" SOURCE_DIR "${_pkg}_SOURCE_DIR")
FetchContent_GetProperties("${_lib}" BINARY_DIR "${_pkg}_BINARY_DIR")
if(NOT EXISTS "${${_pkg}_BINARY_DIR}/include")
make_directory("${${_pkg}_BINARY_DIR}/include")
endif()

break()
endif()

endforeach()

if(TARGET "${_lib}::${_lib}")
set("${_pkg}_FOUND" TRUE)
else()
set("${_pkg}_FOUND" FALSE)
endif()

if(DEFINED "_${_pkg}_SUBPROJECT")
unset("${_pkg}_SUBPROJECT")
unset("_${_pkg}_SUBPROJECT")
endif()
if(DEFINED "_${_pkg}_DIR")
unset("${_lib}_DIR")
unset("_${_pkg}_DIR")
endif()
if(DEFINED "_${_pkg}_FIND_METHOD")
unset("${_pkg}_FIND_METHOD")
unset("_${_pkg}_FIND_METHOD")
endif()
unset(_lib)
unset(_pkg)
unset(_url)
57 changes: 36 additions & 21 deletions src/stdlib_io.fypp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,16 @@ module stdlib_io
! Private API that is exposed so that we can test it in tests
public :: parse_mode

! Format strings with edit descriptors for each type and kind
character(*), parameter :: &
FMT_INT = '(*(i0,1x))', &
FMT_REAL_SP = '(*(es15.8e2,1x))', &
FMT_REAL_DP = '(*(es24.16e3,1x))', &
FMT_REAL_QP = '(*(es44.35e4,1x))', &
FMT_COMPLEX_SP = '(*(es15.8e2,1x,es15.8e2))', &
FMT_COMPLEX_DP = '(*(es24.16e3,1x,es24.16e3))', &
FMT_COMPLEX_QP = '(*(es44.35e4,1x,es44.35e4))'

interface loadtxt
!! version: experimental
!!
Expand Down Expand Up @@ -78,13 +88,22 @@ contains

! determine number of columns
ncol = number_of_columns(s)
#:if 'complex' in t1
ncol = ncol / 2
#:endif

! determine number or rows
nrow = number_of_rows_numeric(s)
nrow = number_of_rows(s)

allocate(d(nrow, ncol))
do i = 1, nrow
read(s, *) d(i, :)
#:if 'real' in t1
read(s, FMT_REAL_${k1}$) d(i, :)
#:elif 'complex' in t1
read(s, FMT_COMPLEX_${k1}$) d(i, :)
#:else
read(s, *) d(i, :)
#:endif
end do
close(s)

Expand Down Expand Up @@ -116,7 +135,15 @@ contains
integer :: s, i
s = open(filename, "w")
do i = 1, size(d, 1)
write(s, *) d(i, :)
#:if 'real' in t1
write(s, FMT_REAL_${k1}$) d(i, :)
#:elif 'complex' in t1
write(s, FMT_COMPLEX_${k1}$) d(i, :)
#:elif 'integer' in t1
write(s, FMT_INT) d(i, :)
#:else
write(s, *) d(i, :)
#:endif
end do
close(s)
end subroutine savetxt_${t1[0]}$${k1}$
Expand Down Expand Up @@ -147,36 +174,24 @@ contains
end function number_of_columns


integer function number_of_rows_numeric(s) result(nrows)
integer function number_of_rows(s) result(nrows)
!! version: experimental
!!
!! determine number or rows
integer,intent(in)::s
!! Determine the number or rows in a file
integer, intent(in)::s
integer :: ios

real :: r
complex :: z

rewind(s)
nrows = 0
do
read(s, *, iostat=ios) r
read(s, *, iostat=ios)
if (ios /= 0) exit
nrows = nrows + 1
end do

rewind(s)

! If there are no rows of real numbers, it may be that they are complex
if( nrows == 0) then
do
read(s, *, iostat=ios) z
if (ios /= 0) exit
nrows = nrows + 1
end do
rewind(s)
end if
end function number_of_rows_numeric
end function number_of_rows


integer function open(filename, mode, iostat) result(u)
Expand Down Expand Up @@ -314,4 +329,4 @@ contains

end function parse_mode

end module
end module stdlib_io
6 changes: 5 additions & 1 deletion src/tests/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
if (NOT TARGET "test-drive::test-drive")
find_package("test-drive" REQUIRED)
endif()

macro(ADDTEST name)
add_executable(test_${name} test_${name}.f90)
target_link_libraries(test_${name} ${PROJECT_NAME})
target_link_libraries(test_${name} "${PROJECT_NAME}" "test-drive::test-drive")
add_test(NAME ${name}
COMMAND $<TARGET_FILE:test_${name}> ${CMAKE_CURRENT_BINARY_DIR}
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
Expand Down
22 changes: 21 additions & 1 deletion src/tests/Makefile.manual
Original file line number Diff line number Diff line change
@@ -1,6 +1,17 @@
.PHONY: all clean test

all test clean:
LIB = libstdlib-testing.a
SRC = testdrive.F90
OBJS = $(SRC:.F90=.o)
MODS = $(OBJS:.o=.mod)
FETCH = curl -L

all test:: $(LIB)

testdrive.F90:
$(FETCH) https://github.com/fortran-lang/test-drive/raw/main/src/testdrive.F90 > $@

all test clean::
$(MAKE) -f Makefile.manual --directory=ascii $@
$(MAKE) -f Makefile.manual --directory=bitsets $@
$(MAKE) -f Makefile.manual --directory=io $@
Expand All @@ -13,3 +24,12 @@ all test clean:
$(MAKE) -f Makefile.manual --directory=math $@
$(MAKE) -f Makefile.manual --directory=stringlist $@
$(MAKE) -f Makefile.manual --directory=linalg $@

$(LIB): $(OBJS)
ar rcs $@ $^

clean::
$(RM) $(LIB) $(OBJS) $(MODS) $(SRCGEN)

%.o: %.F90
$(FC) $(FFLAGS) -I.. -c $<
4 changes: 2 additions & 2 deletions src/tests/Makefile.manual.test.mk
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# Common Makefile rules that are included from each test subdirectory's
# Makefile

CPPFLAGS += -I../..
LDFLAGS += -L../.. -lstdlib
CPPFLAGS += -I../.. -I..
LDFLAGS += -L../.. -L.. -lstdlib-testing -lstdlib

OBJS = $(PROGS_SRC:.f90=.o)
PROGS = $(OBJS:.o=)
Expand Down
Loading