1<?php
2
3namespace Drupal\KernelTests\Core\Queue;
4
5use Drupal\Core\Database\Database;
6use Drupal\Core\Queue\DatabaseQueue;
7use Drupal\Core\Queue\Memory;
8use Drupal\KernelTests\KernelTestBase;
9
10/**
11 * Queues and dequeues a set of items to check the basic queue functionality.
12 *
13 * @group Queue
14 */
15class QueueTest extends KernelTestBase {
16
17  /**
18   * Tests the System queue.
19   */
20  public function testSystemQueue() {
21    // Create two queues.
22    $queue1 = new DatabaseQueue($this->randomMachineName(), Database::getConnection());
23    $queue1->createQueue();
24    $queue2 = new DatabaseQueue($this->randomMachineName(), Database::getConnection());
25    $queue2->createQueue();
26
27    $this->runQueueTest($queue1, $queue2);
28  }
29
30  /**
31   * Tests the Memory queue.
32   */
33  public function testMemoryQueue() {
34    // Create two queues.
35    $queue1 = new Memory($this->randomMachineName());
36    $queue1->createQueue();
37    $queue2 = new Memory($this->randomMachineName());
38    $queue2->createQueue();
39
40    $this->runQueueTest($queue1, $queue2);
41  }
42
43  /**
44   * Queues and dequeues a set of items to check the basic queue functionality.
45   *
46   * @param \Drupal\Core\Queue\QueueInterface $queue1
47   *   An instantiated queue object.
48   * @param \Drupal\Core\Queue\QueueInterface $queue2
49   *   An instantiated queue object.
50   */
51  protected function runQueueTest($queue1, $queue2) {
52    // Create four items.
53    $data = [];
54    for ($i = 0; $i < 4; $i++) {
55      $data[] = [$this->randomMachineName() => $this->randomMachineName()];
56    }
57
58    // Queue items 1 and 2 in the queue1.
59    $queue1->createItem($data[0]);
60    $queue1->createItem($data[1]);
61
62    // Retrieve two items from queue1.
63    $items = [];
64    $new_items = [];
65
66    $items[] = $item = $queue1->claimItem();
67    $new_items[] = $item->data;
68
69    $items[] = $item = $queue1->claimItem();
70    $new_items[] = $item->data;
71
72    // First two dequeued items should match the first two items we queued.
73    $this->assertEquals(2, $this->queueScore($data, $new_items), 'Two items matched');
74
75    // Add two more items.
76    $queue1->createItem($data[2]);
77    $queue1->createItem($data[3]);
78
79    $this->assertSame(4, $queue1->numberOfItems(), 'Queue 1 is not empty after adding items.');
80    $this->assertSame(0, $queue2->numberOfItems(), 'Queue 2 is empty while Queue 1 has items');
81
82    $items[] = $item = $queue1->claimItem();
83    $new_items[] = $item->data;
84
85    $items[] = $item = $queue1->claimItem();
86    $new_items[] = $item->data;
87
88    // All dequeued items should match the items we queued exactly once,
89    // therefore the score must be exactly 4.
90    $this->assertEquals(4, $this->queueScore($data, $new_items), 'Four items matched');
91
92    // There should be no duplicate items.
93    $this->assertEquals(4, $this->queueScore($new_items, $new_items), 'Four items matched');
94
95    // Delete all items from queue1.
96    foreach ($items as $item) {
97      $queue1->deleteItem($item);
98    }
99
100    // Check that both queues are empty.
101    $this->assertSame(0, $queue1->numberOfItems(), 'Queue 1 is empty');
102    $this->assertSame(0, $queue2->numberOfItems(), 'Queue 2 is empty');
103  }
104
105  /**
106   * Returns the number of equal items in two arrays.
107   */
108  protected function queueScore($items, $new_items) {
109    $score = 0;
110    foreach ($items as $item) {
111      foreach ($new_items as $new_item) {
112        if ($item === $new_item) {
113          $score++;
114        }
115      }
116    }
117    return $score;
118  }
119
120}
121