Skip to content

Commit 1509975

Browse files
committed
Update 'test_prometheus_metrics-t' with new coherence tests
This new set of tests aims to check consistency between metrics exposed by both, the Admin interface and the Prometheus exporter.
1 parent 5c79db3 commit 1509975

File tree

1 file changed

+175
-2
lines changed

1 file changed

+175
-2
lines changed

test/tap/tests/test_prometheus_metrics-t.cpp

Lines changed: 175 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ using std::vector;
2929
using std::pair;
3030
using std::string;
3131
using std::tuple;
32+
using std::map;
3233

3334
CommandLine cl;
3435

@@ -891,7 +892,157 @@ const vector<pair<string, tuple<setup, metric_trigger, metric_check>>> metric_te
891892
},
892893
};
893894

894-
using std::map;
895+
string status_to_string(int status) {
896+
if (status == 1) {
897+
return "ONLINE";
898+
} else if (status == 2) {
899+
return "SHUNNED";
900+
} else if (status == 3) {
901+
return "OFFLINE_SOFT";
902+
} else if (status == 4) {
903+
return "OFFLINE_HARD";
904+
} else if (status == 5) {
905+
return "SHUNNED_REPLICATION_LAG";
906+
} else {
907+
assert(0);
908+
}
909+
}
910+
911+
const char RUNTIME_SRVS[] {
912+
"SELECT"
913+
" hostgroup_id,"
914+
" (hostname || \":\" || port) AS endpoint,"
915+
" gtid_port,"
916+
" status,"
917+
" weight,"
918+
" compression,"
919+
" max_connections,"
920+
" max_replication_lag,"
921+
" use_ssl,"
922+
" max_latency_ms"
923+
" FROM"
924+
" runtime_mysql_servers"
925+
};
926+
927+
enum SRV_FLD {
928+
hosgroup_id = 0,
929+
endpoint,
930+
gtid_port,
931+
status,
932+
weight,
933+
compression,
934+
max_connections,
935+
max_replication_lag,
936+
use_ssl,
937+
max_latency_ms
938+
};
939+
940+
const map<string,int> m_srvs_metrics {
941+
{ "proxysql_runtime_mysql_servers_status", SRV_FLD::status },
942+
{ "proxysql_runtime_mysql_servers_weight", SRV_FLD::weight },
943+
{ "proxysql_runtime_mysql_servers_compression", SRV_FLD::compression },
944+
{ "proxysql_runtime_mysql_servers_max_connections", SRV_FLD::max_connections },
945+
{ "proxysql_runtime_mysql_servers_max_replication_lag", SRV_FLD::max_replication_lag },
946+
{ "proxysql_runtime_mysql_servers_use_ssl", SRV_FLD::use_ssl },
947+
{ "proxysql_runtime_mysql_servers_max_latency_ms", SRV_FLD::max_latency_ms },
948+
};
949+
950+
using p_srv_metrics = pair<mysql_row_t,vector<pair<string,double>>>;
951+
using nlohmann::json;
952+
953+
int check_srvs_metrics(
954+
const vector<mysql_row_t>& srvs, const map<string,double>& cur_metrics
955+
) {
956+
const auto match_start = [] (const string s1, const string s2) {
957+
return s1.rfind(s2) == 0;
958+
};
959+
960+
// 1. Find all defined metrics
961+
bool match = true;
962+
const uint32_t exp_checks = m_srvs_metrics.size() * srvs.size();
963+
uint32_t act_checks = 0;
964+
965+
// 2. Check all defined metrics match
966+
for (const mysql_row_t& row : srvs) {
967+
diag(
968+
"Checking matching ept metrics for server srv_row=\"%s\"",
969+
json(row).dump().c_str()
970+
);
971+
972+
for (const auto& p_id_val : cur_metrics) {
973+
auto metric_it {
974+
std::find_if(m_srvs_metrics.begin(), m_srvs_metrics.end(),
975+
[p_id_val] (const auto& p) { return p_id_val.first.rfind(p.first, 0) == 0; }
976+
)
977+
};
978+
979+
if (metric_it != std::end(m_srvs_metrics)) {
980+
const string& srv_ept { row[SRV_FLD::endpoint] };
981+
const string& srv_hg { row[SRV_FLD::hosgroup_id] };
982+
const auto& tags { extract_metric_tags(p_id_val.first) };
983+
984+
if (tags.at("endpoint") == srv_ept && tags.at("hostgroup") == srv_hg) {
985+
diag(
986+
"Checking matching ept metric ept=\"%s\" hg=%s metric=\"%s\" val=%lf",
987+
srv_ept.c_str(), srv_hg.c_str(), p_id_val.first.c_str(), p_id_val.second
988+
);
989+
990+
const string mval_str {
991+
metric_it->first.rfind("status") != std::string::npos ?
992+
status_to_string(int32_t(p_id_val.second))
993+
: std::to_string(int32_t(p_id_val.second))
994+
};
995+
996+
match = row[metric_it->second] == mval_str;
997+
match = row[SRV_FLD::gtid_port] == tags.at("gtid_port");
998+
act_checks += 1;
999+
1000+
if (!match) {
1001+
diag(
1002+
"FAIL - Mismatch found checking metric "
1003+
"exp_val=%s act_val=%s exp_gtid_port=%s act_gtid_port=%s",
1004+
row[metric_it->second].c_str(),
1005+
mval_str.c_str(),
1006+
row[SRV_FLD::gtid_port].c_str(),
1007+
tags.at("gtid_port").c_str()
1008+
);
1009+
}
1010+
}
1011+
}
1012+
}
1013+
}
1014+
1015+
ok(match, "Metrics values should match for Admin and Exporter");
1016+
ok(
1017+
exp_checks == act_checks,
1018+
"All supported metrics should be found for server entries exp_checks=%d act_checks=%d",
1019+
exp_checks, act_checks
1020+
);
1021+
1022+
return EXIT_SUCCESS;
1023+
}
1024+
1025+
int coherence_check_runtime_servers(MYSQL* admin) {
1026+
map<string,double> cur_metrics {};
1027+
int rc = get_cur_metrics(admin, cur_metrics);
1028+
if (rc) { return EXIT_FAILURE; }
1029+
1030+
auto srvs_rows { mysql_query_ext_rows(admin, RUNTIME_SRVS) };
1031+
if (srvs_rows.first) {
1032+
diag(
1033+
"Failed to fetch 'runtime_mysql_servers' rows errno=%d error=\"%s\" query=\"%s\"",
1034+
srvs_rows.first, mysql_error(admin), RUNTIME_SRVS
1035+
);
1036+
return EXIT_FAILURE;
1037+
}
1038+
1039+
return check_srvs_metrics(srvs_rows.second, cur_metrics);
1040+
}
1041+
1042+
const vector<pair<string, std::function<int(MYSQL*)>>> coherence_checks {
1043+
// Check current 'runtime_mysql_servers' values matches the ones exposed by its metrics
1044+
{ "proxysql_runtime_mysql_servers_{*} - Matching Admin Interface", coherence_check_runtime_servers },
1045+
};
8951046

