Skip to content

Commit 7a0a18f

Browse files
committed
Improve C++/Java Aeron tests and coverage
1 parent 728bb27 commit 7a0a18f

File tree

10 files changed

+838
-53
lines changed

10 files changed

+838
-53
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ dkms.conf
5555

5656
# debug information files
5757
*.dwo
58+
*.gcov
5859

5960
# macOS
6061
.DS_Store

cpp/CMakeLists.txt

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ project(epoch_cpp VERSION 0.1.0 LANGUAGES C CXX)
44
add_library(epoch_cpp src/epoch.cpp src/engine.cpp src/actor_id.cpp src/aeron_transport.cpp)
55

66
target_include_directories(epoch_cpp PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include)
7+
target_compile_definitions(epoch_cpp PRIVATE EPOCH_TESTING)
78

89
target_compile_features(epoch_cpp PUBLIC cxx_std_17)
910

@@ -41,10 +42,21 @@ enable_testing()
4142
add_executable(epoch_cpp_test tests/epoch_vector_test.cpp)
4243
target_link_libraries(epoch_cpp_test PRIVATE epoch_cpp)
4344
add_test(NAME epoch_cpp_vector COMMAND epoch_cpp_test)
45+
target_compile_definitions(epoch_cpp_test PRIVATE EPOCH_TESTING)
46+
47+
add_executable(epoch_cpp_core_test tests/core_test.cpp)
48+
target_link_libraries(epoch_cpp_core_test PRIVATE epoch_cpp)
49+
add_test(NAME epoch_cpp_core COMMAND epoch_cpp_core_test)
50+
target_compile_definitions(epoch_cpp_core_test PRIVATE EPOCH_TESTING)
51+
52+
add_executable(epoch_cpp_aeron_test tests/aeron_transport_test.cpp)
53+
target_link_libraries(epoch_cpp_aeron_test PRIVATE epoch_cpp)
54+
add_test(NAME epoch_cpp_aeron COMMAND epoch_cpp_aeron_test)
55+
target_compile_definitions(epoch_cpp_aeron_test PRIVATE EPOCH_TESTING)
4456

4557
option(EPOCH_COVERAGE "Enable coverage instrumentation" OFF)
4658
if (EPOCH_COVERAGE)
47-
foreach(target epoch_cpp epoch_cpp_test)
59+
foreach(target epoch_cpp epoch_cpp_test epoch_cpp_core_test epoch_cpp_aeron_test)
4860
target_compile_options(${target} PRIVATE -O0 -g --coverage)
4961
target_link_options(${target} PRIVATE --coverage)
5062
endforeach()

cpp/include/epoch/aeron_transport.h

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,4 +55,39 @@ class AeronTransport final : public Transport {
5555
aeron_subscription_t *subscription_ = nullptr;
5656
};
5757

58+
namespace detail {
59+
60+
struct AeronHooks {
61+
int (*context_init)(aeron_context_t **);
62+
int (*context_set_dir)(aeron_context_t *, const char *);
63+
int (*init)(aeron_t **, aeron_context_t *);
64+
int (*start)(aeron_t *);
65+
int (*async_add_publication)(aeron_async_add_publication_t **, aeron_t *, const char *, int32_t);
66+
int (*async_add_publication_poll)(aeron_publication_t **, aeron_async_add_publication_t *);
67+
int (*async_add_subscription)(aeron_async_add_subscription_t **, aeron_t *, const char *, int32_t,
68+
aeron_on_available_image_t, void *, aeron_on_unavailable_image_t, void *);
69+
int (*async_add_subscription_poll)(aeron_subscription_t **, aeron_async_add_subscription_t *);
70+
int64_t (*publication_offer)(aeron_publication_t *, const uint8_t *, size_t,
71+
aeron_reserved_value_supplier_t, void *);
72+
int (*subscription_poll)(aeron_subscription_t *, aeron_fragment_handler_t, void *, size_t);
73+
int (*publication_close)(aeron_publication_t *, aeron_notification_t, void *);
74+
int (*subscription_close)(aeron_subscription_t *, aeron_notification_t, void *);
75+
int (*close)(aeron_t *);
76+
int (*context_close)(aeron_context_t *);
77+
const char *(*errmsg)();
78+
};
79+
80+
AeronHooks &aeron_hooks();
81+
82+
} // namespace detail
83+
84+
#ifdef EPOCH_TESTING
85+
namespace test {
86+
87+
detail::AeronHooks &aeron_hooks();
88+
void reset_aeron_hooks();
89+
90+
} // namespace test
91+
#endif
92+
5893
} // namespace epoch

