2 /*********************************************************************************
3 * SugarCRM Community Edition is a customer relationship management program developed by
4 * SugarCRM, Inc. Copyright (C) 2004-2013 SugarCRM Inc.
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.
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
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
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.
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.
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 ********************************************************************************/
37 require_once 'include/SugarQueue/SugarJobQueue.php';
38 require_once 'include/SugarQueue/SugarCronJobs.php';
39 require_once 'modules/SchedulersJobs/SchedulersJob.php';
41 class CronTest extends Sugar_PHPUnit_Framework_TestCase
43 static public $jobCalled = false;
46 public static function setUpBeforeClass()
48 $GLOBALS['current_user'] = SugarTestUserUtilities::createAnonymousUser();
50 $GLOBALS['db']->query("DELETE FROM job_queue WHERE status='queued'");
53 public static function tearDownAdterClass()
55 SugarTestUserUtilities::removeAllCreatedAnonymousUsers();
58 public function setUp()
60 $this->jq = $jobq = new SugarCronJobs();
61 self::$jobCalled = false;
62 if(isset($GLOBALS['sugar_config']['cron'])) {
63 $this->config_cron = $GLOBALS['sugar_config']['cron'];
67 public function tearDown()
69 $GLOBALS['db']->query("DELETE FROM job_queue WHERE scheduler_id='unittest'");
70 if(isset($GLOBALS['sugar_config']['cron'])) {
71 $GLOBALS['sugar_config']['cron'] = $this->config_cron;
73 unset($GLOBALS['sugar_config']['cron']);
77 public function testConfig()
79 $GLOBALS['sugar_config']['cron'] = array('max_cron_jobs' => 12, 'max_cron_runtime' => 34, 'min_cron_interval' => 56);
80 $jobq = new SugarCronJobs();
81 $this->assertEquals(12, $jobq->max_jobs, "Wrong setting for max_jobs");
82 $this->assertEquals(34, $jobq->max_runtime, "Wrong setting for max_runtime");
83 $this->assertEquals(56, $jobq->min_interval, "Wrong setting for min_interval");
86 public function testThrottle()
88 $this->jq->throttle();
89 $this->assertFalse($this->jq->throttle(), "Should prohibit second time");
92 $this->jq->min_interval = 1;
93 $this->assertTrue($this->jq->throttle(), "Should allow after delay");
96 public static function cronJobFunction()
98 self::$jobCalled = true;
102 public static function cronJobLongFunction()
104 self::$jobCalled = true;
109 public function testQueueJob()
111 $job = new SchedulersJob();
112 $job->status = SchedulersJob::JOB_STATUS_QUEUED;
113 $job->scheduler_id = 'unittest';
114 $job->execute_time = TimeDate::getInstance()->nowDb();
115 $job->name = "Unit test Job";
116 $job->target = "function::CronTest::cronJobFunction";
117 $job->assigned_user_id = $GLOBALS['current_user']->id;
121 $this->jq->min_interval = 0; // disable throttle
122 $this->jq->disable_schedulers = true;
123 $this->jq->runCycle();
124 $this->assertTrue(self::$jobCalled, "Job was not called");
125 $this->assertTrue($this->jq->runOk(), "Wrong OK flag");
126 $job = new SchedulersJob();
127 $job->retrieve($jobid);
128 $this->assertEquals(SchedulersJob::JOB_SUCCESS, $job->resolution, "Wrong resolution");
129 $this->assertEquals(SchedulersJob::JOB_STATUS_DONE, $job->status, "Wrong status");
130 $this->assertEmpty(session_id(), "Session not destroyed");
133 public function testQueueFailJob()
135 $job = new SchedulersJob();
136 $job->status = SchedulersJob::JOB_STATUS_QUEUED;
137 $job->scheduler_id = 'unittest';
138 $job->execute_time = TimeDate::getInstance()->nowDb();
139 $job->name = "Unit test Job";
140 $job->target = "function::test::test";
141 $job->assigned_user_id = $GLOBALS['current_user']->id;
145 $this->jq->min_interval = 0; // disable throttle
146 $this->jq->disable_schedulers = true;
147 $this->jq->runCycle();
149 $this->assertFalse($this->jq->runOk(), "Wrong OK flag");
150 $job = new SchedulersJob();
151 $job->retrieve($jobid);
152 $this->assertEquals(SchedulersJob::JOB_FAILURE, $job->resolution, "Wrong resolution");
153 $this->assertEquals(SchedulersJob::JOB_STATUS_DONE, $job->status, "Wrong status");
154 $this->assertEmpty(session_id(), "Session not destroyed");
157 public function testJobsCount()
159 // job 1 - oldest, should be executed
160 $job = new SchedulersJob();
161 $job->status = SchedulersJob::JOB_STATUS_QUEUED;
162 $job->scheduler_id = 'unittest';
163 $job->execute_time = TimeDate::getInstance()->nowDb();
164 $job->date_entered = '2010-01-01 12:00:00';
165 $job->name = "Unit test Job 1";
166 $job->target = "function::CronTest::cronJobFunction";
167 $job->assigned_user_id = $GLOBALS['current_user']->id;
170 // job 2 - newer, should not be executed
171 $job = new SchedulersJob();
172 $job->status = SchedulersJob::JOB_STATUS_QUEUED;
173 $job->scheduler_id = 'unittest';
174 $job->execute_time = TimeDate::getInstance()->nowDb();
175 $job->date_entered = '2012-01-01 12:00:00';
176 $job->name = "Unit test Job 2";
177 $job->target = "function::CronTest::cronJobFunction";
178 $job->assigned_user_id = $GLOBALS['current_user']->id;
182 $this->jq->min_interval = 0; // disable throttle
183 $this->jq->max_jobs = 1; // only one job per cycle
184 $this->jq->disable_schedulers = true;
185 $this->jq->runCycle();
187 $this->assertTrue(self::$jobCalled, "Job was not called");
188 $job = new SchedulersJob();
189 $job->retrieve($jobid1);
190 $this->assertEquals(SchedulersJob::JOB_STATUS_DONE, $job->status, "Wrong status");
191 $this->assertEquals(SchedulersJob::JOB_SUCCESS, $job->resolution, "Wrong resolution");
192 // test that second one wasn't run
193 $job = new SchedulersJob();
194 $job->retrieve($jobid2);
195 $this->assertEquals(SchedulersJob::JOB_STATUS_QUEUED, $job->status, "Wrong status");
198 public function testJobsTimeCutoff()
200 // job 1 - oldest, should be executed
201 $job = new SchedulersJob();
202 $job->status = SchedulersJob::JOB_STATUS_QUEUED;
203 $job->scheduler_id = 'unittest';
204 $job->execute_time = TimeDate::getInstance()->nowDb();
205 $job->date_entered = '2010-01-01 12:00:00';
206 $job->name = "Unit test Job 1";
207 $job->target = "function::CronTest::cronJobLongFunction";
208 $job->assigned_user_id = $GLOBALS['current_user']->id;
211 // job 2 - newer, should not be executed
212 $job = new SchedulersJob();
213 $job->status = SchedulersJob::JOB_STATUS_QUEUED;
214 $job->scheduler_id = 'unittest';
215 $job->execute_time = TimeDate::getInstance()->nowDb();
216 $job->date_entered = '2012-01-01 12:00:00';
217 $job->name = "Unit test Job 2";
218 $job->target = "function::CronTest::cronJobLongFunction";
219 $job->assigned_user_id = $GLOBALS['current_user']->id;
223 $this->jq->min_interval = 0; // disable throttle
224 $this->jq->max_jobs = 10;
225 $this->jq->max_runtime = 1; // only 1 sec runtime
226 $this->jq->disable_schedulers = true;
227 $this->jq->runCycle();
229 $this->assertTrue(self::$jobCalled, "Job was not called");
230 $job = new SchedulersJob();
231 $job->retrieve($jobid1);
232 $this->assertEquals(SchedulersJob::JOB_STATUS_DONE, $job->status, "Wrong status");
233 $this->assertEquals(SchedulersJob::JOB_SUCCESS, $job->resolution, "Wrong resolution");
234 // test that second one wasn't run
235 $job = new SchedulersJob();
236 $job->retrieve($jobid2);
237 $this->assertEquals(SchedulersJob::JOB_STATUS_QUEUED, $job->status, "Wrong status");
240 public function testJobsCleanup()
242 // job 1 - oldest, should be executed
243 $job = new SchedulersJob();
244 $job->update_date_modified = false;
245 $job->status = SchedulersJob::JOB_STATUS_RUNNING;
246 $job->scheduler_id = 'unittest';
247 $job->execute_time = TimeDate::getInstance()->nowDb();
248 $job->date_entered = '2010-01-01 12:00:00';
249 $job->date_modified = '2010-01-01 12:00:00';
250 $job->name = "Unit test Job 1";
251 $job->target = "function::CronTest::cronJobFunction";
252 $job->assigned_user_id = $GLOBALS['current_user']->id;
256 $this->jq->min_interval = 0; // disable throttle
257 $this->jq->disable_schedulers = true;
258 $this->jq->runCycle();
260 $this->assertFalse(self::$jobCalled, "Job was called");
261 $this->assertFalse($this->jq->runOk(), "Wrong OK flag");
262 $job = new SchedulersJob();
263 $job->retrieve($jobid1);
264 $this->assertEquals(SchedulersJob::JOB_STATUS_DONE, $job->status, "Wrong status");
265 $this->assertEquals(SchedulersJob::JOB_FAILURE, $job->resolution, "Wrong resolution");
266 $this->assertEmpty(session_id(), "Session not destroyed");