oceanbase/mittest/ob_mittest_utils.h
stdliu f8c5c2647f [FEAT MERGE] Merge syslog user experience improvement to master
Co-authored-by: Charles0429 <xiezhenjiang@gmail.com>
Co-authored-by: tino247 <tino247@126.com>
Co-authored-by: chaser-ch <chaser.ch@antgroup.com>
2023-02-06 15:52:24 +08:00

170 lines
5.0 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.
*/
#ifndef OCEANBASE_UNITTEST_CLUSTER_OB_UTILS_H
#define OCEANBASE_UNITTEST_CLUSTER_OB_UTILS_H
#include <sys/stat.h>
#include <sys/types.h>
#include <gmock/gmock.h>
#include <unistd.h>
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
#include <netinet/in.h>
#include "lib/oblog/ob_log.h"
#include "lib/oblog/ob_log_module.h"
#include "lib/utility/ob_macro_utils.h"
#include "lib/time/ob_time_utility.h"
namespace oceanbase
{
namespace unittest
{
std::string __attribute__ ((weak)) _executeShellCommand(std::string command)
{
char buffer[256];
std::string result = "";
const char * cmd = command.c_str();
FILE* pipe = popen(cmd, "r");
if (!pipe) throw std::runtime_error("popen() failed!");
try {
while (!feof(pipe))
if (fgets(buffer, 128, pipe) != NULL)
result += buffer;
} catch (...) {
pclose(pipe);
throw;
}
pclose(pipe);
return result;
}
bool __attribute__ ((weak)) _isAvailablePort(unsigned short usPort)
{
char shellCommand[256], pcPort[6];
sprintf(shellCommand, "netstat -lntu | awk '{print $4}' | grep ':' | cut -d \":\" -f 2 | sort | uniq | grep %hu", usPort);
sprintf(pcPort, "%hu", usPort);
std::string output = _executeShellCommand(std::string(shellCommand));
if(output.find(std::string(pcPort)) != std::string::npos)
return false;
else
return true;
}
int __attribute__ ((weak)) listen_occupy_port(int port, int &server_fd_ret)
{
struct sockaddr_in address;
int opt = 1;
int server_fd;
if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) {
perror("socket failed");
return -1;
}
memset(&address, '0', sizeof(address));
if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR,
&opt, sizeof(opt))) {
perror("setsockopt");
return -1;
}
address.sin_family = AF_INET;
address.sin_addr.s_addr = INADDR_ANY;
address.sin_port = htons(port);
if (bind(server_fd, (struct sockaddr *)&address,
sizeof(address))<0) {
perror("bind failed");
return -1;
}
if (listen(server_fd, 3) < 0) {
perror("listen");
return -1;
}
server_fd_ret = server_fd;
return 0;
}
void __attribute__ ((weak)) get_netport_range(int &start_port, int &end_port)
{
char *mit_network_start_port_env = getenv("mit_network_start_port");
char *mit_network_port_num_env = getenv("mit_network_port_num");
if (mit_network_start_port_env != nullptr && mit_network_port_num_env != nullptr) {
start_port = atoi(mit_network_start_port_env);
end_port = atoi(mit_network_port_num_env) + start_port;
start_port = (start_port+3) / 3 * 3;
STORAGE_LOG(INFO, "get netport from env", K(start_port), K(end_port));
} else {
//srand(oceanbase::common::ObTimeUtility::current_time());
start_port = 11000;
end_port = start_port + 100;
STORAGE_LOG(INFO, "get netport rand", K(start_port), K(end_port));
}
}
int64_t __attribute__ ((weak)) get_rpc_port(int &server_fd_ret)
{
int find_port = 0;
server_fd_ret = 0;
int server_fd = -1;
int server_fd1 = -1;
int server_fd2 = -1;
int start_port = 0;
int end_port = 0;
get_netport_range(start_port, end_port);
for (int port = start_port; port + 2 < end_port; port = port + 3) {
if (_isAvailablePort(port) && _isAvailablePort(port + 1) && _isAvailablePort(port + 2)) {
bool can_use = false;
bool can_use1 = false;
bool can_use2 = false;
can_use = (listen_occupy_port(port, server_fd) == 0);
if (can_use) {
can_use1 = (listen_occupy_port(port+1, server_fd1) == 0);
if (can_use1) {
can_use2 = (listen_occupy_port(port+2, server_fd2) == 0);
}
}
if (can_use && can_use1 && can_use2) {
find_port = port + 1;
server_fd_ret = server_fd;
close(server_fd1);
close(server_fd2);
break;
} else {
STORAGE_LOG(INFO, "find port fail continue try", K(can_use), K(can_use1), K(can_use2), K(port));
if (can_use) {
close(server_fd);
}
if (can_use1) {
close(server_fd1);
}
if (can_use2) {
close(server_fd2);
}
sleep(1);
}
}
}
STORAGE_LOG(INFO, "find port", K(find_port));
if (find_port == 0) {
STORAGE_LOG_RET(WARN, OB_ERR_UNEXPECTED, "find port fail", K(find_port));
STORAGE_LOG_RET(WARN, OB_ERR_UNEXPECTED, "net", "ss", _executeShellCommand("ss -antlp").c_str());
OB_ASSERT(false);
}
return find_port;
}
}
}
#endif