@@ -43,8 +43,11 @@ namespace http = olp::http;
4343
4444static const std::string kGoodResponse = " Response1234" ;
4545static const std::string kBadResponse = " Cancelled" ;
46- static constexpr int kCancelledStatus =
46+ constexpr int kCancelledStatus =
4747 static_cast <int >(http::ErrorCode::CANCELLED_ERROR);
48+ constexpr http::RequestId kRequestId = 1234u ;
49+ constexpr auto kSleepFor = std::chrono::seconds(1 );
50+ constexpr auto kWaitFor = std::chrono::seconds(5 );
4851
4952client::HttpResponse GetHttpResponse (ErrorCode error, std::string status) {
5053 return client::HttpResponse (static_cast <int >(error), status);
@@ -167,22 +170,62 @@ TEST(PendingUrlRequestsTest, IsCancelled) {
167170 const std::string url1 = " url1" ;
168171 const std::string url2 = " url2" ;
169172
173+ auto check_cancelled = [&](client::HttpResponse response) {
174+ ASSERT_EQ (response.GetStatus (), kCancelledStatus );
175+ };
176+
177+ auto check_not_cancelled = [&](client::HttpResponse response) {
178+ ASSERT_NE (response.GetStatus (), kCancelledStatus );
179+ };
180+
181+ auto complete_call = [&](http::RequestId request_id, const std::string& url) {
182+ std::this_thread::sleep_for (kSleepFor );
183+ pending_requests.OnRequestCompleted (
184+ request_id, url,
185+ GetHttpResponse (http::HttpStatusCode::OK, kGoodResponse ,
186+ {{" header1" , " value1" }, {" header2" , " value2" }}));
187+ };
188+
170189 {
171190 SCOPED_TRACE (" Cancel one request" );
172191
173192 auto request_valid = pending_requests[url1];
174193 auto request_cancelled = pending_requests[url2];
175194 ASSERT_TRUE (request_valid && request_cancelled);
176195
177- request_valid->Append ([&](client::HttpResponse) {} );
178- auto request_id = request_cancelled->Append ([&](client::HttpResponse) {} );
196+ request_valid->Append (check_not_cancelled );
197+ auto request_id = request_cancelled->Append (check_cancelled );
179198
180199 ASSERT_FALSE (request_valid->IsCancelled ());
181200 ASSERT_FALSE (request_cancelled->IsCancelled ());
182201
202+ std::future<void > future1, future2;
203+
204+ request_valid->ExecuteOrCancelled ([&](http::RequestId& id) {
205+ id = kRequestId ;
206+ future1 = std::async (std::launch::async, complete_call, id, url1);
207+ return client::CancellationToken ([] {
208+ // Should not be called
209+ EXPECT_TRUE (false ) << " Cancellation called on not cancelled request" ;
210+ });
211+ });
212+
213+ request_cancelled->ExecuteOrCancelled ([&](http::RequestId& id) {
214+ id = kRequestId + 1 ;
215+ return client::CancellationToken ([&] {
216+ future2 = std::async (std::launch::async, complete_call, id, url2);
217+ });
218+ });
219+
183220 EXPECT_TRUE (pending_requests.Cancel (url2, request_id));
184221 EXPECT_FALSE (request_valid->IsCancelled ());
185222 EXPECT_TRUE (request_cancelled->IsCancelled ());
223+
224+ ASSERT_EQ (future1.wait_for (kWaitFor ), std::future_status::ready);
225+ ASSERT_EQ (future2.wait_for (kWaitFor ), std::future_status::ready);
226+
227+ // Cancell all and wait to leave a clean state for the next scope
228+ ASSERT_TRUE (pending_requests.CancelAllAndWait ());
186229 }
187230
188231 {
@@ -192,15 +235,34 @@ TEST(PendingUrlRequestsTest, IsCancelled) {
192235 auto request2 = pending_requests[url2];
193236 ASSERT_TRUE (request1 && request2);
194237
195- request1->Append ([&](client::HttpResponse) {} );
196- request2->Append ([&](client::HttpResponse) {} );
238+ request1->Append (check_cancelled );
239+ request2->Append (check_cancelled );
197240
198241 ASSERT_FALSE (request1->IsCancelled ());
199242 ASSERT_FALSE (request2->IsCancelled ());
200243
244+ std::future<void > future1, future2;
245+
246+ request1->ExecuteOrCancelled ([&](http::RequestId& id) {
247+ id = kRequestId ;
248+ return client::CancellationToken ([&] {
249+ future1 = std::async (std::launch::async, complete_call, id, url1);
250+ });
251+ });
252+
253+ request2->ExecuteOrCancelled ([&](http::RequestId& id) {
254+ id = kRequestId + 1 ;
255+ return client::CancellationToken ([&] {
256+ future2 = std::async (std::launch::async, complete_call, id, url2);
257+ });
258+ });
259+
201260 EXPECT_TRUE (pending_requests.CancelAll ());
202261 EXPECT_TRUE (request1->IsCancelled ());
203262 EXPECT_TRUE (request2->IsCancelled ());
263+
264+ ASSERT_EQ (future1.wait_for (kWaitFor ), std::future_status::ready);
265+ ASSERT_EQ (future2.wait_for (kWaitFor ), std::future_status::ready);
204266 }
205267}
206268
@@ -256,19 +318,40 @@ TEST(PendingUrlRequestsTest, ExecuteOrCancelled) {
256318 client::PendingUrlRequests pending_requests;
257319 const std::string url = " url" ;
258320
321+ auto check_cancelled = [&](client::HttpResponse response) {
322+ ASSERT_EQ (response.GetStatus (), kCancelledStatus );
323+ };
324+
259325 // Check that ExecuteOrCancelled is behaving correctly
260326 auto request_ptr = pending_requests[url];
261327 ASSERT_TRUE (request_ptr);
262328 ASSERT_FALSE (request_ptr->IsCancelled ());
263329 ASSERT_EQ (request_ptr.use_count (), 2 );
264330
331+ request_ptr->Append (check_cancelled);
332+
265333 bool is_cancelled = false ;
266334 bool cancel_func_called = false ;
335+ std::future<void > future;
267336
268337 // Set request Id
269338 request_ptr->ExecuteOrCancelled (
270- [&](http::RequestId&) {
271- return client::CancellationToken ([&] { is_cancelled = true ; });
339+ [&](http::RequestId& id) {
340+ return client::CancellationToken ([&] {
341+ is_cancelled = true ;
342+ id = kRequestId ;
343+ future = std::async (
344+ std::launch::async,
345+ [&](http::RequestId request_id, const std::string& url) {
346+ std::this_thread::sleep_for (kSleepFor );
347+ pending_requests.OnRequestCompleted (
348+ request_id, url,
349+ GetHttpResponse (
350+ http::HttpStatusCode::OK, kGoodResponse ,
351+ {{" header1" , " value1" }, {" header2" , " value2" }}));
352+ },
353+ id, url);
354+ });
272355 },
273356 [] { EXPECT_TRUE (false ) << " Cancel function should not be called!" ; });
274357
@@ -284,31 +367,50 @@ TEST(PendingUrlRequestsTest, ExecuteOrCancelled) {
284367
285368 EXPECT_TRUE (is_cancelled);
286369 EXPECT_TRUE (cancel_func_called);
370+
371+ ASSERT_EQ (future.wait_for (kWaitFor ), std::future_status::ready);
287372}
288373
289374TEST (PendingUrlRequestsTest, SameUrlAfterCancel) {
290- // This test covers the user case were you have a cancelled request and
291- // afterwards a new request with the same URL. In this case both should
292- // exist at the same time, one in the pending request list the other in the
293- // cancelled list.
375+ // This test covers the use- case were you have a cancelled request which is in
376+ // the process of waiting for the network cancel answer and afterwards a new
377+ // request with the same URL. In this case both should exist at the same time,
378+ // one in the pending request list the other in the cancelled list.
294379 client::PendingUrlRequests pending_requests;
295380 const std::string url = " url1" ;
381+ std::future<void > future_cancelled, future_valid;
382+
383+ auto check_cancelled = [&](client::HttpResponse response) {
384+ ASSERT_EQ (response.GetStatus (), kCancelledStatus );
385+ };
386+
387+ auto check_not_cancelled = [&](client::HttpResponse response) {
388+ ASSERT_NE (response.GetStatus (), kCancelledStatus );
389+ };
296390
297391 // Add request to be cancelled
298392 auto request_ptr = pending_requests[url];
299393 ASSERT_TRUE (request_ptr);
300394 ASSERT_FALSE (request_ptr->IsCancelled ());
301395 ASSERT_EQ (request_ptr.use_count (), 2 );
302396
303- client::HttpResponse response_cancelled;
304- auto cancel_id = request_ptr->Append ([&](client::HttpResponse response) {
305- response_cancelled = std::move (response);
306- });
397+ auto cancel_id = request_ptr->Append (check_cancelled);
307398
308- const http::RequestId request_id = 1234 ;
309399 request_ptr->ExecuteOrCancelled ([&](http::RequestId& id) {
310- id = request_id;
311- return client::CancellationToken ();
400+ id = kRequestId ;
401+ return client::CancellationToken ([&] {
402+ future_cancelled =
403+ std::async (std::launch::async,
404+ [&](http::RequestId request_id, const std::string& url) {
405+ std::this_thread::sleep_for (kSleepFor );
406+ pending_requests.OnRequestCompleted (
407+ request_id, url,
408+ GetHttpResponse (
409+ http::HttpStatusCode::OK, kGoodResponse ,
410+ {{" header1" , " value1" }, {" header2" , " value2" }}));
411+ },
412+ id, url);
413+ });
312414 });
313415
314416 // Now cancel the request
@@ -322,22 +424,26 @@ TEST(PendingUrlRequestsTest, SameUrlAfterCancel) {
322424 ASSERT_EQ (new_request_ptr.use_count (), 2 );
323425 ASSERT_FALSE (new_request_ptr == request_ptr);
324426
325- client::HttpResponse response_valid;
326- new_request_ptr->Append ([&](client::HttpResponse response) {
327- response_valid = std::move (response);
328- });
427+ new_request_ptr->Append (check_not_cancelled);
329428
330- const http::RequestId new_request_id = 1 + request_id;
331429 new_request_ptr->ExecuteOrCancelled ([&](http::RequestId& id) {
332- id = new_request_id;
430+ id = kRequestId + 1 ;
431+ future_valid = std::async (
432+ std::launch::async,
433+ [&](http::RequestId request_id, const std::string& url) {
434+ std::this_thread::sleep_for (kSleepFor );
435+ pending_requests.OnRequestCompleted (
436+ request_id, url,
437+ GetHttpResponse (http::HttpStatusCode::OK, kGoodResponse ,
438+ {{" header1" , " value1" }, {" header2" , " value2" }}));
439+ },
440+ id, url);
441+
333442 return client::CancellationToken ();
334443 });
335444
336- // First trigger the valid response, then the cancelled
337- http::Headers headers = {{" header1" , " value1" }, {" header2" , " value2" }};
338- const auto response_in =
339- GetHttpResponse (http::HttpStatusCode::OK, kGoodResponse , headers);
340- pending_requests.OnRequestCompleted (request_id, url, response_in);
445+ ASSERT_EQ (future_cancelled.wait_for (kWaitFor ), std::future_status::ready);
446+ ASSERT_EQ (future_valid.wait_for (kWaitFor ), std::future_status::ready);
341447}
342448
343449TEST (PendingUrlRequestsTest, CallbackCalled) {
0 commit comments