Merge pull request #15759 from tunbola/active-option-values-for-custom-group
[civicrm-core.git] / tests / phpunit / CRM / Queue / RunnerTest.php
1 <?php
2 /*
3 +--------------------------------------------------------------------+
4 | Copyright CiviCRM LLC. All rights reserved. |
5 | |
6 | This work is published under the GNU AGPLv3 license with some |
7 | permitted exceptions and without any warranty. For full license |
8 | and copyright information, see https://civicrm.org/licensing |
9 +--------------------------------------------------------------------+
10 */
11
12 /**
13 * Ensure that various queue implementations comply with the interface
14 * @group headless
15 */
16 class CRM_Queue_RunnerTest extends CiviUnitTestCase {
17
18 public function setUp() {
19 parent::setUp();
20 $this->queueService = CRM_Queue_Service::singleton(TRUE);
21 $this->queue = $this->queueService->create([
22 'type' => 'Sql',
23 'name' => 'test-queue',
24 ]);
25 self::$_recordedValues = [];
26 }
27
28 public function tearDown() {
29 unset($this->queue);
30 unset($this->queueService);
31
32 CRM_Utils_Time::resetTime();
33
34 $tablesToTruncate = ['civicrm_queue_item'];
35 $this->quickCleanup($tablesToTruncate);
36 }
37
38 public function testRunAllNormal() {
39 // prepare a list of tasks with an error in the middle
40 $this->queue->createItem(new CRM_Queue_Task(
41 ['CRM_Queue_RunnerTest', '_recordValue'],
42 ['a'],
43 'Add "a"'
44 ));
45 $this->queue->createItem(new CRM_Queue_Task(
46 ['CRM_Queue_RunnerTest', '_recordValue'],
47 ['b'],
48 'Add "b"'
49 ));
50 $this->queue->createItem(new CRM_Queue_Task(
51 ['CRM_Queue_RunnerTest', '_recordValue'],
52 ['c'],
53 'Add "c"'
54 ));
55
56 // run the list of tasks
57 $runner = new CRM_Queue_Runner([
58 'queue' => $this->queue,
59 'errorMode' => CRM_Queue_Runner::ERROR_ABORT,
60 ]);
61 $this->assertEquals(self::$_recordedValues, []);
62 $this->assertEquals(3, $this->queue->numberOfItems());
63 $result = $runner->runAll();
64 $this->assertEquals(TRUE, $result);
65 $this->assertEquals(self::$_recordedValues, ['a', 'b', 'c']);
66 $this->assertEquals(0, $this->queue->numberOfItems());
67 }
68
69 /**
70 * Run a series of tasks.
71 *
72 * One of the tasks will insert more TODOs at the start of the list.
73 */
74 public function testRunAll_AddMore() {
75 // Prepare a list of tasks with an error in the middle.
76 $this->queue->createItem(new CRM_Queue_Task(
77 ['CRM_Queue_RunnerTest', '_recordValue'],
78 ['a'],
79 'Add "a"'
80 ));
81 $this->queue->createItem(new CRM_Queue_Task(
82 ['CRM_Queue_RunnerTest', '_enqueueNumbers'],
83 [1, 3],
84 'Add more'
85 ));
86 $this->queue->createItem(new CRM_Queue_Task(
87 ['CRM_Queue_RunnerTest', '_recordValue'],
88 ['b'],
89 'Add "b"'
90 ));
91
92 // run the list of tasks
93 $runner = new CRM_Queue_Runner([
94 'queue' => $this->queue,
95 'errorMode' => CRM_Queue_Runner::ERROR_ABORT,
96 ]);
97 $this->assertEquals(self::$_recordedValues, []);
98 $this->assertEquals(3, $this->queue->numberOfItems());
99 $result = $runner->runAll();
100 $this->assertEquals(TRUE, $result);
101 $this->assertEquals(self::$_recordedValues, ['a', 1, 2, 3, 'b']);
102 $this->assertEquals(0, $this->queue->numberOfItems());
103 }
104
105 /**
106 * Run a series of tasks; when one throws an
107 * exception, ignore it and continue
108 */
109 public function testRunAll_Continue_Exception() {
110 // prepare a list of tasks with an error in the middle
111 $this->queue->createItem(new CRM_Queue_Task(
112 ['CRM_Queue_RunnerTest', '_recordValue'],
113 ['a'],
114 'Add "a"'
115 ));
116 $this->queue->createItem(new CRM_Queue_Task(
117 ['CRM_Queue_RunnerTest', '_throwException'],
118 ['b'],
119 'Throw exception'
120 ));
121 $this->queue->createItem(new CRM_Queue_Task(
122 ['CRM_Queue_RunnerTest', '_recordValue'],
123 ['c'],
124 'Add "c"'
125 ));
126
127 // run the list of tasks
128 $runner = new CRM_Queue_Runner([
129 'queue' => $this->queue,
130 'errorMode' => CRM_Queue_Runner::ERROR_CONTINUE,
131 ]);
132 $this->assertEquals(self::$_recordedValues, []);
133 $this->assertEquals(3, $this->queue->numberOfItems());
134 $result = $runner->runAll();
135 // FIXME useless return
136 $this->assertEquals(TRUE, $result);
137 $this->assertEquals(self::$_recordedValues, ['a', 'c']);
138 $this->assertEquals(0, $this->queue->numberOfItems());
139 }
140
141 /**
142 * Run a series of tasks; when one throws an exception,
143 * abort processing and return it to the queue.
144 */
145 public function testRunAll_Abort_Exception() {
146 // prepare a list of tasks with an error in the middle
147 $this->queue->createItem(new CRM_Queue_Task(
148 ['CRM_Queue_RunnerTest', '_recordValue'],
149 ['a'],
150 'Add "a"'
151 ));
152 $this->queue->createItem(new CRM_Queue_Task(
153 ['CRM_Queue_RunnerTest', '_throwException'],
154 ['b'],
155 'Throw exception'
156 ));
157 $this->queue->createItem(new CRM_Queue_Task(
158 ['CRM_Queue_RunnerTest', '_recordValue'],
159 ['c'],
160 'Add "c"'
161 ));
162
163 // run the list of tasks
164 $runner = new CRM_Queue_Runner([
165 'queue' => $this->queue,
166 'errorMode' => CRM_Queue_Runner::ERROR_ABORT,
167 ]);
168 $this->assertEquals(self::$_recordedValues, []);
169 $this->assertEquals(3, $this->queue->numberOfItems());
170 $result = $runner->runAll();
171 $this->assertEquals(1, $result['is_error']);
172 // nothing from 'c'
173 $this->assertEquals(self::$_recordedValues, ['a']);
174 // 'b' and 'c' remain
175 $this->assertEquals(2, $this->queue->numberOfItems());
176 }
177
178 /**
179 * Run a series of tasks; when one returns false,
180 * abort processing and return it to the queue.
181 */
182 public function testRunAll_Abort_False() {
183 // prepare a list of tasks with an error in the middle
184 $this->queue->createItem(new CRM_Queue_Task(
185 ['CRM_Queue_RunnerTest', '_recordValue'],
186 ['a'],
187 'Add "a"'
188 ));
189 $this->queue->createItem(new CRM_Queue_Task(
190 ['CRM_Queue_RunnerTest', '_returnFalse'],
191 [],
192 'Return false'
193 ));
194 $this->queue->createItem(new CRM_Queue_Task(
195 ['CRM_Queue_RunnerTest', '_recordValue'],
196 ['c'],
197 'Add "c"'
198 ));
199
200 // run the list of tasks
201 $runner = new CRM_Queue_Runner([
202 'queue' => $this->queue,
203 'errorMode' => CRM_Queue_Runner::ERROR_ABORT,
204 ]);
205 $this->assertEquals(self::$_recordedValues, []);
206 $this->assertEquals(3, $this->queue->numberOfItems());
207 $result = $runner->runAll();
208 $this->assertEquals(1, $result['is_error']);
209 // nothing from 'c'
210 $this->assertEquals(self::$_recordedValues, ['a']);
211 // 'b' and 'c' remain
212 $this->assertEquals(2, $this->queue->numberOfItems());
213 }
214
215 /**
216 * Queue tasks
217 * @var array
218 */
219 protected static $_recordedValues;
220
221 /**
222 * @param $taskCtx
223 * @param $value
224 *
225 * @return bool
226 */
227 public static function _recordValue($taskCtx, $value) {
228 self::$_recordedValues[] = $value;
229 return TRUE;
230 }
231
232 /**
233 * @param $taskCtx
234 *
235 * @return bool
236 */
237 public static function _returnFalse($taskCtx) {
238 return FALSE;
239 }
240
241 /**
242 * @param $taskCtx
243 * @param $value
244 *
245 * @throws Exception
246 */
247 public static function _throwException($taskCtx, $value) {
248 throw new Exception("Manufactured error: $value");
249 }
250
251 /**
252 * @param $taskCtx
253 * @param $low
254 * @param $high
255 *
256 * @return bool
257 */
258 public static function _enqueueNumbers($taskCtx, $low, $high) {
259 for ($i = $low; $i <= $high; $i++) {
260 $taskCtx->queue->createItem(new CRM_Queue_Task(
261 ['CRM_Queue_RunnerTest', '_recordValue'],
262 [$i],
263 sprintf('Add number "%d"', $i)
264 ), [
265 'weight' => -1,
266 ]);
267 }
268 return TRUE;
269 }
270
271 }