Rewrite SimpleWorkerTest to tests of particular services
[MAILPOET-2539]
This commit is contained in:
committed by
Jack Kitterhing
parent
9c02da4626
commit
04f266518b
218
tests/integration/Cron/CronWorkerRunnerTest.php
Normal file
218
tests/integration/Cron/CronWorkerRunnerTest.php
Normal file
@ -0,0 +1,218 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace MailPoet\Test\Cron;
|
||||||
|
|
||||||
|
use Codeception\Stub;
|
||||||
|
use Codeception\Stub\Expected;
|
||||||
|
use MailPoet\Cron\CronHelper;
|
||||||
|
use MailPoet\Cron\CronWorkerRunner;
|
||||||
|
use MailPoet\Cron\Workers\SimpleWorkerMockImplementation;
|
||||||
|
use MailPoet\Models\ScheduledTask;
|
||||||
|
use MailPoetVendor\Carbon\Carbon;
|
||||||
|
use MailPoetVendor\Idiorm\ORM;
|
||||||
|
|
||||||
|
require_once __DIR__ . '/Workers/SimpleWorkerMockImplementation.php';
|
||||||
|
|
||||||
|
class CronWorkerRunnerTest extends \MailPoetTest {
|
||||||
|
/** @var CronWorkerRunner */
|
||||||
|
private $cron_worker_runner;
|
||||||
|
|
||||||
|
/** @var CronHelper */
|
||||||
|
private $cron_helper;
|
||||||
|
|
||||||
|
function _before() {
|
||||||
|
$this->cron_worker_runner = $this->di_container->get(CronWorkerRunner::class);
|
||||||
|
$this->cron_helper = $this->di_container->get(CronHelper::class);
|
||||||
|
ORM::raw_execute('TRUNCATE ' . ScheduledTask::$_table);
|
||||||
|
}
|
||||||
|
|
||||||
|
function testItCanInitBeforeProcessing() {
|
||||||
|
$worker = $this->make(SimpleWorkerMockImplementation::class, [
|
||||||
|
'init' => Expected::once(),
|
||||||
|
'scheduleAutomatically' => Expected::once(false),
|
||||||
|
]);
|
||||||
|
$this->cron_worker_runner->run($worker);
|
||||||
|
}
|
||||||
|
|
||||||
|
function testItPreparesTask() {
|
||||||
|
$worker = $this->make(SimpleWorkerMockImplementation::class, [
|
||||||
|
'prepareTaskStrategy' => Expected::once(true),
|
||||||
|
'processTaskStrategy' => Expected::never(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
$task = $this->createScheduledTask();
|
||||||
|
$result = $this->cron_worker_runner->run($worker);
|
||||||
|
expect($result)->true();
|
||||||
|
expect(ScheduledTask::findOne($task->id)->status)->null();
|
||||||
|
}
|
||||||
|
|
||||||
|
function testItProcessesTask() {
|
||||||
|
$worker = $this->make(SimpleWorkerMockImplementation::class, [
|
||||||
|
'prepareTaskStrategy' => Expected::never(),
|
||||||
|
'processTaskStrategy' => Expected::once(true),
|
||||||
|
]);
|
||||||
|
|
||||||
|
$task = $this->createRunningTask();
|
||||||
|
$result = $this->cron_worker_runner->run($worker);
|
||||||
|
expect($result)->true();
|
||||||
|
expect(ScheduledTask::findOne($task->id)->status)->same(ScheduledTask::STATUS_COMPLETED);
|
||||||
|
}
|
||||||
|
|
||||||
|
function testItFailsToProcessWithoutTasks() {
|
||||||
|
$worker = $this->make(SimpleWorkerMockImplementation::class, [
|
||||||
|
'scheduleAutomatically' => Expected::once(false),
|
||||||
|
'prepareTaskStrategy' => Expected::never(),
|
||||||
|
'processTaskStrategy' => Expected::never(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
$result = $this->cron_worker_runner->run($worker);
|
||||||
|
expect($result)->false();
|
||||||
|
}
|
||||||
|
|
||||||
|
function testItFailsToProcessWithoutProcessingRequirementsMet() {
|
||||||
|
$worker = $this->make(SimpleWorkerMockImplementation::class, [
|
||||||
|
'checkProcessingRequirements' => Expected::once(false),
|
||||||
|
'prepareTaskStrategy' => Expected::never(),
|
||||||
|
'processTaskStrategy' => Expected::never(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
$this->createScheduledTask();
|
||||||
|
$this->createRunningTask();
|
||||||
|
|
||||||
|
$result = $this->cron_worker_runner->run($worker);
|
||||||
|
expect($result)->false();
|
||||||
|
}
|
||||||
|
|
||||||
|
function testItCanScheduleTaskAutomatically() {
|
||||||
|
$in_one_week = Carbon::now()->addWeek()->startOfDay();
|
||||||
|
$worker = $this->make(SimpleWorkerMockImplementation::class, [
|
||||||
|
'scheduleAutomatically' => Expected::once(true),
|
||||||
|
'getTaskType' => Expected::atLeastOnce(SimpleWorkerMockImplementation::TASK_TYPE),
|
||||||
|
'getNextRunDate' => Expected::once($in_one_week),
|
||||||
|
]);
|
||||||
|
|
||||||
|
$result = $this->cron_worker_runner->run($worker);
|
||||||
|
expect($result)->false();
|
||||||
|
expect(ScheduledTask::findOne()->scheduled_at)->same($in_one_week->format('Y-m-d H:i:s'));
|
||||||
|
}
|
||||||
|
|
||||||
|
function testItWillRescheduleTaskIfItIsRunningForTooLong() {
|
||||||
|
$worker = $this->make(SimpleWorkerMockImplementation::class, [
|
||||||
|
'processTaskStrategy' => Expected::once(false),
|
||||||
|
]);
|
||||||
|
$worker->__construct();
|
||||||
|
|
||||||
|
$task = $this->createRunningTask();
|
||||||
|
$task = ScheduledTask::findOne($task->id); // make sure `updated_at` is set by the DB
|
||||||
|
|
||||||
|
$result = $this->cron_worker_runner->run($worker);
|
||||||
|
expect($result)->true();
|
||||||
|
|
||||||
|
$scheduled_at = $task->scheduled_at;
|
||||||
|
$task->updated_at = Carbon::createFromTimestamp(strtotime($task->updated_at))
|
||||||
|
->subMinutes(CronWorkerRunner::TASK_RUN_TIMEOUT + 1);
|
||||||
|
$task->save();
|
||||||
|
|
||||||
|
$result = $this->cron_worker_runner->run($worker);
|
||||||
|
expect($result)->true();
|
||||||
|
|
||||||
|
$task = ScheduledTask::findOne($task->id);
|
||||||
|
expect($task->scheduled_at)->greaterThan($scheduled_at);
|
||||||
|
expect($task->status)->same(ScheduledTask::STATUS_SCHEDULED);
|
||||||
|
expect($task->in_progress)->isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
function testItWillRescheduleATaskIfItFails() {
|
||||||
|
$worker = $this->make(SimpleWorkerMockImplementation::class, [
|
||||||
|
'processTaskStrategy' => Expected::once(function () {
|
||||||
|
throw new \Exception('test error');
|
||||||
|
}),
|
||||||
|
]);
|
||||||
|
|
||||||
|
$task = $this->createRunningTask();
|
||||||
|
$scheduled_at = $task->scheduled_at;
|
||||||
|
try {
|
||||||
|
$this->cron_worker_runner->run($worker);
|
||||||
|
$this->fail('An exception should be thrown');
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
expect($e->getMessage())->equals('test error');
|
||||||
|
$task = ScheduledTask::findOne($task->id);
|
||||||
|
expect($task->scheduled_at)->greaterThan($scheduled_at);
|
||||||
|
expect($task->status)->same(ScheduledTask::STATUS_SCHEDULED);
|
||||||
|
expect($task->reschedule_count)->equals(1);
|
||||||
|
expect($task->in_progress)->isEmpty();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function testWillNotRescheduleATaskOnCronTimeout() {
|
||||||
|
$worker = $this->make(SimpleWorkerMockImplementation::class, [
|
||||||
|
'processTaskStrategy' => Expected::once(function () {
|
||||||
|
$this->cron_helper->enforceExecutionLimit(microtime(true) - CronHelper::DAEMON_EXECUTION_LIMIT - 1);
|
||||||
|
}),
|
||||||
|
]);
|
||||||
|
|
||||||
|
$task = $this->createRunningTask();
|
||||||
|
$scheduled_at = $task->scheduled_at;
|
||||||
|
try {
|
||||||
|
$this->cron_worker_runner->run($worker);
|
||||||
|
$this->fail('An exception should be thrown');
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
expect($e->getCode())->same(CronHelper::DAEMON_EXECUTION_LIMIT_REACHED);
|
||||||
|
$task = ScheduledTask::findOne($task->id);
|
||||||
|
expect($scheduled_at)->equals($task->scheduled_at);
|
||||||
|
expect($task->status)->null();
|
||||||
|
expect($task->reschedule_count)->equals(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function testItWillNotRunInMultipleInstances() {
|
||||||
|
$worker = $this->make(SimpleWorkerMockImplementation::class, [
|
||||||
|
'supportsMultipleInstances' => Expected::once(false),
|
||||||
|
'processTaskStrategy' => Expected::never(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
$task = $this->createRunningTask();
|
||||||
|
$task->in_progress = true;
|
||||||
|
$task->save();
|
||||||
|
|
||||||
|
$this->cron_worker_runner->run($worker);
|
||||||
|
}
|
||||||
|
|
||||||
|
function testItThrowsExceptionWhenExecutionLimitIsReached() {
|
||||||
|
$worker = $this->make(SimpleWorkerMockImplementation::class, [
|
||||||
|
'processTaskStrategy' => Expected::never(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
$cron_worker_runner = Stub::copy($this->cron_worker_runner, [
|
||||||
|
'timer' => microtime(true) - $this->di_container->get(CronHelper::class)->getDaemonExecutionLimit(),
|
||||||
|
]);
|
||||||
|
try {
|
||||||
|
$cron_worker_runner->run($worker);
|
||||||
|
self::fail('Maximum execution time limit exception was not thrown.');
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
expect($e->getMessage())->same('Maximum execution time has been reached.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function createScheduledTask() {
|
||||||
|
$task = ScheduledTask::create();
|
||||||
|
$task->type = SimpleWorkerMockImplementation::TASK_TYPE;
|
||||||
|
$task->status = ScheduledTask::STATUS_SCHEDULED;
|
||||||
|
$task->scheduled_at = Carbon::createFromTimestamp(current_time('timestamp'));
|
||||||
|
$task->save();
|
||||||
|
return $task;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function createRunningTask() {
|
||||||
|
$task = ScheduledTask::create();
|
||||||
|
$task->type = SimpleWorkerMockImplementation::TASK_TYPE;
|
||||||
|
$task->status = null;
|
||||||
|
$task->scheduled_at = Carbon::createFromTimestamp(current_time('timestamp'));
|
||||||
|
$task->save();
|
||||||
|
return $task;
|
||||||
|
}
|
||||||
|
|
||||||
|
function _after() {
|
||||||
|
ORM::raw_execute('TRUNCATE ' . ScheduledTask::$_table);
|
||||||
|
}
|
||||||
|
}
|
58
tests/integration/Cron/CronWorkerSchedulerTest.php
Normal file
58
tests/integration/Cron/CronWorkerSchedulerTest.php
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace MailPoet\Test\Cron;
|
||||||
|
|
||||||
|
use MailPoet\Cron\CronWorkerScheduler;
|
||||||
|
use MailPoet\Models\ScheduledTask;
|
||||||
|
use MailPoetVendor\Carbon\Carbon;
|
||||||
|
use MailPoetVendor\Idiorm\ORM;
|
||||||
|
|
||||||
|
require_once __DIR__ . '/Workers/SimpleWorkerMockImplementation.php';
|
||||||
|
|
||||||
|
class CronWorkerSchedulerTest extends \MailPoetTest {
|
||||||
|
/** @var CronWorkerScheduler */
|
||||||
|
private $cron_worker_scheduler;
|
||||||
|
|
||||||
|
function _before() {
|
||||||
|
$this->cron_worker_scheduler = $this->di_container->get(CronWorkerScheduler::class);
|
||||||
|
ORM::raw_execute('TRUNCATE ' . ScheduledTask::$_table);
|
||||||
|
}
|
||||||
|
|
||||||
|
function testItSchedulesTask() {
|
||||||
|
$next_run_date = Carbon::now()->addWeek();
|
||||||
|
$this->cron_worker_scheduler->schedule('test', $next_run_date);
|
||||||
|
|
||||||
|
$tasks = ScheduledTask::findMany();
|
||||||
|
expect($tasks)->count(1);
|
||||||
|
expect($tasks[0]->type)->same('test');
|
||||||
|
expect($tasks[0]->status)->same(ScheduledTask::STATUS_SCHEDULED);
|
||||||
|
expect($tasks[0]->scheduled_at)->same($next_run_date->format('Y-m-d H:i:s'));
|
||||||
|
}
|
||||||
|
|
||||||
|
function testItDoesNotScheduleTaskTwice() {
|
||||||
|
$next_run_date = Carbon::now()->addWeek();
|
||||||
|
$this->cron_worker_scheduler->schedule('test', $next_run_date);
|
||||||
|
expect(ScheduledTask::findMany())->count(1);
|
||||||
|
|
||||||
|
$result = $this->cron_worker_scheduler->schedule('test', $next_run_date);
|
||||||
|
expect($result)->false();
|
||||||
|
expect(ScheduledTask::findMany())->count(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
function testItReschedulesTask() {
|
||||||
|
$next_run_date = Carbon::now()->subDay();
|
||||||
|
$task = $this->cron_worker_scheduler->schedule('test', $next_run_date);
|
||||||
|
$this->cron_worker_scheduler->reschedule($task, 10);
|
||||||
|
|
||||||
|
$tasks = ScheduledTask::findMany();
|
||||||
|
expect($tasks)->count(1);
|
||||||
|
expect($tasks[0]->type)->same('test');
|
||||||
|
expect($tasks[0]->status)->same(ScheduledTask::STATUS_SCHEDULED);
|
||||||
|
expect($tasks[0]->scheduled_at)->greaterThan($next_run_date);
|
||||||
|
expect($tasks[0]->scheduled_at)->greaterThan(Carbon::now());
|
||||||
|
}
|
||||||
|
|
||||||
|
function _after() {
|
||||||
|
ORM::raw_execute('TRUNCATE ' . ScheduledTask::$_table);
|
||||||
|
}
|
||||||
|
}
|
@ -3,7 +3,6 @@
|
|||||||
namespace MailPoet\Test\Cron\Workers;
|
namespace MailPoet\Test\Cron\Workers;
|
||||||
|
|
||||||
use Codeception\Stub;
|
use Codeception\Stub;
|
||||||
use Codeception\Stub\Expected;
|
|
||||||
use MailPoet\Cron\CronHelper;
|
use MailPoet\Cron\CronHelper;
|
||||||
use MailPoet\Cron\Workers\SimpleWorkerMockImplementation as MockSimpleWorker;
|
use MailPoet\Cron\Workers\SimpleWorkerMockImplementation as MockSimpleWorker;
|
||||||
use MailPoet\DI\ContainerWrapper;
|
use MailPoet\DI\ContainerWrapper;
|
||||||
@ -12,7 +11,7 @@ use MailPoet\Settings\SettingsRepository;
|
|||||||
use MailPoetVendor\Carbon\Carbon;
|
use MailPoetVendor\Carbon\Carbon;
|
||||||
use MailPoetVendor\Idiorm\ORM;
|
use MailPoetVendor\Idiorm\ORM;
|
||||||
|
|
||||||
require_once('SimpleWorkerMockImplementation.php');
|
require_once __DIR__ . '/SimpleWorkerMockImplementation.php';
|
||||||
|
|
||||||
class SimpleWorkerTest extends \MailPoetTest {
|
class SimpleWorkerTest extends \MailPoetTest {
|
||||||
function _before() {
|
function _before() {
|
||||||
@ -36,15 +35,6 @@ class SimpleWorkerTest extends \MailPoetTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function testItThrowsExceptionWhenExecutionLimitIsReached() {
|
|
||||||
try {
|
|
||||||
$this->worker->process(microtime(true) - $this->cron_helper->getDaemonExecutionLimit());
|
|
||||||
self::fail('Maximum execution time limit exception was not thrown.');
|
|
||||||
} catch (\Exception $e) {
|
|
||||||
expect($e->getMessage())->equals('Maximum execution time has been reached.');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function testItSchedulesTask() {
|
function testItSchedulesTask() {
|
||||||
expect(ScheduledTask::where('type', MockSimpleWorker::TASK_TYPE)->findMany())->isEmpty();
|
expect(ScheduledTask::where('type', MockSimpleWorker::TASK_TYPE)->findMany())->isEmpty();
|
||||||
(new MockSimpleWorker())->schedule();
|
(new MockSimpleWorker())->schedule();
|
||||||
@ -60,214 +50,6 @@ class SimpleWorkerTest extends \MailPoetTest {
|
|||||||
expect(count(ScheduledTask::where('type', MockSimpleWorker::TASK_TYPE)->findMany()))->equals(1);
|
expect(count(ScheduledTask::where('type', MockSimpleWorker::TASK_TYPE)->findMany()))->equals(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
function testItCanGetScheduledTasks() {
|
|
||||||
$worker = new MockSimpleWorker();
|
|
||||||
expect($worker->getDueTasks())->isEmpty();
|
|
||||||
$this->createScheduledTask();
|
|
||||||
expect($worker->getDueTasks())->notEmpty();
|
|
||||||
}
|
|
||||||
|
|
||||||
function testItCanGetABatchOfScheduledTasks() {
|
|
||||||
$worker = new MockSimpleWorker();
|
|
||||||
for ($i = 0; $i < MockSimpleWorker::TASK_BATCH_SIZE + 5; $i += 1) {
|
|
||||||
$this->createScheduledTask();
|
|
||||||
}
|
|
||||||
expect(count($worker->getDueTasks()))->equals(MockSimpleWorker::TASK_BATCH_SIZE);
|
|
||||||
}
|
|
||||||
|
|
||||||
function testItCanGetRunningTasks() {
|
|
||||||
$worker = new MockSimpleWorker();
|
|
||||||
expect($worker->getRunningTasks())->isEmpty();
|
|
||||||
$this->createRunningTask();
|
|
||||||
expect($worker->getRunningTasks())->notEmpty();
|
|
||||||
}
|
|
||||||
|
|
||||||
function testItCanGetBatchOfRunningTasks() {
|
|
||||||
$worker = new MockSimpleWorker();
|
|
||||||
for ($i = 0; $i < MockSimpleWorker::TASK_BATCH_SIZE + 5; $i += 1) {
|
|
||||||
$this->createRunningTask();
|
|
||||||
}
|
|
||||||
expect(count($worker->getRunningTasks()))->equals(MockSimpleWorker::TASK_BATCH_SIZE);
|
|
||||||
}
|
|
||||||
|
|
||||||
function testItCanGetBatchOfCompletedTasks() {
|
|
||||||
$worker = new MockSimpleWorker();
|
|
||||||
for ($i = 0; $i < MockSimpleWorker::TASK_BATCH_SIZE + 5; $i += 1) {
|
|
||||||
$this->createCompletedTask();
|
|
||||||
}
|
|
||||||
expect(count($worker->getCompletedTasks()))->equals(MockSimpleWorker::TASK_BATCH_SIZE);
|
|
||||||
}
|
|
||||||
|
|
||||||
function testItFailsToProcessWithoutTasks() {
|
|
||||||
expect($this->worker->process())->false();
|
|
||||||
}
|
|
||||||
|
|
||||||
function testItFailsToProcessWithoutProcessingRequirementsMet() {
|
|
||||||
$this->createScheduledTask();
|
|
||||||
$this->createRunningTask();
|
|
||||||
$worker = Stub::make(
|
|
||||||
$this->worker,
|
|
||||||
['checkProcessingRequirements' => false],
|
|
||||||
$this
|
|
||||||
);
|
|
||||||
$worker->__construct();
|
|
||||||
expect($worker->process())->false();
|
|
||||||
}
|
|
||||||
|
|
||||||
function testItCanInitBeforeProcessing() {
|
|
||||||
$worker = Stub::make(
|
|
||||||
$this->worker,
|
|
||||||
[
|
|
||||||
'init' => Expected::once(),
|
|
||||||
'schedule' => Expected::once(),
|
|
||||||
],
|
|
||||||
$this
|
|
||||||
);
|
|
||||||
$worker->__construct();
|
|
||||||
$worker->process();
|
|
||||||
}
|
|
||||||
|
|
||||||
function testItProcesses() {
|
|
||||||
$this->createScheduledTask();
|
|
||||||
$this->createRunningTask();
|
|
||||||
expect($this->worker->process())->true();
|
|
||||||
}
|
|
||||||
|
|
||||||
function testItPreparesTask() {
|
|
||||||
$task = $this->createScheduledTask();
|
|
||||||
$this->worker->prepareTask($task, microtime(true));
|
|
||||||
expect($task->status)->null();
|
|
||||||
}
|
|
||||||
|
|
||||||
function testItProcessesTask() {
|
|
||||||
$task = $this->createRunningTask();
|
|
||||||
$result = $this->worker->processTask($task, microtime(true));
|
|
||||||
expect($task->status)->equals(ScheduledTask::STATUS_COMPLETED);
|
|
||||||
expect($result)->equals(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
function testItReturnsFalseIfInnerProcessingFunctionReturnsFalse() {
|
|
||||||
$task = $this->createRunningTask();
|
|
||||||
$worker = Stub::construct(
|
|
||||||
$this->worker,
|
|
||||||
[],
|
|
||||||
['processTaskStrategy' => false],
|
|
||||||
$this
|
|
||||||
);
|
|
||||||
$result = $worker->processTask($task, microtime(true));
|
|
||||||
expect($task->status)->equals(null);
|
|
||||||
expect($result)->equals(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
function testItCanRescheduleTasks() {
|
|
||||||
$task = $this->createRunningTask();
|
|
||||||
$scheduled_at = $task->scheduled_at;
|
|
||||||
$this->worker->reschedule($task, 10);
|
|
||||||
expect($scheduled_at < $task->scheduled_at)->true();
|
|
||||||
expect($task->status)->equals(ScheduledTask::STATUS_SCHEDULED);
|
|
||||||
}
|
|
||||||
|
|
||||||
function testWillRescheduleATaskIfItFails() {
|
|
||||||
$task = $this->createRunningTask();
|
|
||||||
$worker = Stub::construct(
|
|
||||||
$this->worker,
|
|
||||||
[],
|
|
||||||
[
|
|
||||||
'processTaskStrategy' => function () {
|
|
||||||
throw new \Exception('test error');
|
|
||||||
},
|
|
||||||
],
|
|
||||||
$this
|
|
||||||
);
|
|
||||||
$scheduled_at = $task->scheduled_at;
|
|
||||||
try {
|
|
||||||
$worker->process();
|
|
||||||
$this->fail('An exception should be thrown');
|
|
||||||
} catch (\Exception $e) {
|
|
||||||
expect($e->getMessage())->equals('test error');
|
|
||||||
$task = ScheduledTask::findOne($task->id);
|
|
||||||
expect($scheduled_at < $task->scheduled_at)->true();
|
|
||||||
expect($task->status)->equals(ScheduledTask::STATUS_SCHEDULED);
|
|
||||||
expect($task->reschedule_count)->equals(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function testWillNotRescheduleATaskOnCronTimeout() {
|
|
||||||
$task = $this->createRunningTask();
|
|
||||||
$worker = Stub::construct(
|
|
||||||
$this->worker,
|
|
||||||
[],
|
|
||||||
[
|
|
||||||
'processTaskStrategy' => function () {
|
|
||||||
$this->cron_helper->enforceExecutionLimit(microtime(true) - CronHelper::DAEMON_EXECUTION_LIMIT - 1);
|
|
||||||
},
|
|
||||||
],
|
|
||||||
$this
|
|
||||||
);
|
|
||||||
$scheduled_at = $task->scheduled_at;
|
|
||||||
try {
|
|
||||||
$worker->process();
|
|
||||||
$this->fail('An exception should be thrown');
|
|
||||||
} catch (\Exception $e) {
|
|
||||||
expect($e->getCode())->equals(CronHelper::DAEMON_EXECUTION_LIMIT_REACHED);
|
|
||||||
$task = ScheduledTask::findOne($task->id);
|
|
||||||
expect($scheduled_at)->equals($task->scheduled_at);
|
|
||||||
expect($task->status)->equals(null);
|
|
||||||
expect($task->reschedule_count)->equals(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function testItWillNotRunInMultipleInstances() {
|
|
||||||
$worker = $this->getMockBuilder(MockSimpleWorker::class)
|
|
||||||
->setMethods(['processTaskStrategy'])
|
|
||||||
->getMock();
|
|
||||||
$worker->expects($this->once())
|
|
||||||
->method('processTaskStrategy')
|
|
||||||
->willReturn(true);
|
|
||||||
$task = $this->createRunningTask();
|
|
||||||
expect(empty($task->in_progress))->equals(true);
|
|
||||||
expect($worker->processTask($task, microtime(true)))->equals(true);
|
|
||||||
$task->in_progress = true;
|
|
||||||
expect($worker->processTask($task, microtime(true)))->equals(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
function testItWillResetTheInProgressFlagOnFail() {
|
|
||||||
$worker = $this->getMockBuilder(MockSimpleWorker::class)
|
|
||||||
->setMethods(['processTaskStrategy'])
|
|
||||||
->getMock();
|
|
||||||
$worker->expects($this->once())
|
|
||||||
->method('processTaskStrategy')
|
|
||||||
->willThrowException(new \Exception('test error'));
|
|
||||||
$task = $this->createRunningTask();
|
|
||||||
try {
|
|
||||||
$worker->processTask($task, microtime(true));
|
|
||||||
$this->fail('An exception should be thrown');
|
|
||||||
} catch (\Exception $e) {
|
|
||||||
expect($e->getMessage())->equals('test error');
|
|
||||||
expect(empty($task->in_progress))->equals(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function testItWillRescheduleTaskIfItIsRunningForTooLong() {
|
|
||||||
$worker = $this->getMockBuilder(MockSimpleWorker::class)
|
|
||||||
->setMethods(['processTaskStrategy'])
|
|
||||||
->getMock();
|
|
||||||
$worker->expects($this->once())
|
|
||||||
->method('processTaskStrategy')
|
|
||||||
->willReturn(true);
|
|
||||||
$task = $this->createRunningTask();
|
|
||||||
$task = ScheduledTask::findOne($task->id); // make sure `updated_at` is set by the DB
|
|
||||||
expect($worker->processTask($task, microtime(true)))->equals(true);
|
|
||||||
$scheduled_at = $task->scheduled_at;
|
|
||||||
$task->updated_at = Carbon::createFromTimestamp(strtotime($task->updated_at))
|
|
||||||
->subMinutes(MockSimpleWorker::TASK_RUN_TIMEOUT + 1);
|
|
||||||
expect($worker->processTask($task, microtime(true)))->equals(false);
|
|
||||||
$task = ScheduledTask::findOne($task->id);
|
|
||||||
expect($scheduled_at < $task->scheduled_at)->true();
|
|
||||||
expect($task->status)->equals(ScheduledTask::STATUS_SCHEDULED);
|
|
||||||
expect(empty($task->in_progress))->equals(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
function testItCalculatesNextRunDateWithinNextWeekBoundaries() {
|
function testItCalculatesNextRunDateWithinNextWeekBoundaries() {
|
||||||
$current_date = Carbon::createFromTimestamp(current_time('timestamp'));
|
$current_date = Carbon::createFromTimestamp(current_time('timestamp'));
|
||||||
$next_run_date = (new MockSimpleWorker())->getNextRunDate();
|
$next_run_date = (new MockSimpleWorker())->getNextRunDate();
|
||||||
@ -278,33 +60,6 @@ class SimpleWorkerTest extends \MailPoetTest {
|
|||||||
expect($difference)->greaterOrEquals(0);
|
expect($difference)->greaterOrEquals(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function createScheduledTask() {
|
|
||||||
$task = ScheduledTask::create();
|
|
||||||
$task->type = MockSimpleWorker::TASK_TYPE;
|
|
||||||
$task->status = ScheduledTask::STATUS_SCHEDULED;
|
|
||||||
$task->scheduled_at = Carbon::createFromTimestamp(current_time('timestamp'));
|
|
||||||
$task->save();
|
|
||||||
return $task;
|
|
||||||
}
|
|
||||||
|
|
||||||
private function createRunningTask() {
|
|
||||||
$task = ScheduledTask::create();
|
|
||||||
$task->type = MockSimpleWorker::TASK_TYPE;
|
|
||||||
$task->status = null;
|
|
||||||
$task->scheduled_at = Carbon::createFromTimestamp(current_time('timestamp'));
|
|
||||||
$task->save();
|
|
||||||
return $task;
|
|
||||||
}
|
|
||||||
|
|
||||||
private function createCompletedTask() {
|
|
||||||
$task = ScheduledTask::create();
|
|
||||||
$task->type = MockSimpleWorker::TASK_TYPE;
|
|
||||||
$task->status = ScheduledTask::STATUS_COMPLETED;
|
|
||||||
$task->scheduled_at = Carbon::createFromTimestamp(current_time('timestamp'));
|
|
||||||
$task->save();
|
|
||||||
return $task;
|
|
||||||
}
|
|
||||||
|
|
||||||
function _after() {
|
function _after() {
|
||||||
$this->di_container->get(SettingsRepository::class)->truncate();
|
$this->di_container->get(SettingsRepository::class)->truncate();
|
||||||
ORM::raw_execute('TRUNCATE ' . ScheduledTask::$_table);
|
ORM::raw_execute('TRUNCATE ' . ScheduledTask::$_table);
|
||||||
|
@ -157,6 +157,142 @@ class ScheduledTaskTest extends \MailPoetTest {
|
|||||||
expect($timeout)->equals(ScheduledTask::MAX_RESCHEDULE_TIMEOUT);
|
expect($timeout)->equals(ScheduledTask::MAX_RESCHEDULE_TIMEOUT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function testItCanGetDueTasks() {
|
||||||
|
// due (scheduled in past)
|
||||||
|
ScheduledTask::createOrUpdate([
|
||||||
|
'type' => 'test',
|
||||||
|
'status' => ScheduledTask::STATUS_SCHEDULED,
|
||||||
|
'scheduled_at' => Carbon::now()->subDay(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
// deleted (should not be fetched)
|
||||||
|
ScheduledTask::createOrUpdate([
|
||||||
|
'type' => 'test',
|
||||||
|
'status' => ScheduledTask::STATUS_SCHEDULED,
|
||||||
|
'scheduled_at' => Carbon::now()->subDay(),
|
||||||
|
'deleted_at' => Carbon::now(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
// scheduled in future (should not be fetched)
|
||||||
|
ScheduledTask::createOrUpdate([
|
||||||
|
'type' => 'test',
|
||||||
|
'status' => ScheduledTask::STATUS_SCHEDULED,
|
||||||
|
'scheduled_at' => Carbon::now()->addDay(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
// wrong status (should not be fetched)
|
||||||
|
ScheduledTask::createOrUpdate([
|
||||||
|
'type' => 'test',
|
||||||
|
'status' => null,
|
||||||
|
'scheduled_at' => Carbon::now()->subDay(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
$tasks = ScheduledTask::findDueByType('test', 10);
|
||||||
|
expect($tasks)->count(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
function testItCanGetRunningTasks() {
|
||||||
|
// running (scheduled in past)
|
||||||
|
ScheduledTask::createOrUpdate([
|
||||||
|
'type' => 'test',
|
||||||
|
'status' => null,
|
||||||
|
'scheduled_at' => Carbon::now()->subDay(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
// deleted (should not be fetched)
|
||||||
|
ScheduledTask::createOrUpdate([
|
||||||
|
'type' => 'test',
|
||||||
|
'status' => null,
|
||||||
|
'scheduled_at' => Carbon::now()->subDay(),
|
||||||
|
'deleted_at' => Carbon::now(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
// scheduled in future (should not be fetched)
|
||||||
|
ScheduledTask::createOrUpdate([
|
||||||
|
'type' => 'test',
|
||||||
|
'status' => null,
|
||||||
|
'scheduled_at' => Carbon::now()->addDay(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
// wrong status (should not be fetched)
|
||||||
|
ScheduledTask::createOrUpdate([
|
||||||
|
'type' => 'test',
|
||||||
|
'status' => ScheduledTask::STATUS_COMPLETED,
|
||||||
|
'scheduled_at' => Carbon::now()->subDay(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
$tasks = ScheduledTask::findRunningByType('test', 10);
|
||||||
|
expect($tasks)->count(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
function testItCanGetCompletedTasks() {
|
||||||
|
// completed (scheduled in past)
|
||||||
|
ScheduledTask::createOrUpdate([
|
||||||
|
'type' => 'test',
|
||||||
|
'status' => ScheduledTask::STATUS_COMPLETED,
|
||||||
|
'scheduled_at' => Carbon::now()->subDay(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
// deleted (should not be fetched)
|
||||||
|
ScheduledTask::createOrUpdate([
|
||||||
|
'type' => 'test',
|
||||||
|
'status' => ScheduledTask::STATUS_COMPLETED,
|
||||||
|
'scheduled_at' => Carbon::now()->subDay(),
|
||||||
|
'deleted_at' => Carbon::now(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
// scheduled in future (should not be fetched)
|
||||||
|
ScheduledTask::createOrUpdate([
|
||||||
|
'type' => 'test',
|
||||||
|
'status' => ScheduledTask::STATUS_COMPLETED,
|
||||||
|
'scheduled_at' => Carbon::now()->addDay(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
// wrong status (should not be fetched)
|
||||||
|
ScheduledTask::createOrUpdate([
|
||||||
|
'type' => 'test',
|
||||||
|
'status' => ScheduledTask::STATUS_SCHEDULED,
|
||||||
|
'scheduled_at' => Carbon::now()->subDay(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
$tasks = ScheduledTask::findCompletedByType('test', 10);
|
||||||
|
expect($tasks)->count(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
function testItCanGetFutureScheduledTasks() {
|
||||||
|
// scheduled (in future)
|
||||||
|
ScheduledTask::createOrUpdate([
|
||||||
|
'type' => 'test',
|
||||||
|
'status' => ScheduledTask::STATUS_SCHEDULED,
|
||||||
|
'scheduled_at' => Carbon::now()->addDay(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
// deleted (should not be fetched)
|
||||||
|
ScheduledTask::createOrUpdate([
|
||||||
|
'type' => 'test',
|
||||||
|
'status' => ScheduledTask::STATUS_SCHEDULED,
|
||||||
|
'scheduled_at' => Carbon::now()->addDay(),
|
||||||
|
'deleted_at' => Carbon::now(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
// scheduled in past (should not be fetched)
|
||||||
|
ScheduledTask::createOrUpdate([
|
||||||
|
'type' => 'test',
|
||||||
|
'status' => ScheduledTask::STATUS_SCHEDULED,
|
||||||
|
'scheduled_at' => Carbon::now()->subDay(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
// wrong status (should not be fetched)
|
||||||
|
ScheduledTask::createOrUpdate([
|
||||||
|
'type' => 'test',
|
||||||
|
'status' => null,
|
||||||
|
'scheduled_at' => Carbon::now()->addDay(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
$tasks = ScheduledTask::findDueByType('test', 10);
|
||||||
|
expect($tasks)->count(1);
|
||||||
|
}
|
||||||
|
|
||||||
function _after() {
|
function _after() {
|
||||||
ORM::raw_execute('TRUNCATE ' . ScheduledTask::$_table);
|
ORM::raw_execute('TRUNCATE ' . ScheduledTask::$_table);
|
||||||
ORM::raw_execute('TRUNCATE ' . ScheduledTaskSubscriber::$_table);
|
ORM::raw_execute('TRUNCATE ' . ScheduledTaskSubscriber::$_table);
|
||||||
|
Reference in New Issue
Block a user