Version 1
[yaffs-website] / web / core / modules / system / tests / src / Kernel / System / CronQueueTest.php
diff --git a/web/core/modules/system/tests/src/Kernel/System/CronQueueTest.php b/web/core/modules/system/tests/src/Kernel/System/CronQueueTest.php
new file mode 100644 (file)
index 0000000..649a2c7
--- /dev/null
@@ -0,0 +1,112 @@
+<?php
+
+namespace Drupal\Tests\system\Kernel\System;
+
+use Drupal\Core\Database\Database;
+use Drupal\KernelTests\KernelTestBase;
+
+/**
+ * Tests the Cron Queue runner.
+ *
+ * @group system
+ */
+class CronQueueTest extends KernelTestBase {
+
+  /**
+   * The modules to enable.
+   *
+   * @var array
+   */
+  public static $modules = ['system', 'cron_queue_test'];
+
+  /**
+   * The database connection.
+   *
+   * @var \Drupal\Core\Database\Connection
+   */
+  protected $connection;
+
+  /**
+   * The cron service.
+   *
+   * @var \Drupal\Core\Cron
+   */
+  protected $cron;
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+
+    // These additional tables are necessary because $this->cron->run() calls
+    // system_cron().
+    $this->installSchema('system', ['key_value_expire']);
+
+    $this->connection = Database::getConnection();
+    $this->cron = \Drupal::service('cron');
+  }
+
+  /**
+   * Tests that exceptions thrown by workers are handled properly.
+   */
+  public function testExceptions() {
+    // Get the queue to test the normal Exception.
+    $queue = $this->container->get('queue')->get('cron_queue_test_exception');
+
+    // Enqueue an item for processing.
+    $queue->createItem([$this->randomMachineName() => $this->randomMachineName()]);
+
+    // Run cron; the worker for this queue should throw an exception and handle
+    // it.
+    $this->cron->run();
+    $this->assertEqual(\Drupal::state()->get('cron_queue_test_exception'), 1);
+
+    // The item should be left in the queue.
+    $this->assertEqual($queue->numberOfItems(), 1, 'Failing item still in the queue after throwing an exception.');
+
+    // Expire the queue item manually. system_cron() relies in REQUEST_TIME to
+    // find queue items whose expire field needs to be reset to 0. This is a
+    // Kernel test, so REQUEST_TIME won't change when cron runs.
+    // @see system_cron()
+    // @see \Drupal\Core\Cron::processQueues()
+    $this->connection->update('queue')
+      ->condition('name', 'cron_queue_test_exception')
+      ->fields(['expire' => REQUEST_TIME - 1])
+      ->execute();
+    $this->cron->run();
+    $this->assertEqual(\Drupal::state()->get('cron_queue_test_exception'), 2);
+    $this->assertEqual($queue->numberOfItems(), 0, 'Item was processed and removed from the queue.');
+
+    // Get the queue to test the specific SuspendQueueException.
+    $queue = $this->container->get('queue')->get('cron_queue_test_broken_queue');
+
+    // Enqueue several item for processing.
+    $queue->createItem('process');
+    $queue->createItem('crash');
+    $queue->createItem('ignored');
+
+    // Run cron; the worker for this queue should process as far as the crashing
+    // item.
+    $this->cron->run();
+
+    // Only one item should have been processed.
+    $this->assertEqual($queue->numberOfItems(), 2, 'Failing queue stopped processing at the failing item.');
+
+    // Check the items remaining in the queue. The item that throws the
+    // exception gets released by cron, so we can claim it again to check it.
+    $item = $queue->claimItem();
+    $this->assertEqual($item->data, 'crash', 'Failing item remains in the queue.');
+    $item = $queue->claimItem();
+    $this->assertEqual($item->data, 'ignored', 'Item beyond the failing item remains in the queue.');
+
+    // Test the requeueing functionality.
+    $queue = $this->container->get('queue')->get('cron_queue_test_requeue_exception');
+    $queue->createItem([]);
+    $this->cron->run();
+
+    $this->assertEqual(\Drupal::state()->get('cron_queue_test_requeue_exception'), 2);
+    $this->assertFalse($queue->numberOfItems());
+  }
+
+}