Skip to content

Commit 47028c9

Browse files
committed
Unit tests: add push benchmark, consumer queue tests
1 parent 6b76bae commit 47028c9

File tree

3 files changed

+151
-59
lines changed

3 files changed

+151
-59
lines changed

testing/CMakeLists.txt

Lines changed: 63 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -1,59 +1,63 @@
1-
project(lsltests
2-
VERSION 1.14.0
3-
LANGUAGES CXX
4-
DESCRIPTION "Unit tests for liblsl"
5-
)
6-
cmake_minimum_required (VERSION 3.12)
7-
enable_testing()
8-
9-
option(LSL_BENCHMARKS "Enable benchmarks in unit tests" OFF)
10-
11-
add_library(catch_main OBJECT catch_main.cpp)
12-
target_compile_features(catch_main PUBLIC cxx_std_11)
13-
14-
target_compile_definitions(catch_main PRIVATE LSL_VERSION_INFO="${LSL_VERSION_INFO}")
15-
if(LSL_BENCHMARKS)
16-
target_compile_definitions(catch_main PUBLIC CATCH_CONFIG_ENABLE_BENCHMARKING)
17-
endif()
18-
19-
add_executable(lsl_test_exported
20-
DataType.cpp
21-
discovery.cpp
22-
move.cpp
23-
timesync.cpp
24-
)
25-
target_link_libraries(lsl_test_exported PRIVATE lsl catch_main)
26-
27-
add_executable(lsl_test_internal
28-
asiocancel.cpp
29-
inireader.cpp
30-
stringfuncs.cpp
31-
streaminfo.cpp
32-
)
33-
target_link_libraries(lsl_test_internal PRIVATE lslobj lslboost catch_main)
34-
35-
if(LSL_BENCHMARKS)
36-
# to get somewhat reproducible performance numbers:
37-
# /usr/bin/time -v testing/lsl_bench_exported --benchmark-samples 100 bounce
38-
# [unix only] | binary | nr. of samples | test name
39-
add_executable(lsl_bench_exported
40-
bench_ext_bounce.cpp
41-
bench_ext_common.cpp
42-
)
43-
target_link_libraries(lsl_bench_exported PRIVATE lsl catch_main)
44-
installLSLApp(lsl_bench_exported)
45-
46-
add_executable(lsl_bench_internal
47-
bench_int_sleep.cpp
48-
)
49-
target_link_libraries(lsl_bench_internal PRIVATE lslobj lslboost catch_main)
50-
installLSLApp(lsl_bench_internal)
51-
endif()
52-
53-
set(LSL_TESTS lsl_test_exported lsl_test_internal)
54-
foreach(lsltest ${LSL_TESTS})
55-
add_test(NAME ${lsltest} COMMAND ${lsltest} --wait-for-keypress never)
56-
installLSLApp(${lsltest})
57-
endforeach()
58-
59-
installLSLAuxFiles(lsl_test_exported directory lslcfgs)
1+
project(lsltests
2+
VERSION 1.14.0
3+
LANGUAGES CXX
4+
DESCRIPTION "Unit tests for liblsl"
5+
)
6+
cmake_minimum_required (VERSION 3.12)
7+
enable_testing()
8+
9+
option(LSL_BENCHMARKS "Enable benchmarks in unit tests" OFF)
10+
11+
add_library(catch_main OBJECT catch_main.cpp)
12+
target_compile_features(catch_main PUBLIC cxx_std_11)
13+
14+
target_compile_definitions(catch_main PRIVATE LSL_VERSION_INFO="${LSL_VERSION_INFO}")
15+
if(LSL_BENCHMARKS)
16+
target_compile_definitions(catch_main PUBLIC CATCH_CONFIG_ENABLE_BENCHMARKING)
17+
endif()
18+
19+
add_executable(lsl_test_exported
20+
DataType.cpp
21+
discovery.cpp
22+
move.cpp
23+
timesync.cpp
24+
)
25+
target_link_libraries(lsl_test_exported PRIVATE lsl catch_main)
26+
27+
find_package(Threads REQUIRED)
28+
29+
add_executable(lsl_test_internal
30+
asiocancel.cpp
31+
inireader.cpp
32+
stringfuncs.cpp
33+
streaminfo.cpp
34+
test_int_samples.cpp
35+
)
36+
target_link_libraries(lsl_test_internal PRIVATE lslobj lslboost catch_main)
37+
38+
if(LSL_BENCHMARKS)
39+
# to get somewhat reproducible performance numbers:
40+
# /usr/bin/time -v testing/lsl_bench_exported --benchmark-samples 100 bounce
41+
# [unix only] | binary | nr. of samples | test name
42+
add_executable(lsl_bench_exported
43+
bench_ext_bounce.cpp
44+
bench_ext_common.cpp
45+
bench_ext_pushpull.cpp
46+
)
47+
target_link_libraries(lsl_bench_exported PRIVATE lsl catch_main Threads::Threads)
48+
installLSLApp(lsl_bench_exported)
49+
50+
add_executable(lsl_bench_internal
51+
bench_int_sleep.cpp
52+
)
53+
target_link_libraries(lsl_bench_internal PRIVATE lslobj lslboost catch_main)
54+
installLSLApp(lsl_bench_internal)
55+
endif()
56+
57+
set(LSL_TESTS lsl_test_exported lsl_test_internal)
58+
foreach(lsltest ${LSL_TESTS})
59+
add_test(NAME ${lsltest} COMMAND ${lsltest} --wait-for-keypress never)
60+
installLSLApp(${lsltest})
61+
endforeach()
62+
63+
installLSLAuxFiles(lsl_test_exported directory lslcfgs)

