Merge pull request #15808 from civicrm/5.20
[civicrm-core.git] / tests / phpunit / CRM / Queue / RunnerTest.php
CommitLineData
6a488035
TO
1<?php
2/*
3 +--------------------------------------------------------------------+
2fe49090 4 | CiviCRM version 5 |
6a488035 5 +--------------------------------------------------------------------+
f299f7db 6 | Copyright CiviCRM LLC (c) 2004-2020 |
6a488035
TO
7 +--------------------------------------------------------------------+
8 | This file is a part of CiviCRM. |
9 | |
10 | CiviCRM is free software; you can copy, modify, and distribute it |
11 | under the terms of the GNU Affero General Public License |
12 | Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
13 | |
14 | CiviCRM is distributed in the hope that it will be useful, but |
15 | WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
17 | See the GNU Affero General Public License for more details. |
18 | |
19 | You should have received a copy of the GNU Affero General Public |
20 | License and the CiviCRM Licensing Exception along |
21 | with this program; if not, contact CiviCRM LLC |
22 | at info[AT]civicrm[DOT]org. If you have questions about the |
23 | GNU Affero General Public License or the licensing of CiviCRM, |
24 | see the CiviCRM license FAQ at http://civicrm.org/licensing |
25 +--------------------------------------------------------------------+
d25dd0ee 26 */
6a488035 27
6a488035
TO
28/**
29 * Ensure that various queue implementations comply with the interface
acb109b7 30 * @group headless
6a488035
TO
31 */
32class CRM_Queue_RunnerTest extends CiviUnitTestCase {
6a488035 33
00be9182 34 public function setUp() {
6a488035 35 parent::setUp();
6a488035 36 $this->queueService = CRM_Queue_Service::singleton(TRUE);
9099cab3 37 $this->queue = $this->queueService->create([
92915c55
TO
38 'type' => 'Sql',
39 'name' => 'test-queue',
9099cab3
CW
40 ]);
41 self::$_recordedValues = [];
6a488035
TO
42 }
43
00be9182 44 public function tearDown() {
6a488035
TO
45 unset($this->queue);
46 unset($this->queueService);
b6708aeb 47
6a488035
TO
48 CRM_Utils_Time::resetTime();
49
9099cab3 50 $tablesToTruncate = ['civicrm_queue_item'];
6a488035
TO
51 $this->quickCleanup($tablesToTruncate);
52 }
53
00be9182 54 public function testRunAllNormal() {
6a488035
TO
55 // prepare a list of tasks with an error in the middle
56 $this->queue->createItem(new CRM_Queue_Task(
9099cab3
CW
57 ['CRM_Queue_RunnerTest', '_recordValue'],
58 ['a'],
92915c55
TO
59 'Add "a"'
60 ));
6a488035 61 $this->queue->createItem(new CRM_Queue_Task(
9099cab3
CW
62 ['CRM_Queue_RunnerTest', '_recordValue'],
63 ['b'],
92915c55
TO
64 'Add "b"'
65 ));
6a488035 66 $this->queue->createItem(new CRM_Queue_Task(
9099cab3
CW
67 ['CRM_Queue_RunnerTest', '_recordValue'],
68 ['c'],
92915c55
TO
69 'Add "c"'
70 ));
6a488035
TO
71
72 // run the list of tasks
9099cab3 73 $runner = new CRM_Queue_Runner([
92915c55
TO
74 'queue' => $this->queue,
75 'errorMode' => CRM_Queue_Runner::ERROR_ABORT,
9099cab3
CW
76 ]);
77 $this->assertEquals(self::$_recordedValues, []);
6a488035
TO
78 $this->assertEquals(3, $this->queue->numberOfItems());
79 $result = $runner->runAll();
80 $this->assertEquals(TRUE, $result);
9099cab3 81 $this->assertEquals(self::$_recordedValues, ['a', 'b', 'c']);
6a488035
TO
82 $this->assertEquals(0, $this->queue->numberOfItems());
83 }
84
85 /**
fe482240
EM
86 * Run a series of tasks.
87 *
88 * One of the tasks will insert more TODOs at the start of the list.
6a488035 89 */
00be9182 90 public function testRunAll_AddMore() {
fe482240 91 // Prepare a list of tasks with an error in the middle.
6a488035 92 $this->queue->createItem(new CRM_Queue_Task(
9099cab3
CW
93 ['CRM_Queue_RunnerTest', '_recordValue'],
94 ['a'],
92915c55
TO
95 'Add "a"'
96 ));
6a488035 97 $this->queue->createItem(new CRM_Queue_Task(
9099cab3
CW
98 ['CRM_Queue_RunnerTest', '_enqueueNumbers'],
99 [1, 3],
92915c55
TO
100 'Add more'
101 ));
6a488035 102 $this->queue->createItem(new CRM_Queue_Task(
9099cab3
CW
103 ['CRM_Queue_RunnerTest', '_recordValue'],
104 ['b'],
92915c55
TO
105 'Add "b"'
106 ));
6a488035
TO
107
108 // run the list of tasks
9099cab3 109 $runner = new CRM_Queue_Runner([
92915c55
TO
110 'queue' => $this->queue,
111 'errorMode' => CRM_Queue_Runner::ERROR_ABORT,
9099cab3
CW
112 ]);
113 $this->assertEquals(self::$_recordedValues, []);
6a488035
TO
114 $this->assertEquals(3, $this->queue->numberOfItems());
115 $result = $runner->runAll();
116 $this->assertEquals(TRUE, $result);
9099cab3 117 $this->assertEquals(self::$_recordedValues, ['a', 1, 2, 3, 'b']);
6a488035
TO
118 $this->assertEquals(0, $this->queue->numberOfItems());
119 }
120
121 /**
122 * Run a series of tasks; when one throws an
123 * exception, ignore it and continue
124 */
00be9182 125 public function testRunAll_Continue_Exception() {
6a488035
TO
126 // prepare a list of tasks with an error in the middle
127 $this->queue->createItem(new CRM_Queue_Task(
9099cab3
CW
128 ['CRM_Queue_RunnerTest', '_recordValue'],
129 ['a'],
92915c55
TO
130 'Add "a"'
131 ));
6a488035 132 $this->queue->createItem(new CRM_Queue_Task(
9099cab3
CW
133 ['CRM_Queue_RunnerTest', '_throwException'],
134 ['b'],
92915c55
TO
135 'Throw exception'
136 ));
6a488035 137 $this->queue->createItem(new CRM_Queue_Task(
9099cab3
CW
138 ['CRM_Queue_RunnerTest', '_recordValue'],
139 ['c'],
92915c55
TO
140 'Add "c"'
141 ));
6a488035
TO
142
143 // run the list of tasks
9099cab3 144 $runner = new CRM_Queue_Runner([
92915c55
TO
145 'queue' => $this->queue,
146 'errorMode' => CRM_Queue_Runner::ERROR_CONTINUE,
9099cab3
CW
147 ]);
148 $this->assertEquals(self::$_recordedValues, []);
6a488035
TO
149 $this->assertEquals(3, $this->queue->numberOfItems());
150 $result = $runner->runAll();
151 // FIXME useless return
152 $this->assertEquals(TRUE, $result);
9099cab3 153 $this->assertEquals(self::$_recordedValues, ['a', 'c']);
6a488035
TO
154 $this->assertEquals(0, $this->queue->numberOfItems());
155 }
156
157 /**
158 * Run a series of tasks; when one throws an exception,
159 * abort processing and return it to the queue.
160 */
00be9182 161 public function testRunAll_Abort_Exception() {
6a488035
TO
162 // prepare a list of tasks with an error in the middle
163 $this->queue->createItem(new CRM_Queue_Task(
9099cab3
CW
164 ['CRM_Queue_RunnerTest', '_recordValue'],
165 ['a'],
92915c55
TO
166 'Add "a"'
167 ));
6a488035 168 $this->queue->createItem(new CRM_Queue_Task(
9099cab3
CW
169 ['CRM_Queue_RunnerTest', '_throwException'],
170 ['b'],
92915c55
TO
171 'Throw exception'
172 ));
6a488035 173 $this->queue->createItem(new CRM_Queue_Task(
9099cab3
CW
174 ['CRM_Queue_RunnerTest', '_recordValue'],
175 ['c'],
92915c55
TO
176 'Add "c"'
177 ));
6a488035
TO
178
179 // run the list of tasks
9099cab3 180 $runner = new CRM_Queue_Runner([
92915c55
TO
181 'queue' => $this->queue,
182 'errorMode' => CRM_Queue_Runner::ERROR_ABORT,
9099cab3
CW
183 ]);
184 $this->assertEquals(self::$_recordedValues, []);
6a488035
TO
185 $this->assertEquals(3, $this->queue->numberOfItems());
186 $result = $runner->runAll();
187 $this->assertEquals(1, $result['is_error']);
188 // nothing from 'c'
9099cab3 189 $this->assertEquals(self::$_recordedValues, ['a']);
6a488035
TO
190 // 'b' and 'c' remain
191 $this->assertEquals(2, $this->queue->numberOfItems());
192 }
193
194 /**
195 * Run a series of tasks; when one returns false,
196 * abort processing and return it to the queue.
197 */
00be9182 198 public function testRunAll_Abort_False() {
6a488035
TO
199 // prepare a list of tasks with an error in the middle
200 $this->queue->createItem(new CRM_Queue_Task(
9099cab3
CW
201 ['CRM_Queue_RunnerTest', '_recordValue'],
202 ['a'],
92915c55
TO
203 'Add "a"'
204 ));
6a488035 205 $this->queue->createItem(new CRM_Queue_Task(
9099cab3
CW
206 ['CRM_Queue_RunnerTest', '_returnFalse'],
207 [],
92915c55
TO
208 'Return false'
209 ));
6a488035 210 $this->queue->createItem(new CRM_Queue_Task(
9099cab3
CW
211 ['CRM_Queue_RunnerTest', '_recordValue'],
212 ['c'],
92915c55
TO
213 'Add "c"'
214 ));
6a488035
TO
215
216 // run the list of tasks
9099cab3 217 $runner = new CRM_Queue_Runner([
92915c55
TO
218 'queue' => $this->queue,
219 'errorMode' => CRM_Queue_Runner::ERROR_ABORT,
9099cab3
CW
220 ]);
221 $this->assertEquals(self::$_recordedValues, []);
6a488035
TO
222 $this->assertEquals(3, $this->queue->numberOfItems());
223 $result = $runner->runAll();
224 $this->assertEquals(1, $result['is_error']);
225 // nothing from 'c'
9099cab3 226 $this->assertEquals(self::$_recordedValues, ['a']);
6a488035
TO
227 // 'b' and 'c' remain
228 $this->assertEquals(2, $this->queue->numberOfItems());
229 }
230
39b959db
SL
231 /**
232 * Queue tasks
233 * @var array
234 */
235 protected static $_recordedValues;
6a488035 236
4cbe18b8
EM
237 /**
238 * @param $taskCtx
239 * @param $value
240 *
241 * @return bool
242 */
39b959db 243 public static function _recordValue($taskCtx, $value) {
6a488035
TO
244 self::$_recordedValues[] = $value;
245 return TRUE;
246 }
247
4cbe18b8
EM
248 /**
249 * @param $taskCtx
250 *
251 * @return bool
252 */
39b959db 253 public static function _returnFalse($taskCtx) {
6a488035
TO
254 return FALSE;
255 }
256
4cbe18b8
EM
257 /**
258 * @param $taskCtx
259 * @param $value
260 *
261 * @throws Exception
262 */
39b959db 263 public static function _throwException($taskCtx, $value) {
6a488035
TO
264 throw new Exception("Manufactured error: $value");
265 }
b6708aeb 266
4cbe18b8
EM
267 /**
268 * @param $taskCtx
269 * @param $low
270 * @param $high
271 *
272 * @return bool
273 */
39b959db 274 public static function _enqueueNumbers($taskCtx, $low, $high) {
6a488035
TO
275 for ($i = $low; $i <= $high; $i++) {
276 $taskCtx->queue->createItem(new CRM_Queue_Task(
9099cab3
CW
277 ['CRM_Queue_RunnerTest', '_recordValue'],
278 [$i],
6a488035 279 sprintf('Add number "%d"', $i)
9099cab3 280 ), [
6a488035 281 'weight' => -1,
9099cab3 282 ]);
6a488035
TO
283 }
284 return TRUE;
285 }
96025800 286
6a488035 287}