mirror of
https://github.com/boostorg/redis.git
synced 2026-01-19 04:42:09 +00:00
Adds support for PUNSUBSCRIBE (#339)
Adds a test covering UNSUBSCRIBE and PUNSUBSCRIBE close #306
This commit is contained in:
committed by
GitHub
parent
0460b38e14
commit
6791e759f9
@@ -68,3 +68,19 @@ void run_coroutine_test(net::awaitable<void> op, std::chrono::steady_clock::dura
|
||||
throw std::runtime_error("Coroutine test did not finish");
|
||||
}
|
||||
#endif // BOOST_ASIO_HAS_CO_AWAIT
|
||||
|
||||
// Finds a value in the output of the CLIENT INFO command
|
||||
// format: key1=value1 key2=value2
|
||||
// TODO: duplicated
|
||||
std::string_view find_client_info(std::string_view client_info, std::string_view key)
|
||||
{
|
||||
std::string prefix{key};
|
||||
prefix += '=';
|
||||
|
||||
auto const pos = client_info.find(prefix);
|
||||
if (pos == std::string_view::npos)
|
||||
return {};
|
||||
auto const pos_begin = pos + prefix.size();
|
||||
auto const pos_end = client_info.find(' ', pos_begin);
|
||||
return client_info.substr(pos_begin, pos_end - pos_begin);
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
|
||||
#include <chrono>
|
||||
#include <memory>
|
||||
#include <string_view>
|
||||
|
||||
// The timeout for tests involving communication to a real server.
|
||||
// Some tests use a longer timeout by multiplying this value by some
|
||||
@@ -35,3 +36,7 @@ void run(
|
||||
boost::redis::config cfg = make_test_config(),
|
||||
boost::system::error_code ec = boost::asio::error::operation_aborted,
|
||||
boost::redis::operation op = boost::redis::operation::receive);
|
||||
|
||||
// Finds a value in the output of the CLIENT INFO command
|
||||
// format: key1=value1 key2=value2
|
||||
std::string_view find_client_info(std::string_view client_info, std::string_view key);
|
||||
|
||||
@@ -6,10 +6,14 @@
|
||||
|
||||
#include <boost/redis/connection.hpp>
|
||||
#include <boost/redis/logger.hpp>
|
||||
#include <boost/redis/request.hpp>
|
||||
#include <boost/redis/response.hpp>
|
||||
|
||||
#include <boost/asio/experimental/channel_error.hpp>
|
||||
#include <boost/system/errc.hpp>
|
||||
|
||||
#include <string>
|
||||
|
||||
#define BOOST_TEST_MODULE conn_push
|
||||
#include <boost/test/included/unit_test.hpp>
|
||||
|
||||
@@ -327,4 +331,71 @@ BOOST_AUTO_TEST_CASE(many_subscribers)
|
||||
BOOST_TEST(finished);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(test_unsubscribe)
|
||||
{
|
||||
net::io_context ioc;
|
||||
connection conn{ioc};
|
||||
|
||||
// Subscribe to 3 channels and 2 patterns. Use CLIENT INFO to verify this took effect
|
||||
request req_subscribe;
|
||||
req_subscribe.push("SUBSCRIBE", "ch1", "ch2", "ch3");
|
||||
req_subscribe.push("PSUBSCRIBE", "ch1*", "ch2*");
|
||||
req_subscribe.push("CLIENT", "INFO");
|
||||
|
||||
// Then, unsubscribe from some of them, and verify again
|
||||
request req_unsubscribe;
|
||||
req_unsubscribe.push("UNSUBSCRIBE", "ch1");
|
||||
req_unsubscribe.push("PUNSUBSCRIBE", "ch2*");
|
||||
req_unsubscribe.push("CLIENT", "INFO");
|
||||
|
||||
// Finally, ping to verify that the connection is still usable
|
||||
request req_ping;
|
||||
req_ping.push("PING", "test_unsubscribe");
|
||||
|
||||
response<std::string> resp_subscribe, resp_unsubscribe, resp_ping;
|
||||
|
||||
bool subscribe_finished = false, unsubscribe_finished = false, ping_finished = false,
|
||||
run_finished = false;
|
||||
|
||||
auto on_ping = [&](error_code ec, std::size_t) {
|
||||
BOOST_TEST(ec == error_code());
|
||||
ping_finished = true;
|
||||
BOOST_TEST(std::get<0>(resp_ping).has_value());
|
||||
BOOST_TEST(std::get<0>(resp_ping).value() == "test_unsubscribe");
|
||||
conn.cancel();
|
||||
};
|
||||
|
||||
auto on_unsubscribe = [&](error_code ec, std::size_t) {
|
||||
unsubscribe_finished = true;
|
||||
BOOST_TEST(ec == error_code());
|
||||
BOOST_TEST(std::get<0>(resp_unsubscribe).has_value());
|
||||
BOOST_TEST(find_client_info(std::get<0>(resp_unsubscribe).value(), "sub") == "2");
|
||||
BOOST_TEST(find_client_info(std::get<0>(resp_unsubscribe).value(), "psub") == "1");
|
||||
conn.async_exec(req_ping, resp_ping, on_ping);
|
||||
};
|
||||
|
||||
auto on_subscribe = [&](error_code ec, std::size_t) {
|
||||
subscribe_finished = true;
|
||||
BOOST_TEST(ec == error_code());
|
||||
BOOST_TEST(std::get<0>(resp_subscribe).has_value());
|
||||
BOOST_TEST(find_client_info(std::get<0>(resp_subscribe).value(), "sub") == "3");
|
||||
BOOST_TEST(find_client_info(std::get<0>(resp_subscribe).value(), "psub") == "2");
|
||||
conn.async_exec(req_unsubscribe, resp_unsubscribe, on_unsubscribe);
|
||||
};
|
||||
|
||||
conn.async_exec(req_subscribe, resp_subscribe, on_subscribe);
|
||||
|
||||
conn.async_run(make_test_config(), [&run_finished](error_code ec) {
|
||||
BOOST_TEST(ec == net::error::operation_aborted);
|
||||
run_finished = true;
|
||||
});
|
||||
|
||||
ioc.run_for(test_timeout);
|
||||
|
||||
BOOST_TEST(subscribe_finished);
|
||||
BOOST_TEST(unsubscribe_finished);
|
||||
BOOST_TEST(ping_finished);
|
||||
BOOST_TEST(run_finished);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
@@ -29,21 +29,6 @@ using boost::system::error_code;
|
||||
|
||||
namespace {
|
||||
|
||||
// Finds a value in the output of the CLIENT INFO command
|
||||
// format: key1=value1 key2=value2
|
||||
std::string_view find_client_info(std::string_view client_info, std::string_view key)
|
||||
{
|
||||
std::string prefix{key};
|
||||
prefix += '=';
|
||||
|
||||
auto const pos = client_info.find(prefix);
|
||||
if (pos == std::string_view::npos)
|
||||
return {};
|
||||
auto const pos_begin = pos + prefix.size();
|
||||
auto const pos_end = client_info.find(' ', pos_begin);
|
||||
return client_info.substr(pos_begin, pos_end - pos_begin);
|
||||
}
|
||||
|
||||
// Creates a user with a known password. Harmless if the user already exists
|
||||
void setup_password()
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user