void test_bnd_buf_get() { int ret; char * s; bnd_buf * buffer = get_test_buffer(); assert(bnd_buf_free_slots(buffer)==0); assert(bnd_buf_items_count(buffer)==2); s=bnd_buf_get(buffer); assert(strcmp(s,"new password")==0); assert(bnd_buf_free_slots(buffer)==1); ret = bnd_buf_put(buffer,"third password"); assert(ret==1); s=bnd_buf_get(buffer); assert(strcmp(s,"second password")==0); assert(bnd_buf_free_slots(buffer)==1); assert(bnd_buf_items_count(buffer)==1); s=bnd_buf_get(buffer); assert(strcmp(s,"third password")==0); assert(bnd_buf_free_slots(buffer)==2); assert(bnd_buf_items_count(buffer)==0); }
void test_bnd_buf_rotation() { int ret; char * s; bnd_buf * buffer = get_test_buffer(); assert(bnd_buf_free_slots(buffer)==0); assert(bnd_buf_items_count(buffer)==2); /* put in full buffer */ ret = bnd_buf_put(buffer,"third password"); assert(ret==0); s=bnd_buf_get(buffer); assert(strcmp(s,"new password")==0); assert(bnd_buf_free_slots(buffer)==1); /* put in buffer with free place */ ret = bnd_buf_put(buffer,"third password"); assert(ret==1); /* put in full buffer */ ret = bnd_buf_put(buffer,"fourth password"); assert(ret==0); s=bnd_buf_get(buffer); assert(strcmp(s,"second password")==0); assert(bnd_buf_free_slots(buffer)==1); assert(bnd_buf_items_count(buffer)==1); /* put in buffer with free place */ ret = bnd_buf_put(buffer,"fourth password"); assert(ret==1); s=bnd_buf_get(buffer); assert(strcmp(s,"third password")==0); assert(bnd_buf_free_slots(buffer)==1); assert(bnd_buf_items_count(buffer)==1); s=bnd_buf_get(buffer); assert(strcmp(s,"fourth password")==0); assert(bnd_buf_free_slots(buffer)==2); assert(bnd_buf_items_count(buffer)==0); }
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; }
// 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(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); }