Skip to content
Snippets Groups Projects
Commit c796dde5 authored by Ted Bowman's avatar Ted Bowman Committed by Adam G-H
Browse files

Issue #3374753 by tedbow, phenaproxima: HookCronTest is broken and doesn't...

Issue #3374753 by tedbow, phenaproxima: HookCronTest is broken and doesn't test how often status checks will be run
parent fa85870d
No related branches found
No related tags found
2 merge requests!989Issue #3356804 by phenaproxima: Flag a warning during status check if the...,!936Issue #3374753: Run status whenever cron is run
...@@ -7,7 +7,6 @@ namespace Drupal\Tests\automatic_updates\Functional; ...@@ -7,7 +7,6 @@ namespace Drupal\Tests\automatic_updates\Functional;
use Behat\Mink\Element\NodeElement; use Behat\Mink\Element\NodeElement;
use Drupal\automatic_updates\CronUpdateStage; use Drupal\automatic_updates\CronUpdateStage;
use Drupal\automatic_updates\StatusCheckMailer; use Drupal\automatic_updates\StatusCheckMailer;
use Drupal\automatic_updates_test\Datetime\TestTime;
use Drupal\automatic_updates_test\EventSubscriber\TestSubscriber1; use Drupal\automatic_updates_test\EventSubscriber\TestSubscriber1;
use Drupal\automatic_updates_test_status_checker\EventSubscriber\TestSubscriber2; use Drupal\automatic_updates_test_status_checker\EventSubscriber\TestSubscriber2;
use Drupal\Core\Url; use Drupal\Core\Url;
...@@ -142,8 +141,6 @@ class StatusCheckTest extends AutomaticUpdatesFunctionalTestBase { ...@@ -142,8 +141,6 @@ class StatusCheckTest extends AutomaticUpdatesFunctionalTestBase {
// Confirm a user without the permission to run status checks does not // Confirm a user without the permission to run status checks does not
// have a link to run the checks when the checks need to be run again. // have a link to run the checks when the checks need to be run again.
// @todo Change this to fake the request time in
// https://www.drupal.org/node/3113971.
/** @var \Drupal\Core\KeyValueStore\KeyValueStoreInterface $key_value */ /** @var \Drupal\Core\KeyValueStore\KeyValueStoreInterface $key_value */
$key_value = $this->container->get('keyvalue.expirable')->get('automatic_updates'); $key_value = $this->container->get('keyvalue.expirable')->get('automatic_updates');
$key_value->delete('status_check_last_run'); $key_value->delete('status_check_last_run');
...@@ -247,7 +244,7 @@ class StatusCheckTest extends AutomaticUpdatesFunctionalTestBase { ...@@ -247,7 +244,7 @@ class StatusCheckTest extends AutomaticUpdatesFunctionalTestBase {
} }
/** /**
* Tests status check results on admin pages.. * Tests status check results on admin pages.
* *
* @param string $admin_route * @param string $admin_route
* The admin route to check. * The admin route to check.
...@@ -271,9 +268,6 @@ class StatusCheckTest extends AutomaticUpdatesFunctionalTestBase { ...@@ -271,9 +268,6 @@ class StatusCheckTest extends AutomaticUpdatesFunctionalTestBase {
// a link to run the checks when the checks need to be run again. // a link to run the checks when the checks need to be run again.
$expected_results = [$this->createValidationResult(SystemManager::REQUIREMENT_ERROR)]; $expected_results = [$this->createValidationResult(SystemManager::REQUIREMENT_ERROR)];
TestSubscriber1::setTestResult($expected_results, StatusCheckEvent::class); TestSubscriber1::setTestResult($expected_results, StatusCheckEvent::class);
// @todo Change this to use ::delayRequestTime() to simulate running cron
// after a 24 wait instead of directly deleting 'status_check_last_run'
// https://www.drupal.org/node/3113971.
/** @var \Drupal\Core\KeyValueStore\KeyValueStoreInterface $key_value */ /** @var \Drupal\Core\KeyValueStore\KeyValueStoreInterface $key_value */
$key_value = $this->container->get('keyvalue.expirable')->get('automatic_updates'); $key_value = $this->container->get('keyvalue.expirable')->get('automatic_updates');
$key_value->delete('status_check_last_run'); $key_value->delete('status_check_last_run');
...@@ -297,9 +291,7 @@ class StatusCheckTest extends AutomaticUpdatesFunctionalTestBase { ...@@ -297,9 +291,7 @@ class StatusCheckTest extends AutomaticUpdatesFunctionalTestBase {
'1 warning' => $this->createValidationResult(SystemManager::REQUIREMENT_WARNING), '1 warning' => $this->createValidationResult(SystemManager::REQUIREMENT_WARNING),
]; ];
TestSubscriber1::setTestResult($expected_results, StatusCheckEvent::class); TestSubscriber1::setTestResult($expected_results, StatusCheckEvent::class);
// Confirm a new message is displayed if the cron is run after an hour. $this->runStatusChecks();
$this->delayRequestTime();
$this->cronRun();
$this->drupalGet(Url::fromRoute($admin_route)); $this->drupalGet(Url::fromRoute($admin_route));
$assert->pageTextContainsOnce(static::$errorsExplanation); $assert->pageTextContainsOnce(static::$errorsExplanation);
// Confirm on admin pages that the summary will be displayed. // Confirm on admin pages that the summary will be displayed.
...@@ -311,25 +303,22 @@ class StatusCheckTest extends AutomaticUpdatesFunctionalTestBase { ...@@ -311,25 +303,22 @@ class StatusCheckTest extends AutomaticUpdatesFunctionalTestBase {
$assert->pageTextNotContains($expected_results['1 warning']->messages[0]); $assert->pageTextNotContains($expected_results['1 warning']->messages[0]);
$assert->pageTextNotContains($expected_results['1 warning']->summary); $assert->pageTextNotContains($expected_results['1 warning']->summary);
// Confirm that if cron runs less than hour after it previously ran it will // Confirm the status check event is not dispatched on every admin page
// not run the checkers again. // load.
$unexpected_results = [ $unexpected_results = [
'2 errors' => $this->createValidationResult(SystemManager::REQUIREMENT_ERROR, 2), '2 errors' => $this->createValidationResult(SystemManager::REQUIREMENT_ERROR, 2),
'2 warnings' => $this->createValidationResult(SystemManager::REQUIREMENT_WARNING, 2), '2 warnings' => $this->createValidationResult(SystemManager::REQUIREMENT_WARNING, 2),
]; ];
TestSubscriber1::setTestResult($unexpected_results, StatusCheckEvent::class); TestSubscriber1::setTestResult($unexpected_results, StatusCheckEvent::class);
$this->delayRequestTime(30);
$this->cronRun();
$this->drupalGet(Url::fromRoute($admin_route)); $this->drupalGet(Url::fromRoute($admin_route));
$assert->pageTextNotContains($unexpected_results['2 errors']->summary); $assert->pageTextNotContains($unexpected_results['2 errors']->summary);
$assert->pageTextContainsOnce((string) $expected_results['1 error']->summary); $assert->pageTextContainsOnce((string) $expected_results['1 error']->summary);
$assert->pageTextNotContains($unexpected_results['2 warnings']->summary); $assert->pageTextNotContains($unexpected_results['2 warnings']->summary);
$assert->pageTextNotContains($expected_results['1 warning']->messages[0]); $assert->pageTextNotContains($expected_results['1 warning']->messages[0]);
// Confirm that is if cron is run over an hour after the checkers were // Confirm the updated results will be shown when status checks are run
// previously run the checkers will be run again. // again.
$this->delayRequestTime(31); $this->runStatusChecks();
$this->cronRun();
$expected_results = $unexpected_results; $expected_results = $unexpected_results;
$this->drupalGet(Url::fromRoute($admin_route)); $this->drupalGet(Url::fromRoute($admin_route));
// Confirm on admin pages only the error summary will be displayed if there // Confirm on admin pages only the error summary will be displayed if there
...@@ -347,8 +336,7 @@ class StatusCheckTest extends AutomaticUpdatesFunctionalTestBase { ...@@ -347,8 +336,7 @@ class StatusCheckTest extends AutomaticUpdatesFunctionalTestBase {
$expected_results = [$this->createValidationResult(SystemManager::REQUIREMENT_WARNING, 2)]; $expected_results = [$this->createValidationResult(SystemManager::REQUIREMENT_WARNING, 2)];
TestSubscriber1::setTestResult($expected_results, StatusCheckEvent::class); TestSubscriber1::setTestResult($expected_results, StatusCheckEvent::class);
$this->delayRequestTime(); $this->runStatusChecks();
$this->cronRun();
$this->drupalGet(Url::fromRoute($admin_route)); $this->drupalGet(Url::fromRoute($admin_route));
// Confirm that the warnings summary is displayed on admin pages if there // Confirm that the warnings summary is displayed on admin pages if there
// are no errors. // are no errors.
...@@ -361,8 +349,7 @@ class StatusCheckTest extends AutomaticUpdatesFunctionalTestBase { ...@@ -361,8 +349,7 @@ class StatusCheckTest extends AutomaticUpdatesFunctionalTestBase {
$expected_results = [$this->createValidationResult(SystemManager::REQUIREMENT_WARNING)]; $expected_results = [$this->createValidationResult(SystemManager::REQUIREMENT_WARNING)];
TestSubscriber1::setTestResult($expected_results, StatusCheckEvent::class); TestSubscriber1::setTestResult($expected_results, StatusCheckEvent::class);
$this->delayRequestTime(); $this->runStatusChecks();
$this->cronRun();
$this->drupalGet(Url::fromRoute($admin_route)); $this->drupalGet(Url::fromRoute($admin_route));
$assert->pageTextNotContains(static::$errorsExplanation); $assert->pageTextNotContains(static::$errorsExplanation);
// Confirm that a single warning is displayed and not the summary on admin // Confirm that a single warning is displayed and not the summary on admin
...@@ -761,15 +748,11 @@ class StatusCheckTest extends AutomaticUpdatesFunctionalTestBase { ...@@ -761,15 +748,11 @@ class StatusCheckTest extends AutomaticUpdatesFunctionalTestBase {
} }
/** /**
* Delays the request for the test. * Runs status checks.
*
* @param int $minutes
* The number of minutes to delay request time. Defaults to 61 minutes.
*/ */
private function delayRequestTime(int $minutes = 61): void { private function runStatusChecks(): void {
static $total_delay = 0; $this->drupalGet('/admin/reports/status');
$total_delay += $minutes; $this->clickLink('Rerun readiness checks');
TestTime::setFakeTimeByOffset("+$total_delay minutes");
} }
} }
...@@ -2,7 +2,9 @@ ...@@ -2,7 +2,9 @@
namespace Drupal\Tests\automatic_updates\Kernel; namespace Drupal\Tests\automatic_updates\Kernel;
use Drupal\automatic_updates\Validation\StatusChecker; use Drupal\automatic_updates\CronUpdateStage;
use Drupal\automatic_updates_test\Datetime\TestTime;
use Drupal\package_manager\Event\StatusCheckEvent;
/** /**
* @group automatic_updates * @group automatic_updates
...@@ -12,25 +14,47 @@ class HookCronTest extends AutomaticUpdatesKernelTestBase { ...@@ -12,25 +14,47 @@ class HookCronTest extends AutomaticUpdatesKernelTestBase {
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
protected static $modules = ['automatic_updates']; protected static $modules = ['automatic_updates', 'automatic_updates_test'];
/** /**
* Tests that our cron hook does not run if we're at the command line. * Tests that our cron hook will run status checks.
*/ */
public function testCronHookBypassedAtCommandLine(): void { public function testStatusChecksRunOnCron(): void {
if (PHP_SAPI !== 'cli') { // Set the core version to 9.8.1 so there will not be an update attempted.
$this->markTestSkipped('This test requires that PHP be running at the command line.'); // The hook_cron implementations will not be run if there is an update.
} // @see \Drupal\automatic_updates\CronUpdateStage::run()
// @todo Remove this is https://drupal.org/i/3357969
// The status check should not have run yet. $this->setCoreVersion('9.8.1');
/** @var \Drupal\automatic_updates\Validation\StatusChecker $status_checker */ // Undo override of the 'serverApi' property from the parent test class.
$status_checker = $this->container->get(StatusChecker::class); // @see \Drupal\Tests\automatic_updates\Kernel\AutomaticUpdatesKernelTestBase::setUp
$this->assertNull($status_checker->getLastRunTime()); $property = new \ReflectionProperty(CronUpdateStage::class, 'serverApi');
$property->setValue(NULL, 'cli');
$this->assertTrue(CronUpdateStage::isCommandLine());
$status_check_count = 0;
$this->addEventTestListener(function () use (&$status_check_count) {
$status_check_count++;
}, StatusCheckEvent::class);
// Since we're at the command line, status checks should still not run, even // Since we're at the command line, status checks should still not run, even
// if we do run cron. // if we do run cron.
$this->container->get('cron')->run(); $this->container->get('cron')->run();
$this->assertNull($status_checker->getResults()); $this->assertSame(0, $status_check_count);
// If we are on the web the status checks should run.
$property->setValue(NULL, 'cgi-fcgi');
$this->assertFalse(CronUpdateStage::isCommandLine());
$this->container->get('cron')->run();
$this->assertSame(1, $status_check_count);
// Ensure that the status checks won't run if less than an hour has passed.
TestTime::setFakeTimeByOffset("+30 minutes");
$this->container->get('cron')->run();
$this->assertSame(1, $status_check_count);
// The status checks should run if more than an hour has passed.
TestTime::setFakeTimeByOffset("+61 minutes");
$this->container->get('cron')->run();
$this->assertSame(2, $status_check_count);
} }
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment