mirror of
https://github.com/boostorg/redis.git
synced 2026-01-19 04:42:09 +00:00
Adds example that does not user awaitable ops.
This commit is contained in:
@@ -82,6 +82,15 @@ if (MSVC)
|
||||
target_compile_definitions(cpp20_intro PRIVATE _WIN32_WINNT=0x0601)
|
||||
endif()
|
||||
|
||||
add_executable(cpp20_intro_awaitable_ops examples/cpp20_intro_awaitable_ops.cpp)
|
||||
target_link_libraries(cpp20_intro_awaitable_ops common)
|
||||
target_compile_features(cpp20_intro_awaitable_ops PUBLIC cxx_std_20)
|
||||
add_test(cpp20_intro_awaitable_ops cpp20_intro_awaitable_ops)
|
||||
if (MSVC)
|
||||
target_compile_options(cpp20_intro_awaitable_ops PRIVATE /bigobj)
|
||||
target_compile_definitions(cpp20_intro_awaitable_ops PRIVATE _WIN32_WINNT=0x0601)
|
||||
endif()
|
||||
|
||||
add_executable(cpp17_intro examples/cpp17_intro.cpp)
|
||||
target_compile_features(cpp17_intro PUBLIC cxx_std_17)
|
||||
add_test(cpp17_intro cpp17_intro)
|
||||
@@ -199,6 +208,14 @@ if (MSVC)
|
||||
target_compile_definitions(test_conn_exec PRIVATE _WIN32_WINNT=0x0601)
|
||||
endif()
|
||||
|
||||
add_executable(test_conn_exec_retry tests/conn_exec_retry.cpp)
|
||||
target_compile_features(test_conn_exec_retry PUBLIC cxx_std_20)
|
||||
add_test(test_conn_exec_retry test_conn_exec_retry)
|
||||
if (MSVC)
|
||||
target_compile_options(test_conn_exec_retry PRIVATE /bigobj)
|
||||
target_compile_definitions(test_conn_exec_retry PRIVATE _WIN32_WINNT=0x0601)
|
||||
endif()
|
||||
|
||||
add_executable(test_conn_push tests/conn_push.cpp)
|
||||
target_compile_features(test_conn_push PUBLIC cxx_std_20)
|
||||
add_test(test_conn_push test_conn_push)
|
||||
|
||||
33
README.md
33
README.md
@@ -15,7 +15,7 @@ the cases will be concerned with only three library entities
|
||||
|
||||
For example, the coroutine below uses a short-lived connection to read Redis
|
||||
[hashes](https://redis.io/docs/data-types/hashes/)
|
||||
in a `std::map` (see cpp20_intro.cpp, cpp17_intro.cpp and containers.cpp)
|
||||
in a `std::map`
|
||||
|
||||
```cpp
|
||||
auto async_main() -> net::awaitable<void>
|
||||
@@ -41,30 +41,32 @@ auto async_main() -> net::awaitable<void>
|
||||
}
|
||||
```
|
||||
|
||||
For different versions of this example using different styles see
|
||||
|
||||
* cpp20_intro.cpp: Does not use awaitable operators
|
||||
* cpp20_intro_awaitable_ops.cpp: The version above.
|
||||
* cpp17_intro.cpp: Requires C++17 only.
|
||||
* cpp20_intro_tls.cpp: Communicates over TLS.
|
||||
|
||||
The execution of `connection::async_exec` above is composed with
|
||||
`connection::async_run` with the aid of the Asio awaitable `operator ||`
|
||||
that ensures that one operation is cancelled as soon as the other
|
||||
completes, these functions play the following roles
|
||||
|
||||
* `connection::async_exec`: Execute commands by queuing the request
|
||||
for writing and wait for the response sent back by Redis. It can be
|
||||
called from multiple places in your code concurrently.
|
||||
for writing. It will wait for the response sent back by Redis and
|
||||
can be called from multiple places in your code concurrently.
|
||||
* `connection::async_run`: Coordinate low-level read and write
|
||||
operations. More specifically, it will hand IO control to
|
||||
`async_exec` when a response arrives, to
|
||||
`aedis::connection::async_receive` when a server-push is received
|
||||
`async_receive` when a server-push is received
|
||||
and will trigger writes of pending requests when a reconnection
|
||||
occurs.
|
||||
|
||||
The role played by `async_run` can be better understood in the context
|
||||
of long-lived connections, which we will cover in the next section.
|
||||
Before that however, the reader might want to skim over the examples
|
||||
Before that however, the reader might want to skim over some further examples
|
||||
|
||||
* cpp17_intro.cpp: The Aedis hello-world program. Sends one command and quits the connection.
|
||||
* cpp17_intro_sync.cpp: Shows how to use the connection class synchronously.
|
||||
* cpp17_low_level_sync.cpp: Sends a ping synchronously using the low-level API.
|
||||
* cpp20_intro.cpp: Like cpp17_intro.cpp but uses awaitable operators.
|
||||
* cpp20_intro_tls.cpp: Same as intro.cpp but over TLS.
|
||||
* cpp20_containers.cpp: Shows how to send and receive STL containers and how to use transactions.
|
||||
* cpp20_serialization.cpp: Shows how to serialize types using Boost.Json.
|
||||
* cpp20_resolve_with_sentinel.cpp: Shows how to resolve a master address using sentinels.
|
||||
@@ -72,6 +74,7 @@ Before that however, the reader might want to skim over the examples
|
||||
* cpp20_echo_server.cpp: A simple TCP echo server.
|
||||
* cpp20_chat_room.cpp: A command line chat built on Redis pubsub.
|
||||
* cpp20_low_level_async.cpp: Sends a ping asynchronously using the low-level API.
|
||||
* cpp17_low_level_sync.cpp: Sends a ping synchronously using the low-level API.
|
||||
|
||||
To avoid repetition code that is common to some examples has been
|
||||
grouped in common.hpp. The main function used in some async examples
|
||||
@@ -159,7 +162,7 @@ auto run(std::shared_ptr<connection> conn) -> net::awaitable<void>
|
||||
```
|
||||
|
||||
The definition of `receiver` and `healthy_checker` above can be found
|
||||
in subscriber.cpp. Adding a loop around `async_run` produces a simple
|
||||
in cpp20_subscriber.cpp. Adding a loop around `async_run` produces a simple
|
||||
way to support reconnection _while there are pending operations on the connection_,
|
||||
for example, to reconnect to the same address
|
||||
|
||||
@@ -187,7 +190,7 @@ auto run(std::shared_ptr<connection> conn) -> net::awaitable<void>
|
||||
}
|
||||
```
|
||||
|
||||
For failover with sentinels see `resolve_with_sentinel.cpp`. At
|
||||
For failover with sentinels see `cpp20_resolve_with_sentinel.cpp`. At
|
||||
this point the reasons for why `async_run` was introduced in Aedis
|
||||
might have become apparent to the reader
|
||||
|
||||
@@ -225,7 +228,7 @@ co_await (conn.async_exec(...) || time.async_wait(...))
|
||||
* The cancellation will be ignored if the request has already
|
||||
been written to the socket.
|
||||
* NOTE: It is usually a better idea to have a healthy checker than adding
|
||||
per request timeout, see subscriber.cpp for an example.
|
||||
per request timeout, see cpp20_subscriber.cpp for an example.
|
||||
|
||||
```cpp
|
||||
co_await (conn.async_run(...) || time.async_wait(...))
|
||||
@@ -302,7 +305,7 @@ std::map<std::string, mystruct> map {...};
|
||||
req.push_range("HSET", "key", map);
|
||||
```
|
||||
|
||||
Example serialization.cpp shows how store json strings in Redis.
|
||||
Example cpp20_serialization.cpp shows how store json strings in Redis.
|
||||
|
||||
<a name="responses"></a>
|
||||
|
||||
@@ -1006,7 +1009,7 @@ Acknowledgement to people that helped shape Aedis
|
||||
|
||||
* `connection::async_receive_event` is now being used to communicate
|
||||
internal events to the user, such as resolve, connect, push etc. For
|
||||
examples see subscriber.cpp and `connection::event`.
|
||||
examples see cpp20_subscriber.cpp and `connection::event`.
|
||||
|
||||
* The `aedis` directory has been moved to `include` to look more
|
||||
similar to Boost libraries. Users should now replace `-I/aedis-path`
|
||||
|
||||
@@ -45,7 +45,7 @@ auto main() -> int
|
||||
auto on_run = [](auto ec)
|
||||
{
|
||||
if (ec)
|
||||
return log(ec, "on_exec: ");
|
||||
return log(ec, "on_run: ");
|
||||
};
|
||||
|
||||
// async_exec callback.
|
||||
|
||||
@@ -6,15 +6,19 @@
|
||||
|
||||
#include <boost/asio.hpp>
|
||||
#if defined(BOOST_ASIO_HAS_CO_AWAIT)
|
||||
#include <boost/asio/experimental/awaitable_operators.hpp>
|
||||
#include <aedis.hpp>
|
||||
#include "common/common.hpp"
|
||||
|
||||
namespace net = boost::asio;
|
||||
namespace resp3 = aedis::resp3;
|
||||
using namespace net::experimental::awaitable_operators;
|
||||
using aedis::adapt;
|
||||
|
||||
auto run(std::shared_ptr<connection> conn) -> net::awaitable<void>
|
||||
{
|
||||
co_await connect(conn, "127.0.0.1", "6379");
|
||||
co_await conn->async_run();
|
||||
}
|
||||
|
||||
// Called from the main function (see main.cpp)
|
||||
auto async_main() -> net::awaitable<void>
|
||||
{
|
||||
@@ -25,9 +29,10 @@ auto async_main() -> net::awaitable<void>
|
||||
|
||||
std::tuple<aedis::ignore, std::string, aedis::ignore> resp;
|
||||
|
||||
auto conn = std::make_shared<connection>(co_await net::this_coro::executor);
|
||||
co_await connect(conn, "127.0.0.1", "6379");
|
||||
co_await (conn->async_run() || conn->async_exec(req, adapt(resp)));
|
||||
auto ex = co_await net::this_coro::executor;
|
||||
auto conn = std::make_shared<connection>(ex);
|
||||
net::co_spawn(ex, run(conn), net::detached);
|
||||
co_await conn->async_exec(req, adapt(resp));
|
||||
|
||||
std::cout << "PING: " << std::get<1>(resp) << std::endl;
|
||||
}
|
||||
|
||||
35
examples/cpp20_intro_awaitable_ops.cpp
Normal file
35
examples/cpp20_intro_awaitable_ops.cpp
Normal file
@@ -0,0 +1,35 @@
|
||||
/* Copyright (c) 2018-2022 Marcelo Zimbres Silva (mzimbres@gmail.com)
|
||||
*
|
||||
* Distributed under the Boost Software License, Version 1.0. (See
|
||||
* accompanying file LICENSE.txt)
|
||||
*/
|
||||
|
||||
#include <boost/asio.hpp>
|
||||
#if defined(BOOST_ASIO_HAS_CO_AWAIT)
|
||||
#include <boost/asio/experimental/awaitable_operators.hpp>
|
||||
#include <aedis.hpp>
|
||||
#include "common/common.hpp"
|
||||
|
||||
namespace net = boost::asio;
|
||||
namespace resp3 = aedis::resp3;
|
||||
using namespace net::experimental::awaitable_operators;
|
||||
using aedis::adapt;
|
||||
|
||||
// Called from the main function (see main.cpp)
|
||||
auto async_main() -> net::awaitable<void>
|
||||
{
|
||||
resp3::request req;
|
||||
req.push("HELLO", 3);
|
||||
req.push("PING", "Hello world");
|
||||
req.push("QUIT");
|
||||
|
||||
std::tuple<aedis::ignore, std::string, aedis::ignore> resp;
|
||||
|
||||
auto conn = std::make_shared<connection>(co_await net::this_coro::executor);
|
||||
co_await connect(conn, "127.0.0.1", "6379");
|
||||
co_await (conn->async_run() || conn->async_exec(req, adapt(resp)));
|
||||
|
||||
std::cout << "PING: " << std::get<1>(resp) << std::endl;
|
||||
}
|
||||
|
||||
#endif // defined(BOOST_ASIO_HAS_CO_AWAIT)
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
namespace aedis::resp3::detail {
|
||||
|
||||
auto has_push_response(std::string_view cmd) -> bool
|
||||
auto has_response(std::string_view cmd) -> bool
|
||||
{
|
||||
if (cmd == "SUBSCRIBE") return true;
|
||||
if (cmd == "PSUBSCRIBE") return true;
|
||||
|
||||
@@ -62,7 +62,7 @@ void to_bulk(Request& to, T n)
|
||||
|
||||
namespace detail {
|
||||
|
||||
auto has_push_response(std::string_view cmd) -> bool;
|
||||
auto has_response(std::string_view cmd) -> bool;
|
||||
|
||||
template <class T>
|
||||
struct add_bulk_impl {
|
||||
@@ -386,7 +386,7 @@ public:
|
||||
private:
|
||||
void check_cmd(std::string_view cmd)
|
||||
{
|
||||
if (!detail::has_push_response(cmd))
|
||||
if (!detail::has_response(cmd))
|
||||
++commands_;
|
||||
|
||||
if (cmd == "HELLO")
|
||||
|
||||
@@ -122,123 +122,3 @@ BOOST_AUTO_TEST_CASE(cancel_request_if_not_connected)
|
||||
|
||||
ioc.run();
|
||||
}
|
||||
|
||||
// TODO: This test is broken.
|
||||
BOOST_AUTO_TEST_CASE(request_retry_false)
|
||||
{
|
||||
resp3::request req0;
|
||||
req0.get_config().coalesce = false;
|
||||
req0.get_config().cancel_on_connection_lost = true;
|
||||
req0.push("HELLO", 3);
|
||||
|
||||
resp3::request req1;
|
||||
req1.get_config().coalesce = true;
|
||||
req1.get_config().cancel_on_connection_lost = true;
|
||||
req1.push("BLPOP", "any", 0);
|
||||
|
||||
resp3::request req2;
|
||||
req2.get_config().coalesce = true;
|
||||
req2.get_config().cancel_on_connection_lost = false;
|
||||
req2.get_config().cancel_if_unresponded = true;
|
||||
req2.push("PING");
|
||||
|
||||
net::io_context ioc;
|
||||
connection conn{ioc};
|
||||
|
||||
net::steady_timer st{ioc};
|
||||
st.expires_after(std::chrono::seconds{1});
|
||||
st.async_wait([&](auto){
|
||||
// Cancels the request before receiving the response. This
|
||||
// should cause the second request to complete with error
|
||||
// although it has cancel_on_connection_lost = false.
|
||||
conn.cancel(aedis::operation::run);
|
||||
});
|
||||
|
||||
auto const endpoints = resolve();
|
||||
net::connect(conn.next_layer(), endpoints);
|
||||
|
||||
conn.async_exec(req0, adapt(), [](auto ec, auto){
|
||||
BOOST_TEST(!ec);
|
||||
});
|
||||
|
||||
conn.async_exec(req1, adapt(), [](auto ec, auto){
|
||||
BOOST_CHECK_EQUAL(ec, boost::system::errc::errc_t::operation_canceled);
|
||||
});
|
||||
|
||||
conn.async_exec(req2, adapt(), [](auto ec, auto){
|
||||
BOOST_CHECK_EQUAL(ec, boost::system::errc::errc_t::operation_canceled);
|
||||
});
|
||||
|
||||
conn.async_run([](auto ec){
|
||||
BOOST_CHECK_EQUAL(ec, boost::system::errc::errc_t::operation_canceled);
|
||||
});
|
||||
|
||||
ioc.run();
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(request_retry_true)
|
||||
{
|
||||
resp3::request req0;
|
||||
req0.get_config().coalesce = false;
|
||||
req0.get_config().cancel_on_connection_lost = true;
|
||||
req0.push("HELLO", 3);
|
||||
|
||||
resp3::request req1;
|
||||
req1.get_config().coalesce = true;
|
||||
req1.get_config().cancel_on_connection_lost = true;
|
||||
req1.push("BLPOP", "any", 0);
|
||||
|
||||
resp3::request req2;
|
||||
req2.get_config().coalesce = true;
|
||||
req2.get_config().cancel_on_connection_lost = false;
|
||||
req2.get_config().cancel_if_unresponded = false;
|
||||
req2.push("PING");
|
||||
|
||||
resp3::request req3;
|
||||
req3.get_config().coalesce = true;
|
||||
req3.get_config().cancel_on_connection_lost = true;
|
||||
req3.get_config().cancel_if_unresponded = true;
|
||||
req3.push("QUIT");
|
||||
|
||||
net::io_context ioc;
|
||||
connection conn{ioc};
|
||||
|
||||
net::steady_timer st{ioc};
|
||||
st.expires_after(std::chrono::seconds{1});
|
||||
st.async_wait([&](auto){
|
||||
// Cancels the request before receiving the response. This
|
||||
// should cause the second request to complete with error
|
||||
// although it has cancel_on_connection_lost = false.
|
||||
conn.cancel(aedis::operation::run);
|
||||
});
|
||||
|
||||
auto const endpoints = resolve();
|
||||
net::connect(conn.next_layer(), endpoints);
|
||||
|
||||
conn.async_exec(req0, adapt(), [](auto ec, auto){
|
||||
BOOST_TEST(!ec);
|
||||
});
|
||||
|
||||
conn.async_exec(req1, adapt(), [](auto ec, auto){
|
||||
BOOST_CHECK_EQUAL(ec, boost::system::errc::errc_t::operation_canceled);
|
||||
});
|
||||
|
||||
conn.async_exec(req2, adapt(), [&](auto ec, auto){
|
||||
BOOST_TEST(!ec);
|
||||
conn.async_exec(req3, adapt(), [&](auto ec, auto){
|
||||
BOOST_TEST(!ec);
|
||||
});
|
||||
});
|
||||
|
||||
conn.async_run([&](auto ec){
|
||||
BOOST_CHECK_EQUAL(ec, boost::system::errc::errc_t::operation_canceled);
|
||||
conn.reset_stream();
|
||||
net::connect(conn.next_layer(), endpoints);
|
||||
conn.async_run([&](auto ec){
|
||||
std::cout << ec.message() << std::endl;
|
||||
BOOST_TEST(!ec);
|
||||
});
|
||||
});
|
||||
|
||||
ioc.run();
|
||||
}
|
||||
|
||||
148
tests/conn_exec_retry.cpp
Normal file
148
tests/conn_exec_retry.cpp
Normal file
@@ -0,0 +1,148 @@
|
||||
/* Copyright (c) 2018-2022 Marcelo Zimbres Silva (mzimbres@gmail.com)
|
||||
*
|
||||
* Distributed under the Boost Software License, Version 1.0. (See
|
||||
* accompanying file LICENSE.txt)
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <boost/asio.hpp>
|
||||
#include <boost/system/errc.hpp>
|
||||
|
||||
#define BOOST_TEST_MODULE low level
|
||||
#include <boost/test/included/unit_test.hpp>
|
||||
|
||||
#include <aedis.hpp>
|
||||
#include <aedis/src.hpp>
|
||||
|
||||
#include "common.hpp"
|
||||
|
||||
namespace net = boost::asio;
|
||||
namespace resp3 = aedis::resp3;
|
||||
using error_code = boost::system::error_code;
|
||||
using connection = aedis::connection;
|
||||
using aedis::adapt;
|
||||
|
||||
BOOST_AUTO_TEST_CASE(request_retry_false)
|
||||
{
|
||||
resp3::request req0;
|
||||
req0.get_config().coalesce = false;
|
||||
req0.get_config().cancel_on_connection_lost = true;
|
||||
req0.push("HELLO", 3);
|
||||
|
||||
resp3::request req1;
|
||||
req1.get_config().coalesce = true;
|
||||
req1.get_config().cancel_on_connection_lost = true;
|
||||
req1.push("BLPOP", "any", 0);
|
||||
|
||||
resp3::request req2;
|
||||
req2.get_config().coalesce = true;
|
||||
req2.get_config().cancel_on_connection_lost = false;
|
||||
req2.get_config().cancel_if_unresponded = true;
|
||||
req2.push("PING");
|
||||
|
||||
net::io_context ioc;
|
||||
connection conn{ioc};
|
||||
|
||||
net::steady_timer st{ioc};
|
||||
st.expires_after(std::chrono::seconds{1});
|
||||
st.async_wait([&](auto){
|
||||
// Cancels the request before receiving the response. This
|
||||
// should cause the third request to complete with error
|
||||
// although it has cancel_on_connection_lost = false. The reason
|
||||
// being is has already been written so
|
||||
// cancel_on_connection_lost does not apply.
|
||||
conn.cancel(aedis::operation::run);
|
||||
});
|
||||
|
||||
auto const endpoints = resolve();
|
||||
net::connect(conn.next_layer(), endpoints);
|
||||
|
||||
conn.async_exec(req0, adapt(), [](auto ec, auto){
|
||||
BOOST_TEST(!ec);
|
||||
});
|
||||
|
||||
conn.async_exec(req1, adapt(), [](auto ec, auto){
|
||||
BOOST_CHECK_EQUAL(ec, boost::system::errc::errc_t::operation_canceled);
|
||||
});
|
||||
|
||||
conn.async_exec(req2, adapt(), [](auto ec, auto){
|
||||
BOOST_CHECK_EQUAL(ec, boost::system::errc::errc_t::operation_canceled);
|
||||
});
|
||||
|
||||
conn.async_run([](auto ec){
|
||||
BOOST_CHECK_EQUAL(ec, boost::system::errc::errc_t::operation_canceled);
|
||||
});
|
||||
|
||||
ioc.run();
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(request_retry_true)
|
||||
{
|
||||
resp3::request req0;
|
||||
req0.get_config().coalesce = false;
|
||||
req0.get_config().cancel_on_connection_lost = true;
|
||||
req0.push("HELLO", 3);
|
||||
|
||||
resp3::request req1;
|
||||
req1.get_config().coalesce = true;
|
||||
req1.get_config().cancel_on_connection_lost = true;
|
||||
req1.push("BLPOP", "any", 0);
|
||||
|
||||
resp3::request req2;
|
||||
req2.get_config().coalesce = true;
|
||||
req2.get_config().cancel_on_connection_lost = false;
|
||||
req2.get_config().cancel_if_unresponded = false;
|
||||
req2.push("PING");
|
||||
|
||||
resp3::request req3;
|
||||
req3.get_config().coalesce = true;
|
||||
req3.get_config().cancel_on_connection_lost = true;
|
||||
req3.get_config().cancel_if_unresponded = true;
|
||||
req3.push("QUIT");
|
||||
|
||||
net::io_context ioc;
|
||||
connection conn{ioc};
|
||||
|
||||
net::steady_timer st{ioc};
|
||||
st.expires_after(std::chrono::seconds{1});
|
||||
st.async_wait([&](auto){
|
||||
// Cancels the request before receiving the response. This
|
||||
// should cause the thrid request to not complete with error
|
||||
// since it has cancel_if_unresponded = true and cancellation commes
|
||||
// after it was written.
|
||||
conn.cancel(aedis::operation::run);
|
||||
});
|
||||
|
||||
auto const endpoints = resolve();
|
||||
net::connect(conn.next_layer(), endpoints);
|
||||
|
||||
conn.async_exec(req0, adapt(), [](auto ec, auto){
|
||||
BOOST_TEST(!ec);
|
||||
});
|
||||
|
||||
conn.async_exec(req1, adapt(), [](auto ec, auto){
|
||||
BOOST_CHECK_EQUAL(ec, boost::system::errc::errc_t::operation_canceled);
|
||||
});
|
||||
|
||||
conn.async_exec(req2, adapt(), [&](auto ec, auto){
|
||||
BOOST_TEST(!ec);
|
||||
conn.async_exec(req3, adapt(), [&](auto ec, auto){
|
||||
BOOST_TEST(!ec);
|
||||
});
|
||||
});
|
||||
|
||||
conn.async_run([&](auto ec){
|
||||
// The first cacellation.
|
||||
BOOST_CHECK_EQUAL(ec, boost::system::errc::errc_t::operation_canceled);
|
||||
conn.reset_stream();
|
||||
|
||||
// Reconnects and runs again to test req3.
|
||||
net::connect(conn.next_layer(), endpoints);
|
||||
conn.async_run([&](auto ec){
|
||||
std::cout << ec.message() << std::endl;
|
||||
BOOST_TEST(!ec);
|
||||
});
|
||||
});
|
||||
|
||||
ioc.run();
|
||||
}
|
||||
@@ -295,173 +295,189 @@ std::vector<node_type> const attr_e1a
|
||||
std::vector<node_type> const attr_e1b
|
||||
{ {resp3::type::attribute, 0UL, 0UL, {}} };
|
||||
|
||||
#define S01 "#11\r\n"
|
||||
#define S02 "#f\r\n"
|
||||
#define S03 "#t\r\n"
|
||||
#define S04 "$?\r\n;0\r\n"
|
||||
#define S05 "%11\r\n"
|
||||
#define S06 "$?\r\n;4\r\nHell\r\n;5\r\no wor\r\n;1\r\nd\r\n;0\r\n"
|
||||
#define S07 "$?\r\n;b\r\nHell\r\n;5\r\no wor\r\n;1\r\nd\r\n;0\r\n"
|
||||
#define S08 "*1\r\n:11\r\n"
|
||||
#define S09 ":-3\r\n"
|
||||
#define S10 ":11\r\n"
|
||||
#define S11 ":3\r\n"
|
||||
#define S12 "_\r\n"
|
||||
#define S13 ">4\r\n+pubsub\r\n+message\r\n+some-channel\r\n+some message\r\n"
|
||||
#define S14 ">0\r\n"
|
||||
#define S15 "*3\r\n$2\r\n11\r\n$2\r\n22\r\n$1\r\n3\r\n"
|
||||
#define S16 "%4\r\n$4\r\nkey1\r\n$6\r\nvalue1\r\n$4\r\nkey2\r\n$6\r\nvalue2\r\n$4\r\nkey3\r\n$6\r\nvalue3\r\n$4\r\nkey3\r\n$6\r\nvalue3\r\n"
|
||||
#define S17 "*1\r\n" S16
|
||||
#define S18 "|1\r\n+key-popularity\r\n%2\r\n$1\r\na\r\n,0.1923\r\n$1\r\nb\r\n,0.0012\r\n"
|
||||
#define S19 "|0\r\n"
|
||||
#define S20 "*3\r\n$2\r\n11\r\n$2\r\n22\r\n$1\r\n3\r\n"
|
||||
#define S21 "*1\r\n*1\r\n$2\r\nab\r\n"
|
||||
#define S22 "*1\r\n*1\r\n*1\r\n*1\r\n*1\r\n*1\r\na\r\n"
|
||||
#define S23 "*0\r\n"
|
||||
#define S24 "*3\r\n$2\r\n11\r\n$2\r\n22\r\n$1\r\n3\r\n"
|
||||
#define S25 "~6\r\n+orange\r\n+apple\r\n+one\r\n+two\r\n+three\r\n+orange\r\n"
|
||||
#define S26 "*1\r\n" S25
|
||||
#define S27 "~0\r\n"
|
||||
#define S28 "-Error\r\n"
|
||||
#define S29 "-\r\n"
|
||||
#define S30 "%0\r\n"
|
||||
#define S31 ",1.23\r\n"
|
||||
#define S32 ",inf\r\n"
|
||||
#define S33 ",-inf\r\n"
|
||||
#define S34 ",1.23\r\n"
|
||||
#define S35 ",er\r\n"
|
||||
#define S36 "!21\r\nSYNTAX invalid syntax\r\n"
|
||||
#define S37 "!0\r\n\r\n"
|
||||
#define S38 "!3\r\nfoo\r\n"
|
||||
#define S39 "=15\r\ntxt:Some string\r\n"
|
||||
#define S40 "=0\r\n\r\n"
|
||||
#define S41 "(3492890328409238509324850943850943825024385\r\n"
|
||||
#define S42 "(\r\n"
|
||||
#define S43 "+OK\r\n"
|
||||
#define S44 "+\r\n"
|
||||
#define S45 "s11\r\n"
|
||||
#define S46 ":adf\r\n"
|
||||
#define S47 "%rt\r\n$4\r\nkey1\r\n$6\r\nvalue1\r\n$4\r\nkey2\r\n$6\r\nvalue2\r\n"
|
||||
#define S48 "$?\r\n;d\r\nHell\r\n;5\r\no wor\r\n;1\r\nd\r\n;0\r\n"
|
||||
#define S49 "$l\r\nhh\r\n"
|
||||
#define S50 ":\r\n"
|
||||
#define S51 "#\r\n"
|
||||
#define S52 ",\r\n"
|
||||
#define S53 "$2\r\nhh\r\n"
|
||||
#define S54 "$26\r\nhhaa\aaaa\raaaaa\r\naaaaaaaaaa\r\n"
|
||||
#define S55 "$0\r\n\r\n"
|
||||
#define S01a "#11\r\n"
|
||||
#define S01b "#f\r\n"
|
||||
#define S01c "#t\r\n"
|
||||
#define S01d "#\r\n"
|
||||
|
||||
#define S02a "$?\r\n;0\r\n"
|
||||
#define S02b "$?\r\n;4\r\nHell\r\n;5\r\no wor\r\n;1\r\nd\r\n;0\r\n"
|
||||
#define S02c "$?\r\n;b\r\nHell\r\n;5\r\no wor\r\n;1\r\nd\r\n;0\r\n"
|
||||
#define S02d "$?\r\n;d\r\nHell\r\n;5\r\no wor\r\n;1\r\nd\r\n;0\r\n"
|
||||
|
||||
#define S03a "%11\r\n"
|
||||
#define S03b "%4\r\n$4\r\nkey1\r\n$6\r\nvalue1\r\n$4\r\nkey2\r\n$6\r\nvalue2\r\n$4\r\nkey3\r\n$6\r\nvalue3\r\n$4\r\nkey3\r\n$6\r\nvalue3\r\n"
|
||||
#define S03c "%0\r\n"
|
||||
#define S03d "%rt\r\n$4\r\nkey1\r\n$6\r\nvalue1\r\n$4\r\nkey2\r\n$6\r\nvalue2\r\n"
|
||||
|
||||
#define S04a "*1\r\n:11\r\n"
|
||||
#define S04b "*3\r\n$2\r\n11\r\n$2\r\n22\r\n$1\r\n3\r\n"
|
||||
#define S04c "*1\r\n" S03b
|
||||
#define S04d "*1\r\n" S09a
|
||||
#define S04e "*3\r\n$2\r\n11\r\n$2\r\n22\r\n$1\r\n3\r\n"
|
||||
#define S04f "*1\r\n*1\r\n$2\r\nab\r\n"
|
||||
#define S04g "*1\r\n*1\r\n*1\r\n*1\r\n*1\r\n*1\r\na\r\n"
|
||||
#define S04h "*0\r\n"
|
||||
#define S04i "*3\r\n$2\r\n11\r\n$2\r\n22\r\n$1\r\n3\r\n"
|
||||
|
||||
#define S05a ":-3\r\n"
|
||||
#define S05b ":11\r\n"
|
||||
#define s05c ":3\r\n"
|
||||
#define S05d ":adf\r\n"
|
||||
#define S05e ":\r\n"
|
||||
|
||||
#define S06a "_\r\n"
|
||||
|
||||
#define S07a ">4\r\n+pubsub\r\n+message\r\n+some-channel\r\n+some message\r\n"
|
||||
#define S07b ">0\r\n"
|
||||
|
||||
#define S08a "|1\r\n+key-popularity\r\n%2\r\n$1\r\na\r\n,0.1923\r\n$1\r\nb\r\n,0.0012\r\n"
|
||||
#define S08b "|0\r\n"
|
||||
|
||||
#define S09a "~6\r\n+orange\r\n+apple\r\n+one\r\n+two\r\n+three\r\n+orange\r\n"
|
||||
#define S09b "~0\r\n"
|
||||
|
||||
#define S10a "-Error\r\n"
|
||||
#define S10b "-\r\n"
|
||||
|
||||
#define S11a ",1.23\r\n"
|
||||
#define S11b ",inf\r\n"
|
||||
#define S11c ",-inf\r\n"
|
||||
#define S11d ",1.23\r\n"
|
||||
#define S11e ",er\r\n"
|
||||
#define S11f ",\r\n"
|
||||
|
||||
#define S12a "!21\r\nSYNTAX invalid syntax\r\n"
|
||||
#define S12b "!0\r\n\r\n"
|
||||
#define S12c "!3\r\nfoo\r\n"
|
||||
|
||||
#define S13a "=15\r\ntxt:Some string\r\n"
|
||||
#define S13b "=0\r\n\r\n"
|
||||
|
||||
#define S14a "(3492890328409238509324850943850943825024385\r\n"
|
||||
#define S14b "(\r\n"
|
||||
|
||||
#define S15a "+OK\r\n"
|
||||
#define S15b "+\r\n"
|
||||
|
||||
#define S16a "s11\r\n"
|
||||
|
||||
#define S17a "$l\r\nhh\r\n"
|
||||
#define S17b "$2\r\nhh\r\n"
|
||||
#define S18c "$26\r\nhhaa\aaaa\raaaaa\r\naaaaaaaaaa\r\n"
|
||||
#define S18d "$0\r\n\r\n"
|
||||
|
||||
#define NUMBER_TEST_CONDITIONS(test) \
|
||||
test(ex, make_expected(S01, std::optional<bool>{}, aedis::error::unexpected_bool_value)); \
|
||||
test(ex, make_expected(S02, bool{false})); \
|
||||
test(ex, make_expected(S02, node_type{resp3::type::boolean, 1UL, 0UL, {"f"}})); \
|
||||
test(ex, make_expected(S03, bool{true})); \
|
||||
test(ex, make_expected(S03, node_type{resp3::type::boolean, 1UL, 0UL, {"t"}})); \
|
||||
test(ex, make_expected(S03, op_bool_ok)); \
|
||||
test(ex, make_expected(S03, std::map<int, int>{}, aedis::error::expects_resp3_map)); \
|
||||
test(ex, make_expected(S03, std::set<int>{}, aedis::error::expects_resp3_set)); \
|
||||
test(ex, make_expected(S03, std::unordered_map<int, int>{}, aedis::error::expects_resp3_map)); \
|
||||
test(ex, make_expected(S03, std::unordered_set<int>{}, aedis::error::expects_resp3_set)); \
|
||||
test(ex, make_expected(S04, streamed_string_e2)); \
|
||||
test(ex, make_expected(S05, int{}, aedis::error::expects_resp3_simple_type));\
|
||||
test(ex, make_expected(S05, std::optional<int>{}, aedis::error::expects_resp3_simple_type));; \
|
||||
test(ex, make_expected(S06, int{}, aedis::error::not_a_number)); \
|
||||
test(ex, make_expected(S06, std::string{"Hello word"})); \
|
||||
test(ex, make_expected(S06, streamed_string_e1)); \
|
||||
test(ex, make_expected(S07, std::string{}, aedis::error::not_a_number)); \
|
||||
test(ex, make_expected(S08, std::tuple<int>{11})); \
|
||||
test(ex, make_expected(S09, node_type{resp3::type::number, 1UL, 0UL, {"-3"}})); \
|
||||
test(ex, make_expected(S10, int{11})); \
|
||||
test(ex, make_expected(S10, op_int_ok)); \
|
||||
test(ex, make_expected(S10, std::list<std::string>{}, aedis::error::expects_resp3_aggregate)); \
|
||||
test(ex, make_expected(S10, std::map<std::string, std::string>{}, aedis::error::expects_resp3_map)); \
|
||||
test(ex, make_expected(S10, std::set<std::string>{}, aedis::error::expects_resp3_set)); \
|
||||
test(ex, make_expected(S10, std::unordered_map<std::string, std::string>{}, aedis::error::expects_resp3_map)); \
|
||||
test(ex, make_expected(S10, std::unordered_set<std::string>{}, aedis::error::expects_resp3_set)); \
|
||||
test(ex, make_expected(S11, array_type2{}, aedis::error::expects_resp3_aggregate));\
|
||||
test(ex, make_expected(S11, node_type{resp3::type::number, 1UL, 0UL, {"3"}})); \
|
||||
test(ex, make_expected(S12, array_type{}, aedis::error::resp3_null));\
|
||||
test(ex, make_expected(S12, int{0}, aedis::error::resp3_null)); \
|
||||
test(ex, make_expected(S12, map_type{}, aedis::error::resp3_null));\
|
||||
test(ex, make_expected(S12, op_type_01{}));\
|
||||
test(ex, make_expected(S12, op_type_02{}));\
|
||||
test(ex, make_expected(S12, op_type_03{}));\
|
||||
test(ex, make_expected(S12, op_type_04{}));\
|
||||
test(ex, make_expected(S12, op_type_05{}));\
|
||||
test(ex, make_expected(S12, op_type_06{}));\
|
||||
test(ex, make_expected(S12, op_type_07{}));\
|
||||
test(ex, make_expected(S12, op_type_08{}));\
|
||||
test(ex, make_expected(S12, op_type_09{}));\
|
||||
test(ex, make_expected(S12, std::list<int>{}, aedis::error::resp3_null));\
|
||||
test(ex, make_expected(S12, std::vector<int>{}, aedis::error::resp3_null));\
|
||||
test(ex, make_expected(S13, push_e1a)); \
|
||||
test(ex, make_expected(S14, push_e1b)); \
|
||||
test(ex, make_expected(S15, map_type{}, aedis::error::expects_resp3_map));\
|
||||
test(ex, make_expected(S16, map_e1f));\
|
||||
test(ex, make_expected(S16, map_e1g));\
|
||||
test(ex, make_expected(S16, map_e1k));\
|
||||
test(ex, make_expected(S16, map_e1l));\
|
||||
test(ex, make_expected(S16, map_expected_1a));\
|
||||
test(ex, make_expected(S16, map_expected_1b));\
|
||||
test(ex, make_expected(S16, map_expected_1c));\
|
||||
test(ex, make_expected(S16, map_expected_1d));\
|
||||
test(ex, make_expected(S16, map_expected_1e));\
|
||||
test(ex, make_expected(S17, std::tuple<op_map_type>{map_expected_1d}));\
|
||||
test(ex, make_expected(S18, attr_e1a)); \
|
||||
test(ex, make_expected(S19, attr_e1b)); \
|
||||
test(ex, make_expected(S20, array_e1a));\
|
||||
test(ex, make_expected(S20, array_e1b));\
|
||||
test(ex, make_expected(S20, array_e1c));\
|
||||
test(ex, make_expected(S20, array_e1f));\
|
||||
test(ex, make_expected(S20, array_e1g));\
|
||||
test(ex, make_expected(S20, array_e1h));\
|
||||
test(ex, make_expected(S20, array_type2{}, aedis::error::incompatible_size));\
|
||||
test(ex, make_expected(S20, tuple_int_2{}, aedis::error::incompatible_size));\
|
||||
test(ex, make_expected(S21, array_type2{}, aedis::error::nested_aggregate_not_supported));\
|
||||
test(ex, make_expected(S22, vec_node_type{}, aedis::error::exceeeds_max_nested_depth));\
|
||||
test(ex, make_expected(S23, array_e1d));\
|
||||
test(ex, make_expected(S23, array_e1e));\
|
||||
test(ex, make_expected(S24, set_type{}, aedis::error::expects_resp3_set)); \
|
||||
test(ex, make_expected(S25, set_e1c)); \
|
||||
test(ex, make_expected(S25, set_e1d)); \
|
||||
test(ex, make_expected(S25, set_e1f)); \
|
||||
test(ex, make_expected(S25, set_e1g)); \
|
||||
test(ex, make_expected(S25, set_expected1a)); \
|
||||
test(ex, make_expected(S25, set_expected_1e)); \
|
||||
test(ex, make_expected(S25, set_type{"apple", "one", "orange", "three", "two"})); \
|
||||
test(ex, make_expected(S26, std::tuple<uset_type>{set_e1c})); \
|
||||
test(ex, make_expected(S27, std::vector<node_type>{ {resp3::type::set, 0UL, 0UL, {}} })); \
|
||||
test(ex, make_expected(S28, aedis::ignore{}, aedis::error::resp3_simple_error)); \
|
||||
test(ex, make_expected(S28, node_type{resp3::type::simple_error, 1UL, 0UL, {"Error"}}, aedis::error::resp3_simple_error)); \
|
||||
test(ex, make_expected(S29, node_type{resp3::type::simple_error, 1UL, 0UL, {""}}, aedis::error::resp3_simple_error)); \
|
||||
test(ex, make_expected(S30, map_type{}));\
|
||||
test(ex, make_expected(S31, node_type{resp3::type::doublean, 1UL, 0UL, {"1.23"}}));\
|
||||
test(ex, make_expected(S32, node_type{resp3::type::doublean, 1UL, 0UL, {"inf"}}));\
|
||||
test(ex, make_expected(S33, node_type{resp3::type::doublean, 1UL, 0UL, {"-inf"}}));\
|
||||
test(ex, make_expected(S34, double{1.23}));\
|
||||
test(ex, make_expected(S35, double{0}, aedis::error::not_a_double));\
|
||||
test(ex, make_expected(S36, node_type{resp3::type::blob_error, 1UL, 0UL, {"SYNTAX invalid syntax"}}, aedis::error::resp3_blob_error));\
|
||||
test(ex, make_expected(S37, node_type{resp3::type::blob_error, 1UL, 0UL, {}}, aedis::error::resp3_blob_error));\
|
||||
test(ex, make_expected(S38, aedis::ignore{}, aedis::error::resp3_blob_error));\
|
||||
test(ex, make_expected(S39, node_type{resp3::type::verbatim_string, 1UL, 0UL, {"txt:Some string"}}));\
|
||||
test(ex, make_expected(S40, node_type{resp3::type::verbatim_string, 1UL, 0UL, {}}));\
|
||||
test(ex, make_expected(S41, node_type{resp3::type::big_number, 1UL, 0UL, {"3492890328409238509324850943850943825024385"}}));\
|
||||
test(ex, make_expected(S42, int{}, aedis::error::empty_field));\
|
||||
test(ex, make_expected(S43, std::optional<std::string>{"OK"}));\
|
||||
test(ex, make_expected(S43, std::string{"OK"}));\
|
||||
test(ex, make_expected(S44, std::optional<std::string>{""}));\
|
||||
test(ex, make_expected(S44, std::string{""}));\
|
||||
test(ex, make_expected(S45, int{}, aedis::error::invalid_data_type));\
|
||||
test(ex, make_expected(S46, int{11}, aedis::error::not_a_number));\
|
||||
test(ex, make_expected(S47, map_type{}, aedis::error::not_a_number));\
|
||||
test(ex, make_expected(S48, std::string{}, aedis::error::not_a_number));\
|
||||
test(ex, make_expected(S49, std::string{}, aedis::error::not_a_number));\
|
||||
test(ex, make_expected(S50, int{}, aedis::error::empty_field));\
|
||||
test(ex, make_expected(S51, std::optional<bool>{}, aedis::error::empty_field));\
|
||||
test(ex, make_expected(S52, std::string{}, aedis::error::empty_field));\
|
||||
test(ex, make_expected(S53, node_type{resp3::type::blob_string, 1UL, 0UL, {"hh"}}));\
|
||||
test(ex, make_expected(S54, node_type{resp3::type::blob_string, 1UL, 0UL, {"hhaa\aaaa\raaaaa\r\naaaaaaaaaa"}}));\
|
||||
test(ex, make_expected(S55, node_type{resp3::type::blob_string, 1UL, 0UL, {}}));\
|
||||
test(ex, make_expected(S01a, std::optional<bool>{}, aedis::error::unexpected_bool_value)); \
|
||||
test(ex, make_expected(S01b, bool{false})); \
|
||||
test(ex, make_expected(S01b, node_type{resp3::type::boolean, 1UL, 0UL, {"f"}})); \
|
||||
test(ex, make_expected(S01c, bool{true})); \
|
||||
test(ex, make_expected(S01c, node_type{resp3::type::boolean, 1UL, 0UL, {"t"}})); \
|
||||
test(ex, make_expected(S01c, op_bool_ok)); \
|
||||
test(ex, make_expected(S01c, std::map<int, int>{}, aedis::error::expects_resp3_map)); \
|
||||
test(ex, make_expected(S01c, std::set<int>{}, aedis::error::expects_resp3_set)); \
|
||||
test(ex, make_expected(S01c, std::unordered_map<int, int>{}, aedis::error::expects_resp3_map)); \
|
||||
test(ex, make_expected(S01c, std::unordered_set<int>{}, aedis::error::expects_resp3_set)); \
|
||||
test(ex, make_expected(S02a, streamed_string_e2)); \
|
||||
test(ex, make_expected(S03a, int{}, aedis::error::expects_resp3_simple_type));\
|
||||
test(ex, make_expected(S03a, std::optional<int>{}, aedis::error::expects_resp3_simple_type));; \
|
||||
test(ex, make_expected(S02b, int{}, aedis::error::not_a_number)); \
|
||||
test(ex, make_expected(S02b, std::string{"Hello word"})); \
|
||||
test(ex, make_expected(S02b, streamed_string_e1)); \
|
||||
test(ex, make_expected(S02c, std::string{}, aedis::error::not_a_number)); \
|
||||
test(ex, make_expected(S04a, std::tuple<int>{11})); \
|
||||
test(ex, make_expected(S05a, node_type{resp3::type::number, 1UL, 0UL, {"-3"}})); \
|
||||
test(ex, make_expected(S05b, int{11})); \
|
||||
test(ex, make_expected(S05b, op_int_ok)); \
|
||||
test(ex, make_expected(S05b, std::list<std::string>{}, aedis::error::expects_resp3_aggregate)); \
|
||||
test(ex, make_expected(S05b, std::map<std::string, std::string>{}, aedis::error::expects_resp3_map)); \
|
||||
test(ex, make_expected(S05b, std::set<std::string>{}, aedis::error::expects_resp3_set)); \
|
||||
test(ex, make_expected(S05b, std::unordered_map<std::string, std::string>{}, aedis::error::expects_resp3_map)); \
|
||||
test(ex, make_expected(S05b, std::unordered_set<std::string>{}, aedis::error::expects_resp3_set)); \
|
||||
test(ex, make_expected(s05c, array_type2{}, aedis::error::expects_resp3_aggregate));\
|
||||
test(ex, make_expected(s05c, node_type{resp3::type::number, 1UL, 0UL, {"3"}})); \
|
||||
test(ex, make_expected(S06a, array_type{}, aedis::error::resp3_null));\
|
||||
test(ex, make_expected(S06a, int{0}, aedis::error::resp3_null)); \
|
||||
test(ex, make_expected(S06a, map_type{}, aedis::error::resp3_null));\
|
||||
test(ex, make_expected(S06a, op_type_01{}));\
|
||||
test(ex, make_expected(S06a, op_type_02{}));\
|
||||
test(ex, make_expected(S06a, op_type_03{}));\
|
||||
test(ex, make_expected(S06a, op_type_04{}));\
|
||||
test(ex, make_expected(S06a, op_type_05{}));\
|
||||
test(ex, make_expected(S06a, op_type_06{}));\
|
||||
test(ex, make_expected(S06a, op_type_07{}));\
|
||||
test(ex, make_expected(S06a, op_type_08{}));\
|
||||
test(ex, make_expected(S06a, op_type_09{}));\
|
||||
test(ex, make_expected(S06a, std::list<int>{}, aedis::error::resp3_null));\
|
||||
test(ex, make_expected(S06a, std::vector<int>{}, aedis::error::resp3_null));\
|
||||
test(ex, make_expected(S07a, push_e1a)); \
|
||||
test(ex, make_expected(S07b, push_e1b)); \
|
||||
test(ex, make_expected(S04b, map_type{}, aedis::error::expects_resp3_map));\
|
||||
test(ex, make_expected(S03b, map_e1f));\
|
||||
test(ex, make_expected(S03b, map_e1g));\
|
||||
test(ex, make_expected(S03b, map_e1k));\
|
||||
test(ex, make_expected(S03b, map_e1l));\
|
||||
test(ex, make_expected(S03b, map_expected_1a));\
|
||||
test(ex, make_expected(S03b, map_expected_1b));\
|
||||
test(ex, make_expected(S03b, map_expected_1c));\
|
||||
test(ex, make_expected(S03b, map_expected_1d));\
|
||||
test(ex, make_expected(S03b, map_expected_1e));\
|
||||
test(ex, make_expected(S04c, std::tuple<op_map_type>{map_expected_1d}));\
|
||||
test(ex, make_expected(S08a, attr_e1a)); \
|
||||
test(ex, make_expected(S08b, attr_e1b)); \
|
||||
test(ex, make_expected(S04e, array_e1a));\
|
||||
test(ex, make_expected(S04e, array_e1b));\
|
||||
test(ex, make_expected(S04e, array_e1c));\
|
||||
test(ex, make_expected(S04e, array_e1f));\
|
||||
test(ex, make_expected(S04e, array_e1g));\
|
||||
test(ex, make_expected(S04e, array_e1h));\
|
||||
test(ex, make_expected(S04e, array_type2{}, aedis::error::incompatible_size));\
|
||||
test(ex, make_expected(S04e, tuple_int_2{}, aedis::error::incompatible_size));\
|
||||
test(ex, make_expected(S04f, array_type2{}, aedis::error::nested_aggregate_not_supported));\
|
||||
test(ex, make_expected(S04g, vec_node_type{}, aedis::error::exceeeds_max_nested_depth));\
|
||||
test(ex, make_expected(S04h, array_e1d));\
|
||||
test(ex, make_expected(S04h, array_e1e));\
|
||||
test(ex, make_expected(S04i, set_type{}, aedis::error::expects_resp3_set)); \
|
||||
test(ex, make_expected(S09a, set_e1c)); \
|
||||
test(ex, make_expected(S09a, set_e1d)); \
|
||||
test(ex, make_expected(S09a, set_e1f)); \
|
||||
test(ex, make_expected(S09a, set_e1g)); \
|
||||
test(ex, make_expected(S09a, set_expected1a)); \
|
||||
test(ex, make_expected(S09a, set_expected_1e)); \
|
||||
test(ex, make_expected(S09a, set_type{"apple", "one", "orange", "three", "two"})); \
|
||||
test(ex, make_expected(S04d, std::tuple<uset_type>{set_e1c})); \
|
||||
test(ex, make_expected(S09b, std::vector<node_type>{ {resp3::type::set, 0UL, 0UL, {}} })); \
|
||||
test(ex, make_expected(S10a, aedis::ignore{}, aedis::error::resp3_simple_error)); \
|
||||
test(ex, make_expected(S10a, node_type{resp3::type::simple_error, 1UL, 0UL, {"Error"}}, aedis::error::resp3_simple_error)); \
|
||||
test(ex, make_expected(S10b, node_type{resp3::type::simple_error, 1UL, 0UL, {""}}, aedis::error::resp3_simple_error)); \
|
||||
test(ex, make_expected(S03c, map_type{}));\
|
||||
test(ex, make_expected(S11a, node_type{resp3::type::doublean, 1UL, 0UL, {"1.23"}}));\
|
||||
test(ex, make_expected(S11b, node_type{resp3::type::doublean, 1UL, 0UL, {"inf"}}));\
|
||||
test(ex, make_expected(S11c, node_type{resp3::type::doublean, 1UL, 0UL, {"-inf"}}));\
|
||||
test(ex, make_expected(S11d, double{1.23}));\
|
||||
test(ex, make_expected(S11e, double{0}, aedis::error::not_a_double));\
|
||||
test(ex, make_expected(S12a, node_type{resp3::type::blob_error, 1UL, 0UL, {"SYNTAX invalid syntax"}}, aedis::error::resp3_blob_error));\
|
||||
test(ex, make_expected(S12b, node_type{resp3::type::blob_error, 1UL, 0UL, {}}, aedis::error::resp3_blob_error));\
|
||||
test(ex, make_expected(S12c, aedis::ignore{}, aedis::error::resp3_blob_error));\
|
||||
test(ex, make_expected(S13a, node_type{resp3::type::verbatim_string, 1UL, 0UL, {"txt:Some string"}}));\
|
||||
test(ex, make_expected(S13b, node_type{resp3::type::verbatim_string, 1UL, 0UL, {}}));\
|
||||
test(ex, make_expected(S14a, node_type{resp3::type::big_number, 1UL, 0UL, {"3492890328409238509324850943850943825024385"}}));\
|
||||
test(ex, make_expected(S14b, int{}, aedis::error::empty_field));\
|
||||
test(ex, make_expected(S15a, std::optional<std::string>{"OK"}));\
|
||||
test(ex, make_expected(S15a, std::string{"OK"}));\
|
||||
test(ex, make_expected(S15b, std::optional<std::string>{""}));\
|
||||
test(ex, make_expected(S15b, std::string{""}));\
|
||||
test(ex, make_expected(S16a, int{}, aedis::error::invalid_data_type));\
|
||||
test(ex, make_expected(S05d, int{11}, aedis::error::not_a_number));\
|
||||
test(ex, make_expected(S03d, map_type{}, aedis::error::not_a_number));\
|
||||
test(ex, make_expected(S02d, std::string{}, aedis::error::not_a_number));\
|
||||
test(ex, make_expected(S17a, std::string{}, aedis::error::not_a_number));\
|
||||
test(ex, make_expected(S05e, int{}, aedis::error::empty_field));\
|
||||
test(ex, make_expected(S01d, std::optional<bool>{}, aedis::error::empty_field));\
|
||||
test(ex, make_expected(S11f, std::string{}, aedis::error::empty_field));\
|
||||
test(ex, make_expected(S17b, node_type{resp3::type::blob_string, 1UL, 0UL, {"hh"}}));\
|
||||
test(ex, make_expected(S18c, node_type{resp3::type::blob_string, 1UL, 0UL, {"hhaa\aaaa\raaaaa\r\naaaaaaaaaa"}}));\
|
||||
test(ex, make_expected(S18d, node_type{resp3::type::blob_string, 1UL, 0UL, {}}));\
|
||||
test(ex, make_expected(make_blob_string(blob), node_type{resp3::type::blob_string, 1UL, 0UL, {blob}}));\
|
||||
|
||||
BOOST_AUTO_TEST_CASE(parser)
|
||||
@@ -489,7 +505,7 @@ BOOST_AUTO_TEST_CASE(ignore_adapter_simple_error)
|
||||
boost::system::error_code ec;
|
||||
|
||||
test_stream ts {ioc};
|
||||
ts.append(S28);
|
||||
ts.append(S10a);
|
||||
resp3::read(ts, net::dynamic_buffer(rbuffer), adapt2(), ec);
|
||||
BOOST_CHECK_EQUAL(ec, aedis::error::resp3_simple_error);
|
||||
BOOST_TEST(!rbuffer.empty());
|
||||
@@ -502,7 +518,7 @@ BOOST_AUTO_TEST_CASE(ignore_adapter_blob_error)
|
||||
boost::system::error_code ec;
|
||||
|
||||
test_stream ts {ioc};
|
||||
ts.append(S36);
|
||||
ts.append(S12a);
|
||||
resp3::read(ts, net::dynamic_buffer(rbuffer), adapt2(), ec);
|
||||
BOOST_CHECK_EQUAL(ec, aedis::error::resp3_blob_error);
|
||||
BOOST_TEST(!rbuffer.empty());
|
||||
@@ -515,7 +531,7 @@ BOOST_AUTO_TEST_CASE(ignore_adapter_no_error)
|
||||
boost::system::error_code ec;
|
||||
|
||||
test_stream ts {ioc};
|
||||
ts.append(S10);
|
||||
ts.append(S05b);
|
||||
resp3::read(ts, net::dynamic_buffer(rbuffer), adapt2(), ec);
|
||||
BOOST_TEST(!ec);
|
||||
BOOST_TEST(rbuffer.empty());
|
||||
|
||||
Reference in New Issue
Block a user