testing/bench_ext_pushpull.cpp

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
#include "catch.hpp"
2+
#include "helper_type.hpp"
3+
#include <atomic>
4+
#include <list>
5+
#include <lsl_cpp.h>
6+
#include <string>
7+
#include <thread>
8+
9+
TEMPLATE_TEST_CASE("pushpull", "[basic][throughput]", char, float, std::string) {
10+
const std::size_t max_nchan = 128, chunk_size = 128;
11+
const std::size_t param_nchan[] = {1, max_nchan};
12+
const std::size_t param_inlets[] = {0, 1, 10};
13+
14+
const TestType data[max_nchan * chunk_size] = {TestType()};
15+
//TestType data_out[max_n * chunk_size];
16+
17+
const char *name = SampleType<TestType>::fmt_string();
18+
lsl::channel_format_t cf = (lsl::channel_format_t)SampleType<TestType>::chan_fmt;
19+
20+
for (auto nchan : param_nchan) {
21+
lsl::stream_outlet out(
22+
lsl::stream_info(name, "PushPull", (int) nchan, lsl::IRREGULAR_RATE, cf, "streamid"));
23+
auto found_stream_info(lsl::resolve_stream("name", name, 1, 2.0));
24+
REQUIRE(!found_stream_info.empty());
25+
26+
std::list<lsl::stream_inlet> inlet_list;
27+
for (auto n_inlets : param_inlets) {
28+
while (inlet_list.size() < n_inlets) {
29+
inlet_list.emplace_front(found_stream_info[0], 1, false);
30+
inlet_list.front().open_stream(.5);
31+
}
32+
33+
BENCHMARK("push_sample_nchan_" + std::to_string(nchan)+"_inlets_"+std::to_string(n_inlets)) {
34+
for (size_t s = 0; s < chunk_size; s++) out.push_sample(data);
35+
};
36+
37+
BENCHMARK("push_chunk_nchan_" + std::to_string(nchan)+"_inlets_"+std::to_string(n_inlets)) {
38+
out.push_chunk_multiplexed(data, chunk_size);
39+
};
40+
for(auto &inlet: inlet_list)
41+
inlet.flush();
42+
}
43+
}
44+
}

testing/test_int_samples.cpp

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
#include "../src/consumer_queue.h"
2+
#include "../src/sample.h"
3+
#include "catch.hpp"
4+
#include <atomic>
5+
#include <thread>
6+
7+
TEST_CASE("consumer_queue", "[queue][basic]") {
8+
const int size = 10;
9+
lsl::factory fac(lsl_channel_format_t::cft_int8, 4, size / 2);
10+
lsl::consumer_queue queue(size);
11+
for (int i = 0; i <= size; ++i) queue.push_sample(fac.new_sample(i, true));
12+
13+
// Does the queue respect the capacity?
14+
CHECK(queue.read_available() == size);
15+
16+
// Are the right samples dropped when going over capacity?
17+
CHECK(static_cast<int>(queue.pop_sample()->timestamp) == 1);
18+
19+
// Does flush() return the correct count?
20+
CHECK(queue.flush() == size - 1);
21+
22+
// Is the queue empty after flush()ing?
23+
CHECK(queue.empty());
24+
}
25+
26+
TEST_CASE("consumer_queue_threaded", "[queue][threads]") {
27+
const int size = 10000;
28+
lsl::factory fac(lsl_channel_format_t::cft_int8, 4, 1);
29+
auto sample = fac.new_sample(0.0, true);
30+
lsl::consumer_queue queue(size);
31+
std::atomic<bool> done{false};
32+
33+
std::thread pusher([&]() {
34+
for (int i = 0; i < size; ++i) queue.push_sample(sample);
35+
INFO(queue.read_available());
36+
done = true;
37+
});
38+
39+
unsigned int n = 0, total = 0;
40+
// Pull samples until the pusher is done and the queue is empty
41+
while((n = queue.flush()) != 0 || !done) total+=n;
42+
CHECK(total == size);
43+
pusher.join();
44+
}

0 commit comments

Comments
 (0)