]> CyberLeo.Net >> Repos - Github/sugarcrm.git/blob - tests/modules/SchedulersJobs/SchedulersJobsTest.php
Release 6.5.1
[Github/sugarcrm.git] / tests / modules / SchedulersJobs / SchedulersJobsTest.php
1 <?php
2 /*********************************************************************************
3  * SugarCRM Community Edition is a customer relationship management program developed by
4  * SugarCRM, Inc. Copyright (C) 2004-2012 SugarCRM Inc.
5  * 
6  * This program is free software; you can redistribute it and/or modify it under
7  * the terms of the GNU Affero General Public License version 3 as published by the
8  * Free Software Foundation with the addition of the following permission added
9  * to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
10  * IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY
11  * OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
12  * 
13  * This program is distributed in the hope that it will be useful, but WITHOUT
14  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
15  * FOR A PARTICULAR PURPOSE.  See the GNU Affero General Public License for more
16  * details.
17  * 
18  * You should have received a copy of the GNU Affero General Public License along with
19  * this program; if not, see http://www.gnu.org/licenses or write to the Free
20  * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21  * 02110-1301 USA.
22  * 
23  * You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road,
24  * SW2-130, Cupertino, CA 95014, USA. or at email address contact@sugarcrm.com.
25  * 
26  * The interactive user interfaces in modified source and object code versions
27  * of this program must display Appropriate Legal Notices, as required under
28  * Section 5 of the GNU Affero General Public License version 3.
29  * 
30  * In accordance with Section 7(b) of the GNU Affero General Public License version 3,
31  * these Appropriate Legal Notices must retain the display of the "Powered by
32  * SugarCRM" logo. If the display of the logo is not reasonably feasible for
33  * technical reasons, the Appropriate Legal Notices must display the words
34  * "Powered by SugarCRM".
35  ********************************************************************************/
36
37
38 require_once 'modules/SchedulersJobs/SchedulersJob.php';
39 require_once 'tests/SugarTestUserUtilities.php';
40 require_once 'tests/SugarTestAccountUtilities.php';
41
42 class SchedulersJobsTest extends Sugar_PHPUnit_Framework_TestCase
43 {
44     public $jobs = array();
45     public $scheduler;
46
47     public function setUp()
48     {
49         $this->db = DBManagerFactory::getInstance();
50     }
51
52     public function tearDown()
53     {
54         if(!empty($this->jobs)) {
55             $jobs = implode("','", $this->jobs);
56             $this->db->query("DELETE FROM job_queue WHERE id IN ('$jobs')");
57         }
58         SugarTestUserUtilities::removeAllCreatedAnonymousUsers();
59         $ids = SugarTestAccountUtilities::getCreatedAccountIds();
60         if(!empty($ids)) {
61             SugarTestAccountUtilities::removeAllCreatedAccounts();
62         }
63         if(!empty($this->scheduler)) {
64            $this->db->query("DELETE FROM schedulers where id = '{$this->scheduler->id}'");
65         }
66     }
67
68     protected function createJob($data)
69     {
70         $job = new TestSchedulersJob();
71         $job->status = SchedulersJob::JOB_STATUS_QUEUED;
72         foreach($data as $key => $val) {
73             $job->$key = $val;
74         }
75         $job->save();
76         $this->jobs[] = $job->id;
77         return $job;
78     }
79
80     public function testJobCreate()
81     {
82         $job = $this->createJob(array("name" => "TestCreate"));
83         $job->status = SchedulersJob::JOB_STATUS_DONE;
84         $job->save();
85         $this->assertNotEmpty($job->id);
86         $job->retrieve($job->id);
87         $this->assertEquals("TestCreate", $job->name, "Wrong name");
88         $this->assertEquals(SchedulersJob::JOB_STATUS_DONE, $job->status, "Wrong status");
89     }
90
91     public function testJobSuccess()
92     {
93         $job = $this->createJob(array("name" => "Test Success"));
94         $job->succeedJob();
95
96         $job->retrieve($job->id);
97         $this->assertEquals(SchedulersJob::JOB_SUCCESS, $job->resolution, "Wrong resolution");
98         $this->assertEquals(SchedulersJob::JOB_STATUS_DONE, $job->status, "Wrong status");
99
100         $job = $this->createJob(array("name" => "Test Success 2"));
101         $job->succeedJob("very good!");
102         $job->db->commit();
103         $job->retrieve($job->id);
104         $this->assertEquals(SchedulersJob::JOB_SUCCESS, $job->resolution, "Wrong resolution");
105         $this->assertEquals(SchedulersJob::JOB_STATUS_DONE, $job->status, "Wrong status");
106         $this->assertContains("very good!", $job->message);
107         $this->assertEmpty($job->failure_count, "Wrong failure count");
108     }
109
110     public function testJobFailure()
111     {
112         $job = $this->createJob(array("name" => "Test Fail"));
113         $job->failJob();
114
115         $job->retrieve($job->id);
116         $this->assertEquals(SchedulersJob::JOB_FAILURE, $job->resolution, "Wrong resolution");
117         $this->assertEquals(SchedulersJob::JOB_STATUS_DONE, $job->status, "Wrong status");
118         $this->assertEquals(1, $job->failure_count, "Wrong failure count");
119
120
121         $job = $this->createJob(array("name" => "Test Fail 2"));
122         $job->failJob("very bad!");
123         $job->db->commit();
124         $job->retrieve($job->id);
125         $this->assertEquals(SchedulersJob::JOB_FAILURE, $job->resolution, "Wrong resolution");
126         $this->assertEquals(SchedulersJob::JOB_STATUS_DONE, $job->status, "Wrong status");
127         $this->assertContains("very bad!", $job->message);
128     }
129
130     public function testJobPartial()
131     {
132         global $timedate;
133         $now = $timedate->getNow();
134         $job = $this->createJob(array("name" => "Test Later", "job_delay" => 57));
135         $job->postponeJob();
136
137         $job->retrieve($job->id);
138         $this->assertEquals(SchedulersJob::JOB_PARTIAL, $job->resolution, "Wrong resolution");
139         $this->assertEquals(SchedulersJob::JOB_STATUS_QUEUED, $job->status, "Wrong status");
140         $date = $timedate->fromDb($job->execute_time_db);
141         $this->assertEquals($now->ts+57, $date->ts);
142
143         $job = $this->createJob(array("name" => "Test Later 2", "job_delay" => 42));
144         $job->postponeJob("who knows?");
145         $job->db->commit();
146         $job->retrieve($job->id);
147         $this->assertEquals(SchedulersJob::JOB_PARTIAL, $job->resolution, "Wrong resolution");
148         $this->assertEquals(SchedulersJob::JOB_STATUS_QUEUED, $job->status, "Wrong status");
149         $this->assertContains("who knows?", $job->message);
150         // then succeed
151         $job->succeedJob();
152         $job->retrieve($job->id);
153         $this->assertEquals(SchedulersJob::JOB_SUCCESS, $job->resolution, "Wrong resolution");
154         $this->assertEquals(SchedulersJob::JOB_STATUS_DONE, $job->status, "Wrong status");
155     }
156
157     static public function staticJobFunction1($job, $data = null)
158     {
159          global $testJobFunction1Args;
160          $testJobFunction1Args = func_get_args();
161          return $data != "failme";
162     }
163
164     static private function staticJobFunctionPrivate($job, $data = null)
165     {
166          global $testJobFunction1Args;
167          $testJobFunction1Args = func_get_args();
168          return $data != "failme";
169     }
170
171     static public function staticJobFunctionErrors($job, $data = null)
172     {
173         trigger_error("User Warning", E_USER_WARNING);
174         $fp = fopen("/nosuchfile", "r"); // generate warning
175          return $data != "failme";
176     }
177
178     static public function staticJobFunctionInternal($job, $data = null)
179     {
180         if($data == "errors") {
181             trigger_error("User Warning", E_USER_WARNING);
182         }
183         if($data == "failme") {
184             $job->failJob("Job Failed");
185             return true;
186         } else {
187             $job->succeedJob("Job OK");
188             return false;
189         }
190     }
191
192     static public function staticJobFunctionAccount($job, $data = null)
193     {
194         SugarTestAccountUtilities::createAccount($data);
195         return $data != "failme";
196     }
197
198     public function testJobRunFunc()
199     {
200         global $testJobFunction1Args;
201         $GLOBALS['current_user'] = SugarTestUserUtilities::createAnonymousUser();
202         $testJobFunction1Args = array();
203         $job = $this->createJob(array("name" => "Test Func", "status" => SchedulersJob::JOB_STATUS_RUNNING,
204                 "target" => "function::testJobFunction1", "assigned_user_id" => $GLOBALS['current_user']->id));
205         $job->runJob();
206         $job->retrieve($job->id);
207         $this->assertEquals(SchedulersJob::JOB_SUCCESS, $job->resolution, "Wrong resolution");
208         $this->assertEquals(SchedulersJob::JOB_STATUS_DONE, $job->status, "Wrong status");
209         $this->assertEquals(1, count($testJobFunction1Args), "Wrong number of args to function");
210         $this->assertInstanceOf(get_class($job), $testJobFunction1Args[0], "Wrong type of arg 1");
211         $this->assertEquals($testJobFunction1Args[0]->id, $job->id, "Argument 1 ID doesn't match");
212         // function with args
213         $job = $this->createJob(array("name" => "Test Func 2", "status" => SchedulersJob::JOB_STATUS_RUNNING,
214                 "target" => "function::testJobFunction1",
215                 "data" => "function data", "assigned_user_id" => $GLOBALS['current_user']->id));
216         $job->runJob();
217         $job->retrieve($job->id);
218         $this->assertEquals(SchedulersJob::JOB_SUCCESS, $job->resolution, "Wrong resolution");
219         $this->assertEquals(SchedulersJob::JOB_STATUS_DONE, $job->status, "Wrong status");
220         $this->assertEquals(2, count($testJobFunction1Args), "Wrong number of args to function");
221         $this->assertEquals($testJobFunction1Args[1], "function data", "Argument 2 doesn't match");
222         // function returns failure
223         $job = $this->createJob(array("name" => "Test Func 2", "status" => SchedulersJob::JOB_STATUS_RUNNING,
224                 "target" => "function::testJobFunction1",
225                 "data" => "failme", "assigned_user_id" => $GLOBALS['current_user']->id));
226         $job->runJob();
227         $job->retrieve($job->id);
228         $this->assertEquals(SchedulersJob::JOB_FAILURE, $job->resolution, "Wrong resolution");
229         $this->assertEquals(SchedulersJob::JOB_STATUS_DONE, $job->status, "Wrong status");
230         $this->assertEquals(2, count($testJobFunction1Args), "Wrong number of args to function");
231         // static function
232         $testJobFunction1Args = array();
233         $job = $this->createJob(array("name" => "Test Func 3", "status" => SchedulersJob::JOB_STATUS_RUNNING,
234                 "target" => "function::SchedulersJobsTest::staticJobFunction1", "assigned_user_id" => $GLOBALS['current_user']->id));
235         $job->runJob();
236         $job->retrieve($job->id);
237         $this->assertEquals(SchedulersJob::JOB_SUCCESS, $job->resolution, "Wrong resolution");
238         $this->assertEquals(SchedulersJob::JOB_STATUS_DONE, $job->status, "Wrong status");
239         $this->assertEquals(1, count($testJobFunction1Args), "Wrong number of args to function");
240     }
241
242     public function testJobRunBadFunc()
243     {
244         $GLOBALS['current_user'] = SugarTestUserUtilities::createAnonymousUser();
245         $testJobFunction1Args = array();
246         // unknown function
247         $job = $this->createJob(array("name" => "Test Bad Func", "status" => SchedulersJob::JOB_STATUS_RUNNING,
248                 "target" => "function::nosuchfunctionblahblah", "assigned_user_id" => $GLOBALS['current_user']->id));
249         $job->runJob();
250         $job->retrieve($job->id);
251         $this->assertEquals(SchedulersJob::JOB_FAILURE, $job->resolution, "Wrong resolution");
252         $this->assertEquals(SchedulersJob::JOB_STATUS_DONE, $job->status, "Wrong status");
253         $this->assertContains("nosuchfun", $job->message);
254         // No user
255         $job = $this->createJob(array("name" => "Test Bad Func 2", "status" => SchedulersJob::JOB_STATUS_RUNNING,
256                 "target" => "function::testJobFunction1"));
257         $job->runJob();
258         $job->retrieve($job->id);
259         $this->assertEquals(SchedulersJob::JOB_FAILURE, $job->resolution, "Wrong resolution");
260         $this->assertEquals(SchedulersJob::JOB_STATUS_DONE, $job->status, "Wrong status");
261         $this->assertContains("No User ID", $job->message);
262         // Bad user ID
263         $job = $this->createJob(array("name" => "Test Bad Func 3", "status" => SchedulersJob::JOB_STATUS_RUNNING,
264                 "target" => "function::testJobFunction1", "assigned_user_id" => "Unexisting User"));
265         $job->runJob();
266         $job->retrieve($job->id);
267         $this->assertEquals(SchedulersJob::JOB_FAILURE, $job->resolution, "Wrong resolution");
268         $this->assertEquals(SchedulersJob::JOB_STATUS_DONE, $job->status, "Wrong status");
269         $this->assertContains("Unexisting User", $job->message);
270         // Private function
271         $testJobFunction1Args = array();
272         $job = $this->createJob(array("name" => "Test Bad Func 4", "status" => SchedulersJob::JOB_STATUS_RUNNING,
273                 "target" => "function::SchedulersJobsTest::staticJobFunctionPrivate", "assigned_user_id" => $GLOBALS['current_user']->id));
274         $job->runJob();
275         $job->retrieve($job->id);
276         $this->assertEquals(SchedulersJob::JOB_FAILURE, $job->resolution, "Wrong resolution");
277         $this->assertEquals(SchedulersJob::JOB_STATUS_DONE, $job->status, "Wrong status");
278         $this->assertContains("staticJobFunctionPrivate", $job->message);
279         // Bad target type
280         $testJobFunction1Args = array();
281         $job = $this->createJob(array("name" => "Test Bad Func 5", "status" => SchedulersJob::JOB_STATUS_RUNNING,
282                 "target" => "whatever::SchedulersJobsTest::staticJobFunctionPrivate", "assigned_user_id" => $GLOBALS['current_user']->id));
283         $job->runJob();
284         $job->retrieve($job->id);
285         $this->assertEquals(SchedulersJob::JOB_FAILURE, $job->resolution, "Wrong resolution");
286         $this->assertEquals(SchedulersJob::JOB_STATUS_DONE, $job->status, "Wrong status");
287         $this->assertContains("whatever", $job->message);
288     }
289
290     public function testJobErrors()
291     {
292         $GLOBALS['current_user'] = SugarTestUserUtilities::createAnonymousUser();
293         $job = $this->createJob(array("name" => "Test Func Errors", "status" => SchedulersJob::JOB_STATUS_RUNNING,
294                 "target" => "function::SchedulersJobsTest::staticJobFunctionErrors", "assigned_user_id" => $GLOBALS['current_user']->id));
295         $job->runJob();
296         $job->retrieve($job->id);
297         $this->assertEquals(SchedulersJob::JOB_SUCCESS, $job->resolution, "Wrong resolution");
298         $this->assertEquals(SchedulersJob::JOB_STATUS_DONE, $job->status, "Wrong status");
299         $this->assertContains("User Warning", $job->message);
300         $this->assertContains("nosuchfile", $job->message);
301         // failing
302         $job = $this->createJob(array("name" => "Test Func Errors", "status" => SchedulersJob::JOB_STATUS_RUNNING,
303                 "target" => "function::SchedulersJobsTest::staticJobFunctionErrors", "data" => "failme", "assigned_user_id" => $GLOBALS['current_user']->id));
304         $job->runJob();
305         $job->retrieve($job->id);
306         $this->assertEquals(SchedulersJob::JOB_FAILURE, $job->resolution, "Wrong resolution");
307         $this->assertEquals(SchedulersJob::JOB_STATUS_DONE, $job->status, "Wrong status");
308         $this->assertContains("User Warning", $job->message);
309         $this->assertContains("nosuchfile", $job->message);
310     }
311
312     public function testJobResolution()
313     {
314         $GLOBALS['current_user'] = SugarTestUserUtilities::createAnonymousUser();
315         $job = $this->createJob(array("name" => "Test Func Errors", "status" => SchedulersJob::JOB_STATUS_RUNNING,
316                 "target" => "function::SchedulersJobsTest::staticJobFunctionInternal","assigned_user_id" => $GLOBALS['current_user']->id));
317         $job->runJob();
318         $job->retrieve($job->id);
319         $this->assertEquals(SchedulersJob::JOB_SUCCESS, $job->resolution, "Wrong resolution");
320         $this->assertEquals(SchedulersJob::JOB_STATUS_DONE, $job->status, "Wrong status");
321         $this->assertContains("Job OK", $job->message);
322         // failing
323         $job = $this->createJob(array("name" => "Test Func Errors 2", "status" => SchedulersJob::JOB_STATUS_RUNNING,
324                 "target" => "function::SchedulersJobsTest::staticJobFunctionInternal", "data" => "failme", "assigned_user_id" => $GLOBALS['current_user']->id));
325         $job->runJob();
326         $job->retrieve($job->id);
327         $this->assertEquals(SchedulersJob::JOB_FAILURE, $job->resolution, "Wrong resolution");
328         $this->assertEquals(SchedulersJob::JOB_STATUS_DONE, $job->status, "Wrong status");
329         $this->assertContains("Job Failed", $job->message);
330         // errors
331         $job = $this->createJob(array("name" => "Test Func Errors", "status" => SchedulersJob::JOB_STATUS_RUNNING,
332                 "target" => "function::SchedulersJobsTest::staticJobFunctionInternal", "data" => "errors",
333              "assigned_user_id" => $GLOBALS['current_user']->id));
334         $job->runJob();
335         $job->retrieve($job->id);
336         $this->assertEquals(SchedulersJob::JOB_SUCCESS, $job->resolution, "Wrong resolution");
337         $this->assertEquals(SchedulersJob::JOB_STATUS_DONE, $job->status, "Wrong status");
338         $this->assertContains("Job OK", $job->message);
339         $this->assertContains("User Warning", $job->message);
340     }
341
342     public function testJobClients()
343     {
344         $GLOBALS['current_user'] = SugarTestUserUtilities::createAnonymousUser();
345         $job = $this->createJob(array("name" => "Test Func Clients", "status" => SchedulersJob::JOB_STATUS_RUNNING,
346                 "target" => "function::SchedulersJobsTest::staticJobFunctionInternal", "client" => "UnitTests",
347                 "assigned_user_id" => $GLOBALS['current_user']->id));
348         $res = SchedulersJob::runJobId($job->id, "UnitTests");
349         $job->retrieve($job->id);
350         $this->assertTrue($res, "Bad result from runJobId");
351         $this->assertEquals(SchedulersJob::JOB_SUCCESS, $job->resolution, "Wrong resolution");
352         $this->assertEquals(SchedulersJob::JOB_STATUS_DONE, $job->status, "Wrong status");
353         $this->assertContains("Job OK", $job->message);
354         // wrong client
355         $job = $this->createJob(array("name" => "Test Func Clients 2", "status" => SchedulersJob::JOB_STATUS_RUNNING,
356                 "target" => "function::SchedulersJobsTest::staticJobFunctionInternal", "client" => "UnitTests",
357                 "assigned_user_id" => $GLOBALS['current_user']->id));
358         $res = SchedulersJob::runJobId($job->id, "UnitTests2");
359         $this->assertFalse($res === true, "Bad result from runJobId");
360         // wrong ID
361         $res = SchedulersJob::runJobId("where's waldo?", "UnitTests2");
362         $this->assertFalse($res === true, "Bad result from runJobId");
363     }
364
365     public function testJobURL()
366     {
367         $GLOBALS['current_user'] = SugarTestUserUtilities::createAnonymousUser();
368         $job = $this->createJob(array("name" => "Test Url", "status" => SchedulersJob::JOB_STATUS_RUNNING,
369                 "target" => "url::".$GLOBALS['sugar_config']['site_url']."/"));
370         $job->runJob();
371         $job->retrieve($job->id);
372         $this->assertEquals(SchedulersJob::JOB_SUCCESS, $job->resolution, "Wrong resolution");
373         $this->assertEquals(SchedulersJob::JOB_STATUS_DONE, $job->status, "Wrong status");
374         // Bad URL
375         $job = $this->createJob(array("name" => "Test Url 2", "status" => SchedulersJob::JOB_STATUS_RUNNING,
376                 "target" => "url::".$GLOBALS['sugar_config']['site_url']."/blahblahblah"));
377         $job->runJob();
378         $job->retrieve($job->id);
379         $this->assertEquals(SchedulersJob::JOB_FAILURE, $job->resolution, "Wrong resolution");
380         $this->assertEquals(SchedulersJob::JOB_STATUS_DONE, $job->status, "Wrong status");
381     }
382
383     public function testJobUsers()
384     {
385         $GLOBALS['current_user'] = SugarTestUserUtilities::createAnonymousUser();
386         $user1 = SugarTestUserUtilities::createAnonymousUser();
387         $user2 = SugarTestUserUtilities::createAnonymousUser();
388         $job = $this->createJob(array("name" => "Test User 1", "status" => SchedulersJob::JOB_STATUS_RUNNING,
389                 "assigned_user_id" => $user1->id, "target" => "function::SchedulersJobsTest::staticJobFunctionAccount", "data" => "useracc1"));
390         $job->runJob();
391         $job->retrieve($job->id);
392         $this->assertEquals(SchedulersJob::JOB_SUCCESS, $job->resolution, "Wrong resolution");
393         $this->assertEquals(SchedulersJob::JOB_STATUS_DONE, $job->status, "Wrong status");
394
395         $job = $this->createJob(array("name" => "Test User 2", "status" => SchedulersJob::JOB_STATUS_RUNNING,
396                 "assigned_user_id" => $user2->id, "target" => "function::SchedulersJobsTest::staticJobFunctionAccount", "data" => "useracc2"));
397         $job->runJob();
398         $job->retrieve($job->id);
399         $this->assertEquals(SchedulersJob::JOB_SUCCESS, $job->resolution, "Wrong resolution");
400         $this->assertEquals(SchedulersJob::JOB_STATUS_DONE, $job->status, "Wrong status");
401
402         $a1 = new Account();
403         $a1->retrieve('useracc1');
404         $this->assertEquals($user1->id, $a1->created_by, "Wrong creating user ID for account 1");
405         $a2 = new Account();
406         $a2->retrieve('useracc2');
407         $this->assertEquals($user2->id, $a2->created_by, "Wrong creating user ID for account 2");
408     }
409
410     public function testJobRetries()
411     {
412         $GLOBALS['current_user'] = SugarTestUserUtilities::createAnonymousUser();
413         $user1 = SugarTestUserUtilities::createAnonymousUser();
414         $user2 = SugarTestUserUtilities::createAnonymousUser();
415         global $timedate;
416         $now = $timedate->getNow();
417
418         $job = $this->createJob(array("name" => "Test User 1", "status" => SchedulersJob::JOB_STATUS_RUNNING,
419                 "assigned_user_id" => $user1->id, "target" => "function::nosuchfunction",
420                 "requeue" => true, "retry_count" => 2, "job_delay" => 1, "min_interval" => 242));
421         $job->runJob();
422         $this->assertTrue($job->onFailureCalled, "onFailure wasn't called");
423         $this->assertEmpty($job->onFinalFailureCalled, "onFinalFailure was called prematurely");
424         $job->retrieve($job->id);
425         $this->assertEquals(SchedulersJob::JOB_FAILURE, $job->resolution, "Wrong resolution");
426         $this->assertEquals(SchedulersJob::JOB_STATUS_QUEUED, $job->status, "Wrong status");
427         $this->assertEquals(1, $job->failure_count, "Wrong failure count");
428         $date = $timedate->fromDb($job->execute_time_db);
429         $this->assertEquals($now->ts+242, $date->ts);
430         // try again
431         $job->onFailureCalled = null;
432         $job->onFinalFailureCalled = null;
433         $job->status = SchedulersJob::JOB_STATUS_RUNNING;
434         $job->save();
435         $job->runJob();
436         $this->assertTrue($job->onFailureCalled, "onFailure wasn't called");
437         $this->assertEmpty($job->onFinalFailureCalled, "onFinalFailure was called prematurely");
438         $job->retrieve($job->id);
439         $this->assertEquals(SchedulersJob::JOB_FAILURE, $job->resolution, "Wrong resolution");
440         $this->assertEquals(SchedulersJob::JOB_STATUS_QUEUED, $job->status, "Wrong status");
441         $this->assertEquals(2, $job->failure_count, "Wrong failure count");
442         // and try again
443         $job->status = SchedulersJob::JOB_STATUS_RUNNING;
444         $job->onFailureCalled = null;
445         $job->onFinalFailureCalled = null;
446         $job->save();
447         $job->runJob();
448         $job->retrieve($job->id);
449         $this->assertEquals(SchedulersJob::JOB_FAILURE, $job->resolution, "Wrong resolution");
450         $this->assertEquals(SchedulersJob::JOB_STATUS_DONE, $job->status, "Wrong status");
451         $this->assertEquals(3, $job->failure_count, "Wrong failure count");
452         $this->assertTrue($job->onFinalFailureCalled, "onFinalFailure wasn't called");
453         $this->assertEmpty($job->onFailureCalled, "onFailure was called");
454     }
455
456     public function testJobDelete()
457     {
458         $job = $this->createJob(array("name" => "TestCreate"));
459         $job->status = SchedulersJob::JOB_STATUS_DONE;
460         $job->save();
461         $this->assertNotEmpty($job->id);
462         $id = $job->id;
463         $job->retrieve($id);
464         $this->assertNotEmpty($job->id);
465         $job->mark_deleted($id);
466         $job = new SchedulersJob();
467         $job->retrieve($job->id, true, false);
468         $this->assertEmpty($job->id);
469     }
470
471     /**
472      * @ticket 52705
473      */
474     public function testJobLastRun()
475     {
476         $this->scheduler = new Scheduler(false);
477         $this->scheduler->job_interval =  "*::*::*::*::*";
478         $this->scheduler->job = "function::testJobFunction1";
479         $this->scheduler->status = "Active";
480         $this->scheduler->last_run = null;
481         $this->scheduler->save();
482         $GLOBALS['current_user'] = SugarTestUserUtilities::createAnonymousUser();
483         $testJobFunction1Args = array();
484         $job = $this->createJob(array("name" => "Test Func", "status" => SchedulersJob::JOB_STATUS_RUNNING,
485                 "target" => "function::testJobFunction1", "assigned_user_id" => $GLOBALS['current_user']->id,
486                 "scheduler_id" => $this->scheduler->id));
487         $job->runJob();
488         $job->retrieve($job->id);
489         $this->assertEquals(SchedulersJob::JOB_SUCCESS, $job->resolution, "Wrong resolution");
490         $this->assertEquals(SchedulersJob::JOB_STATUS_DONE, $job->status, "Wrong status");
491         $this->scheduler->retrieve($this->scheduler->id);
492         $this->assertNotEmpty($this->scheduler->last_run, "Last run was not updated");
493     }
494
495     public function testCleanupJobs()
496     {
497         $GLOBALS['current_user'] = SugarTestUserUtilities::createAnonymousUser();
498         $this->scheduler = new Scheduler(false);
499         $this->scheduler->id = create_guid();
500         $newjob = $this->createJob(array("name" => "Test Func", "status" => SchedulersJob::JOB_STATUS_DONE,
501                         "target" => "function::testJobFunction1", "assigned_user_id" => $GLOBALS['current_user']->id,
502                         "scheduler_id" => $this->scheduler->id));
503         $oldjob = $this->createJob(array("name" => "Test Func", "status" => SchedulersJob::JOB_STATUS_DONE,
504                         "target" => "function::testJobFunction1", "assigned_user_id" => $GLOBALS['current_user']->id,
505                         "scheduler_id" => $this->scheduler->id, 'update_date_modified' => false,
506                 'date_modified' => TimeDate::getInstance()->getNow()->modify("-10 days")->asDB()));
507         $oldestjob = $this->createJob(array("name" => "Test Func", "status" => SchedulersJob::JOB_STATUS_DONE,
508                         "target" => "function::testJobFunction1", "assigned_user_id" => $GLOBALS['current_user']->id,
509                         "scheduler_id" => $this->scheduler->id, 'update_date_modified' => false,
510                 'date_modified' => TimeDate::getInstance()->getNow()->modify("-100 days")->asDb()));
511
512         $this->assertNotEmpty($newjob->id);
513         $this->assertNotEmpty($oldjob->id);
514         $this->assertNotEmpty($oldestjob->id);
515
516         $cleanjob = $this->createJob(array("name" => "Test Func", "status" => SchedulersJob::JOB_STATUS_RUNNING,
517                         "target" => "function::cleanJobQueue", "assigned_user_id" => $GLOBALS['current_user']->id,
518                         "scheduler_id" => $this->scheduler->id));
519         $cleanjob->runJob();
520         // new job should be still there
521         $job = new SchedulersJob();
522         $job->retrieve($newjob->id);
523         $this->assertEquals($newjob->id, $job->id);
524         // old job should be deleted
525         $job = new SchedulersJob();
526         $job->retrieve($oldjob->id);
527         $this->assertEmpty($job->id);
528         $job->retrieve($oldjob->id, true, false);
529         $this->assertEquals($oldjob->id, $job->id);
530         // oldest job should be purged
531         $count = $this->db->getOne("SELECT count(*) from {$job->table_name} WHERE id='{$oldestjob->id}'");
532         $this->assertEquals(0, $count);
533     }
534 }
535
536 class TestSchedulersJob extends SchedulersJob
537 {
538     public $onFailureCalled;
539     public $onFinalFailureCalled;
540
541     public function onFailureRetry()
542     {
543         $this->onFailureCalled = true;
544     }
545
546     public function onFinalFailure()
547     {
548         $this->onFinalFailureCalled = true;
549     }
550 }
551
552 function testJobFunction1($job, $data = null)
553 {
554      global $testJobFunction1Args;
555      $testJobFunction1Args = func_get_args();
556      return $data != "failme";
557 }