static void recv_size_err_callback_check_fn( atbus::channel::io_stream_channel* channel, // 事件触发的channel atbus::channel::io_stream_connection* connection, // 事件触发的连接 int status, // libuv传入的转态码 void* input, // 额外参数(不同事件不同含义) size_t s // 额外参数长度 ) { CASE_EXPECT_NE(NULL, channel); CASE_EXPECT_NE(NULL, connection); if (EN_ATBUS_ERR_INVALID_SIZE == status) { CASE_EXPECT_NE(NULL, input); CASE_EXPECT_EQ(EN_ATBUS_ERR_INVALID_SIZE, status); CASE_EXPECT_EQ(0, channel->error_code); } else if (EN_ATBUS_ERR_READ_FAILED == status) { CASE_EXPECT_EQ(NULL, input); CASE_EXPECT_EQ(EN_ATBUS_ERR_READ_FAILED, status); CASE_EXPECT_TRUE(UV_ECONNRESET == channel->error_code || UV_EOF == channel->error_code); } else { CASE_EXPECT_TRUE(EN_ATBUS_ERR_INVALID_SIZE == status || EN_ATBUS_ERR_READ_FAILED == status); } ++g_check_flag; }
static int node_reg_test_add_endpoint_fn(const atbus::node& n, atbus::endpoint* ep, int) { ++recv_msg_history.add_endpoint_count; CASE_EXPECT_NE(NULL, ep); CASE_EXPECT_NE(n.get_self_endpoint(), ep); return 0; }
CASE_TEST(coroutine_task, custom_action) { typedef std::shared_ptr< cotask::task<> > task_ptr_type; cotask::task<>::action_ptr_t action = cotask::task<>::action_ptr_t(new test_context_task_action()); task_ptr_type co_task = cotask::task<>::create(action); task_ptr_type co_another_task = cotask::task<>::create(action); // share action g_test_coroutine_task_status = 0; CASE_EXPECT_EQ(0, co_task->start()); CASE_EXPECT_EQ(g_test_coroutine_task_status, 1); CASE_EXPECT_FALSE(co_task->is_completed()); CASE_EXPECT_EQ(0, co_another_task->start()); CASE_EXPECT_EQ(g_test_coroutine_task_status, 2); CASE_EXPECT_EQ(0, co_task->resume()); CASE_EXPECT_EQ(g_test_coroutine_task_status, 3); CASE_EXPECT_EQ(0, co_another_task->resume()); CASE_EXPECT_EQ(g_test_coroutine_task_status, 4); CASE_EXPECT_TRUE(co_task->is_completed()); CASE_EXPECT_TRUE(co_another_task->is_completed()); CASE_EXPECT_GT(0, co_another_task->resume()); CASE_EXPECT_EQ(g_test_coroutine_task_status, 4); ++ g_test_coroutine_task_status; CASE_EXPECT_EQ(g_test_coroutine_task_status, 5); CASE_EXPECT_NE(co_task->get_id(), 0); }
static void listen_callback_test_fn( atbus::channel::io_stream_channel* channel, // 事件触发的channel atbus::channel::io_stream_connection* connection, // 事件触发的连接 int status, // libuv传入的转态码 void*, // 额外参数(不同事件不同含义) size_t s // 额外参数长度 ) { CASE_EXPECT_NE(NULL, channel); CASE_EXPECT_NE(NULL, connection); CASE_EXPECT_EQ(0, status); CASE_EXPECT_EQ(0, channel->error_code); // listen accepted event connection->evt.callbacks[atbus::channel::io_stream_callback_evt_t::EN_FN_ACCEPTED] = accepted_callback_test_fn; ++g_check_flag; }
CASE_TEST(buffer, buffer_block) { // size align CASE_EXPECT_EQ( atbus::detail::buffer_block::full_size(99), atbus::detail::buffer_block::head_size(99) + atbus::detail::buffer_block::padding_size(99) ); // malloc char buf[4 * 1024] = {0}; atbus::detail::buffer_block* p = atbus::detail::buffer_block::malloc(99); CASE_EXPECT_NE(NULL, p); CASE_EXPECT_EQ(99, p->size()); // size and size extend protect p->pop(50); CASE_EXPECT_EQ(49, p->size()); CASE_EXPECT_EQ(99, p->raw_size()); CASE_EXPECT_EQ(atbus::detail::fn::buffer_next(p->raw_data(), 50), p->data()); CASE_EXPECT_NE(p->raw_data(), p->data()); p->pop(100); CASE_EXPECT_EQ(0, p->size()); CASE_EXPECT_EQ(atbus::detail::fn::buffer_next(p->raw_data(), 99), p->data()); atbus::detail::buffer_block::free(p); // failed void* next_free = atbus::detail::buffer_block::create(buf, 256, 256); CASE_EXPECT_EQ(NULL, next_free); for (size_t i = 0; i < sizeof(atbus::detail::buffer_block); ++ i) { CASE_EXPECT_EQ(buf[i], 0); } // data bound size_t fs = atbus::detail::buffer_block::full_size(256); next_free = atbus::detail::buffer_block::create(buf, sizeof(buf), 256); p = reinterpret_cast<atbus::detail::buffer_block*>(buf); CASE_EXPECT_EQ(atbus::detail::fn::buffer_next(p->raw_data(), 256), next_free); CASE_EXPECT_EQ(atbus::detail::fn::buffer_next(buf, fs), next_free); memset(p->data(), -1, p->size()); CASE_EXPECT_EQ(buf[fs], 0); CASE_EXPECT_EQ(buf[fs - 1], -1); }
// reset by peer(client) CASE_TEST(channel, io_stream_tcp_reset_by_client) { atbus::channel::io_stream_channel svr, cli; atbus::channel::io_stream_init(&svr, NULL, NULL); atbus::channel::io_stream_init(&cli, NULL, NULL); svr.evt.callbacks[atbus::channel::io_stream_callback_evt_t::EN_FN_DISCONNECTED] = disconnected_callback_test_fn; int check_flag = g_check_flag = 0; int inited_fds = 0; inited_fds += setup_channel(svr, "ipv6://:::16387", NULL); CASE_EXPECT_EQ(1, g_check_flag); CASE_EXPECT_NE(NULL, svr.ev_loop); if (0 == inited_fds) { return; } inited_fds = 0; inited_fds += setup_channel(cli, NULL, "ipv4://127.0.0.1:16387"); inited_fds += setup_channel(cli, NULL, "dns://localhost:16387"); inited_fds += setup_channel(cli, NULL, "ipv6://::1:16387"); while (g_check_flag - check_flag < 2 * inited_fds + 1) { atbus::channel::io_stream_run(&svr, atbus::adapter::RUN_NOWAIT); atbus::channel::io_stream_run(&cli, atbus::adapter::RUN_NOWAIT); CASE_THREAD_SLEEP_MS(8); } CASE_EXPECT_NE(0, cli.conn_pool.size()); check_flag = g_check_flag; atbus::channel::io_stream_close(&cli); CASE_EXPECT_EQ(0, cli.conn_pool.size()); while (g_check_flag - check_flag < inited_fds) { atbus::channel::io_stream_run(&svr, atbus::adapter::RUN_NOWAIT); CASE_THREAD_SLEEP_MS(8); } CASE_EXPECT_EQ(1, svr.conn_pool.size()); atbus::channel::io_stream_close(&svr); CASE_EXPECT_EQ(0, svr.conn_pool.size()); }
static void recv_callback_check_fn( atbus::channel::io_stream_channel* channel, // 事件触发的channel atbus::channel::io_stream_connection* connection, // 事件触发的连接 int status, // libuv传入的转态码 void* input, // 额外参数(不同事件不同含义) size_t s // 额外参数长度 ) { CASE_EXPECT_NE(NULL, channel); CASE_EXPECT_NE(NULL, connection); if (status < 0) { CASE_EXPECT_EQ(NULL, input); CASE_EXPECT_EQ(0, s); CASE_EXPECT_TRUE(UV_EOF == channel->error_code || UV_ECONNRESET == channel->error_code); return; } CASE_EXPECT_NE(NULL, input); CASE_EXPECT_EQ(0, status); CASE_EXPECT_EQ(0, channel->error_code); CASE_EXPECT_FALSE(g_check_buff_sequence.empty()); if (g_check_buff_sequence.empty()) { return; } ++ g_recv_rec.first; g_recv_rec.second += s; CASE_EXPECT_EQ(s, g_check_buff_sequence.front().second); char* buff = get_test_buffer(); char* input_buff = reinterpret_cast<char*>(input); for (size_t i = 0; i < g_check_buff_sequence.front().second; ++ i) { CASE_EXPECT_EQ(buff[i + g_check_buff_sequence.front().first], input_buff[i]); if (buff[i + g_check_buff_sequence.front().first] != input_buff[i]) { break; } } g_check_buff_sequence.pop_front(); ++g_check_flag; }
static void node_reg_test_setup_exit(uv_loop_t* ev) { size_t left_tick = 128 * 30; // 30s while (left_tick > 0 && UV_EBUSY == uv_loop_close(ev)) { uv_run(ev, UV_RUN_NOWAIT); CASE_THREAD_SLEEP_MS(8); -- left_tick; } CASE_EXPECT_NE(left_tick, 0); }
static void connected_callback_test_fn( atbus::channel::io_stream_channel* channel, // 事件触发的channel atbus::channel::io_stream_connection* connection, // 事件触发的连接 int status, // libuv传入的转态码 void*, // 额外参数(不同事件不同含义) size_t s // 额外参数长度 ) { CASE_EXPECT_NE(NULL, channel); CASE_EXPECT_NE(NULL, connection); CASE_EXPECT_EQ(0, status); CASE_EXPECT_EQ(0, channel->error_code); if (0 != status) { CASE_MSG_INFO() << uv_err_name(channel->error_code) << ":"<< uv_strerror(channel->error_code) << std::endl; } else { CASE_MSG_INFO() << "connect to " << connection->addr.address<< " success" << std::endl; } ++g_check_flag; }
CASE_TEST(crypto_cipher, get_all_cipher_names) { #if defined(CRYPTO_USE_OPENSSL) || defined(CRYPTO_USE_LIBRESSL) || defined(CRYPTO_USE_BORINGSSL) if (!openssl_test_inited) { openssl_test_inited = std::make_shared<openssl_test_init_wrapper>(); } #endif const std::vector<std::string> &all_ciphers = util::crypto::cipher::get_all_cipher_names(); std::stringstream ss; for (size_t i = 0; i < all_ciphers.size(); ++i) { if (i) { ss << ","; } ss << all_ciphers[i]; } CASE_MSG_INFO() << "All ciphers: " << ss.str() << std::endl; CASE_EXPECT_NE(0, all_ciphers.size()); }
CASE_TEST(coroutine_task, functor_action) { typedef std::shared_ptr< cotask::task<> > task_ptr_type; task_ptr_type co_task = cotask::task<>::create(test_context_task_functor()); g_test_coroutine_task_status = 0; CASE_EXPECT_EQ(0, co_task->start()); ++ g_test_coroutine_task_status; CASE_EXPECT_EQ(g_test_coroutine_task_status, 2); CASE_EXPECT_FALSE(co_task->is_completed()); CASE_EXPECT_EQ(0, co_task->resume()); CASE_EXPECT_TRUE(co_task->is_completed()); ++ g_test_coroutine_task_status; CASE_EXPECT_EQ(g_test_coroutine_task_status, 4); CASE_EXPECT_NE(co_task->get_id(), 0); }
CASE_TEST(coroutine_task, mem_function_action) { typedef std::shared_ptr< cotask::task<> > task_ptr_type; test_context_task_mem_function obj; task_ptr_type co_task = cotask::task<>::create(&test_context_task_mem_function::real_run, &obj); g_test_coroutine_task_status = 0; obj.task_id_ = co_task->get_id(); CASE_EXPECT_EQ(0, co_task->start()); ++ g_test_coroutine_task_status; CASE_EXPECT_EQ(g_test_coroutine_task_status, 2); CASE_EXPECT_FALSE(co_task->is_completed()); CASE_EXPECT_EQ(0, co_task->resume()); CASE_EXPECT_TRUE(co_task->is_completed()); ++ g_test_coroutine_task_status; CASE_EXPECT_EQ(g_test_coroutine_task_status, 4); CASE_EXPECT_NE(co_task->get_coroutine_context().get_ret_code(), -1); }
static void connect_failed_callback_test_fn( atbus::channel::io_stream_channel* channel, // 事件触发的channel atbus::channel::io_stream_connection* connection, // 事件触发的连接 int status, // libuv传入的转态码 void*, // 额外参数(不同事件不同含义) size_t s // 额外参数长度 ) { CASE_EXPECT_NE(NULL, channel); CASE_EXPECT_EQ(NULL, connection); CASE_EXPECT_TRUE(EN_ATBUS_ERR_SOCK_CONNECT_FAILED == status || EN_ATBUS_ERR_DNS_GETADDR_FAILED == status); if (EN_ATBUS_ERR_SOCK_CONNECT_FAILED == status) { CASE_EXPECT_EQ(UV_ECONNREFUSED, channel->error_code); } else { CASE_EXPECT_EQ(UV_EAI_NONAME, channel->error_code); } if (0 != channel->error_code) { CASE_MSG_INFO() << uv_err_name(channel->error_code) << ":" << uv_strerror(channel->error_code) << std::endl; } ++g_check_flag; }
// 对父节点重连失败不会导致下线的流程测试 // 对父节点断线重连的流程测试 CASE_TEST(atbus_node_reg, reconnect_father_failed) { atbus::node::conf_t conf; atbus::node::default_conf(&conf); conf.children_mask = 16; uv_loop_t ev_loop; uv_loop_init(&ev_loop); conf.ev_loop = &ev_loop; // 只有发生冲突才会注册不成功,否则会无限重试注册父节点,直到其上线 { atbus::node::ptr_t node_parent = atbus::node::create(); atbus::node::ptr_t node_child = atbus::node::create(); node_parent->on_debug = node_reg_test_on_debug; node_child->on_debug = node_reg_test_on_debug; node_parent->init(0x12345678, &conf); conf.children_mask = 8; conf.father_address = "ipv4://127.0.0.1:16387"; node_child->init(0x12346789, &conf); node_child->set_on_shutdown_handle(node_test_on_shutdown); g_node_test_on_shutdown_check_reason = EN_ATBUS_ERR_ATNODE_INVALID_ID; CASE_EXPECT_EQ(EN_ATBUS_ERR_SUCCESS, node_parent->listen("ipv4://127.0.0.1:16387")); CASE_EXPECT_EQ(EN_ATBUS_ERR_SUCCESS, node_child->listen("ipv4://127.0.0.1:16388")); CASE_EXPECT_EQ(EN_ATBUS_ERR_SUCCESS, node_parent->start()); CASE_EXPECT_EQ(EN_ATBUS_ERR_SUCCESS, node_child->start()); time_t proc_t = time(NULL) + 1; // 先等连接成功 while (atbus::node::state_t::RUNNING != node_child->get_state()) { node_parent->proc(proc_t, 0); node_child->proc(proc_t, 0); CASE_THREAD_SLEEP_MS(8); uv_run(&ev_loop, UV_RUN_NOWAIT); ++ proc_t; } // 关闭父节点 node_parent->reset(); // 重连父节点,但是连接不成功也不会导致下线 // 连接过程中的转态变化 size_t retry_times = 0; while (atbus::node::state_t::RUNNING == node_child->get_state() || retry_times < 16) { proc_t += conf.retry_interval + 1; // node_parent->proc(proc_t, 0); node_child->proc(proc_t, 0); if (atbus::node::state_t::RUNNING != node_child->get_state()) { ++ retry_times; CASE_EXPECT_TRUE(atbus::node::state_t::LOST_PARENT == node_child->get_state() || atbus::node::state_t::CONNECTING_PARENT == node_child->get_state()); CASE_EXPECT_NE(atbus::node::state_t::CREATED, node_child->get_state()); CASE_EXPECT_NE(atbus::node::state_t::INITED, node_child->get_state()); } CASE_THREAD_SLEEP_MS(8); uv_run(&ev_loop, UV_RUN_NOWAIT); uv_run(&ev_loop, UV_RUN_NOWAIT); uv_run(&ev_loop, UV_RUN_NOWAIT); } // 父节点断线重连测试 // 子节点断线后重新注册测试 conf.children_mask = 16; conf.father_address = ""; node_parent->init(0x12345678, &conf); CASE_EXPECT_EQ(EN_ATBUS_ERR_SUCCESS, node_parent->listen("ipv4://127.0.0.1:16387")); CASE_EXPECT_EQ(EN_ATBUS_ERR_SUCCESS, node_parent->start()); while (atbus::node::state_t::RUNNING != node_child->get_state()) { proc_t += conf.retry_interval; node_parent->proc(proc_t, 0); node_child->proc(proc_t, 0); CASE_THREAD_SLEEP_MS(8); uv_run(&ev_loop, UV_RUN_NOWAIT); } { atbus::endpoint* ep1 = node_child->get_endpoint(node_parent->get_id()); atbus::endpoint* ep2 = node_parent->get_endpoint(node_child->get_id()); CASE_EXPECT_NE(NULL, ep1); CASE_EXPECT_NE(NULL, ep2); CASE_EXPECT_EQ(atbus::node::state_t::RUNNING, node_child->get_state()); } // 注册到子节点失败不会导致下线的流程测试 CASE_EXPECT_EQ(atbus::node::state_t::RUNNING, node_parent->get_state()); } while (UV_EBUSY == uv_loop_close(&ev_loop)) { uv_run(&ev_loop, UV_RUN_ONCE); } }
// buffer recv/send size limit CASE_TEST(channel, io_stream_tcp_size_extended) { atbus::channel::io_stream_channel svr, cli; atbus::channel::io_stream_conf conf; atbus::channel::io_stream_init_configure(&conf); conf.send_buffer_limit_size = conf.recv_buffer_max_size + 1; atbus::channel::io_stream_init(&svr, NULL, &conf); atbus::channel::io_stream_init(&cli, NULL, &conf); svr.evt.callbacks[atbus::channel::io_stream_callback_evt_t::EN_FN_RECVED] = recv_size_err_callback_check_fn; cli.evt.callbacks[atbus::channel::io_stream_callback_evt_t::EN_FN_RECVED] = recv_size_err_callback_check_fn; svr.evt.callbacks[atbus::channel::io_stream_callback_evt_t::EN_FN_DISCONNECTED] = disconnected_callback_test_fn; svr.evt.callbacks[atbus::channel::io_stream_callback_evt_t::EN_FN_DISCONNECTED] = disconnected_callback_test_fn; int check_flag = g_check_flag = 0; int inited_fds = 0; inited_fds += setup_channel(svr, "ipv6://:::16387", NULL); CASE_EXPECT_EQ(1, g_check_flag); CASE_EXPECT_NE(NULL, svr.ev_loop); inited_fds = 0; inited_fds += setup_channel(cli, NULL, "ipv4://127.0.0.1:16387"); while (g_check_flag - check_flag < 2 * inited_fds) { atbus::channel::io_stream_run(&svr, atbus::adapter::RUN_NOWAIT); atbus::channel::io_stream_run(&cli, atbus::adapter::RUN_NOWAIT); CASE_THREAD_SLEEP_MS(8); } CASE_EXPECT_NE(0, cli.conn_pool.size()); check_flag = g_check_flag; int res = atbus::channel::io_stream_send(cli.conn_pool.begin()->second.get(), get_test_buffer(), conf.recv_buffer_limit_size + 1); CASE_EXPECT_EQ(0, res); res = atbus::channel::io_stream_send(cli.conn_pool.begin()->second.get(), get_test_buffer(), conf.send_buffer_limit_size + 1); CASE_EXPECT_EQ(EN_ATBUS_ERR_INVALID_SIZE, res); while (g_check_flag - check_flag < 1) { atbus::channel::io_stream_run(&svr, atbus::adapter::RUN_NOWAIT); atbus::channel::io_stream_run(&cli, atbus::adapter::RUN_NOWAIT); CASE_THREAD_SLEEP_MS(32); } // 错误的数据大小会导致连接断开 res = atbus::channel::io_stream_send(cli.conn_pool.begin()->second.get(), get_test_buffer(), conf.send_buffer_limit_size); CASE_EXPECT_EQ(0, res); // 有接收端关闭,所以一定是接收端先出发关闭连接。 // 这里只要判定后触发方完成回调,那么先触发方必然已经完成 while (!cli.conn_pool.empty()) { atbus::channel::io_stream_run(&svr, atbus::adapter::RUN_NOWAIT); atbus::channel::io_stream_run(&cli, atbus::adapter::RUN_NOWAIT); CASE_THREAD_SLEEP_MS(32); } CASE_EXPECT_EQ(0, cli.conn_pool.size()); CASE_EXPECT_EQ(1, svr.conn_pool.size()); atbus::channel::io_stream_close(&cli); atbus::channel::io_stream_close(&svr); }
CASE_TEST(buffer, static_buffer_manager_merge_back) { // merge back : head NN tail ... => head NN NN tail ... { atbus::detail::buffer_manager mgr; CASE_EXPECT_TRUE(mgr.empty()); mgr.set_mode(255, 3); CASE_EXPECT_EQ(255, mgr.limit().limit_size_); CASE_EXPECT_EQ(3, mgr.limit().limit_number_); // init void* pointer; void* check_ptr[3] = { &pointer, &pointer, &pointer }; size_t s, sr; int res = mgr.push_back(pointer, s = 128 - atbus::detail::buffer_block::head_size(128)); CASE_EXPECT_EQ(EN_ATBUS_ERR_SUCCESS, res); CASE_EXPECT_NE(NULL, pointer); memset(pointer, 0xec, s); CASE_EXPECT_EQ(1, mgr.limit().cost_number_); res = mgr.merge_back(check_ptr[0], 129); CASE_EXPECT_EQ(EN_ATBUS_ERR_BUFF_LIMIT, res); CASE_EXPECT_EQ(s, mgr.front()->raw_size()); CASE_EXPECT_EQ(NULL, check_ptr[0]); CASE_EXPECT_EQ(1, mgr.limit().cost_number_); res = mgr.merge_back(check_ptr[1], 0); CASE_EXPECT_EQ(0, res); CASE_EXPECT_EQ(NULL, check_ptr[1]); CASE_EXPECT_EQ(1, mgr.limit().cost_number_); CASE_EXPECT_EQ(pointer, mgr.front()->raw_data()); res = mgr.merge_back(check_ptr[2], sr = 128); CASE_EXPECT_EQ(0, res); CASE_EXPECT_EQ(s + sr, mgr.front()->raw_size()); CASE_EXPECT_EQ(pointer, mgr.front()->raw_data()); CASE_EXPECT_EQ(check_ptr[2], atbus::detail::fn::buffer_next(mgr.front()->raw_data(), s)); CASE_EXPECT_EQ(1, mgr.limit().cost_number_); CHECK_BUFFER(mgr.front()->raw_data(), s, 0xec); } // merge back : ... head NN tail ... => NN tail ... head NN ... { atbus::detail::buffer_manager mgr; CASE_EXPECT_TRUE(mgr.empty()); mgr.set_mode(255, 3); CASE_EXPECT_EQ(255, mgr.limit().limit_size_); CASE_EXPECT_EQ(3, mgr.limit().limit_number_); // init void* pointer; void* check_ptr[2] = { &pointer, &pointer }; size_t s, sr; mgr.push_back(pointer, s = 136 - atbus::detail::buffer_block::head_size(136)); int res = mgr.push_back(pointer, sr = 64 - atbus::detail::buffer_block::head_size(64)); mgr.pop_front(s); CASE_EXPECT_EQ(EN_ATBUS_ERR_SUCCESS, res); CASE_EXPECT_NE(NULL, pointer); memset(pointer, 0xeb, sr); CASE_EXPECT_EQ(1, mgr.limit().cost_number_); res = mgr.merge_back(check_ptr[0], 69); CASE_EXPECT_EQ(EN_ATBUS_ERR_BUFF_LIMIT, res); CASE_EXPECT_EQ(sr, mgr.front()->raw_size()); CASE_EXPECT_EQ(NULL, check_ptr[0]); CASE_EXPECT_EQ(1, mgr.limit().cost_number_); res = mgr.merge_back(check_ptr[1], 64); CASE_EXPECT_EQ(0, res); CASE_EXPECT_EQ(64 + sr, mgr.front()->raw_size()); CASE_EXPECT_NE(pointer, mgr.front()->raw_data()); CASE_EXPECT_EQ(check_ptr[1], atbus::detail::fn::buffer_next(mgr.front()->raw_data(), sr)); CASE_EXPECT_EQ(1, mgr.limit().cost_number_); CASE_EXPECT_GT(pointer, mgr.front()->raw_data()); CHECK_BUFFER(mgr.front()->raw_data(), sr, 0xeb); } // merge back : NN tail ... head NN => NN NN tail ... head NN { atbus::detail::buffer_manager mgr; CASE_EXPECT_TRUE(mgr.empty()); mgr.set_mode(255, 3); CASE_EXPECT_EQ(255, mgr.limit().limit_size_); CASE_EXPECT_EQ(3, mgr.limit().limit_number_); // init void* pointer; void* check_ptr[2] = { &pointer, &pointer }; size_t s, sr; mgr.push_back(pointer, s = 136 - atbus::detail::buffer_block::head_size(136)); mgr.push_back(pointer, 72 - atbus::detail::buffer_block::head_size(72)); mgr.pop_front(s); int res = mgr.push_back(pointer, sr = 64 - atbus::detail::buffer_block::head_size(64)); CASE_EXPECT_EQ(EN_ATBUS_ERR_SUCCESS, res); CASE_EXPECT_NE(NULL, pointer); memset(pointer, 0xec, sr); CASE_EXPECT_EQ(2, mgr.limit().cost_number_); res = mgr.merge_back(check_ptr[0], 69); CASE_EXPECT_EQ(EN_ATBUS_ERR_BUFF_LIMIT, res); CASE_EXPECT_EQ(sr, mgr.back()->raw_size()); CASE_EXPECT_EQ(NULL, check_ptr[0]); CASE_EXPECT_EQ(2, mgr.limit().cost_number_); res = mgr.merge_back(check_ptr[1], 64); CASE_EXPECT_EQ(0, res); CASE_EXPECT_EQ(64 + sr, mgr.back()->raw_size()); CASE_EXPECT_EQ(pointer, mgr.back()->raw_data()); CASE_EXPECT_EQ(check_ptr[1], atbus::detail::fn::buffer_next(mgr.back()->raw_data(), sr)); CASE_EXPECT_EQ(2, mgr.limit().cost_number_); CASE_EXPECT_GT(mgr.front()->raw_data(), check_ptr[1]); CHECK_BUFFER(mgr.back()->raw_data(), sr, 0xec); } }
// merge front ============== merge back CASE_TEST(buffer, dynamic_buffer_manager_merge) { // merge back { atbus::detail::buffer_manager mgr; CASE_EXPECT_TRUE(mgr.empty()); mgr.set_limit(255, 10); CASE_EXPECT_EQ(255, mgr.limit().limit_size_); CASE_EXPECT_EQ(10, mgr.limit().limit_number_); // init void* pointer; void* check_ptr[3] = { &pointer, &pointer, &pointer }; size_t s, sr; int res = mgr.push_front(pointer, s = 128 - atbus::detail::buffer_block::head_size(128)); CASE_EXPECT_EQ(EN_ATBUS_ERR_SUCCESS, res); CASE_EXPECT_NE(NULL, pointer); memset(pointer, 0xef, s); CASE_EXPECT_EQ(1, mgr.limit().cost_number_); res = mgr.merge_back(check_ptr[0], 256 - s); CASE_EXPECT_EQ(EN_ATBUS_ERR_BUFF_LIMIT, res); CASE_EXPECT_EQ(s, mgr.front()->raw_size()); CASE_EXPECT_EQ(NULL, check_ptr[0]); CASE_EXPECT_EQ(1, mgr.limit().cost_number_); res = mgr.merge_back(check_ptr[1], 0); CASE_EXPECT_EQ(0, res); CASE_EXPECT_EQ(NULL, check_ptr[1]); CASE_EXPECT_EQ(1, mgr.limit().cost_number_); CASE_EXPECT_EQ(pointer, mgr.front()->raw_data()); res = mgr.merge_back(check_ptr[2], sr = 255 - s); CASE_EXPECT_EQ(0, res); CASE_EXPECT_EQ(s + sr, mgr.front()->raw_size()); CASE_EXPECT_NE(pointer, mgr.front()->raw_data()); CASE_EXPECT_EQ(check_ptr[2], atbus::detail::fn::buffer_next(mgr.front()->raw_data(), s)); CASE_EXPECT_EQ(1, mgr.limit().cost_number_); CHECK_BUFFER(mgr.front()->raw_data(), s, 0xef); } // merge front { atbus::detail::buffer_manager mgr; CASE_EXPECT_TRUE(mgr.empty()); mgr.set_limit(255, 10); CASE_EXPECT_EQ(255, mgr.limit().limit_size_); CASE_EXPECT_EQ(10, mgr.limit().limit_number_); // init void* pointer; void* check_ptr[3] = { &pointer, &pointer, &pointer }; size_t s, sr; int res = mgr.push_front(pointer, s = 128 - atbus::detail::buffer_block::head_size(128)); CASE_EXPECT_EQ(EN_ATBUS_ERR_SUCCESS, res); CASE_EXPECT_NE(NULL, pointer); memset(pointer, 0xef, s); CASE_EXPECT_EQ(1, mgr.limit().cost_number_); res = mgr.merge_back(check_ptr[0], 256 - s); CASE_EXPECT_EQ(EN_ATBUS_ERR_BUFF_LIMIT, res); CASE_EXPECT_EQ(s, mgr.front()->raw_size()); CASE_EXPECT_EQ(NULL, check_ptr[0]); CASE_EXPECT_EQ(1, mgr.limit().cost_number_); res = mgr.merge_back(check_ptr[1], 0); CASE_EXPECT_EQ(0, res); CASE_EXPECT_EQ(NULL, check_ptr[1]); CASE_EXPECT_EQ(1, mgr.limit().cost_number_); CASE_EXPECT_EQ(pointer, mgr.front()->raw_data()); res = mgr.merge_back(check_ptr[2], sr = 255 - s); CASE_EXPECT_EQ(0, res); CASE_EXPECT_EQ(s + sr, mgr.front()->raw_size()); CASE_EXPECT_NE(pointer, mgr.front()->raw_data()); CASE_EXPECT_EQ(check_ptr[2], atbus::detail::fn::buffer_next(mgr.front()->raw_data(), s)); CASE_EXPECT_EQ(1, mgr.limit().cost_number_); CHECK_BUFFER(mgr.front()->raw_data(), s, 0xef); } }
CASE_TEST(buffer, static_buffer_manager_circle_fb) { atbus::detail::buffer_manager mgr; CASE_EXPECT_TRUE(mgr.empty()); mgr.set_mode(1023, 10); CASE_EXPECT_FALSE(mgr.set_limit(2048, 10)); CASE_EXPECT_EQ(1023, mgr.limit().limit_size_); CASE_EXPECT_EQ(10, mgr.limit().limit_number_); // size limit void* pointer; void* check_ptr[4]; size_t s, sr; int res = mgr.push_front(pointer, s = 256 - atbus::detail::buffer_block::head_size(256)); CASE_EXPECT_EQ(EN_ATBUS_ERR_SUCCESS, res); CASE_EXPECT_NE(NULL, pointer); memset(pointer, 0, s); res = mgr.push_front(pointer, s = 256 - atbus::detail::buffer_block::head_size(256)); CASE_EXPECT_EQ(EN_ATBUS_ERR_SUCCESS, res); CASE_EXPECT_NE(NULL, pointer); memset(pointer, -1, s); res = mgr.push_front(pointer, s= 256 - atbus::detail::buffer_block::head_size(256)); CASE_EXPECT_EQ(EN_ATBUS_ERR_SUCCESS, res); CASE_EXPECT_NE(NULL, pointer); memset(pointer, 0, s); res = mgr.push_front(pointer, 256 + 2 * atbus::detail::buffer_block::head_size(256)); CASE_EXPECT_EQ(EN_ATBUS_ERR_BUFF_LIMIT, res); CASE_EXPECT_EQ(NULL, pointer); res = mgr.push_front(pointer, 257 - atbus::detail::buffer_block::head_size(257)); CASE_EXPECT_EQ(EN_ATBUS_ERR_BUFF_LIMIT, res); CASE_EXPECT_EQ(NULL, pointer); res = mgr.push_front(pointer, s = 255 - atbus::detail::buffer_block::head_size(255) - atbus::detail::buffer_block::padding_size(1)); CASE_EXPECT_EQ(EN_ATBUS_ERR_SUCCESS, res); CASE_EXPECT_NE(NULL, pointer); memset(pointer, -1, s); CASE_EXPECT_EQ(1023 - atbus::detail::buffer_block::padding_size(1), mgr.limit().cost_size_ + atbus::detail::buffer_block::head_size(255) + 3 * atbus::detail::buffer_block::head_size(256)); CASE_EXPECT_EQ(4, mgr.limit().cost_number_); mgr.pop_back(256, false); CASE_EXPECT_EQ(4, mgr.limit().cost_number_); CHECK_BUFFER(mgr.back()->raw_data(), mgr.back()->raw_size(), 0x00); mgr.pop_back(0); mgr.back(check_ptr[0], s, sr); CASE_EXPECT_EQ(3, mgr.limit().cost_number_); CHECK_BUFFER(mgr.back()->raw_data(), mgr.back()->raw_size(), 0xFF); res = mgr.push_front(pointer, 256); CASE_EXPECT_EQ(EN_ATBUS_ERR_BUFF_LIMIT, res); mgr.pop_back(255 - atbus::detail::buffer_block::head_size(256)); CASE_EXPECT_EQ(3, mgr.limit().cost_number_); res = mgr.push_front(check_ptr[2], 128); CASE_EXPECT_EQ(EN_ATBUS_ERR_SUCCESS, res); CASE_EXPECT_EQ(4, mgr.limit().cost_number_); res = mgr.push_front(check_ptr[3], 128); CASE_EXPECT_EQ(EN_ATBUS_ERR_BUFF_LIMIT, res); mgr.pop_back(1); CASE_EXPECT_EQ(3, mgr.limit().cost_number_); CHECK_BUFFER(mgr.back()->raw_data(), mgr.back()->raw_size(), 0x00); res = mgr.push_front(check_ptr[3], 384 - atbus::detail::buffer_block::head_size(100) - atbus::detail::buffer_block::head_size(412) - atbus::detail::buffer_block::padding_size(1)); CASE_EXPECT_EQ(EN_ATBUS_ERR_SUCCESS, res); CASE_EXPECT_EQ(4, mgr.limit().cost_number_); mgr.back(check_ptr[1], s, sr); CASE_EXPECT_TRUE(check_ptr[2] > check_ptr[0]); CASE_EXPECT_TRUE(check_ptr[3] >= check_ptr[0]); CASE_EXPECT_TRUE(check_ptr[3] < check_ptr[2]); CASE_EXPECT_TRUE(check_ptr[1] < check_ptr[0]); }
CASE_TEST(buffer, static_buffer_manager_fb) { atbus::detail::buffer_manager mgr; CASE_EXPECT_TRUE(mgr.empty()); mgr.set_mode(1023, 10); CASE_EXPECT_FALSE(mgr.set_limit(2048, 10)); CASE_EXPECT_EQ(1023, mgr.limit().limit_size_); CASE_EXPECT_EQ(10, mgr.limit().limit_number_); // size limit void* pointer; void* check_ptr[4]; int res = mgr.push_front(pointer, 256 - atbus::detail::buffer_block::head_size(256)); CASE_EXPECT_EQ(EN_ATBUS_ERR_SUCCESS, res); CASE_EXPECT_NE(NULL, pointer); res = mgr.push_front(pointer, 256 - atbus::detail::buffer_block::head_size(256)); CASE_EXPECT_EQ(EN_ATBUS_ERR_SUCCESS, res); CASE_EXPECT_NE(NULL, pointer); res = mgr.push_front(pointer, 256 - atbus::detail::buffer_block::head_size(256)); CASE_EXPECT_EQ(EN_ATBUS_ERR_SUCCESS, res); CASE_EXPECT_NE(NULL, pointer); res = mgr.push_front(pointer, 256 + 2 * atbus::detail::buffer_block::head_size(256)); CASE_EXPECT_EQ(EN_ATBUS_ERR_BUFF_LIMIT, res); CASE_EXPECT_EQ(NULL, pointer); res = mgr.push_front(pointer, 257 - atbus::detail::buffer_block::head_size(257)); CASE_EXPECT_EQ(EN_ATBUS_ERR_BUFF_LIMIT, res); CASE_EXPECT_EQ(NULL, pointer); res = mgr.push_front(pointer, 255 - atbus::detail::buffer_block::head_size(255) - atbus::detail::buffer_block::padding_size(1)); CASE_EXPECT_EQ(EN_ATBUS_ERR_SUCCESS, res); CASE_EXPECT_NE(NULL, pointer); CASE_EXPECT_EQ(1023 - atbus::detail::buffer_block::padding_size(1), mgr.limit().cost_size_ + atbus::detail::buffer_block::head_size(255) + 3 * atbus::detail::buffer_block::head_size(256)); CASE_EXPECT_EQ(4, mgr.limit().cost_number_); mgr.reset(); mgr.set_mode(1023, 3); // from empty to full to empty // should has the same result for (int i = 0; i < 3; ++ i) { // number limit res = mgr.push_front(check_ptr[0], 99); CASE_EXPECT_EQ(EN_ATBUS_ERR_SUCCESS, res); memset(check_ptr[0], -1, 99); res = mgr.push_front(check_ptr[1], 28); CASE_EXPECT_EQ(EN_ATBUS_ERR_SUCCESS, res); memset(check_ptr[1], 0, 28); res = mgr.push_front(check_ptr[2], 17); CASE_EXPECT_EQ(EN_ATBUS_ERR_SUCCESS, res); memset(check_ptr[2], -1, 17); res = mgr.push_front(check_ptr[3], 63); CASE_EXPECT_EQ(EN_ATBUS_ERR_BUFF_LIMIT, res); CASE_EXPECT_EQ(144, mgr.limit().cost_size_); CASE_EXPECT_EQ(3, mgr.limit().cost_number_); // pop and remove block size_t s, sr; res = mgr.back(pointer, sr, s); CASE_EXPECT_EQ(EN_ATBUS_ERR_SUCCESS, res); CASE_EXPECT_EQ(pointer, check_ptr[0]); CASE_EXPECT_EQ(99, s); CASE_EXPECT_EQ(*reinterpret_cast<char*>(pointer), -1); res = mgr.pop_back(128); CASE_EXPECT_EQ(EN_ATBUS_ERR_SUCCESS, res); CASE_EXPECT_EQ(45, mgr.limit().cost_size_); CASE_EXPECT_EQ(2, mgr.limit().cost_number_); res = mgr.back(pointer, sr, s); CASE_EXPECT_EQ(EN_ATBUS_ERR_SUCCESS, res); CASE_EXPECT_EQ(pointer, check_ptr[1]); CASE_EXPECT_EQ(28, s); CASE_EXPECT_EQ(*reinterpret_cast<char*>(pointer), 0); res = mgr.pop_back(100); CASE_EXPECT_EQ(EN_ATBUS_ERR_SUCCESS, res); CASE_EXPECT_EQ(17, mgr.limit().cost_size_); CASE_EXPECT_EQ(1, mgr.limit().cost_number_); res = mgr.back(pointer, sr, s); CASE_EXPECT_EQ(EN_ATBUS_ERR_SUCCESS, res); CASE_EXPECT_EQ(pointer, check_ptr[2]); CASE_EXPECT_EQ(17, s); CASE_EXPECT_EQ(*reinterpret_cast<char*>(pointer), -1); // pop but not remove block mgr.pop_back(10); CASE_EXPECT_EQ(7, mgr.limit().cost_size_); CASE_EXPECT_EQ(1, mgr.limit().cost_number_); res = mgr.back(pointer, sr, s); CASE_EXPECT_EQ(EN_ATBUS_ERR_SUCCESS, res); CASE_EXPECT_EQ(pointer, atbus::detail::fn::buffer_next(check_ptr[2], 10)); CASE_EXPECT_EQ(7, s); CASE_EXPECT_EQ(*reinterpret_cast<char*>(pointer), -1); // pop all res = mgr.pop_back(10); CASE_EXPECT_EQ(EN_ATBUS_ERR_SUCCESS, res); CASE_EXPECT_TRUE(mgr.empty()); CASE_EXPECT_EQ(0, mgr.limit().cost_size_); CASE_EXPECT_EQ(0, mgr.limit().cost_number_); // pop nothing res = mgr.back(pointer, sr, s); CASE_EXPECT_EQ(EN_ATBUS_ERR_NO_DATA, res); CASE_EXPECT_EQ(NULL, pointer); CASE_EXPECT_EQ(0, s); res = mgr.pop_back(10); CASE_EXPECT_EQ(EN_ATBUS_ERR_NO_DATA, res); } }
CASE_TEST(channel, io_stream_tcp_basic) { atbus::adapter::loop_t loop; uv_loop_init(&loop); atbus::channel::io_stream_channel svr, cli; atbus::channel::io_stream_init(&svr, &loop, NULL); atbus::channel::io_stream_init(&cli, &loop, NULL); CASE_EXPECT_EQ(&loop, svr.ev_loop); CASE_EXPECT_EQ(&loop, cli.ev_loop); g_check_flag = 0; int inited_fds = 0; inited_fds += setup_channel(svr, "ipv6://:::16387", NULL); CASE_EXPECT_EQ(1, g_check_flag); CASE_EXPECT_NE(NULL, svr.ev_loop); if (0 == inited_fds) { uv_loop_close(&loop); return; } inited_fds = 0; inited_fds += setup_channel(cli, NULL, "ipv4://127.0.0.1:16387"); inited_fds += setup_channel(cli, NULL, "dns://localhost:16387"); inited_fds += setup_channel(cli, NULL, "ipv6://::1:16387"); int check_flag = g_check_flag; while (g_check_flag - check_flag < 2 * inited_fds) { uv_run(&loop, UV_RUN_ONCE); } svr.evt.callbacks[atbus::channel::io_stream_callback_evt_t::EN_FN_RECVED] = recv_callback_check_fn; cli.evt.callbacks[atbus::channel::io_stream_callback_evt_t::EN_FN_RECVED] = recv_callback_check_fn; char* buf = get_test_buffer(); check_flag = g_check_flag; // small buffer atbus::channel::io_stream_send(cli.conn_pool.begin()->second.get(), buf, 13); g_check_buff_sequence.push_back(std::make_pair(0, 13)); atbus::channel::io_stream_send(cli.conn_pool.begin()->second.get(), buf + 13, 28); g_check_buff_sequence.push_back(std::make_pair(13, 28)); atbus::channel::io_stream_send(cli.conn_pool.begin()->second.get(), buf + 13 + 28, 100); g_check_buff_sequence.push_back(std::make_pair(13 + 28, 100)); // big buffer atbus::channel::io_stream_send(cli.conn_pool.begin()->second.get(), buf + 1024, 56 * 1024 + 3); g_check_buff_sequence.push_back(std::make_pair(1024, 56 * 1024 + 3)); while (g_check_flag - check_flag < 4) { uv_run(&loop, UV_RUN_ONCE); } // many big buffer { check_flag = g_check_flag; atbus::channel::io_stream_channel::conn_pool_t::iterator it = svr.conn_pool.begin(); // 跳过listen的socket if (it->second->addr.address == "ipv6://:::16387") { ++it; } size_t sum_size = 0; g_recv_rec = std::make_pair(0, 0); for (int i = 0; i < 153; ++ i) { size_t s = static_cast<size_t>(rand() % 2048); size_t l = static_cast<size_t>(rand() % 10240) + 20 * 1024; atbus::channel::io_stream_send(it->second.get(), buf + s, l); g_check_buff_sequence.push_back(std::make_pair(s, l)); sum_size += l; } CASE_MSG_INFO() << "send " << sum_size << " bytes data with " << g_check_buff_sequence.size() << " packages done." << std::endl; while (g_check_flag - check_flag < 153) { uv_run(&loop, UV_RUN_ONCE); } CASE_MSG_INFO() << "recv " << g_recv_rec.second << " bytes data with " << g_recv_rec.first << " packages and checked done." << std::endl; } atbus::channel::io_stream_close(&svr); atbus::channel::io_stream_close(&cli); CASE_EXPECT_EQ(0, svr.conn_pool.size()); CASE_EXPECT_EQ(0, cli.conn_pool.size()); uv_loop_close(&loop); }