Skip to content

Commit 79d60cb

Browse files
committed
#12497 Prevent running again already running cron group
1 parent 83b17fe commit 79d60cb

File tree

1 file changed

+52
-97
lines changed

1 file changed

+52
-97
lines changed

app/code/Magento/Cron/Test/Unit/Observer/ProcessCronQueueObserverTest.php

Lines changed: 52 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
use Magento\Cron\Model\Schedule;
99
use Magento\Cron\Observer\ProcessCronQueueObserver as ProcessCronQueueObserver;
1010
use Magento\Framework\App\State;
11+
use Magento\Framework\Profiler\Driver\Standard\StatFactory;
12+
use Magento\Framework\Profiler\Driver\Standard\Stat;
1113

1214
/**
1315
* Class \Magento\Cron\Test\Unit\Model\ObserverTest
@@ -121,6 +123,7 @@ protected function setUp()
121123
)->disableOriginalConstructor()->getMock();
122124
$this->_collection->expects($this->any())->method('addFieldToFilter')->will($this->returnSelf());
123125
$this->_collection->expects($this->any())->method('load')->will($this->returnSelf());
126+
124127
$this->_scheduleFactory = $this->getMockBuilder(
125128
\Magento\Cron\Model\ScheduleFactory::class
126129
)->setMethods(
@@ -170,6 +173,15 @@ protected function setUp()
170173
$this->scheduleResource->method('getConnection')->willReturn($connection);
171174
$connection->method('delete')->willReturn(1);
172175

176+
$this->statFactory = $this->getMockBuilder(StatFactory::class)
177+
->setMethods(['create'])
178+
->getMockForAbstractClass();
179+
180+
$this->stat = $this->getMockBuilder(\Magento\Framework\Profiler\Driver\Standard\Stat::class)
181+
->disableOriginalConstructor()
182+
->getMock();
183+
$this->statFactory->expects($this->any())->method('create')->willReturn($this->stat);
184+
173185
$this->_observer = new ProcessCronQueueObserver(
174186
$this->_objectManager,
175187
$this->_scheduleFactory,
@@ -182,58 +194,38 @@ protected function setUp()
182194
$phpExecutableFinderFactory,
183195
$this->loggerMock,
184196
$this->appStateMock,
197+
$this->statFactory,
185198
$this->lockManagerMock
186199
);
187200
}
188201

189-
/**
190-
* Test case without saved cron jobs in data base
191-
*/
192-
public function testDispatchNoPendingJobs()
193-
{
194-
$lastRun = $this->time + 10000000;
195-
$this->_cache->expects($this->any())->method('load')->will($this->returnValue($lastRun));
196-
$this->_scopeConfig->expects($this->any())->method('getValue')->will($this->returnValue(0));
197-
198-
$this->_config->expects($this->once())->method('getJobs')->will($this->returnValue([]));
199-
200-
$scheduleMock = $this->getMockBuilder(
201-
\Magento\Cron\Model\Schedule::class
202-
)->disableOriginalConstructor()->getMock();
203-
$scheduleMock->expects($this->any())->method('getCollection')->will($this->returnValue($this->_collection));
204-
$this->_scheduleFactory->expects($this->once())->method('create')->will($this->returnValue($scheduleMock));
205-
206-
$this->_observer->execute($this->observer);
207-
}
208-
209202
/**
210203
* Test case for not existed cron jobs in files but in data base is presented
211204
*/
212205
public function testDispatchNoJobConfig()
213206
{
214207
$lastRun = $this->time + 10000000;
215-
$this->_cache->expects($this->any())->method('load')->will($this->returnValue($lastRun));
216-
$this->_scopeConfig->expects($this->any())->method('getValue')->will($this->returnValue(0));
208+
$this->_cache->expects($this->atLeastOnce())->method('load')->will($this->returnValue($lastRun));
209+
$this->_scopeConfig->expects($this->atLeastOnce())->method('getValue')->will($this->returnValue(0));
217210

218211
$this->_config->expects(
219-
$this->any()
212+
$this->atLeastOnce()
220213
)->method(
221214
'getJobs'
222215
)->will(
223216
$this->returnValue(['test_job1' => ['test_data']])
224217
);
225218

226219
$schedule = $this->createPartialMock(\Magento\Cron\Model\Schedule::class, ['getJobCode', '__wakeup']);
227-
$schedule->expects($this->once())->method('getJobCode')->will($this->returnValue('not_existed_job_code'));
220+
$schedule->expects($this->atLeastOnce())->method('getJobCode')->will($this->returnValue('not_existed_job_code'));
228221

229222
$this->_collection->addItem($schedule);
230223

231224
$scheduleMock = $this->getMockBuilder(
232225
\Magento\Cron\Model\Schedule::class
233226
)->disableOriginalConstructor()->getMock();
234-
$scheduleMock->expects($this->any())->method('getCollection')->will($this->returnValue($this->_collection));
235-
$scheduleMock->expects($this->any())->method('getResource')->will($this->returnValue($this->scheduleResource));
236-
$this->_scheduleFactory->expects($this->any())->method('create')->will($this->returnValue($scheduleMock));
227+
$scheduleMock->expects($this->atLeastOnce())->method('getCollection')->will($this->returnValue($this->_collection));
228+
$this->_scheduleFactory->expects($this->atLeastOnce())->method('create')->will($this->returnValue($scheduleMock));
237229

238230
$this->_observer->execute($this->observer);
239231
}
@@ -252,11 +244,13 @@ public function testDispatchCanNotLock()
252244
$schedule = $this->getMockBuilder(
253245
\Magento\Cron\Model\Schedule::class
254246
)->setMethods(
255-
['getJobCode', 'tryLockJob', 'getScheduledAt', '__wakeup', 'save']
247+
['getJobCode', 'tryLockJob', 'getScheduledAt', '__wakeup', 'save', 'setFinishedAt']
256248
)->disableOriginalConstructor()->getMock();
257249
$schedule->expects($this->any())->method('getJobCode')->will($this->returnValue('test_job1'));
258-
$schedule->expects($this->once())->method('getScheduledAt')->will($this->returnValue($dateScheduledAt));
250+
$schedule->expects($this->atLeastOnce())->method('getScheduledAt')->will($this->returnValue($dateScheduledAt));
259251
$schedule->expects($this->once())->method('tryLockJob')->will($this->returnValue(false));
252+
$schedule->expects($this->never())->method('setFinishedAt');
253+
260254
$abstractModel = $this->createMock(\Magento\Framework\Model\AbstractModel::class);
261255
$schedule->expects($this->any())->method('save')->will($this->returnValue($abstractModel));
262256
$this->_collection->addItem($schedule);
@@ -274,7 +268,7 @@ public function testDispatchCanNotLock()
274268
)->disableOriginalConstructor()->getMock();
275269
$scheduleMock->expects($this->any())->method('getCollection')->will($this->returnValue($this->_collection));
276270
$scheduleMock->expects($this->any())->method('getResource')->will($this->returnValue($this->scheduleResource));
277-
$this->_scheduleFactory->expects($this->exactly(2))->method('create')->will($this->returnValue($scheduleMock));
271+
$this->_scheduleFactory->expects($this->atLeastOnce())->method('create')->will($this->returnValue($scheduleMock));
278272

