|
| 1 | +#include <boost/asio.hpp> |
| 2 | +#include <future> |
| 3 | + |
| 4 | +#include "EmptyPort.hpp" |
| 5 | +#include "TestServer.hpp" |
| 6 | +#include "catch.hpp" |
| 7 | + |
| 8 | +#include "bredis/Connection.hpp" |
| 9 | +#include "bredis/MarkerHelpers.hpp" |
| 10 | + |
| 11 | +#include "bredis/Extract.hpp" |
| 12 | + |
| 13 | + |
| 14 | +#include "SocketWithLogging.hpp" |
| 15 | + |
| 16 | +namespace r = bredis; |
| 17 | +namespace asio = boost::asio; |
| 18 | +namespace ep = empty_port; |
| 19 | +namespace ts = test_server; |
| 20 | + |
| 21 | +TEST_CASE("stream", "[connection]") { |
| 22 | + using socket_t = asio::ip::tcp::socket; |
| 23 | +#ifdef BREDIS_DEBUG |
| 24 | + using next_layer_t = r::test::SocketWithLogging<socket_t>; |
| 25 | +#else |
| 26 | + using next_layer_t = socket_t; |
| 27 | +#endif |
| 28 | + using Buffer = boost::asio::streambuf; |
| 29 | + using Iterator = typename r::to_iterator<Buffer>::iterator_t; |
| 30 | + using Extractor = r::extractor<Iterator>; |
| 31 | + |
| 32 | + std::chrono::milliseconds sleep_delay(1); |
| 33 | + |
| 34 | + uint16_t port = ep::get_random<ep::Kind::TCP>(); |
| 35 | + auto port_str = boost::lexical_cast<std::string>(port); |
| 36 | + auto server = ts::make_server({"redis-server", "--port", port_str}); |
| 37 | + ep::wait_port<ep::Kind::TCP>(port); |
| 38 | + asio::io_service io_service; |
| 39 | + |
| 40 | + asio::ip::tcp::endpoint end_point( |
| 41 | + asio::ip::address::from_string("127.0.0.1"), port); |
| 42 | + socket_t socket(io_service, end_point.protocol()); |
| 43 | + socket.connect(end_point); |
| 44 | + |
| 45 | + r::Connection<next_layer_t> c(std::move(socket)); |
| 46 | + |
| 47 | + Buffer rx_buff; |
| 48 | + c.write(r::single_command_t{ "INFO" }); |
| 49 | + auto parse_result0 = c.read(rx_buff); |
| 50 | + auto extract0 = boost::apply_visitor(Extractor(), parse_result0.result); |
| 51 | + auto info = boost::get<r::extracts::string_t>(extract0); |
| 52 | + rx_buff.consume(parse_result0.consumed); |
| 53 | + auto it_begin = info.str.begin(); |
| 54 | + auto it_end = info.str.end(); |
| 55 | + std::string version_str = "redis_version:5."; |
| 56 | + if (info.str.find("redis_version:5.") == std::string::npos) { |
| 57 | + /* not supported by earlier redis versions */ |
| 58 | + return; |
| 59 | + } |
| 60 | + |
| 61 | + |
| 62 | + c.write(r::single_command_t{ "XADD", "mystream", "*", "cpu-temp", "23.4", "load", "2.3" }); |
| 63 | + auto parse_result1 = c.read(rx_buff); |
| 64 | + auto extract1 = boost::apply_visitor(Extractor(), parse_result1.result); |
| 65 | + auto id1 = boost::get<r::extracts::string_t>(extract1); |
| 66 | + rx_buff.consume(parse_result1.consumed); |
| 67 | + |
| 68 | + c.write(r::single_command_t{ "XADD", "mystream", "*", "cpu-temp", "23.2", "load", "2.1" }); |
| 69 | + auto parse_result2 = c.read(rx_buff); |
| 70 | + auto extract2 = boost::apply_visitor(Extractor(), parse_result2.result); |
| 71 | + auto id2 = boost::get<r::extracts::string_t>(extract2); |
| 72 | + rx_buff.consume(parse_result2.consumed); |
| 73 | + |
| 74 | + c.write(r::single_command_t{ "XRANGE" , "mystream", id1.str, id2.str}); |
| 75 | + auto parse_result3 = c.read(rx_buff); |
| 76 | + auto extract3 = boost::apply_visitor(Extractor(), parse_result3.result); |
| 77 | + rx_buff.consume(parse_result3.consumed); |
| 78 | + |
| 79 | + auto& outer_arr = boost::get<r::extracts::array_holder_t>(extract3); |
| 80 | + auto& inner_arr1 = boost::get<r::extracts::array_holder_t>(outer_arr.elements[0]); |
| 81 | + auto& inner_arr2 = boost::get<r::extracts::array_holder_t>(outer_arr.elements[1]); |
| 82 | + |
| 83 | + REQUIRE(boost::get<r::extracts::string_t>(inner_arr1.elements[0]).str == id1.str); |
| 84 | + auto& arr1 = boost::get<r::extracts::array_holder_t>(inner_arr1.elements[1]); |
| 85 | + REQUIRE(boost::get<r::extracts::string_t>(arr1.elements[0]).str == "cpu-temp"); |
| 86 | + REQUIRE(boost::get<r::extracts::string_t>(arr1.elements[1]).str == "23.4"); |
| 87 | + REQUIRE(boost::get<r::extracts::string_t>(arr1.elements[2]).str == "load"); |
| 88 | + REQUIRE(boost::get<r::extracts::string_t>(arr1.elements[3]).str == "2.3"); |
| 89 | + |
| 90 | + REQUIRE(boost::get<r::extracts::string_t>(inner_arr2.elements[0]).str == id2.str); |
| 91 | + auto& arr2 = boost::get<r::extracts::array_holder_t>(inner_arr2.elements[1]); |
| 92 | + REQUIRE(boost::get<r::extracts::string_t>(arr2.elements[0]).str == "cpu-temp"); |
| 93 | + REQUIRE(boost::get<r::extracts::string_t>(arr2.elements[1]).str == "23.2"); |
| 94 | + REQUIRE(boost::get<r::extracts::string_t>(arr2.elements[2]).str == "load"); |
| 95 | + REQUIRE(boost::get<r::extracts::string_t>(arr2.elements[3]).str == "2.1"); |
| 96 | +}; |
0 commit comments