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