skip('support_process_tables() absent -- PR #7353 not merged into develop yet'); return; } $body = preg_replace('/^function\s+support_process_tables\s*\(\s*\)/m', 'function support_process_tables_integ_probe()', $m[0], 1, $rename_count); if ($rename_count !== 1) { throw new RuntimeException("expected exactly one support_process_tables() function rename, found $rename_count"); } eval($body); } support_process_tables_integration_define(); if (!function_exists('support_process_tables_integ_probe')) { return; } function support_process_tables_integration_connect(): mixed { if (!extension_loaded('pdo_mysql')) { return false; } return db_connect_real( getenv('CACTI_TEST_DB_HOST') ?: '127.0.0.1', getenv('CACTI_TEST_DB_USER') ?: 'cacti', getenv('CACTI_TEST_DB_PASS') ?: 'cacti', getenv('CACTI_TEST_DB_NAME') ?: 'cacti', 'mysql', (int) (getenv('CACTI_TEST_DB_PORT') ?: 3306), 1 ); } test('support_process_tables definitions execute as real SQL against a live database', function () { $conn = support_process_tables_integration_connect(); if (!is_object($conn)) { test()->markTestSkipped('no reachable MySQL/MariaDB connection; start docker-compose or set CACTI_TEST_DB_* to run this test.'); } if (!db_table_exists('poller_time', false, $conn)) { test()->markTestSkipped('connected, but the Cacti schema is not present (poller_time missing); import cacti.sql to run this test.'); } $definitions = support_process_tables_integ_probe(); // Mirror show_cacti_processes()'s own reduction: only tables that exist go // into the UNION, in registration order. $sql_inner = ''; foreach ($definitions as $definition) { if (db_table_exists($definition['table'], false, $conn)) { $sql_inner .= ($sql_inner != '' ? ' UNION ' : '') . $definition['select']; } } expect($sql_inner)->not->toBe(''); // The core poller_time table always exists once the schema is imported, so // the UNION is never empty here; a syntax error in any registered SELECT // fragment would surface as `false`, not as a legitimate row count. $total_rows = db_fetch_cell_prepared("SELECT COUNT(*) FROM ($sql_inner) AS rs", [], '', false, $conn); expect($total_rows)->not->toBeFalse() ->and(is_numeric($total_rows))->toBeTrue(); }); test('an empty table set produces a clean zero-row result, not a broken query', function () { $conn = support_process_tables_integration_connect(); if (!is_object($conn)) { test()->markTestSkipped('no reachable MySQL/MariaDB connection; start docker-compose or set CACTI_TEST_DB_* to run this test.'); } // Reproduces show_cacti_processes()'s guard for when db_table_exists() // filters out every candidate table: the function must short-circuit to an // empty result rather than ever building "FROM () AS rs". $sql_inner = ''; foreach (['nonexistent_table_one', 'nonexistent_table_two'] as $missing) { if (db_table_exists($missing, false, $conn)) { $sql_inner .= ($sql_inner != '' ? ' UNION ' : '') . "SELECT 1 FROM $missing"; } } expect($sql_inner)->toBe(''); });