From e0713102855c020676bed411d584173f23df9173 Mon Sep 17 00:00:00 2001 From: Kevin Duret Date: Wed, 4 Oct 2017 17:52:21 +0200 Subject: [PATCH 1/8] fix(cron): fix downtime manager to manage dst --- www/class/centreonDowntime.Broker.class.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/www/class/centreonDowntime.Broker.class.php b/www/class/centreonDowntime.Broker.class.php index c45c36690b7..e016d45469e 100644 --- a/www/class/centreonDowntime.Broker.class.php +++ b/www/class/centreonDowntime.Broker.class.php @@ -323,11 +323,6 @@ public function getApproachingDowntimes($delay) $endTime = $this->setTime($downtime['dtp_end_time'], $timezone, $tomorrow); $endTimestamp = $endTime->getTimestamp(); - # Check if HH:mm time is approaching - if (!$this->isApproachingTime($startTimestamp, $startDelay->getTimestamp(), $endDelay->getTimestamp())) { - continue; - } - # Check if we jump an hour $startTimestamp = $this->manageWinterToSummerTimestamp($startTime, $startTimestamp, $timezone); $endTimestamp = $this->manageWinterToSummerTimestamp($endTime, $endTimestamp, $timezone); @@ -335,6 +330,11 @@ public function getApproachingDowntimes($delay) continue; } + # Check if HH:mm time is approaching + if (!$this->isApproachingTime($startTimestamp, $startDelay->getTimestamp(), $endDelay->getTimestamp())) { + continue; + } + $approaching = false; if (preg_match('/^\d(,\d)*$/', $downtime['dtp_day_of_week']) && preg_match('/^(none)|(all)$/', $downtime['dtp_month_cycle'])) { $approaching = $this->isWeeklyApproachingDowntime( From 6cebd5a9c691f10db12a68b704f06ca306c47426 Mon Sep 17 00:00:00 2001 From: Kevin Duret Date: Wed, 4 Oct 2017 17:50:24 +0200 Subject: [PATCH 2/8] test(acceptance): begin acceptance test for downtime on dst --- behat.yml | 4 + features/DowntimeDST.feature | 76 +++++ features/bootstrap/DowntimeDSTContext.php | 353 ++++++++++++++++++++++ 3 files changed, 433 insertions(+) create mode 100644 features/DowntimeDST.feature create mode 100644 features/bootstrap/DowntimeDSTContext.php diff --git a/behat.yml b/behat.yml index 70cd23304c9..39f68ba9397 100644 --- a/behat.yml +++ b/behat.yml @@ -101,6 +101,10 @@ default: paths: [ %paths.base%/features/DowntimeStartAndStop.feature ] contexts: [ DowntimeStartAndStopContext ] + downtime_dst: + paths: [ %paths.base%/features/DowntimeDST.feature ] + contexts: [ DowntimeDSTContext ] + command_arguments: paths: [ %paths.base%/features/CommandArguments.feature ] contexts: [ CommandArgumentsContext ] diff --git a/features/DowntimeDST.feature b/features/DowntimeDST.feature new file mode 100644 index 00000000000..77bbb265f01 --- /dev/null +++ b/features/DowntimeDST.feature @@ -0,0 +1,76 @@ +Feature: Downtime DST + As a Centreon user + I want to be certain that the downtimes work correctly with DST + To release quality products + + Background: + Given I am logged in a Centreon server located at "Europe/Paris" + And a passive service is monitored + + +# summer changing time + + @critical + Scenario: recurrent downtime starting on summer changing time + Given a recurrent downtime starting on summer changing time + When downtime is approaching + Then the downtime is scheduled + + @critical + Scenario: recurrent downtime ending on summer changing time + Given a recurrent downtime ending on summer changing time + When downtime is approaching + Then the downtime is scheduled + + @critical + Scenario: recurrent downtime starting and ending on summer changing time + Given a recurrent downtime starting and ending on summer changing time + When downtime is approaching + Then the downtime is not scheduled + + @critical + Scenario: recurrent downtime during all day on summer changing date + Given a recurrent downtime during all day on summer changing date + When downtime is approaching + Then the downtime is scheduled + + @critical + Scenario: recurrent downtime of next day of summer changing date + Given a recurrent downtime during all day on summer changing date is scheduled + And a recurrent downtime of next day of summer changing date + When downtime is approaching + Then the downtime is scheduled + + +# winter changing time + + @critical + Scenario: recurrent downtime starting on winter changing time + Given a recurrent downtime starting on winter changing time + When downtime is approaching + Then the downtime is scheduled + + @critical + Scenario: recurrent downtime ending on winter changing time + Given a recurrent downtime ending on winter changing time + When downtime is approaching + Then the downtime is scheduled + + @critical + Scenario: recurrent downtime starting and ending on winter changing time + Given a recurrent downtime starting and ending on winter changing time + When downtime is approaching + Then the downtime is scheduled + + @critical + Scenario: recurrent downtime during all day on winter changing date + Given a recurrent downtime during all day on winter changing date + When downtime is approaching + Then the downtime is scheduled + + @critical + Scenario: recurrent downtime of next day of winter changing date + Given a recurrent downtime during all day on winter changing date is scheduled + And a recurrent downtime of next day of winter changing date + When downtime is approaching + Then the downtime is scheduled \ No newline at end of file diff --git a/features/bootstrap/DowntimeDSTContext.php b/features/bootstrap/DowntimeDSTContext.php new file mode 100644 index 00000000000..711dfde74b1 --- /dev/null +++ b/features/bootstrap/DowntimeDSTContext.php @@ -0,0 +1,353 @@ +page = new RecurrentDowntimeConfigurationPage($this); + + $this->page->setProperties(array( + 'name' => 'test', + 'alias' => $this->service, + 'days' => array(7, 1, 2, 3, 4, 5, 6), + 'start' => $this->downtimeProperties['start_time'], + 'end' => $this->downtimeProperties['end_time'], + 'svc_relation' => $this->host . ' - ' . $this->service + )); + + $this->page->save(); + } + + /** + * @Given a passive service is monitored + */ + public function aPassiveServiceIsMonitored() + { + $page = new ServiceConfigurationPage($this); + $page->setProperties(array( + 'hosts' => $this->host, + 'description' => $this->service, + 'templates' => 'generic-service', + 'check_command' => 'check_centreon_dummy', + 'check_period' => '24x7', + 'max_check_attempts' => 1, + 'normal_check_interval' => 1, + 'retry_check_interval' => 1, + 'active_checks_enabled' => 0, + 'passive_checks_enabled' => 1, + 'notifications_enabled' => 1, + 'notify_on_recovery' => 1, + 'notify_on_critical' => 1, + 'recovery_notification_delay' => 1, + 'cs' => 'admin_admin' + )); + $page->save(); + + $this->reloadAllPollers(); + $this->submitServiceResult($this->host, $this->service, 0, __FUNCTION__); + } + + /** + * @Given a recurrent downtime starting on summer changing time + */ + public function aRecurrentDowntimeStartingOnSummerChangingTime() + { + // on Europe/Paris at 2AM, we jump to 3AM + $this->downtimeProperties = array( + 'start_time' => '02:30', + 'end_time' => '03:30', + 'expected_start' => '2021-03-28 03:00', + 'expected_end' => '2021-03-28 03:30', + 'expected_duration' => '1800', // 30m + 'faketime' => '2021-03-28 01:56:00' + ); + + $this->setDowntime(); + } + + /** + * @Given a recurrent downtime ending on summer changing time + */ + public function aRecurrentDowntimeEndingOnSummerChangingTime() + { + // on Europe/Paris at 2AM, we jump to 3AM + $this->downtimeProperties = array( + 'start_time' => '01:30', + 'end_time' => '02:30', + 'expected_start' => '2021-03-28 01:30', + 'expected_end' => '2021-03-28 03:00', + 'expected_duration' => '1800', // 30m + 'faketime' => '2021-03-28 01:26:00' + ); + + $this->setDowntime(); + } + + /** + * @Given a recurrent downtime starting and ending on summer changing time + */ + public function aRecurrentDowntimeStartingAndEndingOnSummerChangingTime() + { + // on Europe/Paris at 2AM, we jump to 3AM + $this->downtimeProperties = array( + 'start_time' => '02:03', + 'end_time' => '02:33', + 'expected_start' => '', + 'expected_end' => '', + 'expected_duration' => '0', + 'faketime' => '2021-03-28 01:58:00' + ); + + $this->setDowntime(); + } + + /** + * @Given a recurrent downtime during all day on summer changing date + */ + public function aRecurrentDowntimeDuringAllDayOnSummerChangingDate() + { + // on Europe/Paris at 2AM, we jump to 3AM + $this->downtimeProperties = array( + 'start_time' => '00:00', + 'end_time' => '24:00', + 'expected_start' => '2021-03-28 00:00', + 'expected_end' => '2021-03-29 00:00', + 'expected_duration' => '82800', // 23h + 'faketime' => '2021-03-27 23:56:00' + ); + + $this->setDowntime(); + } + + /** + * @Given a recurrent downtime during all day on summer changing date is scheduled + */ + public function aRecurrentDowntimeDuringAllDayOnSummerChangingDateIsScheduled() + { + $this->aRecurrentDowntimeDuringAllDayOnSummerChangingDate(); + $this->downtimeIsApproaching(); + $this->theDowntimeIsScheduled(); + } + + /** + * @Given a recurrent downtime of next day of summer changing date + */ + public function aRecurrentDowntimeOfNextDayOfSummerChangingDate() + { + $this->downtimeProperties = array( + 'start_time' => '00:00', + 'end_time' => '24:00', + 'expected_start' => '2021-03-29 00:00', + 'expected_end' => '2021-03-30 00:00', + 'expected_duration' => '86400', // 24h + 'faketime' => '2021-03-28 23:58:00' + ); + + $this->setDowntime(); + } + + /** + * @Given a recurrent downtime starting on winter changing time + */ + public function aRecurrentDowntimeStartingOnWinterChangingDate() + { + // on Europe/Paris at 3AM, backward to 2AM + $this->downtimeProperties = array( + 'start_time' => '02:03', + 'end_time' => '03:33', + 'expected_start' => '2021-10-31 02:03', + 'expected_end' => '2021-10-31 03:33', + 'expected_duration' => '5400', // 1h30 + 'faketime' => '2021-10-31 01:58:00' + ); + + $this->setDowntime(); + } + + /** + * @Given a recurrent downtime ending on winter changing time + */ + public function aRecurrentDowntimeEndingOnWinterChangingDate() + { + // on Europe/Paris at 3AM, backward to 2AM + $this->downtimeProperties = array( + 'start_time' => '01:00', + 'end_time' => '02:30', + 'expected_start' => '2021-10-31 01:00', + 'expected_end' => '2021-10-31 02:30', + 'expected_duration' => '9000', // 2h30 + 'faketime' => '2021-10-31 00:58:00' + ); + + $this->setDowntime(); + } + + /** + * @Given a recurrent downtime starting and ending on winter changing time + */ + public function aRecurrentDowntimeStartingAndEndingOnWinterChangingDate() + { + // on Europe/Paris at 3AM, backward to 2AM + $this->downtimeProperties = array( + 'start_time' => '02:03', + 'end_time' => '02:33', + 'expected_start' => '2021-10-31 02:03', + 'expected_end' => '2021-10-31 02:33', + 'expected_duration' => '1800', // 30m + 'faketime' => '2021-10-31 01:58:00' + ); + + $this->setDowntime(); + } + + /** + * @Given a recurrent downtime during all day on winter changing date + */ + public function aRecurrentDowntimeDuringAllDayOnWinterChangingDate() + { + // on Europe/Paris at 3AM, backward to 2AM + $this->downtimeProperties = array( + 'start_time' => '00:00', + 'end_time' => '24:00', + 'expected_start' => '2021-10-31 00:00', + 'expected_end' => '2021-11-01 00:00', + 'expected_duration' => '90000', // 25h + 'faketime' => '2021-10-30 23:58:00' + ); + + $this->setDowntime(); + } + + /** + * @Given a recurrent downtime during all day on winter changing date is scheduled + */ + public function aRecurrentDowntimeDuringAllDayOnWinterChangingDateIsScheduled() + { + $this->aRecurrentDowntimeDuringAllDayOnWinterChangingDate(); + $this->downtimeIsApproaching(); + $this->theDowntimeIsScheduled(); + } + + /** + * @Given a recurrent downtime of next day of winter changing date + */ + public function aRecurrentDowntimeOfNextDayOfWinterChangingDate() + { + $this->downtimeProperties = array( + 'start_time' => '00:00', + 'end_time' => '24:00', + 'expected_start' => '2021-11-01 00:00', + 'expected_end' => '2021-11-02 00:00', + 'expected_duration' => '86400', // 24h + 'faketime' => '2021-10-31 23:58:00' + ); + + $this->setDowntime(); + } + + /** + * @When downtime is approaching + */ + public function downtimeIsApproaching() + { + $this->container->execute( + "faketime '" . $this->downtimeProperties['faketime'] . "'" . + " php /usr/share/centreon/cron/downtimeManager.php", + 'web' + ); + } + + /** + * @Then the downtime is scheduled + */ + public function theDowntimeIsScheduled() + { + $this->spin( + function ($context) { + $scheduled = false; + $return = $context->container->execute( + "cat /var/log/centreon-engine/centengine.log", + 'web' + ); + $output = $return['output']; + if ( + preg_match_all( + '/SCHEDULE_SVC_DOWNTIME;' . $this->host . ';' . $this->service . ';(\d+);(\d+);.+/', + $output, + $matches + ) + ) { + $startTimestamp = end($matches[1]); + $endTimestamp = end($matches[2]); + $dateStart = new DateTime('now', new \DateTimeZone('Europe/Paris')); + $dateStart->setTimestamp($startTimestamp); + $dateEnd = new DateTime('now', new \DateTimeZone('Europe/Paris')); + $dateEnd->setTimestamp($endTimestamp); + if ($dateStart->format('Y-m-d H:i') == $this->downtimeProperties['expected_start'] && + $dateEnd->format('Y-m-d H:i') == $this->downtimeProperties['expected_end'] && + ($endTimestamp - $startTimestamp) == $this->downtimeProperties['expected_duration']) { + $scheduled = true; + } + $storageDb = $this->getStorageDatabase(); + $res = $storageDb->query( + "SELECT downtime_id FROM downtimes " . + "WHERE start_time = " . $startTimestamp . " " . + "AND end_time = " . $endTimestamp + ); + if (!$res->fetch()) { + $scheduled = false; + } + } + + return $scheduled; + }, + 'Downtime is not scheduled', + 10 + ); + } + + /** + * @Then the downtime is not scheduled + */ + public function theDowntimeIsNotScheduled() + { + $this->spin( + function ($context) { + $scheduled = true; + $return = $context->container->execute( + "cat /var/log/centreon-engine/centengine.log", + 'web' + ); + $output = $return['output']; + if ( + preg_match( + '/SCHEDULE_SVC_DOWNTIME;' . $this->host . ';' . $this->service . ';(\d+);(\d+);.+/', + $output + ) + ) { + $scheduled = false; + } + + return $scheduled; + }, + 'Downtime is scheduled', + 10 + ); + } +} From 68669039b75c7ca1722c333ab0fcda7c5bbdfee2 Mon Sep 17 00:00:00 2001 From: Kevin Duret Date: Wed, 11 Oct 2017 16:55:37 +0200 Subject: [PATCH 3/8] fix(downtime): improve dst management with downtimes --- features/DowntimeDST.feature | 140 ++++++++++++------ features/bootstrap/DowntimeDSTContext.php | 150 ++++++++++++-------- www/class/centreonExternalCommand.class.php | 97 ++++++++++--- www/class/centreonGMT.class.php | 2 +- 4 files changed, 262 insertions(+), 127 deletions(-) diff --git a/features/DowntimeDST.feature b/features/DowntimeDST.feature index 77bbb265f01..cdd60ca1180 100644 --- a/features/DowntimeDST.feature +++ b/features/DowntimeDST.feature @@ -10,67 +10,123 @@ Feature: Downtime DST # summer changing time - @critical - Scenario: recurrent downtime starting on summer changing time - Given a recurrent downtime starting on summer changing time - When downtime is approaching - Then the downtime is scheduled +# @critical +# Scenario: realtime downtime starting on summer changing time +# Given a downtime starting on summer changing time +# When realtime downtime is applied +# Then the downtime is properly scheduled + +# @critical +# Scenario: recurrent downtime starting on summer changing time +# Given a downtime starting on summer changing time +# When recurrent downtime is applied +# Then the downtime is properly scheduled + +# @critical +# Scenario: recurrent downtime ending on summer changing time +# Given a downtime ending on summer changing time +# When recurrent downtime is applied +# Then the downtime is properly scheduled + +# @critical +# Scenario: realtime downtime ending on summer changing time +# Given a downtime ending on summer changing time +# When realtime downtime is applied +# Then the downtime is properly scheduled @critical - Scenario: recurrent downtime ending on summer changing time - Given a recurrent downtime ending on summer changing time - When downtime is approaching - Then the downtime is scheduled +# Scenario: recurrent downtime starting and ending on summer changing time +# Given a downtime starting and ending on summer changing time +# When recurrent downtime is applied +# Then the downtime is not scheduled @critical - Scenario: recurrent downtime starting and ending on summer changing time - Given a recurrent downtime starting and ending on summer changing time - When downtime is approaching + Scenario: realtime downtime starting and ending on summer changing time + Given a downtime starting and ending on summer changing time + When realtime downtime is applied Then the downtime is not scheduled @critical - Scenario: recurrent downtime during all day on summer changing date - Given a recurrent downtime during all day on summer changing date - When downtime is approaching - Then the downtime is scheduled +# Scenario: recurrent downtime during all day on summer changing date +# Given a downtime during all day on summer changing date +# When recurrent downtime is applied +# Then the downtime is properly scheduled @critical - Scenario: recurrent downtime of next day of summer changing date - Given a recurrent downtime during all day on summer changing date is scheduled - And a recurrent downtime of next day of summer changing date - When downtime is approaching - Then the downtime is scheduled +# Scenario: realtime downtime during all day on summer changing date +# Given a downtime during all day on summer changing date +# When realtime downtime is applied +# Then the downtime is properly scheduled + + @critical +# Scenario: recurrent downtime of next day of summer changing date +# Given a recurrent downtime of next day of summer changing date +# And a downtime during all day on summer changing date is scheduled +# When recurrent downtime is applied +# Then the downtime is properly scheduled + # winter changing time @critical - Scenario: recurrent downtime starting on winter changing time - Given a recurrent downtime starting on winter changing time - When downtime is approaching - Then the downtime is scheduled +# Scenario: recurrent downtime starting on winter changing time +# Given a recurrent downtime starting on winter changing time +# When downtime is applied +# Then the downtime is properly scheduled + + @critical +# Scenario: realtime downtime starting on winter changing time +# Given a downtime starting on winter changing time +# When realtime downtime is applied +# Then the downtime is properly scheduled + + @critical +# Scenario: recurrent downtime ending on winter changing time +# Given a recurrent downtime ending on winter changing time +# When downtime is applied +# Then the downtime is properly scheduled + +# @critical +# Scenario: realtime downtime ending on winter changing time +# Given a downtime ending on winter changing time +# When realtime downtime is applied +# Then the downtime is properly scheduled + + @critical +# Scenario: recurrent downtime starting and ending on winter changing time +# Given a recurrent downtime starting and ending on winter changing time +# When downtime is applied +# Then the downtime is properly scheduled + + @critical +# Scenario: realtime downtime starting and ending on winter changing time +# Given a downtime starting and ending on winter changing time +# When realtime downtime is applied +# Then the downtime is properly scheduled @critical - Scenario: recurrent downtime ending on winter changing time - Given a recurrent downtime ending on winter changing time - When downtime is approaching - Then the downtime is scheduled +# Scenario: recurrent downtime during all day on winter changing date +# Given a recurrent downtime during all day on winter changing date +# When downtime is applied +# Then the downtime is properly scheduled @critical - Scenario: recurrent downtime starting and ending on winter changing time - Given a recurrent downtime starting and ending on winter changing time - When downtime is approaching - Then the downtime is scheduled +# Scenario: realtime downtime during all day on winter changing date +# Given a downtime during all day on winter changing date +# When realtime downtime is applied +# Then the downtime is properly scheduled @critical - Scenario: recurrent downtime during all day on winter changing date - Given a recurrent downtime during all day on winter changing date - When downtime is approaching - Then the downtime is scheduled +# Scenario: recurrent downtime of next day of winter changing date +# Given a recurrent downtime of next day of winter changing date +# And a downtime during all day on winter changing date is scheduled +# When recurrent downtime is applied +# Then the downtime is properly scheduled @critical - Scenario: recurrent downtime of next day of winter changing date - Given a recurrent downtime during all day on winter changing date is scheduled - And a recurrent downtime of next day of winter changing date - When downtime is approaching - Then the downtime is scheduled \ No newline at end of file +# Scenario: realtime downtime of next day of winter changing date +# Given a recurrent downtime of next day of winter changing date +# And a downtime during all day on winter changing date is scheduled +# When realtime downtime is applied +# Then the downtime is properly scheduled \ No newline at end of file diff --git a/features/bootstrap/DowntimeDSTContext.php b/features/bootstrap/DowntimeDSTContext.php index 711dfde74b1..ccc08a11627 100644 --- a/features/bootstrap/DowntimeDSTContext.php +++ b/features/bootstrap/DowntimeDSTContext.php @@ -3,9 +3,6 @@ use Centreon\Test\Behat\CentreonContext; use Centreon\Test\Behat\Configuration\DowntimeConfigurationPage; use Centreon\Test\Behat\Configuration\ServiceConfigurationPage; -use Centreon\Test\Behat\Configuration\CurrentUserConfigurationPage; -use Centreon\Test\Behat\Configuration\DowntimeConfigurationListingPage; -use Centreon\Test\Behat\Configuration\HostConfigurationListingPage; use Centreon\Test\Behat\Configuration\RecurrentDowntimeConfigurationPage; /** @@ -18,7 +15,7 @@ class DowntimeDSTContext extends CentreonContext protected $service = 'downtimeService'; protected $downtimeProperties; - private function setDowntime() + private function setRecurrentDowntime() { $this->page = new RecurrentDowntimeConfigurationPage($this); @@ -34,6 +31,25 @@ private function setDowntime() $this->page->save(); } + private function setRealtimeDowntime() + { + $this->page = new DowntimeConfigurationPage($this); + + $downtimeEndTime = '+2 minutes'; + $this->downtimeEndTime = date("H:i", strtotime($downtimeEndTime)); + $this->page->setProperties(array( + 'type' => DowntimeConfigurationPage::TYPE_SERVICE, + 'service' => $this->host . ' - ' . $this->service, + 'comment' => 'Acceptance test', + 'start_day' => $this->downtimeProperties['start_day'], + 'start_time' => $this->downtimeProperties['start_time'], + 'end_day' => $this->downtimeProperties['end_day'], + 'end_time' => $this->downtimeProperties['end_time'], + )); + + $this->page->save(); + } + /** * @Given a passive service is monitored */ @@ -64,219 +80,224 @@ public function aPassiveServiceIsMonitored() } /** - * @Given a recurrent downtime starting on summer changing time + * @Given a downtime starting on summer changing time */ - public function aRecurrentDowntimeStartingOnSummerChangingTime() + public function aDowntimeStartingOnSummerChangingTime() { // on Europe/Paris at 2AM, we jump to 3AM $this->downtimeProperties = array( + 'start_day' => '2021-03-28', 'start_time' => '02:30', + 'end_day' => '2021-03-28', 'end_time' => '03:30', 'expected_start' => '2021-03-28 03:00', 'expected_end' => '2021-03-28 03:30', 'expected_duration' => '1800', // 30m 'faketime' => '2021-03-28 01:56:00' ); - - $this->setDowntime(); } /** - * @Given a recurrent downtime ending on summer changing time + * @Given a downtime ending on summer changing time */ - public function aRecurrentDowntimeEndingOnSummerChangingTime() + public function aDowntimeEndingOnSummerChangingTime() { // on Europe/Paris at 2AM, we jump to 3AM $this->downtimeProperties = array( + 'start_day' => '2021-03-28', 'start_time' => '01:30', + 'end_day' => '2021-03-28', 'end_time' => '02:30', 'expected_start' => '2021-03-28 01:30', 'expected_end' => '2021-03-28 03:00', 'expected_duration' => '1800', // 30m 'faketime' => '2021-03-28 01:26:00' ); - - $this->setDowntime(); } /** - * @Given a recurrent downtime starting and ending on summer changing time + * @Given a downtime starting and ending on summer changing time */ - public function aRecurrentDowntimeStartingAndEndingOnSummerChangingTime() + public function aDowntimeStartingAndEndingOnSummerChangingTime() { // on Europe/Paris at 2AM, we jump to 3AM $this->downtimeProperties = array( + 'start_day' => '2021-03-28', 'start_time' => '02:03', + 'end_day' => '2021-03-28', 'end_time' => '02:33', 'expected_start' => '', 'expected_end' => '', 'expected_duration' => '0', 'faketime' => '2021-03-28 01:58:00' ); - - $this->setDowntime(); } /** - * @Given a recurrent downtime during all day on summer changing date + * @Given a downtime during all day on summer changing date */ - public function aRecurrentDowntimeDuringAllDayOnSummerChangingDate() + public function aDowntimeDuringAllDayOnSummerChangingDate() { // on Europe/Paris at 2AM, we jump to 3AM $this->downtimeProperties = array( + 'start_day' => '2021-03-28', 'start_time' => '00:00', + 'end_day' => '2021-03-28', 'end_time' => '24:00', 'expected_start' => '2021-03-28 00:00', 'expected_end' => '2021-03-29 00:00', 'expected_duration' => '82800', // 23h 'faketime' => '2021-03-27 23:56:00' ); - - $this->setDowntime(); } /** - * @Given a recurrent downtime during all day on summer changing date is scheduled + * @Given a downtime during all day on summer changing date is scheduled */ - public function aRecurrentDowntimeDuringAllDayOnSummerChangingDateIsScheduled() + public function aDowntimeDuringAllDayOnSummerChangingDateIsScheduled() { - $this->aRecurrentDowntimeDuringAllDayOnSummerChangingDate(); - $this->downtimeIsApproaching(); - $this->theDowntimeIsScheduled(); + $this->aDowntimeDuringAllDayOnSummerChangingDate(); + $this->downtimeIsApplied('recurrent'); + $this->theDowntimeIsProperlyScheduled(); } /** - * @Given a recurrent downtime of next day of summer changing date + * @Given a downtime of next day of summer changing date */ - public function aRecurrentDowntimeOfNextDayOfSummerChangingDate() + public function aDowntimeOfNextDayOfSummerChangingDate() { $this->downtimeProperties = array( + 'start_day' => '2021-03-28', 'start_time' => '00:00', + 'end_day' => '2021-03-28', 'end_time' => '24:00', 'expected_start' => '2021-03-29 00:00', 'expected_end' => '2021-03-30 00:00', 'expected_duration' => '86400', // 24h 'faketime' => '2021-03-28 23:58:00' ); - - $this->setDowntime(); } /** * @Given a recurrent downtime starting on winter changing time */ - public function aRecurrentDowntimeStartingOnWinterChangingDate() + public function aDowntimeStartingOnWinterChangingDate() { // on Europe/Paris at 3AM, backward to 2AM $this->downtimeProperties = array( + 'start_day' => '2021-10-31', 'start_time' => '02:03', + 'end_day' => '2021-10-31', 'end_time' => '03:33', 'expected_start' => '2021-10-31 02:03', 'expected_end' => '2021-10-31 03:33', 'expected_duration' => '5400', // 1h30 'faketime' => '2021-10-31 01:58:00' ); - - $this->setDowntime(); } /** - * @Given a recurrent downtime ending on winter changing time + * @Given a downtime ending on winter changing time */ - public function aRecurrentDowntimeEndingOnWinterChangingDate() + public function aDowntimeEndingOnWinterChangingDate() { // on Europe/Paris at 3AM, backward to 2AM $this->downtimeProperties = array( + 'start_day' => '2021-10-31', 'start_time' => '01:00', + 'end_day' => '2021-10-31', 'end_time' => '02:30', 'expected_start' => '2021-10-31 01:00', 'expected_end' => '2021-10-31 02:30', 'expected_duration' => '9000', // 2h30 'faketime' => '2021-10-31 00:58:00' ); - - $this->setDowntime(); } /** - * @Given a recurrent downtime starting and ending on winter changing time + * @Given a downtime starting and ending on winter changing time */ - public function aRecurrentDowntimeStartingAndEndingOnWinterChangingDate() + public function aDowntimeStartingAndEndingOnWinterChangingDate() { // on Europe/Paris at 3AM, backward to 2AM $this->downtimeProperties = array( + 'start_day' => '2021-10-31', 'start_time' => '02:03', + 'end_day' => '2021-10-31', 'end_time' => '02:33', 'expected_start' => '2021-10-31 02:03', 'expected_end' => '2021-10-31 02:33', 'expected_duration' => '1800', // 30m 'faketime' => '2021-10-31 01:58:00' ); - - $this->setDowntime(); } /** - * @Given a recurrent downtime during all day on winter changing date + * @Given a downtime during all day on winter changing date */ - public function aRecurrentDowntimeDuringAllDayOnWinterChangingDate() + public function aDowntimeDuringAllDayOnWinterChangingDate() { // on Europe/Paris at 3AM, backward to 2AM $this->downtimeProperties = array( + 'start_day' => '2021-10-31', 'start_time' => '00:00', + 'end_day' => '2021-10-31', 'end_time' => '24:00', 'expected_start' => '2021-10-31 00:00', 'expected_end' => '2021-11-01 00:00', 'expected_duration' => '90000', // 25h 'faketime' => '2021-10-30 23:58:00' ); - - $this->setDowntime(); } /** - * @Given a recurrent downtime during all day on winter changing date is scheduled + * @Given a downtime during all day on winter changing date is scheduled */ - public function aRecurrentDowntimeDuringAllDayOnWinterChangingDateIsScheduled() + public function aDowntimeDuringAllDayOnWinterChangingDateIsScheduled() { - $this->aRecurrentDowntimeDuringAllDayOnWinterChangingDate(); - $this->downtimeIsApproaching(); - $this->theDowntimeIsScheduled(); + $this->aDowntimeDuringAllDayOnWinterChangingDate(); + $this->downtimeIsApplied('recurrent'); + $this->theDowntimeIsProperlyScheduled(); } /** - * @Given a recurrent downtime of next day of winter changing date + * @Given a downtime of next day of winter changing date */ - public function aRecurrentDowntimeOfNextDayOfWinterChangingDate() + public function aDowntimeOfNextDayOfWinterChangingDate() { $this->downtimeProperties = array( + 'start_day' => '2021-10-31', 'start_time' => '00:00', + 'end_day' => '2021-10-31', 'end_time' => '24:00', 'expected_start' => '2021-11-01 00:00', 'expected_end' => '2021-11-02 00:00', 'expected_duration' => '86400', // 24h 'faketime' => '2021-10-31 23:58:00' ); - - $this->setDowntime(); } /** - * @When downtime is approaching + * @When :downtimeType downtime is applied */ - public function downtimeIsApproaching() + public function downtimeIsApplied($downtimeType) { - $this->container->execute( - "faketime '" . $this->downtimeProperties['faketime'] . "'" . - " php /usr/share/centreon/cron/downtimeManager.php", - 'web' - ); + if ($downtimeType == 'realtime') { + $this->setRealtimeDowntime(); + } else { + $this->setRecurrentDowntime(); + $this->container->execute( + "faketime '" . $this->downtimeProperties['faketime'] . "'" . + " php /usr/share/centreon/cron/downtimeManager.php", + 'web' + ); + } } /** - * @Then the downtime is scheduled + * @Then the downtime is properly scheduled */ - public function theDowntimeIsScheduled() + public function theDowntimeIsProperlyScheduled() { $this->spin( function ($context) { @@ -286,6 +307,7 @@ function ($context) { 'web' ); $output = $return['output']; + //var_dump($output); if ( preg_match_all( '/SCHEDULE_SVC_DOWNTIME;' . $this->host . ';' . $this->service . ';(\d+);(\d+);.+/', @@ -299,6 +321,9 @@ function ($context) { $dateStart->setTimestamp($startTimestamp); $dateEnd = new DateTime('now', new \DateTimeZone('Europe/Paris')); $dateEnd->setTimestamp($endTimestamp); + var_dump($dateStart->format('Y-m-d H:i')); + var_dump($dateEnd->format('Y-m-d H:i')); + var_dump($endTimestamp - $startTimestamp); if ($dateStart->format('Y-m-d H:i') == $this->downtimeProperties['expected_start'] && $dateEnd->format('Y-m-d H:i') == $this->downtimeProperties['expected_end'] && ($endTimestamp - $startTimestamp) == $this->downtimeProperties['expected_duration']) { @@ -335,6 +360,7 @@ function ($context) { 'web' ); $output = $return['output']; + var_dump($output); if ( preg_match( '/SCHEDULE_SVC_DOWNTIME;' . $this->host . ';' . $this->service . ';(\d+);(\d+);.+/', diff --git a/www/class/centreonExternalCommand.class.php b/www/class/centreonExternalCommand.class.php index 377131592ef..337ffbaf1d3 100644 --- a/www/class/centreonExternalCommand.class.php +++ b/www/class/centreonExternalCommand.class.php @@ -400,6 +400,60 @@ public function acknowledgeService( * Downtime ***********/ + private function getDowntimeTimestampFromDate($date = 'now', $timezone = '', $start = true) + { + $dateTime = new \DateTime($date, new \DateTimeZone($timezone)); + //$dst = $dateTime->format("I"); + + $dateTime2 = clone($dateTime); + $dateTime2->setTimestamp($dateTime2->getTimestamp()); + if ($dateTime2->format("H") != $dateTime->format("H")) { + $hour = $dateTime->format('H'); + $dateTime->setTime($hour, '00'); + return $dateTime->getTimestamp(); + } + + $dateTime3 = clone($dateTime); + $dateTime3->sub(new \DateInterval("PT1H")); + if ($dateTime3->format("H") == $dateTime->format("H")) { + if ($start) { + return $dateTime3->getTimestamp(); + } else { + return $dateTime->getTimestamp(); + } + } + + return $dateTime->getTimestamp(); + +/* + // Check if previous is on winter time + $dateTime2 = clone($dateTime); + $dateTime2->sub(new \DateInterval("PT1H")); + + // Check if next is on summer time + $dateTime3 = clone($dateTime); + $dateTime3->add(new \DateInterval("PT1H")); + + if ($dst == "1" && $dateTime2->format("I") != $dst) { + if () + $hour = $dateTime->format('H'); + $dateTime->setTime($hour, '00'); + $timestamp = $dateTime->getTimestamp(); + } elseif ($dateTime3->format("I") != $dst && $start) { + if ($dateTime->format('H:i') == $dateTime3->format("H:i")) { + + } + $hour = $dateTime->format('H'); + $dateTime->setTime($hour, '00'); + $timestamp = $dateTime->getTimestamp(); + } else { + $timestamp = $dateTime->getTimestamp(); + } + + return $timestamp; + */ + } + /** * * Delete downtimes. @@ -447,17 +501,16 @@ public function addHostDowntime( } if ($hostOrCentreonTime == "0") { - $start_time = $this->GMT->getUTCDateFromString( - $start, - $this->GMT->getMyGTMFromUser($this->userId) - ); - $end_time = $this->GMT->getUTCDateFromString( - $end, - $this->GMT->getMyGTMFromUser($this->userId) - ); + $timezoneId = $this->GMT->getMyGTMFromUser($this->userId); } else { - $start_time = $this->GMT->getUTCDateFromString($start, $this->GMT->getUTCLocationHost($host)); - $end_time = $this->GMT->getUTCDateFromString($end, $this->GMT->getUTCLocationHost($host)); + $timezoneId = $this->GMT->getUTCLocationHost($host); + } + $timezone = $this->GMT->getActiveTimezone($timezoneId); + $start_time = $this->getDowntimeTimestampFromDate($start, $timezone, true); + $end_time = $this->getDowntimeTimestampFromDate($end, $timezone, false); + + if ($end_time == $start_time) { + return; } /* @@ -469,7 +522,7 @@ public function addHostDowntime( * Send command */ if (!isset($duration)) { - $duration = $start_time - $end_time; + $duration = $end_time - $start_time; } $finalHostName = ''; if (!is_numeric($host)) { @@ -524,17 +577,17 @@ public function addSvcDowntime( } if ($hostOrCentreonTime == "0") { - $start_time = $this->GMT->getUTCDateFromString( - $start, - $this->GMT->getMyGTMFromUser($centreon->userId) - ); - $end_time = $this->GMT->getUTCDateFromString( - $end, - $this->GMT->getMyGTMFromUser($centreon->userId) - ); + $timezoneId = $this->GMT->getMyGTMFromUser($this->userId); } else { - $start_time = $this->GMT->getUTCDateFromString($start, $this->GMT->getUTCLocationHost($host)); - $end_time = $this->GMT->getUTCDateFromString($end, $this->GMT->getUTCLocationHost($host)); + $timezoneId = $this->GMT->getUTCLocationHost($host); + } + + $timezone = $this->GMT->getActiveTimezone($timezoneId); + $start_time = $this->getDowntimeTimestampFromDate($start, $timezone, true); + $end_time = $this->getDowntimeTimestampFromDate($end, $timezone, false); + + if ($end_time == $start_time) { + return; } /* @@ -546,7 +599,7 @@ public function addSvcDowntime( * Send command */ if (!isset($duration)) { - $duration = $start_time - $end_time; + $duration = $end_time - $start_time; } $finalHostName = ''; if (!is_numeric($host)) { diff --git a/www/class/centreonGMT.class.php b/www/class/centreonGMT.class.php index 03de8afffc7..e6d42f423c1 100644 --- a/www/class/centreonGMT.class.php +++ b/www/class/centreonGMT.class.php @@ -535,7 +535,7 @@ public function getCentreonTimezone() * @param string $gmt * @return string timezone */ - private function getActiveTimezone($gmt) + public function getActiveTimezone($gmt) { $sTimezone = ""; if (count($this->timezones) == 0) { From 850ea312b071bf6a286acecfc0e86ef20076ff7a Mon Sep 17 00:00:00 2001 From: Kevin Duret Date: Fri, 13 Oct 2017 10:01:41 +0200 Subject: [PATCH 4/8] fix(downtime): fix realtime downtime with dst --- features/DowntimeDST.feature | 160 ++++++++++---------- features/bootstrap/DowntimeDSTContext.php | 87 ++++++----- www/class/centreonDowntime.Broker.class.php | 17 +++ www/class/centreonExternalCommand.class.php | 45 ++---- 4 files changed, 163 insertions(+), 146 deletions(-) diff --git a/features/DowntimeDST.feature b/features/DowntimeDST.feature index cdd60ca1180..560ff1bb0f4 100644 --- a/features/DowntimeDST.feature +++ b/features/DowntimeDST.feature @@ -10,35 +10,35 @@ Feature: Downtime DST # summer changing time -# @critical -# Scenario: realtime downtime starting on summer changing time -# Given a downtime starting on summer changing time -# When realtime downtime is applied -# Then the downtime is properly scheduled + @critical + Scenario: realtime downtime starting on summer changing time + Given a downtime starting on summer changing time + When realtime downtime is applied + Then the downtime is properly scheduled -# @critical -# Scenario: recurrent downtime starting on summer changing time -# Given a downtime starting on summer changing time -# When recurrent downtime is applied -# Then the downtime is properly scheduled + @critical + Scenario: recurrent downtime starting on summer changing time + Given a downtime starting on summer changing time + When recurrent downtime is applied + Then the downtime is properly scheduled -# @critical -# Scenario: recurrent downtime ending on summer changing time -# Given a downtime ending on summer changing time -# When recurrent downtime is applied -# Then the downtime is properly scheduled + @critical + Scenario: recurrent downtime ending on summer changing time + Given a downtime ending on summer changing time + When recurrent downtime is applied + Then the downtime is properly scheduled -# @critical -# Scenario: realtime downtime ending on summer changing time -# Given a downtime ending on summer changing time -# When realtime downtime is applied -# Then the downtime is properly scheduled + @critical + Scenario: realtime downtime ending on summer changing time + Given a downtime ending on summer changing time + When realtime downtime is applied + Then the downtime is properly scheduled @critical -# Scenario: recurrent downtime starting and ending on summer changing time -# Given a downtime starting and ending on summer changing time -# When recurrent downtime is applied -# Then the downtime is not scheduled + Scenario: recurrent downtime starting and ending on summer changing time + Given a downtime starting and ending on summer changing time + When recurrent downtime is applied + Then the downtime is not scheduled @critical Scenario: realtime downtime starting and ending on summer changing time @@ -47,86 +47,86 @@ Feature: Downtime DST Then the downtime is not scheduled @critical -# Scenario: recurrent downtime during all day on summer changing date -# Given a downtime during all day on summer changing date -# When recurrent downtime is applied -# Then the downtime is properly scheduled + Scenario: recurrent downtime during all day on summer changing date + Given a downtime during all day on summer changing date + When recurrent downtime is applied + Then the downtime is properly scheduled @critical -# Scenario: realtime downtime during all day on summer changing date -# Given a downtime during all day on summer changing date -# When realtime downtime is applied -# Then the downtime is properly scheduled + Scenario: realtime downtime during all day on summer changing date + Given a downtime during all day on summer changing date + When realtime downtime is applied + Then the downtime is properly scheduled @critical -# Scenario: recurrent downtime of next day of summer changing date -# Given a recurrent downtime of next day of summer changing date -# And a downtime during all day on summer changing date is scheduled -# When recurrent downtime is applied -# Then the downtime is properly scheduled + Scenario: recurrent downtime of next day of summer changing date + Given a downtime during all day on summer changing date is scheduled + And a downtime of next day of summer changing date + When recurrent downtime is applied + Then the downtime is properly scheduled # winter changing time @critical -# Scenario: recurrent downtime starting on winter changing time -# Given a recurrent downtime starting on winter changing time -# When downtime is applied -# Then the downtime is properly scheduled + Scenario: recurrent downtime starting on winter changing time + Given a downtime starting on winter changing time + When recurrent downtime is applied + Then the downtime is properly scheduled @critical -# Scenario: realtime downtime starting on winter changing time -# Given a downtime starting on winter changing time -# When realtime downtime is applied -# Then the downtime is properly scheduled + Scenario: realtime downtime starting on winter changing time + Given a downtime starting on winter changing time + When realtime downtime is applied + Then the downtime is properly scheduled @critical -# Scenario: recurrent downtime ending on winter changing time -# Given a recurrent downtime ending on winter changing time -# When downtime is applied -# Then the downtime is properly scheduled + Scenario: recurrent downtime ending on winter changing time + Given a downtime ending on winter changing time + When recurrent downtime is applied + Then the downtime is properly scheduled -# @critical -# Scenario: realtime downtime ending on winter changing time -# Given a downtime ending on winter changing time -# When realtime downtime is applied -# Then the downtime is properly scheduled + @critical + Scenario: realtime downtime ending on winter changing time + Given a downtime ending on winter changing time + When realtime downtime is applied + Then the downtime is properly scheduled @critical -# Scenario: recurrent downtime starting and ending on winter changing time -# Given a recurrent downtime starting and ending on winter changing time -# When downtime is applied -# Then the downtime is properly scheduled + Scenario: recurrent downtime starting and ending on winter changing time + Given a downtime starting and ending on winter changing time + When recurrent downtime is applied + Then the downtime is properly scheduled @critical -# Scenario: realtime downtime starting and ending on winter changing time -# Given a downtime starting and ending on winter changing time -# When realtime downtime is applied -# Then the downtime is properly scheduled + Scenario: realtime downtime starting and ending on winter changing time + Given a downtime starting and ending on winter changing time + When realtime downtime is applied + Then the downtime is properly scheduled @critical -# Scenario: recurrent downtime during all day on winter changing date -# Given a recurrent downtime during all day on winter changing date -# When downtime is applied -# Then the downtime is properly scheduled + Scenario: recurrent downtime during all day on winter changing date + Given a downtime during all day on winter changing date + When recurrent downtime is applied + Then the downtime is properly scheduled @critical -# Scenario: realtime downtime during all day on winter changing date -# Given a downtime during all day on winter changing date -# When realtime downtime is applied -# Then the downtime is properly scheduled + Scenario: realtime downtime during all day on winter changing date + Given a downtime during all day on winter changing date + When realtime downtime is applied + Then the downtime is properly scheduled @critical -# Scenario: recurrent downtime of next day of winter changing date -# Given a recurrent downtime of next day of winter changing date -# And a downtime during all day on winter changing date is scheduled -# When recurrent downtime is applied -# Then the downtime is properly scheduled + Scenario: recurrent downtime of next day of winter changing date + Given a downtime during all day on winter changing date is scheduled + And a downtime of next day of winter changing date + When recurrent downtime is applied + Then the downtime is properly scheduled @critical -# Scenario: realtime downtime of next day of winter changing date -# Given a recurrent downtime of next day of winter changing date -# And a downtime during all day on winter changing date is scheduled -# When realtime downtime is applied -# Then the downtime is properly scheduled \ No newline at end of file + Scenario: realtime downtime of next day of winter changing date + Given a downtime during all day on winter changing date is scheduled + And a downtime of next day of winter changing date + When realtime downtime is applied + Then the downtime is properly scheduled \ No newline at end of file diff --git a/features/bootstrap/DowntimeDSTContext.php b/features/bootstrap/DowntimeDSTContext.php index ccc08a11627..8ee9b0e57ec 100644 --- a/features/bootstrap/DowntimeDSTContext.php +++ b/features/bootstrap/DowntimeDSTContext.php @@ -35,8 +35,6 @@ private function setRealtimeDowntime() { $this->page = new DowntimeConfigurationPage($this); - $downtimeEndTime = '+2 minutes'; - $this->downtimeEndTime = date("H:i", strtotime($downtimeEndTime)); $this->page->setProperties(array( 'type' => DowntimeConfigurationPage::TYPE_SERVICE, 'service' => $this->host . ' - ' . $this->service, @@ -77,6 +75,30 @@ public function aPassiveServiceIsMonitored() $this->reloadAllPollers(); $this->submitServiceResult($this->host, $this->service, 0, __FUNCTION__); + $this->waitServiceInMonitoring(); + } + + private function waitServiceInMonitoring() + { + $this->spin( + function ($context) { + $monitored = false; + $storageDb = $context->getStorageDatabase(); + $res = $storageDb->query( + 'SELECT s.service_id ' . + 'FROM hosts h, services s ' . + 'WHERE s.host_id = h.host_id ' . + 'AND h.name = "' . $context->host . '" ' . + 'AND s.description = "' . $context->service . '" ' + ); + if ($res->fetch()) { + $monitored = true; + } + return $monitored; + }, + 'Service ' . $this->host . ' / ' . $this->service . ' is not monitored.', + 30 + ); } /** @@ -86,9 +108,9 @@ public function aDowntimeStartingOnSummerChangingTime() { // on Europe/Paris at 2AM, we jump to 3AM $this->downtimeProperties = array( - 'start_day' => '2021-03-28', + 'start_day' => '2021/03/28', 'start_time' => '02:30', - 'end_day' => '2021-03-28', + 'end_day' => '2021/03/28', 'end_time' => '03:30', 'expected_start' => '2021-03-28 03:00', 'expected_end' => '2021-03-28 03:30', @@ -104,9 +126,9 @@ public function aDowntimeEndingOnSummerChangingTime() { // on Europe/Paris at 2AM, we jump to 3AM $this->downtimeProperties = array( - 'start_day' => '2021-03-28', + 'start_day' => '2021/03/28', 'start_time' => '01:30', - 'end_day' => '2021-03-28', + 'end_day' => '2021/03/28', 'end_time' => '02:30', 'expected_start' => '2021-03-28 01:30', 'expected_end' => '2021-03-28 03:00', @@ -122,9 +144,9 @@ public function aDowntimeStartingAndEndingOnSummerChangingTime() { // on Europe/Paris at 2AM, we jump to 3AM $this->downtimeProperties = array( - 'start_day' => '2021-03-28', + 'start_day' => '2021/03/28', 'start_time' => '02:03', - 'end_day' => '2021-03-28', + 'end_day' => '2021/03/28', 'end_time' => '02:33', 'expected_start' => '', 'expected_end' => '', @@ -140,9 +162,9 @@ public function aDowntimeDuringAllDayOnSummerChangingDate() { // on Europe/Paris at 2AM, we jump to 3AM $this->downtimeProperties = array( - 'start_day' => '2021-03-28', + 'start_day' => '2021/03/28', 'start_time' => '00:00', - 'end_day' => '2021-03-28', + 'end_day' => '2021/03/28', 'end_time' => '24:00', 'expected_start' => '2021-03-28 00:00', 'expected_end' => '2021-03-29 00:00', @@ -167,9 +189,9 @@ public function aDowntimeDuringAllDayOnSummerChangingDateIsScheduled() public function aDowntimeOfNextDayOfSummerChangingDate() { $this->downtimeProperties = array( - 'start_day' => '2021-03-28', + 'start_day' => '2021/03/28', 'start_time' => '00:00', - 'end_day' => '2021-03-28', + 'end_day' => '2021/03/28', 'end_time' => '24:00', 'expected_start' => '2021-03-29 00:00', 'expected_end' => '2021-03-30 00:00', @@ -179,19 +201,19 @@ public function aDowntimeOfNextDayOfSummerChangingDate() } /** - * @Given a recurrent downtime starting on winter changing time + * @Given a downtime starting on winter changing time */ public function aDowntimeStartingOnWinterChangingDate() { // on Europe/Paris at 3AM, backward to 2AM $this->downtimeProperties = array( - 'start_day' => '2021-10-31', + 'start_day' => '2021/10/31', 'start_time' => '02:03', - 'end_day' => '2021-10-31', + 'end_day' => '2021/10/31', 'end_time' => '03:33', 'expected_start' => '2021-10-31 02:03', 'expected_end' => '2021-10-31 03:33', - 'expected_duration' => '5400', // 1h30 + 'expected_duration' => '9000', // 2h30 'faketime' => '2021-10-31 01:58:00' ); } @@ -203,9 +225,9 @@ public function aDowntimeEndingOnWinterChangingDate() { // on Europe/Paris at 3AM, backward to 2AM $this->downtimeProperties = array( - 'start_day' => '2021-10-31', + 'start_day' => '2021/10/31', 'start_time' => '01:00', - 'end_day' => '2021-10-31', + 'end_day' => '2021/10/31', 'end_time' => '02:30', 'expected_start' => '2021-10-31 01:00', 'expected_end' => '2021-10-31 02:30', @@ -221,13 +243,13 @@ public function aDowntimeStartingAndEndingOnWinterChangingDate() { // on Europe/Paris at 3AM, backward to 2AM $this->downtimeProperties = array( - 'start_day' => '2021-10-31', + 'start_day' => '2021/10/31', 'start_time' => '02:03', - 'end_day' => '2021-10-31', + 'end_day' => '2021/10/31', 'end_time' => '02:33', 'expected_start' => '2021-10-31 02:03', 'expected_end' => '2021-10-31 02:33', - 'expected_duration' => '1800', // 30m + 'expected_duration' => '5400', // 1h30 'faketime' => '2021-10-31 01:58:00' ); } @@ -239,9 +261,9 @@ public function aDowntimeDuringAllDayOnWinterChangingDate() { // on Europe/Paris at 3AM, backward to 2AM $this->downtimeProperties = array( - 'start_day' => '2021-10-31', + 'start_day' => '2021/10/31', 'start_time' => '00:00', - 'end_day' => '2021-10-31', + 'end_day' => '2021/10/31', 'end_time' => '24:00', 'expected_start' => '2021-10-31 00:00', 'expected_end' => '2021-11-01 00:00', @@ -266,9 +288,9 @@ public function aDowntimeDuringAllDayOnWinterChangingDateIsScheduled() public function aDowntimeOfNextDayOfWinterChangingDate() { $this->downtimeProperties = array( - 'start_day' => '2021-10-31', + 'start_day' => '2021/11/01', 'start_time' => '00:00', - 'end_day' => '2021-10-31', + 'end_day' => '2021/11/01', 'end_time' => '24:00', 'expected_start' => '2021-11-01 00:00', 'expected_end' => '2021-11-02 00:00', @@ -307,10 +329,9 @@ function ($context) { 'web' ); $output = $return['output']; - //var_dump($output); if ( preg_match_all( - '/SCHEDULE_SVC_DOWNTIME;' . $this->host . ';' . $this->service . ';(\d+);(\d+);.+/', + '/SCHEDULE_SVC_DOWNTIME;' . $context->host . ';' . $context->service . ';(\d+);(\d+);.+/', $output, $matches ) @@ -321,15 +342,12 @@ function ($context) { $dateStart->setTimestamp($startTimestamp); $dateEnd = new DateTime('now', new \DateTimeZone('Europe/Paris')); $dateEnd->setTimestamp($endTimestamp); - var_dump($dateStart->format('Y-m-d H:i')); - var_dump($dateEnd->format('Y-m-d H:i')); - var_dump($endTimestamp - $startTimestamp); - if ($dateStart->format('Y-m-d H:i') == $this->downtimeProperties['expected_start'] && - $dateEnd->format('Y-m-d H:i') == $this->downtimeProperties['expected_end'] && - ($endTimestamp - $startTimestamp) == $this->downtimeProperties['expected_duration']) { + if ($dateStart->format('Y-m-d H:i') == $context->downtimeProperties['expected_start'] && + $dateEnd->format('Y-m-d H:i') == $context->downtimeProperties['expected_end'] && + ($endTimestamp - $startTimestamp) == $context->downtimeProperties['expected_duration']) { $scheduled = true; } - $storageDb = $this->getStorageDatabase(); + $storageDb = $context->getStorageDatabase(); $res = $storageDb->query( "SELECT downtime_id FROM downtimes " . "WHERE start_time = " . $startTimestamp . " " . @@ -360,7 +378,6 @@ function ($context) { 'web' ); $output = $return['output']; - var_dump($output); if ( preg_match( '/SCHEDULE_SVC_DOWNTIME;' . $this->host . ';' . $this->service . ';(\d+);(\d+);.+/', diff --git a/www/class/centreonDowntime.Broker.class.php b/www/class/centreonDowntime.Broker.class.php index e016d45469e..f049c212914 100644 --- a/www/class/centreonDowntime.Broker.class.php +++ b/www/class/centreonDowntime.Broker.class.php @@ -292,6 +292,20 @@ private function manageWinterToSummerTimestamp($time, $timestamp, $timezone) return $timestamp; } + private function manageSummerToWinterTimestamp($timestamp, $timezone) + { + $dstDate = new DateTime('now', $timezone); + $dstDate->setTimestamp($timestamp); + $dateTime2 = clone($dstDate); + $dateTime2->setTimestamp($timestamp - 3600); + + if ($dateTime2->getTimestamp() == $dstDate->getTimestamp()) { + $timestamp = $timestamp - 3600; + } + + return $timestamp; + } + public function getApproachingDowntimes($delay) { $approachingDowntimes = array(); @@ -335,6 +349,9 @@ public function getApproachingDowntimes($delay) continue; } + # check backward of one hour + $startTimestamp = $this->manageSummerToWinterTimestamp($startTimestamp, $timezone); + $approaching = false; if (preg_match('/^\d(,\d)*$/', $downtime['dtp_day_of_week']) && preg_match('/^(none)|(all)$/', $downtime['dtp_month_cycle'])) { $approaching = $this->isWeeklyApproachingDowntime( diff --git a/www/class/centreonExternalCommand.class.php b/www/class/centreonExternalCommand.class.php index 337ffbaf1d3..357b1e41df5 100644 --- a/www/class/centreonExternalCommand.class.php +++ b/www/class/centreonExternalCommand.class.php @@ -403,8 +403,8 @@ public function acknowledgeService( private function getDowntimeTimestampFromDate($date = 'now', $timezone = '', $start = true) { $dateTime = new \DateTime($date, new \DateTimeZone($timezone)); - //$dst = $dateTime->format("I"); + // Winter to summer dst $dateTime2 = clone($dateTime); $dateTime2->setTimestamp($dateTime2->getTimestamp()); if ($dateTime2->format("H") != $dateTime->format("H")) { @@ -413,45 +413,28 @@ private function getDowntimeTimestampFromDate($date = 'now', $timezone = '', $st return $dateTime->getTimestamp(); } + // Summer to winter dst $dateTime3 = clone($dateTime); - $dateTime3->sub(new \DateInterval("PT1H")); - if ($dateTime3->format("H") == $dateTime->format("H")) { + $dateTime3 = $dateTime3->setTimestamp($dateTime3->getTimestamp() - 3600); + if ($dateTime3->getTimestamp() == $dateTime->getTimestamp()) { if ($start) { - return $dateTime3->getTimestamp(); + return $dateTime3->getTimestamp() - 3600; } else { - return $dateTime->getTimestamp(); + return $dateTime3->getTimestamp(); } } - return $dateTime->getTimestamp(); - -/* - // Check if previous is on winter time - $dateTime2 = clone($dateTime); - $dateTime2->sub(new \DateInterval("PT1H")); - - // Check if next is on summer time - $dateTime3 = clone($dateTime); - $dateTime3->add(new \DateInterval("PT1H")); - - if ($dst == "1" && $dateTime2->format("I") != $dst) { - if () - $hour = $dateTime->format('H'); - $dateTime->setTime($hour, '00'); - $timestamp = $dateTime->getTimestamp(); - } elseif ($dateTime3->format("I") != $dst && $start) { - if ($dateTime->format('H:i') == $dateTime3->format("H:i")) { - + $dateTime4 = clone($dateTime); + $dateTime4 = $dateTime3->setTimestamp($dateTime4->getTimestamp() + 3600); + if ($dateTime4->getTimestamp() == $dateTime->getTimestamp()) { + if ($start) { + return $dateTime->getTimestamp(); + } else { + return $dateTime4->getTimestamp() + 3600; } - $hour = $dateTime->format('H'); - $dateTime->setTime($hour, '00'); - $timestamp = $dateTime->getTimestamp(); - } else { - $timestamp = $dateTime->getTimestamp(); } - return $timestamp; - */ + return $dateTime->getTimestamp(); } /** From fd993f02984bbf816eea9cb94ce900d2f8d79ebb Mon Sep 17 00:00:00 2001 From: Kevin Duret Date: Fri, 13 Oct 2017 10:33:22 +0200 Subject: [PATCH 5/8] fix(gmt): get host locations from poller too --- www/class/centreonGMT.class.php | 39 +++++++++++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 2 deletions(-) diff --git a/www/class/centreonGMT.class.php b/www/class/centreonGMT.class.php index e6d42f423c1..1085fa508f6 100644 --- a/www/class/centreonGMT.class.php +++ b/www/class/centreonGMT.class.php @@ -71,6 +71,12 @@ class CentreonGMT */ protected $hostLocations = array(); + /** + * + * @param array $pollerLocations + */ + protected $pollerLocations = array(); + /** * Default timezone setted in adminstration/options * @var string $sDefaultTimezone @@ -495,17 +501,46 @@ public function getHostLocations() return $this->hostLocations; } + $this->getPollerLocations(); + $this->hostLocations = array(); - $query = 'SELECT host_id, timezone FROM hosts WHERE enabled = 1 '; + $query = 'SELECT host_id, instance_id, timezone FROM hosts WHERE enabled = 1 '; $res = $this->dbc->query($query); if (!PEAR::isError($res)) { while ($row = $res->fetchRow()) { - $this->hostLocations[$row['host_id']] = str_replace(':', '', $row['timezone']); + if ($row['timezone'] == "" && isset($this->pollerLocations[$row['instance_id']])) { + $this->hostLocations[$row['host_id']] = $this->pollerLocations[$row['instance_id']]; + } else { + $this->hostLocations[$row['host_id']] = str_replace(':', '', $row['timezone']); + } } } return $this->hostLocations; } + + /** + * Get list of timezone of pollers + * @return array + */ + public function getPollerLocations() + { + if (count($this->pollerLocations)) { + return $this->pollerLocations; + } + + $query = 'SELECT ns.id, t.timezone_name ' . + 'FROM cfg_nagios cfgn, nagios_server ns, timezone t ' . + 'WHERE cfgn.nagios_activate = "1" ' . + 'AND cfgn.nagios_server_id = ns.id ' . + 'AND cfgn.use_timezone = t.timezone_id '; + $res = $this->db->query($query); + while ($row = $res->fetchRow()) { + $this->pollerLocations[$row['id']] = $row['timezone_name']; + } + + return $this->pollerLocations; + } /** * Get default timezone setted in admintration/options From 22ef7c4fe17b8495594ad27460a6ee8e0a113e04 Mon Sep 17 00:00:00 2001 From: Kev Date: Fri, 13 Oct 2017 14:51:06 +0200 Subject: [PATCH 6/8] fix(acceptance): update acceptance tests with dst --- features/bootstrap/DowntimeDSTContext.php | 4 ++-- www/class/centreonDowntime.Broker.class.php | 2 +- www/class/centreonExternalCommand.class.php | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/features/bootstrap/DowntimeDSTContext.php b/features/bootstrap/DowntimeDSTContext.php index 8ee9b0e57ec..438841b5da6 100644 --- a/features/bootstrap/DowntimeDSTContext.php +++ b/features/bootstrap/DowntimeDSTContext.php @@ -189,9 +189,9 @@ public function aDowntimeDuringAllDayOnSummerChangingDateIsScheduled() public function aDowntimeOfNextDayOfSummerChangingDate() { $this->downtimeProperties = array( - 'start_day' => '2021/03/28', + 'start_day' => '2021/03/29', 'start_time' => '00:00', - 'end_day' => '2021/03/28', + 'end_day' => '2021/03/29', 'end_time' => '24:00', 'expected_start' => '2021-03-29 00:00', 'expected_end' => '2021-03-30 00:00', diff --git a/www/class/centreonDowntime.Broker.class.php b/www/class/centreonDowntime.Broker.class.php index f049c212914..c21598987e8 100644 --- a/www/class/centreonDowntime.Broker.class.php +++ b/www/class/centreonDowntime.Broker.class.php @@ -296,7 +296,7 @@ private function manageSummerToWinterTimestamp($timestamp, $timezone) { $dstDate = new DateTime('now', $timezone); $dstDate->setTimestamp($timestamp); - $dateTime2 = clone($dstDate); + $dateTime2 = clone $dstDate; $dateTime2->setTimestamp($timestamp - 3600); if ($dateTime2->getTimestamp() == $dstDate->getTimestamp()) { diff --git a/www/class/centreonExternalCommand.class.php b/www/class/centreonExternalCommand.class.php index 357b1e41df5..59207b2dfdb 100644 --- a/www/class/centreonExternalCommand.class.php +++ b/www/class/centreonExternalCommand.class.php @@ -405,7 +405,7 @@ private function getDowntimeTimestampFromDate($date = 'now', $timezone = '', $st $dateTime = new \DateTime($date, new \DateTimeZone($timezone)); // Winter to summer dst - $dateTime2 = clone($dateTime); + $dateTime2 = clone $dateTime; $dateTime2->setTimestamp($dateTime2->getTimestamp()); if ($dateTime2->format("H") != $dateTime->format("H")) { $hour = $dateTime->format('H'); @@ -414,7 +414,7 @@ private function getDowntimeTimestampFromDate($date = 'now', $timezone = '', $st } // Summer to winter dst - $dateTime3 = clone($dateTime); + $dateTime3 = clone $dateTime; $dateTime3 = $dateTime3->setTimestamp($dateTime3->getTimestamp() - 3600); if ($dateTime3->getTimestamp() == $dateTime->getTimestamp()) { if ($start) { @@ -424,7 +424,7 @@ private function getDowntimeTimestampFromDate($date = 'now', $timezone = '', $st } } - $dateTime4 = clone($dateTime); + $dateTime4 = clone $dateTime; $dateTime4 = $dateTime3->setTimestamp($dateTime4->getTimestamp() + 3600); if ($dateTime4->getTimestamp() == $dateTime->getTimestamp()) { if ($start) { From 1541ec4470c85247363fab1252c2e47b3a175ec0 Mon Sep 17 00:00:00 2001 From: Kevin Duret Date: Tue, 17 Oct 2017 11:17:41 +0200 Subject: [PATCH 7/8] fix(downtime): update downtime date format --- features/bootstrap/DowntimeDSTContext.php | 40 +++++++++---------- .../monitoring/downtime/AddDowntime.php | 4 +- 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/features/bootstrap/DowntimeDSTContext.php b/features/bootstrap/DowntimeDSTContext.php index 438841b5da6..4544a9578ac 100644 --- a/features/bootstrap/DowntimeDSTContext.php +++ b/features/bootstrap/DowntimeDSTContext.php @@ -108,9 +108,9 @@ public function aDowntimeStartingOnSummerChangingTime() { // on Europe/Paris at 2AM, we jump to 3AM $this->downtimeProperties = array( - 'start_day' => '2021/03/28', + 'start_day' => '03/28/2021', 'start_time' => '02:30', - 'end_day' => '2021/03/28', + 'end_day' => '03/28/2021', 'end_time' => '03:30', 'expected_start' => '2021-03-28 03:00', 'expected_end' => '2021-03-28 03:30', @@ -126,9 +126,9 @@ public function aDowntimeEndingOnSummerChangingTime() { // on Europe/Paris at 2AM, we jump to 3AM $this->downtimeProperties = array( - 'start_day' => '2021/03/28', + 'start_day' => '03/28/2021', 'start_time' => '01:30', - 'end_day' => '2021/03/28', + 'end_day' => '03/28/2021', 'end_time' => '02:30', 'expected_start' => '2021-03-28 01:30', 'expected_end' => '2021-03-28 03:00', @@ -144,9 +144,9 @@ public function aDowntimeStartingAndEndingOnSummerChangingTime() { // on Europe/Paris at 2AM, we jump to 3AM $this->downtimeProperties = array( - 'start_day' => '2021/03/28', + 'start_day' => '03/28/2021', 'start_time' => '02:03', - 'end_day' => '2021/03/28', + 'end_day' => '03/28/2021', 'end_time' => '02:33', 'expected_start' => '', 'expected_end' => '', @@ -162,9 +162,9 @@ public function aDowntimeDuringAllDayOnSummerChangingDate() { // on Europe/Paris at 2AM, we jump to 3AM $this->downtimeProperties = array( - 'start_day' => '2021/03/28', + 'start_day' => '03/28/2021', 'start_time' => '00:00', - 'end_day' => '2021/03/28', + 'end_day' => '03/28/2021', 'end_time' => '24:00', 'expected_start' => '2021-03-28 00:00', 'expected_end' => '2021-03-29 00:00', @@ -189,9 +189,9 @@ public function aDowntimeDuringAllDayOnSummerChangingDateIsScheduled() public function aDowntimeOfNextDayOfSummerChangingDate() { $this->downtimeProperties = array( - 'start_day' => '2021/03/29', + 'start_day' => '03/29/2021', 'start_time' => '00:00', - 'end_day' => '2021/03/29', + 'end_day' => '03/29/2021', 'end_time' => '24:00', 'expected_start' => '2021-03-29 00:00', 'expected_end' => '2021-03-30 00:00', @@ -207,9 +207,9 @@ public function aDowntimeStartingOnWinterChangingDate() { // on Europe/Paris at 3AM, backward to 2AM $this->downtimeProperties = array( - 'start_day' => '2021/10/31', + 'start_day' => '10/31/2021', 'start_time' => '02:03', - 'end_day' => '2021/10/31', + 'end_day' => '10/31/2021', 'end_time' => '03:33', 'expected_start' => '2021-10-31 02:03', 'expected_end' => '2021-10-31 03:33', @@ -225,9 +225,9 @@ public function aDowntimeEndingOnWinterChangingDate() { // on Europe/Paris at 3AM, backward to 2AM $this->downtimeProperties = array( - 'start_day' => '2021/10/31', + 'start_day' => '10/31/2021', 'start_time' => '01:00', - 'end_day' => '2021/10/31', + 'end_day' => '10/31/2021', 'end_time' => '02:30', 'expected_start' => '2021-10-31 01:00', 'expected_end' => '2021-10-31 02:30', @@ -243,9 +243,9 @@ public function aDowntimeStartingAndEndingOnWinterChangingDate() { // on Europe/Paris at 3AM, backward to 2AM $this->downtimeProperties = array( - 'start_day' => '2021/10/31', + 'start_day' => '10/31/2021', 'start_time' => '02:03', - 'end_day' => '2021/10/31', + 'end_day' => '10/31/2021', 'end_time' => '02:33', 'expected_start' => '2021-10-31 02:03', 'expected_end' => '2021-10-31 02:33', @@ -261,9 +261,9 @@ public function aDowntimeDuringAllDayOnWinterChangingDate() { // on Europe/Paris at 3AM, backward to 2AM $this->downtimeProperties = array( - 'start_day' => '2021/10/31', + 'start_day' => '10/31/2021', 'start_time' => '00:00', - 'end_day' => '2021/10/31', + 'end_day' => '10/31/2021', 'end_time' => '24:00', 'expected_start' => '2021-10-31 00:00', 'expected_end' => '2021-11-01 00:00', @@ -288,9 +288,9 @@ public function aDowntimeDuringAllDayOnWinterChangingDateIsScheduled() public function aDowntimeOfNextDayOfWinterChangingDate() { $this->downtimeProperties = array( - 'start_day' => '2021/11/01', + 'start_day' => '11/01/2021', 'start_time' => '00:00', - 'end_day' => '2021/11/01', + 'end_day' => '11/01/2021', 'end_time' => '24:00', 'expected_start' => '2021-11-01 00:00', 'expected_end' => '2021-11-02 00:00', diff --git a/www/include/monitoring/downtime/AddDowntime.php b/www/include/monitoring/downtime/AddDowntime.php index 959e861d4b2..6ab5ba36026 100644 --- a/www/include/monitoring/downtime/AddDowntime.php +++ b/www/include/monitoring/downtime/AddDowntime.php @@ -249,8 +249,8 @@ $form->addRule('comment', _("Required Field"), 'required'); $data = array(); - $data["start"] = $centreonGMT->getDate("Y/m/d", time()); - $data["end"] = $centreonGMT->getDate("Y/m/d", time() + 7200); + $data["start"] = $centreonGMT->getDate("m/d/Y", time()); + $data["end"] = $centreonGMT->getDate("m/d/Y", time() + 7200); $data["start_time"] = $centreonGMT->getDate("G:i", time()); $data["end_time"] = $centreonGMT->getDate("G:i", time() + 7200); $data["host_or_hg"] = 1; From c35ace14d9defad686109d8bb0f217b3b46ce6aa Mon Sep 17 00:00:00 2001 From: Kevin Duret Date: Tue, 17 Oct 2017 11:21:45 +0200 Subject: [PATCH 8/8] style(acceptance): improve coding style of downtime dst acceptance tests --- features/bootstrap/DowntimeDSTContext.php | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/features/bootstrap/DowntimeDSTContext.php b/features/bootstrap/DowntimeDSTContext.php index 4544a9578ac..ff92f155301 100644 --- a/features/bootstrap/DowntimeDSTContext.php +++ b/features/bootstrap/DowntimeDSTContext.php @@ -329,13 +329,11 @@ function ($context) { 'web' ); $output = $return['output']; - if ( - preg_match_all( - '/SCHEDULE_SVC_DOWNTIME;' . $context->host . ';' . $context->service . ';(\d+);(\d+);.+/', - $output, - $matches - ) - ) { + if (preg_match_all( + '/SCHEDULE_SVC_DOWNTIME;' . $context->host . ';' . $context->service . ';(\d+);(\d+);.+/', + $output, + $matches + )) { $startTimestamp = end($matches[1]); $endTimestamp = end($matches[2]); $dateStart = new DateTime('now', new \DateTimeZone('Europe/Paris')); @@ -378,12 +376,10 @@ function ($context) { 'web' ); $output = $return['output']; - if ( - preg_match( + if (preg_match( '/SCHEDULE_SVC_DOWNTIME;' . $this->host . ';' . $this->service . ';(\d+);(\d+);.+/', $output - ) - ) { + )) { $scheduled = false; }