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