$overrides * * @return ThresholdScenario */ private function bounded(array $overrides = []) { return ThresholdScenario::threshold($overrides + [ 'thold_type' => 2, 'time_hi' => 90, 'time_low' => 10, ])->alertRecipient('ops@example.org'); } /** * @return void */ public function testReadingInsideBothBoundsEmitsNothing(): void { $outcome = $this->bounded(['lastread' => 50])->poll(); $this->assertTrue($outcome->isSilent()); } /** * @return void */ public function testBreachAtTriggerNotifiesAndLogsTheAlert(): void { $outcome = $this->bounded(['lastread' => 95, 'time_fail_trigger' => 1])->poll(); $this->assertSame(1, $outcome->mailCount()); $this->assertSame([ST_NOTIFYAL], $outcome->logStatuses()); $this->assertSame(STAT_HI, $outcome->persistedAlertState()); } /** * @return void */ public function testBreachBelowTheLowerBoundRecordsTheLowState(): void { $outcome = $this->bounded(['lastread' => 5, 'time_fail_trigger' => 1])->poll(); $this->assertSame(STAT_LO, $outcome->persistedAlertState()); } /** * The hi/low arm mails on restoral. This one writes the restoral to the log * and clears the state, but sends nothing, so an operator watching a * time-based threshold sees the alert and never the all-clear. * * Restoral requires the log-derived fail count to have reached the trigger * (issue #746) - the harness always stubs that count to 0, so the trigger * is set to 0 here to still exercise a threshold with no minimum streak. * * @return void */ public function testRestoralLogsButDoesNotMail(): void { $outcome = $this->bounded([ 'lastread' => 50, 'thold_alert' => STAT_HI, 'thold_fail_count' => 3, 'time_fail_trigger' => 0, 'time_warning_fail_trigger' => 0, ])->poll(); $this->assertSame([ST_NOTIFYRS], $outcome->logStatuses()); $this->assertSame(STAT_NORMAL, $outcome->persistedAlertState()); $this->assertSame(0, $outcome->mailCount()); } /** * See testRestoralLogsButDoesNotMail() for why the trigger is 0 here. * * @return void */ public function testRestoralResetsTheFailCounts(): void { $outcome = $this->bounded([ 'lastread' => 50, 'thold_alert' => STAT_HI, 'thold_fail_count' => 3, 'thold_warning_fail_count' => 2, 'time_fail_trigger' => 0, 'time_warning_fail_trigger' => 0, ])->poll(); $this->assertSame(['alert' => 0, 'warning' => 0], $outcome->persistedFailCounts()); } /** * The early-restoral branch (neither fail count reached its trigger) must * apply the same acknowledgment-reset side effect as the two branches * above it, or an acknowledged threshold that recovers before retriggering * stays acknowledged forever. * * @return void */ public function testRestoralClearsAcknowledgmentWhenResetAckEnabled(): void { $outcome = $this->bounded([ 'lastread' => 50, 'thold_alert' => STAT_HI, 'thold_fail_count' => 3, 'acknowledgment' => 'on', 'reset_ack' => 'on', ])->poll(); $this->assertTrue($outcome->acknowledgmentCleared()); } /** * @return void */ public function testMaintenanceWindowSuppressesNotification(): void { $scenario = $this->bounded(['lastread' => 95, 'time_fail_trigger' => 1]) ->inMaintenance(); $fixture_root = realpath(dirname(__DIR__) . '/Fixtures'); $base_path = realpath($GLOBALS['config']['base_path']); $this->assertNotFalse($fixture_root); $this->assertNotFalse($base_path); $this->assertStringStartsWith($fixture_root . DIRECTORY_SEPARATOR, $base_path . DIRECTORY_SEPARATOR); $outcome = $scenario->poll(); $this->assertSame(0, $outcome->mailCount()); } /** * @return void */ public function testAcknowledgedThresholdDoesNotMailOnBreach(): void { $outcome = $this->bounded([ 'lastread' => 95, 'time_fail_trigger' => 1, 'acknowledgment' => 'on', ])->poll(); $this->assertSame(0, $outcome->mailCount()); } /** * @return void */ public function testUnknownReadingEmitsNoAlert(): void { $outcome = $this->bounded([ 'lastread' => 'U', 'thold_alert' => 2, 'thold_fail_count' => 3, ])->poll(); $this->assertSame(0, $outcome->mailCount()); $this->assertNull($outcome->persistedAlertState()); } /** * @return void */ public function testThresholdWithNoBoundsNeverBreaches(): void { $outcome = ThresholdScenario::threshold(['thold_type' => 2, 'lastread' => 99999]) ->alertRecipient('ops@example.org') ->poll(); $this->assertTrue($outcome->isSilent()); } }