8961047

8971048
int main(int argc, char** argv) {
@@ -901,7 +1052,10 @@ int main(int argc, char** argv) {
9011052
return EXIT_FAILURE;
9021053
}
9031054

904-
plan(metric_tests.size() * 4);
1055+
plan(
1056+
metric_tests.size() * 4
1057+
+ coherence_checks.size() * 2
1058+
);
9051059

9061060
for (const auto& metric_test : metric_tests) {
9071061
// Initialize Admin connection
@@ -959,5 +1113,24 @@ int main(int argc, char** argv) {
9591113
mysql_close(proxysql_admin);
9601114
}
9611115

1116+
{
1117+
MYSQL* admin = mysql_init(NULL);
1118+
1119+
if (!mysql_real_connect(admin, cl.host, cl.admin_username, cl.admin_password, NULL, cl.admin_port, NULL, 0)) {
1120+
fprintf(stderr, "File %s, line %d, Error: %s\n", __FILE__, __LINE__, mysql_error(admin));
1121+
return EXIT_FAILURE;
1122+
}
1123+
1124+
for (const auto& p_id_check : coherence_checks) {
1125+
const string& id { p_id_check.first.c_str() };
1126+
1127+
diag("Started metrics coherence check id=\"%s\"", id.c_str());
1128+
int rc = p_id_check.second(admin);
1129+
diag("Finished metric coherence check id=\"%s\" rc=%d", id.c_str(), rc);
1130+
}
1131+
1132+
mysql_close(admin);
1133+
}
1134+
9621135
return exit_status();
9631136
}

0 commit comments

Comments
 (0)