File: test_issue_50.cpp

package info (click to toggle)
boost1.90 1.90.0-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 593,120 kB
  • sloc: cpp: 4,190,908; xml: 196,648; python: 34,618; ansic: 23,145; asm: 5,468; sh: 3,774; makefile: 1,161; perl: 1,020; sql: 728; ruby: 676; yacc: 478; java: 77; lisp: 24; csh: 6
file content (127 lines) | stat: -rw-r--r-- 3,527 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
/* Copyright (c) 2018-2022 Marcelo Zimbres Silva (mzimbres@gmail.com)
 *
 * Distributed under the Boost Software License, Version 1.0. (See
 * accompanying file LICENSE.txt)
 */

// Must come before any asio header, otherwise build fails on msvc.

#include <boost/redis/connection.hpp>
#include <boost/redis/logger.hpp>

#include <boost/asio/as_tuple.hpp>
#include <boost/asio/awaitable.hpp>
#include <boost/asio/co_spawn.hpp>
#include <boost/asio/io_context.hpp>
#include <boost/asio/redirect_error.hpp>
#include <boost/system/error_code.hpp>

#include <exception>
#define BOOST_TEST_MODULE issue50
#include <boost/test/included/unit_test.hpp>

#include "common.hpp"

#include <iostream>

#if defined(BOOST_ASIO_HAS_CO_AWAIT)

namespace net = boost::asio;
using boost::redis::request;
using boost::redis::response;
using boost::redis::ignore;
using boost::redis::logger;
using boost::redis::config;
using boost::redis::operation;
using boost::redis::connection;
using boost::system::error_code;
using namespace std::chrono_literals;

namespace {

// Push consumer
auto receiver(std::shared_ptr<connection> conn) -> net::awaitable<void>
{
   std::cout << "uuu" << std::endl;
   while (conn->will_reconnect()) {
      std::cout << "dddd" << std::endl;
      // Loop reading Redis pushs messages.
      for (;;) {
         std::cout << "aaaa" << std::endl;
         error_code ec;
         co_await conn->async_receive(net::redirect_error(ec));
         if (ec) {
            std::cout << "Error in async_receive" << std::endl;
            break;
         }
      }
   }

   std::cout << "Exiting the receiver." << std::endl;
}

auto periodic_task(std::shared_ptr<connection> conn) -> net::awaitable<void>
{
   net::steady_timer timer{co_await net::this_coro::executor};
   for (int i = 0; i < 10; ++i) {
      std::cout << "In the loop: " << i << std::endl;
      timer.expires_after(std::chrono::milliseconds(50));
      co_await timer.async_wait();

      // Key is not set so it will cause an error since we are passing
      // an adapter that does not accept null, this will cause an error
      // that result in the connection being closed.
      request req;
      req.push("GET", "mykey");
      auto [ec, u] = co_await conn->async_exec(req, ignore, net::as_tuple);
      if (ec) {
         std::cout << "(1)Error: " << ec << std::endl;
      } else {
         std::cout << "no error: " << std::endl;
      }
   }

   std::cout << "Periodic task done!" << std::endl;
   conn->cancel(operation::run);
   conn->cancel(operation::receive);
   conn->cancel(operation::reconnection);
}

BOOST_AUTO_TEST_CASE(issue_50)
{
   bool receiver_finished = false, periodic_finished = false, run_finished = false;

   net::io_context ctx;
   auto conn = std::make_shared<connection>(ctx.get_executor());

   // Launch the receiver
   net::co_spawn(ctx, receiver(conn), [&](std::exception_ptr exc) {
      if (exc)
         std::rethrow_exception(exc);
      receiver_finished = true;
   });

   // Launch the period task
   net::co_spawn(ctx, periodic_task(conn), [&](std::exception_ptr exc) {
      if (exc)
         std::rethrow_exception(exc);
      periodic_finished = true;
   });

   // Launch run
   conn->async_run(make_test_config(), {}, [&](error_code) {
      run_finished = true;
   });

   ctx.run_for(2 * test_timeout);

   BOOST_TEST(receiver_finished);
   BOOST_TEST(periodic_finished);
   BOOST_TEST(run_finished);
}

}  // namespace

#else
BOOST_AUTO_TEST_CASE(dummy) { }
#endif  // defined(BOOST_ASIO_HAS_CO_AWAIT)