$cacti_root, 'url_path' => '/cacti/', 'cacti_version' => $cacti_version, 'cacti_server_os' => 'unix', ); $GLOBALS['__test_db_calls'] = array(); $GLOBALS['__test_request'] = array(); $GLOBALS['__test_db_fixtures'] = array(); if (!function_exists('get_md5_include_js')) { function get_md5_include_js($path, $async = false) { return ""; } } if (!function_exists('get_md5_include_css')) { function get_md5_include_css($path) { return ""; } } if (!function_exists('get_selected_theme')) { function get_selected_theme() { return $GLOBALS['__test_selected_theme'] ?? 'modern'; } } if (!function_exists('monitor_test_mock_db')) { function monitor_test_mock_db($fn, $match, $result) { $GLOBALS['__test_db_fixtures'][] = array('fn' => $fn, 'match' => $match, 'result' => $result); } } if (!function_exists('monitor_test_reset_db_mocks')) { function monitor_test_reset_db_mocks() { $GLOBALS['__test_db_fixtures'] = array(); } } if (!function_exists('monitor_test_db_result')) { function monitor_test_db_result($fn, $sql, $params, $default) { foreach (array_reverse($GLOBALS['__test_db_fixtures']) as $fixture) { if ($fixture['fn'] !== $fn) { continue; } $match = $fixture['match']; if (is_callable($match)) { if (!$match($sql, $params)) { continue; } } elseif (strpos($sql, $match) === false) { continue; } $result = $fixture['result']; return is_callable($result) ? $result($sql, $params) : $result; } return $default; } } if (!function_exists('db_execute')) { function db_execute($sql) { $GLOBALS['__test_db_calls'][] = array('fn' => 'db_execute', 'sql' => $sql, 'params' => array()); return true; } } if (!function_exists('db_execute_prepared')) { function db_execute_prepared($sql, $params = array()) { $GLOBALS['__test_db_calls'][] = array('fn' => 'db_execute_prepared', 'sql' => $sql, 'params' => $params); return true; } } if (!function_exists('db_fetch_assoc')) { function db_fetch_assoc($sql) { return monitor_test_db_result('db_fetch_assoc', $sql, array(), array()); } } if (!function_exists('db_fetch_assoc_prepared')) { function db_fetch_assoc_prepared($sql, $params = array()) { return monitor_test_db_result('db_fetch_assoc_prepared', $sql, $params, array()); } } if (!function_exists('db_fetch_row')) { function db_fetch_row($sql) { return array(); } } if (!function_exists('db_fetch_row_prepared')) { function db_fetch_row_prepared($sql, $params = array()) { return array(); } } if (!function_exists('db_fetch_cell')) { function db_fetch_cell($sql) { return monitor_test_db_result('db_fetch_cell', $sql, array(), ''); } } if (!function_exists('db_fetch_cell_prepared')) { function db_fetch_cell_prepared($sql, $params = array()) { return monitor_test_db_result('db_fetch_cell_prepared', $sql, $params, ''); } } if (!function_exists('db_index_exists')) { function db_index_exists($table, $index) { return false; } } if (!function_exists('db_column_exists')) { function db_column_exists($table, $column) { return monitor_test_db_result('db_column_exists', $table . '.' . $column, array(), false); } } if (!function_exists('api_plugin_is_enabled')) { function api_plugin_is_enabled($plugin) { return monitor_test_db_result('api_plugin_is_enabled', $plugin, array(), false); } } if (!function_exists('api_plugin_user_realm_auth')) { function api_plugin_user_realm_auth($file) { return monitor_test_db_result('api_plugin_user_realm_auth', $file, array(), false); } } if (!function_exists('array_rekey')) { function array_rekey($array, $key, $value_array) { $return_array = array(); if (!empty($array)) { foreach ($array as $item) { $item_key = $item[$key]; if (is_array($value_array)) { foreach ($value_array as $value) { $return_array[$item_key][$value] = $item[$value]; } } else { $return_array[$item_key] = $item[$value_array]; } } } return $return_array; } } if (!function_exists('db_table_exists')) { function db_table_exists($table) { return monitor_test_db_result('db_table_exists', $table, array(), false); } } if (!function_exists('api_plugin_db_add_column')) { function api_plugin_db_add_column($plugin, $table, $data) { return true; } } if (!function_exists('db_add_column')) { function db_add_column($table, $data) { return true; } } if (!function_exists('db_remove_column')) { function db_remove_column($table, $column) { $GLOBALS['__test_db_calls'][] = array('fn' => 'db_remove_column', 'table' => $table, 'column' => $column, 'sql' => $table); return true; } } if (!function_exists('api_plugin_db_table_create')) { function api_plugin_db_table_create($plugin, $table, $data) { $GLOBALS['__test_db_calls'][] = array('fn' => 'api_plugin_db_table_create', 'plugin' => $plugin, 'table' => $table, 'data' => $data, 'sql' => $table); return true; } } if (!function_exists('db_update_table')) { function db_update_table($table, $data) { $GLOBALS['__test_db_calls'][] = array('fn' => 'db_update_table', 'table' => $table, 'data' => $data, 'sql' => $table); return true; } } $GLOBALS['__test_registered_hooks'] = array(); if (!function_exists('api_plugin_register_hook')) { function api_plugin_register_hook($plugin, $hook, $function, $file, $subtype = '') { $GLOBALS['__test_registered_hooks'][] = array( 'name' => $plugin, 'hook' => $hook, 'function' => $function, 'file' => $file, ); return true; } } $GLOBALS['__test_registered_realms'] = array(); if (!function_exists('api_plugin_register_realm')) { function api_plugin_register_realm($plugin, $file, $description, $enabled) { $GLOBALS['__test_registered_realms'][] = array( 'name' => $plugin, 'file' => $file, 'description' => $description, 'enabled' => $enabled, ); return true; } } $GLOBALS['__test_exec_calls'] = array(); if (!function_exists('exec_background')) { function exec_background($command, $args = '') { $GLOBALS['__test_exec_calls'][] = array('command' => $command, 'args' => $args); } } if (!function_exists('read_config_option')) { function read_config_option($name, $force = false) { return isset($GLOBALS['__test_config_options'][$name]) ? $GLOBALS['__test_config_options'][$name] : ''; } } if (!function_exists('set_config_option')) { function set_config_option($name, $value) { $GLOBALS['__test_config_options'][$name] = $value; } } if (!function_exists('read_user_setting')) { function read_user_setting($name, $default = '', $user = 0) { return $default; } } if (!function_exists('set_user_setting')) { function set_user_setting($name, $value, $user = 0) { } } if (!function_exists('html_escape')) { function html_escape($string) { return htmlspecialchars($string, ENT_QUOTES | ENT_HTML5, 'UTF-8'); } } if (!function_exists('__')) { function __($text, $domain = '') { return $text; } } if (!function_exists('__esc')) { function __esc($text, $domain = '') { return htmlspecialchars($text, ENT_QUOTES | ENT_HTML5, 'UTF-8'); } } if (!function_exists('cacti_log')) { function cacti_log($message, $also_print = false, $log_type = '', $level = 0) { $args = func_get_args(); $GLOBALS["__test_cacti_log"][] = isset($args[0]) ? (string) $args[0] : ""; } } if (!function_exists('cacti_sizeof')) { function cacti_sizeof($array) { return is_array($array) ? count($array) : 0; } } if (!function_exists('is_realm_allowed')) { function is_realm_allowed($realm) { return true; } } if (!function_exists('raise_message')) { function raise_message($id, $text = '', $level = 0) { $GLOBALS['__test_messages'][] = array('id' => $id, 'text' => $text, 'level' => $level); } } if (!function_exists('get_request_var')) { function get_request_var($name) { return $GLOBALS['__test_request'][$name] ?? ''; } } if (!function_exists('isset_request_var')) { function isset_request_var($name) { return isset($GLOBALS['__test_request'][$name]); } } if (!function_exists('validate_store_request_vars')) { function validate_store_request_vars($filters, $sess_prefix = '') { } } if (!function_exists('get_nfilter_request_var')) { function get_nfilter_request_var($name) { return get_request_var($name); } } if (!function_exists('get_filter_request_var')) { function get_filter_request_var($name) { return get_request_var($name); } } if (!function_exists('set_request_var')) { function set_request_var($name, $value) { $GLOBALS['__test_request'][$name] = $value; } } /** * Set the stubbed request vars a test needs, resetting the rest. * * @param array $vars * * @return void */ function test_set_request(array $vars): void { $GLOBALS['__test_request'] = $vars; } // validateRequestVars() is not stubbed here: includes/controller.php declares // it unconditionally, so a global stub would fatal with a redeclare error // once a test loads that file via loadPluginSource()/monitor_test_load(). if (!function_exists('form_input_validate')) { function form_input_validate($value, $name, $regex, $optional, $error) { return $value; } } if (!function_exists('is_error_message')) { function is_error_message() { return false; } } if (!function_exists('sql_save')) { function sql_save($array, $table, $key = 'id') { $GLOBALS['__test_db_calls'][] = array('fn' => 'sql_save', 'table' => $table, 'data' => $array); return isset($array['id']) ? $array['id'] : 1; } } if (!defined('CACTI_PATH_BASE')) { define('CACTI_PATH_BASE', $GLOBALS['config']['base_path']); } if (!defined('POLLER_VERBOSITY_LOW')) { define('POLLER_VERBOSITY_LOW', 2); } if (!defined('POLLER_VERBOSITY_MEDIUM')) { define('POLLER_VERBOSITY_MEDIUM', 3); } if (!defined('POLLER_VERBOSITY_DEBUG')) { define('POLLER_VERBOSITY_DEBUG', 5); } if (!defined('POLLER_VERBOSITY_NONE')) { define('POLLER_VERBOSITY_NONE', 6); } if (!defined('FILTER_VALIDATE_IS_REGEX')) { define('FILTER_VALIDATE_IS_REGEX', 99999); } if (!defined('MESSAGE_LEVEL_INFO')) { define('MESSAGE_LEVEL_INFO', 1); } if (!defined('MESSAGE_LEVEL_ERROR')) { define('MESSAGE_LEVEL_ERROR', 3); } if (!function_exists('plugin_test_read_source')) { function plugin_test_read_source($relative_file) { $path = realpath(__DIR__ . '/../' . $relative_file); if ($path === false) { throw new RuntimeException("Unable to resolve required file: {$relative_file}"); } $contents = file_get_contents($path); if ($contents === false) { throw new RuntimeException("Unable to read required file: {$relative_file}"); } return $contents; } } /** * Load a plugin source file at global scope. * * Some plugin files define data as file-scope variables that the rest of * the plugin reads as globals, and they read $config while doing so. * Requiring them from inside a method would make both halves of that * method-local, so the require happens here and any variable the file * introduced is published to $GLOBALS. * * @param string $path Absolute path to the file. * * @return void */ function monitor_test_load($path) { global $config; $__before = get_defined_vars(); require_once $path; foreach (get_defined_vars() as $__name => $__value) { if (!array_key_exists($__name, $__before) && strncmp($__name, '__', 2) !== 0) { $GLOBALS[$__name] = $__value; } } }