Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion includes/functions.php
Original file line number Diff line number Diff line change
Expand Up @@ -3423,7 +3423,7 @@ function thold_check_threshold(&$thold_data) {
}
}

if (api_plugin_is_enabled('maint') && plugin_maint_check_cacti_host($thold_data['host_id'])) {
if (api_plugin_is_enabled('maint') && function_exists('plugin_maint_check_cacti_host') && plugin_maint_check_cacti_host($thold_data['host_id'])) {
$maint_dev = true;
} else {
$maint_dev = false;
Expand Down
4 changes: 2 additions & 2 deletions includes/polling.php
Original file line number Diff line number Diff line change
Expand Up @@ -637,7 +637,7 @@ function thold_update_host_status() {
$msg = thold_str_replace('<NOTES>', $host['notes'], $msg);
$msg = thold_str_replace("\n", '<br>', $msg);

if (api_plugin_is_enabled('maint') && plugin_maint_check_cacti_host($host['id'])) {
if (api_plugin_is_enabled('maint') && function_exists('plugin_maint_check_cacti_host') && plugin_maint_check_cacti_host($host['id'])) {
cacti_log('WARNING: Device[' . $host['id'] . '] Hostname[' . $host['hostname'] . '] is recovering! Only logging, maint device', true, 'THOLD');
} else {
switch ($host['thold_send_email']) {
Expand Down Expand Up @@ -764,7 +764,7 @@ function thold_update_host_status() {

$alert_email = read_config_option('alert_email');

if (api_plugin_is_enabled('maint') && plugin_maint_check_cacti_host($host['id'])) {
if (api_plugin_is_enabled('maint') && function_exists('plugin_maint_check_cacti_host') && plugin_maint_check_cacti_host($host['id'])) {
cacti_log('WARNING: Device[' . $host['id'] . '] Hostname[' . $host['hostname'] . '] is DOWN. Only logging, maint device', true, 'THOLD');
} else {
if (strtotime($host['status_fail_date']) > 192800 || strtotime($host['status_rec_date']) > 192800) {
Expand Down
123 changes: 123 additions & 0 deletions tests/Unit/MaintCheckGuardTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
<?php
/*
+-------------------------------------------------------------------------+
| Copyright (C) 2004-2026 The Cacti Group |
| |
| This program is free software; you can redistribute it and/or |
| modify it under the terms of the GNU General Public License |
| as published by the Free Software Foundation; either version 2 |
| of the License, or (at your option) any later version. |
+-------------------------------------------------------------------------+
| Cacti: The Complete RRDtool-based Graphing Solution |
+-------------------------------------------------------------------------+
| http://www.cacti.net/ |
+-------------------------------------------------------------------------+
*/

/**
* thold_update_host_status() consults the maint plugin for both the
* recovering-device and down-device notification loops. The call is now
* guarded by function_exists('plugin_maint_check_cacti_host') so a maint
* plugin that is enabled but whose functions file could not be included no
* longer fatals with an undefined-function error. These tests drive both
* maintenance-gated branches so that guard stays in place.
*/
final class MaintCheckGuardTest extends TestCase {
/**
* @return void
*/
public static function setUpBeforeClass(): void {
self::loadPluginSource('includes/functions.php');
self::loadPluginSource('includes/polling.php');
self::loadPluginSourceAlways('includes/arrays.php');
self::loadPluginConstants();
}

/**
* @return string
*/
private function maintIncludesRoot() {
return dirname(__DIR__) . '/Fixtures/cacti-root-maint-includes';
}

/**
* Run thold_update_host_status() against the newer maint layout. A device
* inside a maintenance window is logged and the loop moves on without the
* downstream notification work, so the call returns on its own. Expected
* engine warnings are suppressed, but no Throwable is swallowed, so an
* unexpected error (e.g. a removed guard fataling on an undefined maint
* function) fails the test.
*
* @return void
*/
private function runHostStatus() {
CactiStubs::willAlwaysReturn('api_plugin_is_enabled', true);
Comment thread
TheWitness marked this conversation as resolved.
CactiStubs::willAlwaysReturn('plugin_maint_check_cacti_host', true);
CactiStubs::$configOptions['alert_deadnotify'] = 'on';
$GLOBALS['config']['base_path'] = $this->maintIncludesRoot();
Comment thread
TheWitness marked this conversation as resolved.

set_error_handler(static fn (): bool => true);
ob_start();

try {
thold_update_host_status();
} finally {
ob_end_clean();
restore_error_handler();
}
}

/**
* A recovered device inside a maintenance window is logged, not alerted.
*
* @return void
*/
public function testRecoveringDeviceInMaintenanceIsLoggedNotAlerted(): void {
CactiStubs::willReturnFor('db_fetch_assoc', 'plugin_thold_host_failed', [['host_id' => 42]]);
CactiStubs::willReturnFor('db_fetch_row_prepared', 'FROM host WHERE id', [
'id' => 42,
'hostname' => 'dev42',
'description' => 'Device 42',
'status' => HOST_UP,
'snmp_community' => '',
'snmp_username' => '',
'snmp_version' => 0,
'site_id' => 0,
'location' => '',
'notes' => '',
'status_fail_date' => '0000-00-00 00:00:00',
'availability' => 100,
'total_polls' => 1,
'failed_polls' => 0,
'cur_time' => 0,
'avg_time' => 0,
'thold_send_email' => '0',
]);

$this->runHostStatus();

$this->assertContains(
'WARNING: Device[42] Hostname[dev42] is recovering! Only logging, maint device',
CactiStubs::$log
);
}

/**
* A down device inside a maintenance window is logged, not alerted.
*
* @return void
*/
public function testDownDeviceInMaintenanceIsLoggedNotAlerted(): void {
CactiStubs::willReturnFor('db_fetch_assoc_prepared', 'availability_method', [[
'id' => 77,
'hostname' => 'dev77',
]]);

$this->runHostStatus();

$this->assertContains(
'WARNING: Device[77] Hostname[dev77] is DOWN. Only logging, maint device',
CactiStubs::$log
);
}
}
6 changes: 6 additions & 0 deletions tests/bootstrap-unit.php
Original file line number Diff line number Diff line change
Expand Up @@ -669,6 +669,12 @@ function number_format_i18n($number, $decimals = 0, $baseu = 1000) {
}
}

if (!function_exists('html_split_string')) {
function html_split_string($string, $length = 76, $forgiving = 10) {
return $string;
}
}

if (!defined('FILTER_VALIDATE_IS_REGEX')) {
define('FILTER_VALIDATE_IS_REGEX', 99999);
}
Expand Down
Loading