341 lines
11 KiB
C++
341 lines
11 KiB
C++
/**
|
|
* Copyright (c) 2021 OceanBase
|
|
* OceanBase CE is licensed under Mulan PubL v2.
|
|
* You can use this software according to the terms and conditions of the Mulan PubL v2.
|
|
* You may obtain a copy of Mulan PubL v2 at:
|
|
* http://license.coscl.org.cn/MulanPubL-2.0
|
|
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
|
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
|
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
|
* See the Mulan PubL v2 for more details.
|
|
*/
|
|
|
|
#include <gtest/gtest.h>
|
|
#include <stdlib.h>
|
|
#include <algorithm>
|
|
#include <pthread.h>
|
|
#include <sys/time.h>
|
|
#include "lib/stat/ob_session_stat.h"
|
|
#include "sql/session/ob_sql_session_mgr.h"
|
|
#include "lib/random/ob_random.h"
|
|
#include "rpc/obmysql/obsm_struct.h"
|
|
|
|
using namespace std;
|
|
using namespace oceanbase;
|
|
using namespace oceanbase::common;
|
|
using namespace oceanbase::sql;
|
|
using namespace oceanbase::observer;
|
|
class DISABLED_TestSessionMgr : public ::testing::Test
|
|
{
|
|
public:
|
|
DISABLED_TestSessionMgr():
|
|
mgr_() {
|
|
|
|
}
|
|
|
|
virtual void SetUp()
|
|
{
|
|
mgr_.init();
|
|
}
|
|
|
|
virtual void TearDown()
|
|
{
|
|
}
|
|
private:
|
|
class SessionOperator
|
|
{
|
|
public:
|
|
uint64_t sum;
|
|
SessionOperator() : sum(0) {
|
|
}
|
|
bool operator()(ObSQLSessionMgr::Key key, ObSQLSessionInfo* sess_info) {
|
|
UNUSED(key);
|
|
UNUSED(sess_info);
|
|
sum++;
|
|
return true;
|
|
}
|
|
};
|
|
|
|
protected:
|
|
ObSQLSessionMgr mgr_;
|
|
SessionOperator sess_operator_;
|
|
ObSMConnection conn_;
|
|
};
|
|
|
|
TEST_F(DISABLED_TestSessionMgr, test_exception)
|
|
{
|
|
ObSQLSessionInfo *sess_info = NULL;
|
|
ObSQLSessionInfo *dup_sess = NULL;
|
|
conn_.sessid_ = 1;
|
|
EXPECT_EQ(OB_SUCCESS, mgr_.create_session(&conn_, sess_info));
|
|
EXPECT_EQ(OB_SESSION_ENTRY_EXIST, mgr_.create_session(&conn_, dup_sess));
|
|
EXPECT_EQ(NULL, dup_sess);
|
|
mgr_.revert_session(sess_info);
|
|
}
|
|
|
|
TEST_F(DISABLED_TestSessionMgr, test_create)
|
|
{
|
|
ObSQLSessionInfo *sess_info = NULL;
|
|
int64_t sess_cnt = 0;
|
|
const uint32_t SESSION_COUNT = 100;
|
|
for (uint32_t i = 1; i < SESSION_COUNT; ++i) {
|
|
conn_.sessid_ = i;
|
|
conn_.proxy_sessid_ = i * 10;
|
|
EXPECT_EQ(OB_SUCCESS, mgr_.create_session(&conn_, sess_info));
|
|
EXPECT_TRUE(sess_info);
|
|
EXPECT_EQ(i, sess_info->get_sessid());
|
|
EXPECT_EQ(i * 10, sess_info->get_proxy_sessid());
|
|
EXPECT_EQ(SESSION_INIT, sess_info->get_session_state());
|
|
mgr_.revert_session(sess_info);
|
|
}
|
|
|
|
for (uint32_t i = 1; i < SESSION_COUNT; ++i) {
|
|
EXPECT_EQ(OB_SUCCESS, mgr_.get_session(i, sess_info));
|
|
EXPECT_TRUE(sess_info);
|
|
EXPECT_EQ(i, sess_info->get_sessid());
|
|
EXPECT_EQ(i * 10, sess_info->get_proxy_sessid());
|
|
EXPECT_EQ(SESSION_INIT, sess_info->get_session_state());
|
|
mgr_.revert_session(sess_info);
|
|
mgr_.get_session_count(sess_cnt);
|
|
EXPECT_EQ(SESSION_COUNT - i, sess_cnt);
|
|
ObFreeSessionCtx ctx;
|
|
ctx.tenant_id_ = OB_SYS_TENANT_ID;
|
|
ctx.sessid_ = i;
|
|
ctx.has_inc_active_num_ = false;
|
|
EXPECT_EQ(OB_SUCCESS, mgr_.free_session(ctx));
|
|
}
|
|
}
|
|
|
|
TEST_F(DISABLED_TestSessionMgr, test_performace)
|
|
{
|
|
ObSQLSessionInfo *sess_info = NULL;
|
|
const uint32_t SESSION_COUNT = 500;
|
|
struct timeval get_beg, get_end, stat_beg, stat_end;
|
|
for (uint32_t i = 1; i < SESSION_COUNT; ++i) {
|
|
conn_.sessid_ = i;
|
|
mgr_.create_session(&conn_, sess_info);
|
|
mgr_.revert_session(sess_info);
|
|
}
|
|
gettimeofday(&get_beg, NULL);
|
|
for (uint32_t i = 1; i < SESSION_COUNT; ++i) {
|
|
mgr_.get_session(i, sess_info);
|
|
}
|
|
gettimeofday(&get_end, NULL);
|
|
gettimeofday(&stat_beg, NULL);
|
|
for (uint32_t i = 1; i < SESSION_COUNT; ++i) {
|
|
ObSessionStatEstGuard guard(1, static_cast<uint32_t>(i));
|
|
EVENT_DEC(ACTIVE_SESSIONS);
|
|
}
|
|
gettimeofday(&stat_end, NULL);
|
|
const uint64_t WEIGHT = 1000000;
|
|
OB_LOG(INFO, "performance average",
|
|
"get_session", (WEIGHT * (get_end.tv_sec - get_beg.tv_sec) + get_end.tv_usec - get_beg.tv_usec) / SESSION_COUNT,
|
|
"stat", (WEIGHT * (stat_end.tv_sec - stat_beg.tv_sec) + stat_end.tv_usec - stat_beg.tv_usec) / SESSION_COUNT);
|
|
}
|
|
|
|
TEST_F(DISABLED_TestSessionMgr, test_version)
|
|
{
|
|
ObSQLSessionInfo *sess_info = NULL;
|
|
const uint32_t SESS_ID = 1;
|
|
for (uint32_t i = 0; i < 100; ++i) {
|
|
conn_.sessid_ = SESS_ID;
|
|
conn_.proxy_sessid_ = SESS_ID * 10;
|
|
EXPECT_EQ(OB_SUCCESS, mgr_.create_session(&conn_, sess_info));
|
|
EXPECT_TRUE(sess_info);
|
|
EXPECT_EQ(SESSION_INIT, sess_info->get_session_state());
|
|
EXPECT_EQ(SESS_ID, sess_info->get_sessid());
|
|
EXPECT_EQ(SESS_ID * 10, sess_info->get_proxy_sessid());
|
|
sess_info->set_shadow(true);
|
|
mgr_.revert_session(sess_info);
|
|
}
|
|
|
|
for (uint32_t i = 0; i < 100; ++i) {
|
|
EXPECT_EQ(OB_SUCCESS, mgr_.get_session(SESS_ID, sess_info));
|
|
EXPECT_EQ(SESS_ID, sess_info->get_sessid());
|
|
EXPECT_EQ(SESS_ID * 10, sess_info->get_proxy_sessid());
|
|
EXPECT_EQ(true, sess_info->is_shadow());
|
|
mgr_.revert_session(sess_info);
|
|
}
|
|
}
|
|
|
|
TEST_F(DISABLED_TestSessionMgr, test_for_each)
|
|
{
|
|
ObSQLSessionInfo *sess_info = NULL;
|
|
for (uint32_t i = 0; i < 100; ++i) {
|
|
conn_.sessid_ = i;
|
|
EXPECT_EQ(OB_SUCCESS, mgr_.create_session(&conn_, sess_info));
|
|
EXPECT_TRUE(sess_info);
|
|
mgr_.revert_session(sess_info);
|
|
}
|
|
EXPECT_EQ(OB_SUCCESS, mgr_.for_each_session(sess_operator_));
|
|
EXPECT_EQ(100, sess_operator_.sum);
|
|
}
|
|
|
|
|
|
int64_t create_num = 0;
|
|
class ObStressThread_create : public share::ObThreadPool
|
|
{
|
|
public:
|
|
void run1()
|
|
{
|
|
ObSQLSessionInfo* sess_info = NULL;
|
|
ObSMConnection conn;
|
|
int err = OB_SUCCESS;
|
|
uint32_t N = 1000;
|
|
for (uint32_t i = 0; i < N; i++) {
|
|
uint32_t id = static_cast<uint32_t>(ObRandom::rand(0, N));
|
|
err = mgr_->get_session(id, sess_info);
|
|
if (OB_ENTRY_NOT_EXIST == err) {
|
|
conn.sessid_ = id;
|
|
conn.proxy_sessid_ = id + 1;
|
|
err = mgr_->create_session(&conn, sess_info);
|
|
EXPECT_EQ(true, OB_SUCCESS == err || OB_SESSION_ENTRY_EXIST == err);
|
|
if (OB_SUCCESS == err) {
|
|
ATOMIC_AAF(&create_num, 1);
|
|
EXPECT_EQ(id, sess_info->get_sessid());
|
|
EXPECT_EQ(id + 1, sess_info->get_proxy_sessid());
|
|
// ObSQLSessionInfo::LockGuard lock_guard(sess_info->get_thread_data_lock());
|
|
// sess_info->set_query_start_time(id);
|
|
mgr_->revert_session(sess_info);
|
|
}
|
|
} else {
|
|
EXPECT_EQ(OB_SUCCESS, err);
|
|
// ObSQLSessionInfo::LockGuard lock_guard(sess_info->get_thread_data_lock());
|
|
// EXPECT_EQ(true, 0 == static_cast<uint32_t>(sess_info->get_query_start_time()) ||
|
|
// id == static_cast<uint32_t>(sess_info->get_query_start_time()));
|
|
mgr_->revert_session(sess_info);
|
|
}
|
|
}
|
|
}
|
|
ObSQLSessionMgr * mgr_;
|
|
ObSMConnection *conn_;
|
|
};
|
|
|
|
TEST_F(DISABLED_TestSessionMgr, create_concurrent)
|
|
{
|
|
ObStressThread_create threads;
|
|
threads.mgr_ = &mgr_;
|
|
threads.conn_ = &conn_;
|
|
threads.set_thread_count(4);
|
|
threads.start();
|
|
threads.wait();
|
|
int64_t sess_cnt;
|
|
mgr_.get_session_count(sess_cnt);
|
|
OB_LOG(INFO, "concurrent create result", K(create_num), K(sess_cnt));
|
|
EXPECT_EQ(create_num, sess_cnt);
|
|
}
|
|
|
|
struct ThreadArgs
|
|
{
|
|
ObSQLSessionMgr *mgr_;
|
|
ObSMConnection *conn_;
|
|
uint32_t sess_cnt_;
|
|
};
|
|
|
|
void *thread_func_create_session(void *args)
|
|
{
|
|
ThreadArgs *thd_args = static_cast<ThreadArgs*>(args);
|
|
int ret = OB_SUCCESS;
|
|
ObSMConnection conn;
|
|
for (uint32_t i = 0; i < thd_args->sess_cnt_; ++i) {
|
|
ObSQLSessionInfo *sess_info = NULL;
|
|
uint32_t id = static_cast<uint32_t>(ObRandom::rand(0, thd_args->sess_cnt_));
|
|
conn.sessid_ = id;
|
|
ret = thd_args->mgr_->create_session(&conn, sess_info);
|
|
if (OB_SUCC(ret)) {
|
|
EXPECT_EQ(SESSION_INIT, sess_info->get_session_state());
|
|
thd_args->mgr_->revert_session(sess_info);
|
|
} else {
|
|
EXPECT_EQ(OB_SESSION_ENTRY_EXIST, ret);
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
void *thread_func_get_session(void *args)
|
|
{
|
|
ThreadArgs *thd_args = static_cast<ThreadArgs*>(args);
|
|
int ret = OB_SUCCESS;
|
|
for (uint32_t i = 0; i < thd_args->sess_cnt_; ++i) {
|
|
uint32_t id = static_cast<uint32_t>(ObRandom::rand(0, thd_args->sess_cnt_));
|
|
ObSQLSessionInfo *sess_info = NULL;
|
|
ret = thd_args->mgr_->get_session(id, sess_info);
|
|
EXPECT_EQ(true, OB_SUCCESS == ret || OB_ENTRY_NOT_EXIST == ret);
|
|
if (OB_SUCC(ret)) {
|
|
thd_args->mgr_->revert_session(sess_info);
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
void *thread_func_shadow_session(void *args)
|
|
{
|
|
ThreadArgs *thd_args = static_cast<ThreadArgs*>(args);
|
|
int ret = OB_SUCCESS;
|
|
for (uint32_t i = 0; i < thd_args->sess_cnt_; ++i) {
|
|
uint32_t id = static_cast<uint32_t>(ObRandom::rand(0, thd_args->sess_cnt_));
|
|
ObSQLSessionInfo *sess_info = NULL;
|
|
ret = thd_args->mgr_->get_session(id, sess_info);
|
|
EXPECT_EQ(true, OB_SUCCESS == ret || OB_ENTRY_NOT_EXIST == ret);
|
|
if (OB_SUCC(ret)) {
|
|
sess_info->set_shadow(true);
|
|
thd_args->mgr_->revert_session(sess_info);
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
void *thread_func_free_session(void *args)
|
|
{
|
|
ThreadArgs *thd_args = static_cast<ThreadArgs*>(args);
|
|
int ret = OB_SUCCESS;
|
|
for (uint32_t i = 0; i < thd_args->sess_cnt_; ++i) {
|
|
uint32_t id = static_cast<uint32_t>(ObRandom::rand(0, thd_args->sess_cnt_));
|
|
ObFreeSessionCtx ctx;
|
|
ctx.tenant_id_ = OB_SYS_TENANT_ID;
|
|
ctx.sessid_ = id;
|
|
ctx.has_inc_active_num_ = false;
|
|
ret = thd_args->mgr_->free_session(ctx);
|
|
EXPECT_EQ(true, OB_SUCCESS == ret || OB_ENTRY_NOT_EXIST == ret);
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
TEST_F(DISABLED_TestSessionMgr, concurrent)
|
|
{
|
|
const int64_t THREAD_NUM = 64;
|
|
pthread_t thread_create_arr[THREAD_NUM];
|
|
pthread_t thread_get_arr[THREAD_NUM];
|
|
pthread_t thread_free_arr[THREAD_NUM];
|
|
pthread_t thread_shadow_arr[THREAD_NUM];
|
|
pthread_attr_t *attr_null = NULL;
|
|
|
|
for (int64_t i = 0; i < THREAD_NUM; ++i) {
|
|
ThreadArgs thread_args;
|
|
thread_args.mgr_ = &mgr_;
|
|
thread_args.conn_ = &conn_;
|
|
thread_args.sess_cnt_ = 1000;
|
|
OB_ASSERT(0 == pthread_create(&thread_create_arr[i], attr_null, thread_func_create_session, &thread_args));
|
|
OB_ASSERT(0 == pthread_create(&thread_shadow_arr[i], attr_null, thread_func_shadow_session, &thread_args));
|
|
OB_ASSERT(0 == pthread_create(&thread_get_arr[i], attr_null, thread_func_get_session, &thread_args));
|
|
OB_ASSERT(0 == pthread_create(&thread_free_arr[i], attr_null, thread_func_free_session, &thread_args));
|
|
}
|
|
|
|
for (int64_t i = 0; i < THREAD_NUM; ++i) {
|
|
OB_ASSERT(0 == pthread_join(thread_create_arr[i], NULL));
|
|
OB_ASSERT(0 == pthread_join(thread_get_arr[i], NULL));
|
|
OB_ASSERT(0 == pthread_join(thread_free_arr[i], NULL));
|
|
}
|
|
}
|
|
|
|
int main(int argc, char *argv[])
|
|
{
|
|
srand((unsigned)time(NULL));
|
|
// OB_LOGGER.set_file_name("test_session_mgr.log");
|
|
system("rm -rf test_session_mgr.log");
|
|
OB_LOGGER.set_log_level("INFO");
|
|
OB_LOGGER.set_file_name("test_session_mgr.log", true);
|
|
::testing::InitGoogleTest(&argc, argv);
|
|
return RUN_ALL_TESTS();
|
|
}
|