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;
}
Beispiel #5
0
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);
}
Beispiel #16
0
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);
    }
}
Beispiel #17
0
// 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);
    }
}
Beispiel #18
0
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]);
}
Beispiel #19
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);
}