Skip to content

Commit

Permalink
Add TAP test checking thread conns distribution
Browse files Browse the repository at this point in the history
  • Loading branch information
JavierJF committed Aug 8, 2024
1 parent b19106a commit 1fdaad0
Showing 1 changed file with 132 additions and 0 deletions.
132 changes: 132 additions & 0 deletions test/tap/tests/test_thread_conn_dist-t.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
#include <chrono>
#include <map>
#include <string>
#include <utility>
#include <vector>

#include <sys/resource.h>
#include <unistd.h>

#include "tap.h"
#include "command_line.h"
#include "utils.h"

#include "mysql.h"
#include "json.hpp"

using std::map;
using std::pair;
using std::string;
using std::vector;

using nlohmann::json;

#define TAP_NAME "TAP_THREAD_CONN_DIST___"

const int TEST_DURATION_SEC = get_env_int(TAP_NAME"TEST_DURATION_SEC", 20);
const int ITER_CONN_COUNT = get_env_int(TAP_NAME"ITER_CONN_COUNT", 256);

void incr_proc_limits(uint32_t MAX_CONN_COUNT) {
diag("Elevating process limits if required for conns creation");

struct rlimit limits { 0, 0 };
getrlimit(RLIMIT_NOFILE, &limits);
diag("Old process limits rlim_cur=%ld rlim_max=%ld", limits.rlim_cur, limits.rlim_max);

if (limits.rlim_cur < MAX_CONN_COUNT * 2) {
diag("Updating process max FD limit");
limits.rlim_cur = MAX_CONN_COUNT * 2;
setrlimit(RLIMIT_NOFILE, &limits);
}

diag("New process limits rlim_cur=%ld rlim_max=%ld", limits.rlim_cur, limits.rlim_max);
}

pair<uint32_t,vector<MYSQL*>> create_frontend_conns(CommandLine& cl, uint32_t CONNS_TOTAL) {
vector<MYSQL*> conns {};

for (int i = 0; i < CONNS_TOTAL; i++) {
MYSQL* myconn = mysql_init(NULL);

if (!mysql_real_connect(myconn, cl.host, cl.username, cl.password, NULL, cl.port, NULL, 0)) {
diag(
"Failed to connect addr=%s port=%d user=%s pass=%s err=%s",
cl.host, cl.port, cl.username, cl.password, mysql_error(myconn)
);
return { EXIT_FAILURE, {} };
}

conns.push_back(myconn);
}

return { EXIT_SUCCESS, conns };
}

void check_thread_conn_dist(const map<string,vector<MYSQL*>>& m_thread_conns) {
size_t lo_count = 0;
size_t hg_count = 0;

diag("Dumping per-thread conn count:");
for (const pair<string,vector<MYSQL*>>& thread_conns : m_thread_conns) {
if (lo_count == 0 || thread_conns.second.size() < lo_count) {
lo_count = thread_conns.second.size();
}
if (hg_count == 0 || thread_conns.second.size() > hg_count) {
hg_count = thread_conns.second.size();
}
fprintf(stderr, "Map entry thread=%s count=%ld\n", thread_conns.first.c_str(), thread_conns.second.size());
}

ok(
hg_count / 2 < lo_count,
"Half the highest conn count shouldn't be higher than lowest conn count"
" hg_count=%ld lo_count=%ld",
hg_count, lo_count
);
}

void update_conn_thread_map(vector<MYSQL*>& conns, map<string,vector<MYSQL*>>& m_thread_conns) {
for (MYSQL* myconn : conns) {
json j_session = fetch_internal_session(myconn, false);
string thread_addr { j_session["thread"] };

m_thread_conns[thread_addr].push_back(myconn);
}
}

int main(int argc, char** argv) {
CommandLine cl;

if (cl.getEnv()) {
diag("Failed to get the required environmental variables.");
return EXIT_FAILURE;
}

plan(1);

auto start = std::chrono::system_clock::now();
std::chrono::duration<double> elapsed {};

incr_proc_limits(ITER_CONN_COUNT);

map<string,vector<MYSQL*>> m_thread_conns {};

while (elapsed.count() < TEST_DURATION_SEC) {
pair<uint32_t,vector<MYSQL*>> p_err_conns { create_frontend_conns(cl, ITER_CONN_COUNT) };
if (p_err_conns.first) {
diag("Frontend conn creation failed; aborting further testing err=%d", p_err_conns.first);
return EXIT_FAILURE;
}

update_conn_thread_map(p_err_conns.second, m_thread_conns);

for (MYSQL* conn : p_err_conns.second) {
mysql_close(conn);
}

auto it_end = std::chrono::system_clock::now();
elapsed = it_end - start;
}

check_thread_conn_dist(m_thread_conns);
}

0 comments on commit 1fdaad0

Please sign in to comment.