279273
$this->_observer->execute($this->observer);
280274
}
@@ -284,7 +278,7 @@ public function testDispatchCanNotLock()
284278
*/
285279
public function testDispatchExceptionTooLate()
286280
{
287-
$exceptionMessage = 'Too late for the schedule';
281+
$exceptionMessage = 'Cron Job test_job1 is missed at 2017-07-30 15:00:00';
288282
$scheduleId = 42;
289283
$jobCode = 'test_job1';
290284
$exception = $exceptionMessage . ' Schedule Id: ' . $scheduleId . ' Job Code: ' . $jobCode;
@@ -311,25 +305,25 @@ public function testDispatchExceptionTooLate()
311305
'getScheduleId',
312306
]
313307
)->disableOriginalConstructor()->getMock();
314-
$schedule->expects($this->any())->method('getJobCode')->willReturn($jobCode);
315-
$schedule->expects($this->once())->method('getScheduledAt')->willReturn($dateScheduledAt);
308+
$schedule->expects($this->atLeastOnce())->method('getJobCode')->willReturn($jobCode);
309+
$schedule->expects($this->atLeastOnce())->method('getScheduledAt')->willReturn($dateScheduledAt);
316310
$schedule->expects($this->once())->method('tryLockJob')->willReturn(true);
317311
$schedule->expects(
318-
$this->once()
312+
$this->any()
319313
)->method(
320314
'setStatus'
321315
)->with(
322316
$this->equalTo(\Magento\Cron\Model\Schedule::STATUS_MISSED)
323317
)->willReturnSelf();
324318
$schedule->expects($this->once())->method('setMessages')->with($this->equalTo($exceptionMessage));
325-
$schedule->expects($this->any())->method('getStatus')->willReturn(Schedule::STATUS_MISSED);
326-
$schedule->expects($this->once())->method('getMessages')->willReturn($exceptionMessage);
327-
$schedule->expects($this->once())->method('getScheduleId')->willReturn($scheduleId);
319+
$schedule->expects($this->atLeastOnce())->method('getStatus')->willReturn(Schedule::STATUS_MISSED);
320+
$schedule->expects($this->atLeastOnce())->method('getMessages')->willReturn($exceptionMessage);
328321
$schedule->expects($this->once())->method('save');
329322

