/** * 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. */ #define USING_LOG_PREFIX OBLOG #include #include "share/ob_web_service_root_addr.h" // to_json #include "lib/oblog/ob_log_module.h" #include "lib/string/ob_sql_string.h" // ObSqlString #include "ob_log_sql_server_provider.h" namespace oceanbase { using namespace common; using namespace share; namespace libobcdc { #define CONFIG_SERVER_PORT 6789 #define CONFIG_SERVER_PORT_STR "6789" #define CONFIG_SERVER_IP "127.0.0.1" #define CONFIG_SERVER_PROGRAM "./fake_config_server" class TestLogSQLServerProvider : public ::testing::Test { static const int64_t MAX_JASON_BUFFER_SIZE = 1 << 10; static const int64_t MAX_CONFIG_URL_LENGTH = 1 << 10; static const int64_t MAX_APPNAME_LENGTH = 1 << 10; public: TestLogSQLServerProvider() : rs_leader_(), rs_follower_1_(), rs_follower_2_(), service_pid_(0), server_provider_() {} virtual void SetUp(); virtual void TearDown(); void set_rs_list(const ObRootAddrList &rs_list); protected: ObRootAddr rs_leader_; ObRootAddr rs_follower_1_; ObRootAddr rs_follower_2_; pid_t service_pid_; ObLogSQLServerProvider server_provider_; char appname_[MAX_APPNAME_LENGTH]; char config_url_[MAX_CONFIG_URL_LENGTH]; char json_buffer_[MAX_JASON_BUFFER_SIZE]; }; void TestLogSQLServerProvider::SetUp() { int ret = OB_SUCCESS; const char *config_url_arbitrary_str = "i_am_an_arbitrary_string/versin=1"; const char *appname_str = "test"; // Constructing the ConfigURL // Note that the URL is actually only accessible as "http::/IP:PORT", the subsequent string is an arbitrary string (void)snprintf(config_url_, sizeof(config_url_), "http://%s:%d/%s", CONFIG_SERVER_IP, CONFIG_SERVER_PORT, config_url_arbitrary_str); (void)snprintf(appname_, sizeof(appname_), "%s", appname_str); // Create configure server simulation process pid_t pid = fork(); if (0 == pid) { // Set the child process to a new child process group to facilitate KILL ret = setpgid(pid, pid); if (ret < 0) { LOG_ERROR("setpgid failed", K(errno)); } else if (-1 == (ret = execl( "/bin/bash", CONFIG_SERVER_PROGRAM, CONFIG_SERVER_PROGRAM, CONFIG_SERVER_PORT_STR, (char *)NULL))) { LOG_ERROR("execl failed", K(errno)); } exit(1); } else if (-1 == pid) { LOG_ERROR("fork failed", K(errno)); } else { LOG_INFO("create child", K(pid)); service_pid_ = pid; // wait child process execute. usleep(100000); } // init rs addr list ObSEArray rs_list; rs_leader_.server_.set_ip_addr("10.210.170.11", 100); rs_leader_.role_ = LEADER; rs_leader_.sql_port_ = 2828; rs_list.push_back(rs_leader_); rs_follower_1_.server_.set_ip_addr("10.210.170.16", 200); rs_follower_1_.role_ = FOLLOWER; rs_follower_1_.sql_port_ = 3838; rs_list.push_back(rs_follower_1_); rs_follower_2_.server_.set_ip_addr("10.210.180.96", 300); rs_follower_2_.role_ = FOLLOWER; rs_follower_2_.sql_port_ = 4848; rs_list.push_back(rs_follower_2_); // Setting up the Rootserver list set_rs_list(rs_list); // init Server Provider ret = server_provider_.init(config_url_, appname_); ASSERT_EQ(OB_SUCCESS, ret); // init 3 rootserver ObAddr server; EXPECT_EQ(3, server_provider_.get_server_count()); EXPECT_EQ(OB_SUCCESS, server_provider_.get_server(0, server)); EXPECT_EQ(rs_leader_.server_.get_ipv4(), server.get_ipv4()); EXPECT_EQ(rs_leader_.sql_port_, server.get_port()); EXPECT_EQ(OB_SUCCESS, server_provider_.get_server(1, server)); EXPECT_EQ(rs_follower_1_.server_.get_ipv4(), server.get_ipv4()); EXPECT_EQ(rs_follower_1_.sql_port_, server.get_port()); EXPECT_EQ(OB_SUCCESS, server_provider_.get_server(2, server)); EXPECT_EQ(rs_follower_2_.server_.get_ipv4(), server.get_ipv4()); EXPECT_EQ(rs_follower_2_.sql_port_, server.get_port()); EXPECT_EQ(OB_ENTRY_NOT_EXIST, server_provider_.get_server(3, server)); } void TestLogSQLServerProvider::TearDown() { int status = 0; int64_t orig_server_count = server_provider_.get_server_count(); // Sends SIGINT to all processes in the process group of the child process kill(-service_pid_, SIGINT); pid_t pid = wait(&status); LOG_INFO("child exit", K(pid)); // Refresh error if Configure Server does not exist EXPECT_NE(OB_SUCCESS, server_provider_.refresh_server_list()); // Refresh the error without modifying the previous Server list EXPECT_EQ(orig_server_count, server_provider_.get_server_count()); } void TestLogSQLServerProvider::set_rs_list(const ObRootAddrList &rs_list) { int ret = OB_SUCCESS; ObSqlString cmd; ObSqlString json; usleep(50000); const int64_t cluster_id = 100; ret = ObWebServiceRootAddr::to_json(rs_list, appname_, cluster_id, json); ASSERT_EQ(OB_SUCCESS, ret); LOG_INFO("to_json", K(json)); ret = cmd.assign_fmt("echo -n 'POST / HTTP/1.1\r\nContent-Length: %ld\r\n%s' | nc %s %d &> /dev/null", json.length(), json.ptr(), CONFIG_SERVER_IP, CONFIG_SERVER_PORT); ASSERT_EQ(OB_SUCCESS, ret); ret = system(cmd.ptr()); usleep(50000); } TEST_F(TestLogSQLServerProvider, fetch) { ObAddr server; ObSEArray rs_list; // Test zero RS rs_list.reuse(); set_rs_list(rs_list); // Set up a new RS list ASSERT_EQ(OB_SUCCESS, server_provider_.refresh_server_list()); // Refresh RS list EXPECT_EQ(0, server_provider_.get_server_count()); EXPECT_EQ(OB_ENTRY_NOT_EXIST, server_provider_.get_server(0, server)); // Test one RS rs_list.reuse(); rs_list.push_back(rs_leader_); set_rs_list(rs_list); // Set up a new RS list ASSERT_EQ(OB_SUCCESS, server_provider_.refresh_server_list()); // Refresh RS list EXPECT_EQ(1, server_provider_.get_server_count()); EXPECT_EQ(OB_SUCCESS, server_provider_.get_server(0, server)); EXPECT_EQ(rs_leader_.server_.get_ipv4(), server.get_ipv4()); EXPECT_EQ(rs_leader_.sql_port_, server.get_port()); // Server的端口应该是SQL端口 EXPECT_EQ(OB_ENTRY_NOT_EXIST, server_provider_.get_server(1, server)); EXPECT_EQ(OB_INVALID_ARGUMENT, server_provider_.get_server(-1, server)); // Test two RS rs_list.reuse(); rs_list.push_back(rs_leader_); rs_list.push_back(rs_follower_1_); set_rs_list(rs_list); // Set up a new RS list ASSERT_EQ(OB_SUCCESS, server_provider_.refresh_server_list()); // Refresh RS list EXPECT_EQ(2, server_provider_.get_server_count()); EXPECT_EQ(OB_SUCCESS, server_provider_.get_server(0, server)); EXPECT_EQ(rs_leader_.server_.get_ipv4(), server.get_ipv4()); EXPECT_EQ(rs_leader_.sql_port_, server.get_port()); EXPECT_EQ(OB_SUCCESS, server_provider_.get_server(1, server)); EXPECT_EQ(rs_follower_1_.server_.get_ipv4(), server.get_ipv4()); EXPECT_EQ(rs_follower_1_.sql_port_, server.get_port()); EXPECT_EQ(OB_ENTRY_NOT_EXIST, server_provider_.get_server(2, server)); // Test three RS rs_list.reuse(); rs_list.push_back(rs_leader_); rs_list.push_back(rs_follower_1_); rs_list.push_back(rs_follower_2_); set_rs_list(rs_list); // Set up a new RS list ASSERT_EQ(OB_SUCCESS, server_provider_.refresh_server_list()); // Refresh RS list EXPECT_EQ(3, server_provider_.get_server_count()); EXPECT_EQ(OB_SUCCESS, server_provider_.get_server(0, server)); EXPECT_EQ(rs_leader_.server_.get_ipv4(), server.get_ipv4()); EXPECT_EQ(rs_leader_.sql_port_, server.get_port()); EXPECT_EQ(OB_SUCCESS, server_provider_.get_server(1, server)); EXPECT_EQ(rs_follower_1_.server_.get_ipv4(), server.get_ipv4()); EXPECT_EQ(rs_follower_1_.sql_port_, server.get_port()); EXPECT_EQ(OB_SUCCESS, server_provider_.get_server(2, server)); EXPECT_EQ(rs_follower_2_.server_.get_ipv4(), server.get_ipv4()); EXPECT_EQ(rs_follower_2_.sql_port_, server.get_port()); EXPECT_EQ(OB_ENTRY_NOT_EXIST, server_provider_.get_server(3, server)); } } // end namespace share } // end namespace oceanbase int main(int argc, char **argv) { oceanbase::common::ObLogger::get_logger().set_log_level("INFO"); OB_LOGGER.set_log_level("INFO"); testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); }