Skip to content

Commit df5d8a6

Browse files
author
Andrei Popescu
authored
Fix NetworkMock issue resulting in request lock. (#1121)
This commit fixes a wrong usage of the NetworkMock::ReturnHttpResponse which does not have any sleep time by default and resulted in optimal cases in callback trigger prior to the Network::Send mock call returning which caught the OlpClient PendingUrlRequest with no valid request id set and thus resulted in a lock in waiting for the callback which never came. Some other tests need additional increasing of wait timeout as the delay introduced in NetworkMock response increases the overall execution. Additionaly this adds some more debug logs to PendingUrlRequests class to see what callback is added or cancelled and changes the ApiLookupClientTest.LookupApiAsync to really use the async API as this did not happen due to copy-paste code from LookupApi test. Resolves: OLPEDGE-2409 Signed-off-by: Andrei Popescu <[email protected]>
1 parent fc0ea4a commit df5d8a6

File tree

8 files changed

+247
-188
lines changed

8 files changed

+247
-188
lines changed

olp-cpp-sdk-core/src/client/OlpClient.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -161,13 +161,15 @@ void ExecuteSingleRequest(const std::shared_ptr<http::Network>& network,
161161
return CancellationToken([=] { network->Cancel(id); });
162162
};
163163

164-
pending_request->ExecuteOrCancelled(make_request, [&]() {
164+
auto cancelled_func = [&]() {
165165
OLP_SDK_LOG_DEBUG_F(kLogTag,
166166
"ExecuteSingleRequest - already cancelled, url='%s'",
167167
request.GetUrl().c_str());
168168
callback(PendingUrlRequest::kInvalidRequestId,
169169
ToHttpResponse(kCancelledErrorResponse));
170-
});
170+
};
171+
172+
pending_request->ExecuteOrCancelled(make_request, cancelled_func);
171173
}
172174

173175
NetworkCallbackType GetRetryCallback(

olp-cpp-sdk-core/src/client/PendingUrlRequests.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,12 @@ size_t PendingUrlRequest::Append(NetworkAsyncCallback callback) {
3737
// NOTE: You should not append anything if this request was cancelled
3838
std::lock_guard<std::mutex> lock(mutex_);
3939
const auto callback_id = callbacks_.size();
40+
41+
OLP_SDK_LOG_DEBUG_F(
42+
kLogTag,
43+
"PendingUrlRequest::Append, callback_id=%zu, request_id=%" PRIu64,
44+
callback_id, http_request_id_);
45+
4046
callbacks_.emplace(callback_id, std::move(callback));
4147
return callback_id;
4248
}
@@ -52,6 +58,11 @@ bool PendingUrlRequest::ExecuteOrCancelled(const ExecuteFuncType& func,
5258
bool PendingUrlRequest::Cancel(size_t callback_id) {
5359
std::lock_guard<std::mutex> lock(mutex_);
5460

61+
OLP_SDK_LOG_DEBUG_F(
62+
kLogTag,
63+
"PendingUrlRequest::Cancel, callback_id=%zu, request_id=%" PRIu64,
64+
callback_id, http_request_id_);
65+
5566
auto it = callbacks_.find(callback_id);
5667
if (it == callbacks_.end()) {
5768
// Unknown callback_id

olp-cpp-sdk-core/src/client/PendingUrlRequests.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ class PendingUrlRequest {
7979
bool IsCancelled() const { return context_.IsCancelled(); }
8080

8181
/// Cancels current network request and waits for response.
82+
/// Default wait time is 60 seconds.
8283
bool CancelAndWait(
8384
std::chrono::milliseconds timeout = std::chrono::seconds(60)) {
8485
// Cancel Network call, wait for the Network callback

tests/common/mocks/NetworkMock.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,6 @@ GenerateNetworkMockActions(std::shared_ptr<std::promise<void>> pre_signal,
105105
///
106106
/// NetworkMock Actions
107107
///
108-
109108
NetworkCallback ReturnHttpResponse(http::NetworkResponse response,
110109
const std::string& response_body,
111110
const http::Headers& headers,
@@ -117,11 +116,15 @@ NetworkCallback ReturnHttpResponse(http::NetworkResponse response,
117116
http::Network::HeaderCallback header_callback,
118117
http::Network::DataCallback) mutable {
119118
std::thread([=]() {
119+
std::this_thread::sleep_for(delay);
120+
120121
for (const auto& header : headers) {
121122
header_callback(header.first, header.second);
122123
}
123-
*payload << response_body;
124-
std::this_thread::sleep_for(delay);
124+
125+
payload->seekp(0, std::ios_base::end);
126+
payload->write(response_body.c_str(), response_body.size());
127+
payload->seekp(0);
125128
callback(response);
126129
})
127130
.detach();

tests/common/mocks/NetworkMock.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ GenerateNetworkMockActions(std::shared_ptr<std::promise<void>> pre_signal,
105105
NetworkCallback ReturnHttpResponse(
106106
olp::http::NetworkResponse response, const std::string& response_body,
107107
const olp::http::Headers& headers = {},
108-
std::chrono::nanoseconds delay = std::chrono::nanoseconds(0),
108+
std::chrono::nanoseconds delay = std::chrono::milliseconds(50),
109109
olp::http::RequestId request_id = 5);
110110

111111
inline olp::http::NetworkResponse GetResponse(int status) {

0 commit comments

Comments
 (0)