330323
$this->appStateMock->expects($this->once())->method('getMode')->willReturn(State::MODE_DEVELOPER);
331324

332-
$this->loggerMock->expects($this->once())->method('info')->with($exception);
325+
$this->loggerMock->expects($this->once())->method('info')
326+
->with('Cron Job test_job1 is missed at 2017-07-30 15:00:00');
333327

334328
$this->_collection->addItem($schedule);
335329

@@ -345,7 +339,7 @@ public function testDispatchExceptionTooLate()
345339
->disableOriginalConstructor()->getMock();
346340
$scheduleMock->expects($this->any())->method('getCollection')->willReturn($this->_collection);
347341
$scheduleMock->expects($this->any())->method('getResource')->will($this->returnValue($this->scheduleResource));
348-
$this->_scheduleFactory->expects($this->exactly(2))->method('create')->willReturn($scheduleMock);
342+
$this->_scheduleFactory->expects($this->atLeastOnce())->method('create')->willReturn($scheduleMock);
349343

350344
$this->_observer->execute($this->observer);
351345
}
@@ -400,7 +394,7 @@ public function testDispatchExceptionNoCallback()
400394
)->disableOriginalConstructor()->getMock();
401395
$scheduleMock->expects($this->any())->method('getCollection')->will($this->returnValue($this->_collection));
402396
$scheduleMock->expects($this->any())->method('getResource')->will($this->returnValue($this->scheduleResource));
403-
$this->_scheduleFactory->expects($this->exactly(2))->method('create')->will($this->returnValue($scheduleMock));
397+
$this->_scheduleFactory->expects($this->once())->method('create')->will($this->returnValue($scheduleMock));
404398

