/* Copyright (c) 2019 Marcelo Zimbres Silva (mzimbres at gmail dot com) * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ #include "aedis.hpp" using namespace aedis; void check_size( std::vector const& v, unsigned s, std::string msg) { if (std::size(v) != s) throw std::runtime_error(msg); msg += "size ok."; std::cout << msg << std::endl; } void check_string( std::string const& a, std::string const& b, std::string msg) { if (a != b) throw std::runtime_error(msg); msg += "string ok."; std::cout << msg << std::endl; } template void check_equal( Iter1 begin1, Iter1 end1, Iter2 begin2, std::string msg) { auto const r = std::equal( begin1 , end1 , begin2); if (!r) throw std::runtime_error(msg); msg += "equal ok."; std::cout << msg << std::endl; } void rpush_lrange() { session::sentinel_config scfg {{ "127.0.0.1", "26377" , "127.0.0.1", "26378" , "127.0.0.1", "26379" } , "mymaster" // Instance name , "master" // Instance role }; session::config cfg { scfg , 4 , log::level::info }; net::io_context ioc; session ss {ioc, cfg}; std::array a {"a1", "a2", "a3"}; auto s = flushall() + rpush("a", a) + lrange("a") + ping(); auto const cycle = 4; auto const repeat = 32; for (auto i = 0; i < repeat; ++i) ss.send(s); auto const size = repeat * cycle; auto handler = [&, size, i = 0](auto ec, auto res) mutable { if (ec) { std::cerr << "Error: " << ec.message() << std::endl; return; } std::string const prefix = "Test: "; auto const f = i % cycle; switch (f) { case 0: { check_size(res, 1, prefix); check_string(res.front(), "OK", prefix); } break; case 1: { check_size(res, 1, prefix); check_string(res.front(), "3", prefix); } break; case 2: { check_equal( std::cbegin(res) , std::cend(res) , std::cbegin(a) , prefix); } break; case 3: { check_size(res, 1, prefix); check_string(res.front(), "PONG", prefix); if (i == size - 1) { ss.send(quit()); ss.disable_reconnect(); } } } ++i; }; ss.set_msg_handler(handler); ss.run(); ioc.run(); } struct initiate_async_receive { using executor_type = net::system_executor; std::string const& payload; executor_type get_executor() noexcept { return net::system_executor(); } template < class ReadHandler, class MutableBufferSequence> void operator()(ReadHandler&& handler, MutableBufferSequence const& buffers) const { boost::system::error_code ec; if (std::size(buffers) == 0) { handler(ec, 0); return; } assert(std::size(buffers) != 0); auto begin = boost::asio::buffer_sequence_begin(buffers); assert(std::size(payload) <= std::size(*begin)); char* p = static_cast(begin->data()); std::copy(std::begin(payload), std::end(payload), p); handler(ec, std::size(payload)); } }; struct test_stream { std::string const& payload; using executor_type = net::system_executor; template< class MutableBufferSequence, class ReadHandler = net::default_completion_token_t > void async_read_some( MutableBufferSequence const& buffers, ReadHandler&& handler) { return net::async_initiate( initiate_async_receive{payload}, handler, buffers); } executor_type get_executor() noexcept { return net::system_executor(); } }; struct test_handler { void operator()(boost::system::error_code ec) const { if (ec) std::cout << ec.message() << std::endl; } }; void send(std::string cmd) { net::io_context ioc; session s {ioc}; s.send(std::move(cmd)); s.disable_reconnect(); s.run(); ioc.run(); } void test5() { net::io_context ioc {1}; tcp::socket socket {ioc}; sentinel_op2::config cfg { {"127.0.0.1", "26377", "127.0.0.1", "26378", "127.0.0.1", "26379"} , {"mymaster"} , {"master"} }; instance inst; auto f = [&](auto ec) { instance expected {"127.0.0.1", "6379", "mymaster"}; if (inst == expected) std::cout << "Success: async_get_instance2" << std::endl; else std::cout << "Error: async_get_instance2" << std::endl; }; async_get_instance2(socket, cfg, inst, f); ioc.run(); } int offline() { // Redis answer - Expected vector. std::vector>> payloads { {{"+OK\r\n"}, {"OK"}} , {{":3\r\n"}, {"3"}} , {{"*3\r\n$3\r\none\r\n$3\r\ntwo\r\n$5\r\nthree\r\n"}, {"one", "two", "three"}} , {{"$2\r\nhh\r\n"}, {"hh"}} , {{"-Error\r\n"}, {"Error"}} }; for (auto const& e : payloads) { test_stream ts {e.first}; resp::buffer buffer; resp::response res; async_read(ts, buffer, res, test_handler {}); if (e.second != res.res) std::cout << "Error" << std::endl; else std::cout << "Success: Offline tests." << std::endl; } } int main(int argc, char* argv[]) { //rpush_lrange(); //test5(); //offline(); send(ping()); }