cpp/src/aeron_transport.cpp

Lines changed: 85 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -76,20 +76,78 @@ void throw_if_error(int result, const char *context)
7676
{
7777
if (result < 0)
7878
{
79-
throw std::runtime_error(std::string(context) + ": " + aeron_errmsg());
79+
throw std::runtime_error(std::string(context) + ": " + epoch::detail::aeron_hooks().errmsg());
8080
}
8181
}
8282

8383
void throw_if_null(void *ptr, const char *context)
8484
{
8585
if (ptr == nullptr)
8686
{
87-
throw std::runtime_error(std::string(context) + ": " + aeron_errmsg());
87+
throw std::runtime_error(std::string(context) + ": " + epoch::detail::aeron_hooks().errmsg());
8888
}
8989
}
9090

9191
} // namespace
9292

93+
namespace detail {
94+
95+
AeronHooks &aeron_hooks()
96+
{
97+
static AeronHooks hooks{
98+
aeron_context_init,
99+
aeron_context_set_dir,
100+
aeron_init,
101+
aeron_start,
102+
aeron_async_add_publication,
103+
aeron_async_add_publication_poll,
104+
aeron_async_add_subscription,
105+
aeron_async_add_subscription_poll,
106+
aeron_publication_offer,
107+
aeron_subscription_poll,
108+
aeron_publication_close,
109+
aeron_subscription_close,
110+
aeron_close,
111+
aeron_context_close,
112+
aeron_errmsg,
113+
};
114+
return hooks;
115+
}
116+
117+
} // namespace detail
118+
119+
#ifdef EPOCH_TESTING
120+
namespace test {
121+
122+
detail::AeronHooks &aeron_hooks()
123+
{
124+
return detail::aeron_hooks();
125+
}
126+
127+
void reset_aeron_hooks()
128+
{
129+
detail::aeron_hooks() = detail::AeronHooks{
130+
aeron_context_init,
131+
aeron_context_set_dir,
132+
aeron_init,
133+
aeron_start,
134+
aeron_async_add_publication,
135+
aeron_async_add_publication_poll,
136+
aeron_async_add_subscription,
137+
aeron_async_add_subscription_poll,
138+
aeron_publication_offer,
139+
aeron_subscription_poll,
140+
aeron_publication_close,
141+
aeron_subscription_close,
142+
aeron_close,
143+
aeron_context_close,
144+
aeron_errmsg,
145+
};
146+
}
147+
148+
} // namespace test
149+
#endif
150+
93151
AeronTransport::AeronTransport(AeronConfig config) : config_(std::move(config))
94152
{
95153
if (config_.fragment_limit <= 0)
@@ -104,25 +162,27 @@ AeronTransport::AeronTransport(AeronConfig config) : config_(std::move(config))
104162
try
105163
{
106164
aeron_context_t *context = nullptr;
107-
throw_if_error(aeron_context_init(&context), "aeron_context_init failed");
165+
throw_if_error(detail::aeron_hooks().context_init(&context), "aeron_context_init failed");
108166
if (!config_.aeron_directory.empty())
109167
{
110-
throw_if_error(aeron_context_set_dir(context, config_.aeron_directory.c_str()),
168+
throw_if_error(detail::aeron_hooks().context_set_dir(context, config_.aeron_directory.c_str()),
111169
"aeron_context_set_dir failed");
112170
}
113171
context_ = context;
114172

115173
aeron_t *client = nullptr;
116-
throw_if_error(aeron_init(&client, context_), "aeron_init failed");
117-
throw_if_error(aeron_start(client), "aeron_start failed");
174+
throw_if_error(detail::aeron_hooks().init(&client, context_), "aeron_init failed");
175+
throw_if_error(detail::aeron_hooks().start(client), "aeron_start failed");
118176
client_ = client;
119177

120178
aeron_async_add_publication_t *pub_async = nullptr;
121-
throw_if_error(aeron_async_add_publication(&pub_async, client_, config_.channel.c_str(), config_.stream_id),
179+
throw_if_error(
180+
detail::aeron_hooks().async_add_publication(
181+
&pub_async, client_, config_.channel.c_str(), config_.stream_id),
122182
"aeron_async_add_publication failed");
123183
while (true)
124184
{
125-
int poll_result = aeron_async_add_publication_poll(&publication_, pub_async);
185+
int poll_result = detail::aeron_hooks().async_add_publication_poll(&publication_, pub_async);
126186
if (poll_result == 1)
127187
{
128188
break;
@@ -134,12 +194,19 @@ AeronTransport::AeronTransport(AeronConfig config) : config_(std::move(config))
134194

135195
aeron_async_add_subscription_t *sub_async = nullptr;
136196
throw_if_error(
137-
aeron_async_add_subscription(
138-
&sub_async, client_, config_.channel.c_str(), config_.stream_id, nullptr, nullptr, nullptr, nullptr),
197+
detail::aeron_hooks().async_add_subscription(
198+
&sub_async,
199+
client_,
200+
config_.channel.c_str(),
201+
config_.stream_id,
202+
nullptr,
203+
nullptr,
204+
nullptr,
205+
nullptr),
139206
"aeron_async_add_subscription failed");
140207
while (true)
141208
{
142-
int poll_result = aeron_async_add_subscription_poll(&subscription_, sub_async);
209+
int poll_result = detail::aeron_hooks().async_add_subscription_poll(&subscription_, sub_async);
143210
if (poll_result == 1)
144211
{
145212
break;
@@ -174,7 +241,8 @@ void AeronTransport::send(const Message &message)
174241
std::int64_t result = 0;
175242
do
176243
{
177-
result = aeron_publication_offer(publication_, buffer.data(), buffer.size(), nullptr, nullptr);
244+
result = detail::aeron_hooks().publication_offer(
245+
publication_, buffer.data(), buffer.size(), nullptr, nullptr);
178246
if (result >= 0)
179247
{
180248
stats_.sent_count++;
@@ -238,7 +306,7 @@ std::vector<Message> AeronTransport::poll(std::size_t max)
238306
ctx->stats->received_count++;
239307
};
240308

241-
int fragments = aeron_subscription_poll(subscription_, handler, &context, limit);
309+
int fragments = detail::aeron_hooks().subscription_poll(subscription_, handler, &context, limit);
242310
throw_if_error(fragments, "aeron_subscription_poll failed");
243311
return out;
244312
}
@@ -253,22 +321,22 @@ void AeronTransport::close()
253321

254322
if (publication_ != nullptr)
255323
{
256-
aeron_publication_close(publication_, nullptr, nullptr);
324+
detail::aeron_hooks().publication_close(publication_, nullptr, nullptr);
257325
publication_ = nullptr;
258326
}
259327
if (subscription_ != nullptr)
260328
{
261-
aeron_subscription_close(subscription_, nullptr, nullptr);
329+
detail::aeron_hooks().subscription_close(subscription_, nullptr, nullptr);
262330
subscription_ = nullptr;
263331
}
264332
if (client_ != nullptr)
265333
{
266-
aeron_close(client_);
334+
detail::aeron_hooks().close(client_);
267335
client_ = nullptr;
268336
}
269337
if (context_ != nullptr)
270338
{
271-
aeron_context_close(context_);
339+
detail::aeron_hooks().context_close(context_);
272340
context_ = nullptr;
273341
}
274342
}

0 commit comments

Comments
 (0)