405399
$this->_observer->execute($this->observer);
406400
}
@@ -465,7 +459,7 @@ public function testDispatchExceptionInCallback(
465459
)->disableOriginalConstructor()->getMock();
466460
$scheduleMock->expects($this->any())->method('getCollection')->will($this->returnValue($this->_collection));
467461
$scheduleMock->expects($this->any())->method('getResource')->will($this->returnValue($this->scheduleResource));
468-
$this->_scheduleFactory->expects($this->exactly(2))->method('create')->will($this->returnValue($scheduleMock));
462+
$this->_scheduleFactory->expects($this->once())->method('create')->will($this->returnValue($scheduleMock));
469463
$this->_objectManager
470464
->expects($this->once())
471465
->method('create')
@@ -541,23 +535,22 @@ public function testDispatchRunJob()
541535
$scheduleMethods
542536
)->disableOriginalConstructor()->getMock();
543537
$schedule->expects($this->any())->method('getJobCode')->will($this->returnValue('test_job1'));
544-
$schedule->expects($this->once())->method('getScheduledAt')->will($this->returnValue($dateScheduledAt));
545-
$schedule->expects($this->once())->method('tryLockJob')->will($this->returnValue(true));
538+
$schedule->expects($this->atLeastOnce())->method('getScheduledAt')->will($this->returnValue($dateScheduledAt));
539+
$schedule->expects($this->atLeastOnce())->method('tryLockJob')->will($this->returnValue(true));
540+
$schedule->expects($this->any())->method('setFinishedAt')->willReturnSelf();
546541

547542
// cron start to execute some job
548543
$schedule->expects($this->any())->method('setExecutedAt')->will($this->returnSelf());
549-
$schedule->expects($this->at(5))->method('save');
544+
$schedule->expects($this->atLeastOnce())->method('save');
550545

551546
// cron end execute some job
552547
$schedule->expects(
553-
$this->at(6)
548+
$this->atLeastOnce()
554549
)->method(
555550
'setStatus'
556551
)->with(
557552
$this->equalTo(\Magento\Cron\Model\Schedule::STATUS_SUCCESS)
558-
)->will(
559-
$this->returnSelf()
560-
);
553+
)->willReturnSelf();
561554

562555
$schedule->expects($this->at(8))->method('save');
563556

@@ -576,7 +569,7 @@ public function testDispatchRunJob()
576569
)->disableOriginalConstructor()->getMock();
577570
$scheduleMock->expects($this->any())->method('getCollection')->will($this->returnValue($this->_collection));
578571
$scheduleMock->expects($this->any())->method('getResource')->will($this->returnValue($this->scheduleResource));
579-
$this->_scheduleFactory->expects($this->exactly(2))->method('create')->will($this->returnValue($scheduleMock));
572+
$this->_scheduleFactory->expects($this->once(2))->method('create')->will($this->returnValue($scheduleMock));
580573

581574
$testCronJob = $this->getMockBuilder('CronJob')->setMethods(['execute'])->getMock();
582575
$testCronJob->expects($this->atLeastOnce())->method('execute')->with($schedule);
@@ -783,7 +776,7 @@ public function testDispatchCleanup()
783776
)->setMethods(['getCollection', 'getResource'])->disableOriginalConstructor()->getMock();
784777
$scheduleMock->expects($this->any())->method('getCollection')->will($this->returnValue($collection));
785778
$scheduleMock->expects($this->any())->method('getResource')->will($this->returnValue($this->scheduleResource));
786-
$this->_scheduleFactory->expects($this->at(1))->method('create')->will($this->returnValue($scheduleMock));
779+
$this->_scheduleFactory->expects($this->any())->method('create')->will($this->returnValue($scheduleMock));
787780

788781
$this->_observer->execute($this->observer);
789782
}
@@ -807,55 +800,17 @@ public function testMissedJobsCleanedInTime()
807800
$this->_cache->expects($this->at(2))->method('load')->will($this->returnValue($this->time + 10000000));
808801
$this->_scheduleFactory->expects($this->at(2))->method('create')->will($this->returnValue($scheduleMock));
809802

