Skip to content

Commit 3b98b58

Browse files
committed
Add some basic tests. Doesn't test the samplers yet.
1 parent f7a7037 commit 3b98b58

8 files changed

+271
-0
lines changed

.gitmodules

+3
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
11
[submodule "extlib/tlx"]
22
path = extlib/tlx
33
url = https://github.com/tlx/tlx
4+
[submodule "extlib/googletest"]
5+
path = extlib/googletest
6+
url = https://github.com/google/googletest.git

CMakeLists.txt

+29
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#
44
# Root CMake build script for sampler
55
#
6+
# Copyright (C) 2015-2017 Timo Bingmann <[email protected]>
67
# Copyright (C) 2017 Lorenz Hübschle-Schneider <[email protected]>
78
#
89
# All rights reserved. Published under the BSD-2 license in the LICENSE file.
@@ -34,6 +35,8 @@ option(SAMPLING_USE_LTO
3435
option(SAMPLING_USE_MKL
3536
"Build with Intel MKL random generator if available." ON)
3637

38+
option(SAMPLING_BUILD_TESTS "Build libsampling's tests." OFF)
39+
3740

3841
################################################################################
3942

@@ -224,6 +227,28 @@ macro(set_join var)
224227
string(STRIP ${var} "${${var}}")
225228
endmacro(set_join)
226229

230+
###############################################################################
231+
# enable gtest framework, valgrind, and collection of results
232+
233+
enable_testing()
234+
include(CTest)
235+
236+
### google test + mock - enable "make test" and add_test()
237+
238+
# this fixes compilation with static libs on MSVC
239+
set(gtest_force_shared_crt ON CACHE BOOL "on" FORCE)
240+
if(NOT MSVC)
241+
# silence some warnings
242+
set(GTEST_SAVE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
243+
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-missing-field-initializers -Wno-deprecated")
244+
endif()
245+
246+
add_subdirectory(extlib/googletest/googletest)
247+
248+
if(NOT MSVC)
249+
set(CMAKE_CXX_FLAGS "${GTEST_SAVE_CXX_FLAGS}")
250+
endif()
251+
227252
################################################################################
228253

229254
# use tlx
@@ -297,4 +322,8 @@ add_subdirectory(sampling)
297322
# descend into benchmark suite
298323
add_subdirectory(benchmark)
299324

325+
if(SAMPLING_BUILD_TESTS)
326+
add_subdirectory(tests)
327+
endif()
328+
300329
################################################################################

README.md

+6
Original file line numberDiff line numberDiff line change
@@ -28,4 +28,10 @@ Build with cmake (version 2.8.12 or later is required). Remember to fetch the su
2828

2929
**Optional Dependencies:** An MPI library for Algorithm P's test runner (Algorithm P itself is implemented independently of MPI), Intel Math Kernel Library (MKL) for faster random variate generation
3030

31+
### Tests
32+
33+
To run the tests, set the cmake variable `SAMPLING_BUILD_TESTS` to `ON`. Make sure that the `extlib/googletest` submodule is present. Build, then execute the tests with `ctest`.
34+
35+
We plan to make the test suite more comprehensive in the future.
36+
3137
**[License](/LICENSE):** 2-clause BSD

extlib/googletest

Submodule googletest added at 5490beb

tests/CMakeLists.txt

+85
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
################################################################################
2+
# tests/CMakeLists.txt
3+
#
4+
# Copyright (C) 2015-2017 Timo Bingmann <[email protected]>
5+
# Copyright (C) 2017 Lorenz Hübschle-Schneider <[email protected]>
6+
#
7+
# All rights reserved. Published under the BSD-2 license in the LICENSE file.
8+
################################################################################
9+
10+
include_directories(SYSTEM ${gtest_SOURCE_DIR}/include ${gtest_SOURCE_DIR})
11+
12+
# macro for building test target programs with correct libraries
13+
macro(sampling_build_target TARGETNAME)
14+
15+
add_executable(${TARGETNAME} ${ARGN})
16+
target_link_libraries(${TARGETNAME} sampling gtest gtest_main)
17+
18+
endmacro(sampling_build_target)
19+
20+
# macro for building test programs, without main() in gtest_main
21+
macro(sampling_build_plain PROGNAME)
22+
23+
string(REPLACE "/" "_" TESTNAME "${PROGNAME}") # replace slashes
24+
25+
sampling_build_target(${TESTNAME} ${PROGNAME}.cpp ${ARGN})
26+
27+
endmacro(sampling_build_plain)
28+
29+
# macro for building test programs, adding gtest runner in gtest_main
30+
macro(sampling_build_only PROGNAME)
31+
32+
# append gtest runner program.
33+
sampling_build_plain(${PROGNAME} ${ARGN})
34+
35+
endmacro(sampling_build_only)
36+
37+
# macro for registering test programs: maybe prepend valgrind
38+
macro(sampling_test_only TESTNAME)
39+
40+
set(TARGETNAME ${TESTNAME} ${ARGN})
41+
string(REPLACE "/" "_" TARGETNAME "${TARGETNAME}") # replace slashes
42+
string(REPLACE ";" "_" TARGETNAME "${TARGETNAME}") # stringify list
43+
44+
if(USE_VALGRIND)
45+
# prepend valgrind call
46+
add_test(
47+
NAME ${TARGETNAME}
48+
COMMAND /usr/bin/valgrind ${SAMPLING_VALGRIND_OPTS}
49+
--xml=yes --xml-file=${TESTNAME}.xml
50+
./${TESTNAME} ${ARGN})
51+
else()
52+
add_test(
53+
NAME ${TARGETNAME}
54+
COMMAND ${TESTNAME} ${ARGN})
55+
endif()
56+
57+
endmacro(sampling_test_only)
58+
59+
# macro for building and running test programs
60+
macro(sampling_build_test PROGNAME)
61+
62+
sampling_build_only(${PROGNAME})
63+
64+
string(REPLACE "/" "_" TESTNAME "${PROGNAME}") # replace slashes
65+
sampling_test_only(${TESTNAME})
66+
67+
endmacro(sampling_build_test)
68+
69+
### list of tests in subdirectories
70+
71+
sampling_build_test(hash_test)
72+
sampling_build_test(hypergeometric_distribution_test)
73+
sampling_build_test(statistics_test)
74+
75+
if(MPI_FOUND)
76+
# sampling_build_only(mpi_test)
77+
# # run test with mpirun
78+
# add_test(mpi_test1 ${MPIEXEC} ${MPIEXEC_NUMPROC_FLAG} 1 mpi_test)
79+
# add_test(mpi_test2 ${MPIEXEC} ${MPIEXEC_NUMPROC_FLAG} 2 mpi_test)
80+
# add_test(mpi_test3 ${MPIEXEC} ${MPIEXEC_NUMPROC_FLAG} 3 mpi_test)
81+
# add_test(mpi_test7 ${MPIEXEC} ${MPIEXEC_NUMPROC_FLAG} 7 mpi_test)
82+
# add_test(mpi_test8 ${MPIEXEC} ${MPIEXEC_NUMPROC_FLAG} 8 mpi_test)
83+
endif()
84+
85+
################################################################################

tests/hash_test.cpp

+62
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
/*******************************************************************************
2+
* tests/hash_test.cpp
3+
*
4+
* Copyright (C) 2016-2017 Lorenz Hübschle-Schneider <[email protected]>
5+
*
6+
* All rights reserved. Published under the BSD-2 license in the LICENSE file.
7+
******************************************************************************/
8+
9+
#include <sampling/hash.hpp>
10+
11+
#include <gtest/gtest.h>
12+
13+
using namespace sampling;
14+
15+
template <typename T>
16+
void check_hash(uint32_t reference, const T& val) {
17+
HashCrc32Fallback<T> h;
18+
uint32_t crc = h(val);
19+
ASSERT_EQ(reference, crc);
20+
21+
#ifdef SAMPLING_HAVE_SSE4_2
22+
// SSE4.2 is enabled, check that one as well
23+
HashCrc32Sse42<T> h2;
24+
uint32_t crc2 = h2(val);
25+
ASSERT_EQ(reference, crc2);
26+
#endif
27+
}
28+
29+
TEST(Hash, TestCRC32) {
30+
check_hash(0xb798b438, 0);
31+
check_hash(0x6add1e80, 1);
32+
check_hash(0xa530b397, 426468);
33+
34+
char zeroes4[4], zeroes7[7], zeroes32[32], testvec[44];
35+
memset(&zeroes4, 0, 4);
36+
// 4 char-zeroes should yield the same result as a uint32_t-zero
37+
check_hash(0xb798b438, zeroes4);
38+
39+
// Something oddly-sized
40+
memset(&zeroes7, 0, 7);
41+
check_hash(0x44c19592, zeroes7);
42+
43+
// 32 bytes of zeroes - test vector at
44+
// https://tools.ietf.org/html/draft-ietf-tsvwg-sctpcsum-01
45+
memset(&zeroes32, 0, 32);
46+
check_hash(0x756EC955, zeroes32);
47+
48+
// the other IETF test vector, 13 zeroes followed by byte values 1 to 0x1f
49+
memset(&testvec, 0, 13);
50+
for (size_t i = 1; i <= 0x1f; ++i) {
51+
testvec[i + 12] = i;
52+
}
53+
check_hash(0x5b988D47, testvec);
54+
55+
// Some more random tests
56+
check_hash(0x3e2fbccf, 'a'); // char
57+
check_hash(0x9da0355c, "a"); // char[2]
58+
check_hash(0x64e2a555, "hello world");
59+
check_hash(0x3cc762b0, "123456789");
60+
}
61+
62+
/******************************************************************************/
+48
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/*******************************************************************************
2+
* tests/hypergeometric_distribution_test.cpp
3+
*
4+
* Copyright (C) 2017 Lorenz Hübschle-Schneider <[email protected]>
5+
*
6+
* All rights reserved. Published under the BSD-2 license in the LICENSE file.
7+
******************************************************************************/
8+
9+
#include <sampling/hypergeometric_distribution.hpp>
10+
11+
#include <gtest/gtest.h>
12+
13+
using namespace sampling;
14+
15+
TEST(Hypergeometric, Simple) {
16+
hypergeometric hyp(42);
17+
18+
// Test a known sequence
19+
ASSERT_EQ(9, hyp(10, 6, 14));
20+
ASSERT_EQ(8, hyp(10, 6, 14));
21+
ASSERT_EQ(9, hyp(10, 6, 14));
22+
ASSERT_EQ(9, hyp(10, 6, 14));
23+
ASSERT_EQ(10, hyp(10, 6, 14));
24+
ASSERT_EQ(9, hyp(10, 6, 14));
25+
ASSERT_EQ(8, hyp(10, 6, 14));
26+
ASSERT_EQ(10, hyp(10, 6, 14));
27+
ASSERT_EQ(8, hyp(10, 6, 14));
28+
ASSERT_EQ(9, hyp(10, 6, 14));
29+
30+
// Test with nbad = 0
31+
ASSERT_EQ(7, hyp(10, 0, 7));
32+
ASSERT_EQ(7, hyp(10, 0, 7));
33+
ASSERT_EQ(7, hyp(10, 0, 7));
34+
ASSERT_EQ(7, hyp(10, 0, 7));
35+
36+
ASSERT_EQ(42, hyp(100, 0, 42));
37+
ASSERT_EQ(42, hyp(100, 0, 42));
38+
ASSERT_EQ(42, hyp(100, 0, 42));
39+
ASSERT_EQ(42, hyp(100, 0, 42));
40+
41+
// Test with ngood = 0
42+
ASSERT_EQ(0, hyp(0, 10, 5));
43+
ASSERT_EQ(0, hyp(0, 10, 5));
44+
ASSERT_EQ(0, hyp(0, 10, 5));
45+
ASSERT_EQ(0, hyp(0, 10, 5));
46+
}
47+
48+
/******************************************************************************/

tests/statistics_test.cpp

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/*******************************************************************************
2+
* tests/statistics_test.cpp
3+
*
4+
* Copyright (C) 2015 Timo Bingmann <[email protected]>
5+
* Copyright (C) 2017 Lorenz Hübschle-Schneider <[email protected]>
6+
*
7+
* All rights reserved. Published under the BSD-2 license in the LICENSE file.
8+
******************************************************************************/
9+
10+
#include <sampling/benchmark.hpp>
11+
12+
#include <gtest/gtest.h>
13+
14+
using namespace sampling;
15+
16+
TEST(Statistics, Simple) {
17+
statistics stats;
18+
19+
// Test that empty statistics are handled correctly
20+
ASSERT_EQ(0.0, stats.avg());
21+
ASSERT_EQ(0.0, stats.stddev());
22+
23+
stats.push(1.0);
24+
// Test that stddev() handles a single value
25+
ASSERT_EQ(0.0, stats.stddev());
26+
27+
for (size_t i = 2; i <= 1000; ++i) {
28+
stats.push(1.0 / static_cast<double>(i));
29+
}
30+
31+
ASSERT_EQ(1000, stats.count);
32+
ASSERT_DOUBLE_EQ(0.0074854708605503447, stats.avg());
33+
ASSERT_DOUBLE_EQ(0.039868430925506362, stats.stddev());
34+
ASSERT_DOUBLE_EQ(0.039848491723996423, stats.stddev(0));
35+
}
36+
37+
/******************************************************************************/

0 commit comments

Comments
 (0)