mirror of https://github.com/sysown/proxysql
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
208 lines
5.7 KiB
208 lines
5.7 KiB
/**
|
|
* @file test_init.cpp
|
|
* @brief Implementation of component initialization helpers for unit tests.
|
|
*
|
|
* Each test_init_*() function creates real instances of ProxySQL components,
|
|
* bypassing the full daemon startup sequence. Components are assigned to
|
|
* their respective Glo* global pointers so that internal cross-references
|
|
* work correctly.
|
|
*
|
|
* @see test_init.h for the public interface and usage examples.
|
|
* @see Phase 2.1 of the Unit Testing Framework (GitHub issue #5473)
|
|
*/
|
|
|
|
#include "proxysql.h"
|
|
#include "cpp.h"
|
|
|
|
#include "MySQL_Authentication.hpp"
|
|
#include "PgSQL_Authentication.h"
|
|
#include "MySQL_Query_Cache.h"
|
|
#include "PgSQL_Query_Cache.h"
|
|
#include "MySQL_Query_Processor.h"
|
|
#include "PgSQL_Query_Processor.h"
|
|
|
|
#include "test_globals.h"
|
|
#include "test_init.h"
|
|
|
|
// Extern declarations for Glo* pointers defined in test_globals.cpp.
|
|
// These are normally defined in main.cpp and have no header declarations.
|
|
extern MySQL_Authentication *GloMyAuth;
|
|
extern PgSQL_Authentication *GloPgAuth;
|
|
extern MySQL_Query_Cache *GloMyQC;
|
|
extern PgSQL_Query_Cache *GloPgQC;
|
|
extern MySQL_Query_Processor *GloMyQPro;
|
|
extern PgSQL_Query_Processor *GloPgQPro;
|
|
|
|
// GloMTH is declared extern in proxysql_utils.h.
|
|
// GloPTH has no extern declaration in any header, so we add one here.
|
|
extern PgSQL_Threads_Handler *GloPTH;
|
|
|
|
// ============================================================================
|
|
// Minimal initialization
|
|
// ============================================================================
|
|
|
|
int test_init_minimal() {
|
|
return test_globals_init();
|
|
}
|
|
|
|
void test_cleanup_minimal() {
|
|
test_globals_cleanup();
|
|
}
|
|
|
|
// ============================================================================
|
|
// Authentication
|
|
// ============================================================================
|
|
|
|
int test_init_auth() {
|
|
if (GloMyAuth != nullptr || GloPgAuth != nullptr) {
|
|
// Already initialized — idempotent
|
|
return 0;
|
|
}
|
|
|
|
GloMyAuth = new MySQL_Authentication();
|
|
GloPgAuth = new PgSQL_Authentication();
|
|
|
|
return 0;
|
|
}
|
|
|
|
void test_cleanup_auth() {
|
|
if (GloMyAuth != nullptr) {
|
|
delete GloMyAuth;
|
|
GloMyAuth = nullptr;
|
|
}
|
|
if (GloPgAuth != nullptr) {
|
|
delete GloPgAuth;
|
|
GloPgAuth = nullptr;
|
|
}
|
|
}
|
|
|
|
// ============================================================================
|
|
// Query Cache
|
|
// ============================================================================
|
|
|
|
int test_init_query_cache() {
|
|
if (GloMyQC != nullptr || GloPgQC != nullptr) {
|
|
return 0;
|
|
}
|
|
|
|
// The Query_Cache constructor registers Prometheus metrics via
|
|
// GloVars.prometheus_registry. Provide a real registry so the
|
|
// constructor doesn't crash on nullptr dereference.
|
|
if (GloVars.prometheus_registry == nullptr) {
|
|
GloVars.prometheus_registry = std::make_shared<prometheus::Registry>();
|
|
}
|
|
|
|
GloMyQC = new MySQL_Query_Cache();
|
|
GloPgQC = new PgSQL_Query_Cache();
|
|
|
|
// NOTE: We intentionally do NOT start the purge thread here.
|
|
// Unit tests should call purgeHash() explicitly for deterministic
|
|
// behavior.
|
|
|
|
return 0;
|
|
}
|
|
|
|
void test_cleanup_query_cache() {
|
|
if (GloMyQC != nullptr) {
|
|
delete GloMyQC;
|
|
GloMyQC = nullptr;
|
|
}
|
|
if (GloPgQC != nullptr) {
|
|
delete GloPgQC;
|
|
GloPgQC = nullptr;
|
|
}
|
|
}
|
|
|
|
// ============================================================================
|
|
// Query Processor
|
|
// ============================================================================
|
|
|
|
int test_init_query_processor() {
|
|
if (GloMyQPro != nullptr || GloPgQPro != nullptr) {
|
|
return 0;
|
|
}
|
|
|
|
// Query Processor constructors register Prometheus metrics and
|
|
// read variables from GloMTH/GloPTH. Ensure both are available.
|
|
if (GloVars.prometheus_registry == nullptr) {
|
|
GloVars.prometheus_registry = std::make_shared<prometheus::Registry>();
|
|
}
|
|
if (GloMTH == nullptr) {
|
|
GloMTH = new MySQL_Threads_Handler();
|
|
}
|
|
if (GloPTH == nullptr) {
|
|
GloPTH = new PgSQL_Threads_Handler();
|
|
}
|
|
|
|
// Trigger lazy initialization of VariablesPointers maps.
|
|
// The QP constructor calls get_variable_int() which requires
|
|
// these maps to be populated.
|
|
char **vl = GloMTH->get_variables_list();
|
|
if (vl) {
|
|
for (char **p = vl; *p != nullptr; ++p) free(*p);
|
|
free(vl);
|
|
}
|
|
vl = GloPTH->get_variables_list();
|
|
if (vl) {
|
|
for (char **p = vl; *p != nullptr; ++p) free(*p);
|
|
free(vl);
|
|
}
|
|
|
|
GloMyQPro = new MySQL_Query_Processor();
|
|
GloPgQPro = new PgSQL_Query_Processor();
|
|
|
|
return 0;
|
|
}
|
|
|
|
void test_cleanup_query_processor() {
|
|
if (GloMyQPro != nullptr) {
|
|
delete GloMyQPro;
|
|
GloMyQPro = nullptr;
|
|
}
|
|
if (GloPgQPro != nullptr) {
|
|
delete GloPgQPro;
|
|
GloPgQPro = nullptr;
|
|
}
|
|
// NOTE: We do NOT delete GloMTH/GloPTH here because other
|
|
// components may still reference them. Their cleanup relies
|
|
// on process exit.
|
|
}
|
|
|
|
// ============================================================================
|
|
// HostGroups Manager
|
|
// ============================================================================
|
|
|
|
int test_init_hostgroups() {
|
|
// HostGroups Manager constructors register Prometheus metrics.
|
|
if (GloVars.prometheus_registry == nullptr) {
|
|
GloVars.prometheus_registry = std::make_shared<prometheus::Registry>();
|
|
}
|
|
|
|
if (MyHGM == nullptr) {
|
|
MyHGM = new MySQL_HostGroups_Manager();
|
|
// NOTE: We intentionally do NOT call MyHGM->init() here.
|
|
// init() starts background threads (HGCU_thread, GTID_syncer)
|
|
// that run forever and would cause the test process to hang on
|
|
// exit. The constructor alone sets up the internal SQLite3
|
|
// database and all data structures needed for unit testing.
|
|
}
|
|
|
|
if (PgHGM == nullptr) {
|
|
PgHGM = new PgSQL_HostGroups_Manager();
|
|
// PgHGM->init() is a no-op, but we skip it for consistency.
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
void test_cleanup_hostgroups() {
|
|
if (MyHGM != nullptr) {
|
|
delete MyHGM;
|
|
MyHGM = nullptr;
|
|
}
|
|
if (PgHGM != nullptr) {
|
|
delete PgHGM;
|
|
PgHGM = nullptr;
|
|
}
|
|
}
|