810-
// This item was scheduled 2 days and 2 hours ago
811-
$dateScheduledAt = date('Y-m-d H:i:s', $this->time - 180000);
812-
/** @var \Magento\Cron\Model\Schedule|\PHPUnit_Framework_MockObject_MockObject $schedule1 */
813-
$schedule1 = $this->getMockBuilder(
814-
\Magento\Cron\Model\Schedule::class
815-
)->disableOriginalConstructor()->setMethods(
816-
['getExecutedAt', 'getScheduledAt', 'getStatus', 'delete', '__wakeup']
817-
)->getMock();
818-
$schedule1->expects($this->any())->method('getExecutedAt')->will($this->returnValue(null));
819-
$schedule1->expects($this->any())->method('getScheduledAt')->will($this->returnValue($dateScheduledAt));
820-
$schedule1->expects($this->any())->method('getStatus')->will($this->returnValue(Schedule::STATUS_MISSED));
821-
//we expect this job be deleted from the list
822-
$schedule1->expects($this->once())->method('delete')->will($this->returnValue(true));
823-
$this->_collection->addItem($schedule1);
824-
825-
// This item was scheduled 1 day ago
826-
$dateScheduledAt = date('Y-m-d H:i:s', $this->time - 86400);
827-
$schedule2 = $this->getMockBuilder(
828-
\Magento\Cron\Model\Schedule::class
829-
)->disableOriginalConstructor()->setMethods(
830-
['getExecutedAt', 'getScheduledAt', 'getStatus', 'delete', '__wakeup']
831-
)->getMock();
832-
$schedule2->expects($this->any())->method('getExecutedAt')->will($this->returnValue(null));
833-
$schedule2->expects($this->any())->method('getScheduledAt')->will($this->returnValue($dateScheduledAt));
834-
$schedule2->expects($this->any())->method('getStatus')->will($this->returnValue(Schedule::STATUS_MISSED));
835-
//we don't expect this job be deleted from the list
836-
$schedule2->expects($this->never())->method('delete');
837-
$this->_collection->addItem($schedule2);
838-
839803
$this->_config->expects($this->exactly(2))->method('getJobs')->will($this->returnValue($jobConfig));
840804

841-
$this->_scopeConfig->expects($this->at(0))->method('getValue')
842-
->with($this->equalTo('system/cron/test_group/use_separate_process'))
843-
->will($this->returnValue(0));
844-
$this->_scopeConfig->expects($this->at(1))->method('getValue')
845-
->with($this->equalTo('system/cron/test_group/history_cleanup_every'))
846-
->will($this->returnValue(10));
847-
$this->_scopeConfig->expects($this->at(2))->method('getValue')
848-
->with($this->equalTo('system/cron/test_group/schedule_lifetime'))
849-
->will($this->returnValue(2*24*60));
850-
$this->_scopeConfig->expects($this->at(3))->method('getValue')
851-
->with($this->equalTo('system/cron/test_group/history_success_lifetime'))
852-
->will($this->returnValue(0));
853-
$this->_scopeConfig->expects($this->at(4))->method('getValue')
854-
->with($this->equalTo('system/cron/test_group/history_failure_lifetime'))
855-
->will($this->returnValue(0));
856-
$this->_scopeConfig->expects($this->at(5))->method('getValue')
857-
->with($this->equalTo('system/cron/test_group/schedule_generate_every'))
858-
->will($this->returnValue(0));
805+
$this->_scopeConfig->expects($this->any())->method('getValue')
806+
->willReturnMap([
807+
['system/cron/test_group/use_separate_process', 0],
808+
['system/cron/test_group/history_cleanup_every', 10],
809+
['system/cron/test_group/schedule_lifetime', 2*24*60],
810+
['system/cron/test_group/history_success_lifetime', 0],
811+
['system/cron/test_group/history_failure_lifetime', 0],
812+
['system/cron/test_group/schedule_generate_every', 0],
813+
]);
859814

860815
$this->_collection->expects($this->any())->method('addFieldToFilter')->will($this->returnSelf());
861816
$this->_collection->expects($this->any())->method('load')->will($this->returnSelf());

0 commit comments

Comments
 (0)