diff --git a/application/Espo/Core/ApplicationRunners/Cron.php b/application/Espo/Core/ApplicationRunners/Cron.php index 9aa29f455f..d1a62058bf 100644 --- a/application/Espo/Core/ApplicationRunners/Cron.php +++ b/application/Espo/Core/ApplicationRunners/Cron.php @@ -31,24 +31,25 @@ namespace Espo\Core\ApplicationRunners; use Espo\Core\{ Application\Runner, - CronManager, + Job\JobManager, Utils\Config, }; /** - * Runs cron. + * Runs Cron. */ class Cron implements Runner { use Cli; use SetupSystemUser; - protected $cronManager; - protected $config; + private $jobManager; - public function __construct(CronManager $cronManager, Config $config) + private $config; + + public function __construct(JobManager $jobManager, Config $config) { - $this->cronManager = $cronManager; + $this->jobManager = $jobManager; $this->config = $config; } @@ -60,6 +61,6 @@ class Cron implements Runner return; } - $this->cronManager->run(); + $this->jobManager->process(); } } diff --git a/application/Espo/Core/ApplicationRunners/Job.php b/application/Espo/Core/ApplicationRunners/Job.php index 48f7b2ff1a..df99a98a64 100644 --- a/application/Espo/Core/ApplicationRunners/Job.php +++ b/application/Espo/Core/ApplicationRunners/Job.php @@ -31,7 +31,7 @@ namespace Espo\Core\ApplicationRunners; use Espo\Core\{ Application\Runner, - CronManager, + Job\JobManager, }; use StdClass; @@ -46,17 +46,17 @@ class Job implements Runner protected $params; - protected $cronManager; + private $jobManager; - public function __construct(CronManager $cronManager, StdClass $params) + public function __construct(JobManager $jobManager, StdClass $params) { - $this->cronManager = $cronManager; + $this->jobManager = $jobManager; $this->params = $params; } public function run() : void { - $this->cronManager->runJobById($this->params->id); + $this->jobManager->runJobById($this->params->id); } } diff --git a/application/Espo/Core/Console/Commands/RunJob.php b/application/Espo/Core/Console/Commands/RunJob.php index 0fde4559e7..c5f934cd5b 100644 --- a/application/Espo/Core/Console/Commands/RunJob.php +++ b/application/Espo/Core/Console/Commands/RunJob.php @@ -32,21 +32,23 @@ namespace Espo\Core\Console\Commands; use Espo\Core\{ ORM\EntityManager, Utils\Util, - CronManager, + Job\JobManager, Console\Command, Console\Params, Console\IO, }; +use Throwable; + class RunJob implements Command { - private $cronManager; + private $jobManager; private $entityManager; - public function __construct(CronManager $cronManager, EntityManager $entityManager) + public function __construct(JobManager $jobManager, EntityManager $entityManager) { - $this->cronManager = $cronManager; + $this->jobManager = $jobManager; $this->entityManager = $entityManager; } @@ -80,9 +82,10 @@ class RunJob implements Command 'targetId' => $targetId, ]); - $result = $this->cronManager->runJob($job); - - if (!$result) { + try { + $this->jobManager->runJob($job); + } + catch (Throwable $e) { $io->writeLine("Error: Job '{$jobName}' failed to execute."); return; diff --git a/application/Espo/Core/CronManager.php b/application/Espo/Core/Job/JobManager.php similarity index 79% rename from application/Espo/Core/CronManager.php rename to application/Espo/Core/Job/JobManager.php index 071c3c2f6d..4700f89b3d 100644 --- a/application/Espo/Core/CronManager.php +++ b/application/Espo/Core/Job/JobManager.php @@ -27,7 +27,7 @@ * these Appropriate Legal Notices must retain the display of the "EspoCRM" word. ************************************************************************/ -namespace Espo\Core; +namespace Espo\Core\Job; use Espo\Core\{ Exceptions\Error, @@ -42,6 +42,7 @@ use Espo\Core\{ ORM\EntityManager, Utils\Cron\JobTask, Jobs\JobTargeted, + Utils\Log, }; use Espo\Entities\Job as JobEntity; @@ -53,7 +54,7 @@ use Cron\CronExpression; use Exception; use Throwable; -class CronManager +class JobManager { private $cronJobUtil; @@ -82,17 +83,19 @@ class CronManager protected $lastRunTimeFile = 'data/cache/application/cronLastRunTime.php'; - protected $config; + private $config; - protected $fileManager; + private $fileManager; - protected $entityManager; + private $entityManager; - protected $serviceFactory; + private $serviceFactory; - protected $injectableFactory; + private $injectableFactory; - protected $scheduledJob; + private $scheduledJobUtil; + + private $log; public function __construct( Config $config, @@ -100,14 +103,16 @@ class CronManager EntityManager $entityManager, ServiceFactory $serviceFactory, InjectableFactory $injectableFactory, - ScheduledJob $scheduledJob + ScheduledJob $scheduledJobUtil, + Log $log ) { $this->config = $config; $this->fileManager = $fileManager; $this->entityManager = $entityManager; $this->serviceFactory = $serviceFactory; $this->injectableFactory = $injectableFactory; - $this->scheduledJob = $scheduledJob; + $this->scheduledJobUtil = $scheduledJobUtil; + $this->log = $log; $this->cronJobUtil = new CronJob($this->config, $this->entityManager); @@ -118,26 +123,11 @@ class CronManager $this->useProcessPool = true; } else { - $GLOBALS['log']->warning("CronManager: useProcessPool requires pcntl and posix extensions."); + $this->log->warning("JobManager: useProcessPool requires pcntl and posix extensions."); } } } - protected function getScheduledJobUtil() - { - return $this->scheduledJob; - } - - protected function getCronJobUtil() - { - return $this->cronJobUtil; - } - - protected function getCronScheduledJobUtil() - { - return $this->cronScheduledJobUtil; - } - protected function getLastRunTime() { $lastRunData = $this->fileManager->getPhpContents($this->lastRunTimeFile); @@ -165,6 +155,7 @@ class CronManager { $currentTime = time(); $lastRunTime = $this->getLastRunTime(); + $cronMinInterval = $this->config->get('cronMinInterval', 0); if ($currentTime > ($lastRunTime + $cronMinInterval)) { @@ -174,47 +165,60 @@ class CronManager return false; } - protected function useProcessPool() + protected function useProcessPool() : bool { return $this->useProcessPool; } - public function setUseProcessPool(bool $useProcessPool) + public function setUseProcessPool(bool $useProcessPool) : void { $this->useProcessPool = $useProcessPool; } /** - * Run cron. + * Process jobs. Jobs will be created according scheduling. Then pending jobs will be processed. + * This method supposed to be called on every Cron run or loop iteration of the Daemon. */ - public function run() + public function process() : void { if (!$this->checkLastRunTime()) { - $GLOBALS['log']->info('CronManager: Stop cron running, too frequent execution.'); + $this->log->info('JobManager: Skip job processing. Too frequent execution.'); return; } $this->setLastRunTime(time()); - $this->getCronJobUtil()->markJobsFailed(); - $this->getCronJobUtil()->updateFailedJobAttempts(); + $this->cronJobUtil->markJobsFailed(); + $this->cronJobUtil->updateFailedJobAttempts(); + $this->createJobsFromScheduledJobs(); - $this->getCronJobUtil()->removePendingJobDuplicates(); + + $this->cronJobUtil->removePendingJobDuplicates(); $this->processPendingJobs(); } /** - * Run a portion of pending jobs. + * Process pending jobs from a specific queue. Jobs within a queue are processed one by one. */ - public function processPendingJobs($queue = null, $limit = null, bool $poolDisabled = false, bool $noLock = false) + public function processQueue(string $queue, int $limit) : void { + $this->processPendingJobs($queue, $limit, true, true); + } + + protected function processPendingJobs( + ?string $queue = null, + ?int $limit = null, + bool $poolDisabled = false, + bool $noLock = false + ) : void { + if (is_null($limit)) { $limit = intval($this->config->get('jobMaxPortion', 0)); } - $pendingJobList = $this->getCronJobUtil()->getPendingJobList($queue, $limit); + $pendingJobList = $this->cronJobUtil->getPendingJobList($queue, $limit); $useProcessPool = $this->useProcessPool(); @@ -240,7 +244,7 @@ class CronManager } } - protected function processPendingJob(JobEntity $job, $pool = null, bool $noLock = false) + protected function processPendingJob(JobEntity $job, $pool = null, bool $noLock = false) : void { $useProcessPool = (bool) $pool; @@ -257,9 +261,9 @@ class CronManager } } - if ($noLock || $this->getCronJobUtil()->isJobPending($job->id)) { + if ($noLock || $this->cronJobUtil->isJobPending($job->id)) { if ($job->get('scheduledJobId')) { - if ($this->getCronJobUtil()->isScheduledJobRunning( + if ($this->cronJobUtil->isScheduledJobRunning( $job->get('scheduledJobId'), $job->get('targetId'), $job->get('targetType')) ) { $skip = true; @@ -309,7 +313,7 @@ class CronManager return; } - $this->runJob($job); + $this->runJobInternal($job); } /** @@ -340,13 +344,20 @@ class CronManager $this->entityManager->saveEntity($job); - $this->runJob($job); + $this->runJobInternal($job); } /** * Run a specific job. + * + * @throws Throwable */ - public function runJob(JobEntity $job) + public function runJob(JobEntity $job) : void + { + $this->runJobInternal($job, true); + } + + protected function runJobInternal(JobEntity $job, bool $throwException = false) : void { $isSuccess = true; @@ -362,7 +373,8 @@ class CronManager else { $this->runService($job); } - } catch (Throwable $e) { + } + catch (Throwable $e) { $isSuccess = false; if ($e->getCode() === -1) { @@ -371,11 +383,15 @@ class CronManager $skipLog = true; } else { - $GLOBALS['log']->error( - 'CronManager: Failed job running, job ['. $job->id .']. Error Details: '. - $e->getMessage() .' at '. $e->getFile() . ':' . $e->getLine() + $this->log->error( + "JobManager: Failed job running, job '{$job->id}'. " . + $e->getMessage() . "; at " . $e->getFile() . ":" . $e->getLine() . "." ); } + + if ($throwException) { + throw new $e; + } } $status = $isSuccess ? self::SUCCESS : self::FAILED; @@ -389,16 +405,10 @@ class CronManager $this->entityManager->saveEntity($job); if ($job->get('scheduledJobId') && !$skipLog) { - $this->getCronScheduledJobUtil()->addLogRecord( + $this->cronScheduledJobUtil->addLogRecord( $job->get('scheduledJobId'), $status, null, $job->get('targetId'), $job->get('targetType') ); } - - if ($isSuccess) { - return true; - } - - return false; } protected function runScheduledJob(JobEntity $job) : void @@ -411,7 +421,7 @@ class CronManager ); } - $className = $this->getScheduledJobUtil()->getJobClassName($jobName); + $className = $this->scheduledJobUtil->getJobClassName($jobName); if (!$className) { throw new Error("No class name for job {$jobName}."); @@ -434,7 +444,7 @@ class CronManager $obj->run(); } - protected function runService(JobEntity $job) + protected function runService(JobEntity $job) : void { $serviceName = $job->get('serviceName'); @@ -467,7 +477,7 @@ class CronManager { $jobName = $job->get('job'); - $className = $this->getScheduledJobUtil()->getJobClassName($jobName); + $className = $this->scheduledJobUtil->getJobClassName($jobName); if (!$className) { throw new Error("No class name for job {$jobName}."); @@ -490,10 +500,10 @@ class CronManager $obj->run(); } - protected function createJobsFromScheduledJobs() + protected function createJobsFromScheduledJobs() : void { - $activeScheduledJobList = $this->getCronScheduledJobUtil()->getActiveScheduledJobList(); - $runningScheduledJobIdList = $this->getCronJobUtil()->getRunningScheduledJobIdList(); + $activeScheduledJobList = $this->cronScheduledJobUtil->getActiveScheduledJobList(); + $runningScheduledJobIdList = $this->cronJobUtil->getRunningScheduledJobIdList(); foreach ($activeScheduledJobList as $scheduledJob) { $scheduling = $scheduledJob->get('scheduling'); @@ -508,8 +518,8 @@ class CronManager $cronExpression = CronExpression::factory($scheduling); } catch (Exception $e) { - $GLOBALS['log']->error( - 'CronManager (ScheduledJob ' . $scheduledJob->id . '): Scheduling string error - ' . + $this->log->error( + 'JobManager (ScheduledJob ' . $scheduledJob->id . '): Scheduling string error - ' . $e->getMessage() . '.' ); @@ -520,22 +530,22 @@ class CronManager $nextDate = $cronExpression->getNextRunDate()->format('Y-m-d H:i:s'); } catch (Exception $e) { - $GLOBALS['log']->error( - 'CronManager (ScheduledJob '. $scheduledJob->id . '): ' . + $this->log->error( + 'JobManager (ScheduledJob '. $scheduledJob->id . '): ' . 'Unsupported CRON expression ' . $scheduling . '.' ); continue; } - $jobAlreadyExists = $this->getCronJobUtil()->hasScheduledJobOnMinute($scheduledJob->id, $nextDate); + $jobAlreadyExists = $this->cronJobUtil->hasScheduledJobOnMinute($scheduledJob->id, $nextDate); if ($jobAlreadyExists) { continue; } } - $className = $this->getScheduledJobUtil()->getJobClassName($scheduledJob->get('job')); + $className = $this->scheduledJobUtil->getJobClassName($scheduledJob->get('job')); if ($className) { if (method_exists($className, 'prepare')) { @@ -551,7 +561,7 @@ class CronManager continue; } - $pendingCount = $this->getCronJobUtil()->getPendingCountByScheduledJobId($scheduledJob->id); + $pendingCount = $this->cronJobUtil->getPendingCountByScheduledJobId($scheduledJob->id); if ($asSoonAsPossible) { if ($pendingCount > 0) { diff --git a/application/Espo/Core/Utils/Cron/Job.php b/application/Espo/Core/Utils/Cron/Job.php index 925c1dd025..be1eb639c4 100644 --- a/application/Espo/Core/Utils/Cron/Job.php +++ b/application/Espo/Core/Utils/Cron/Job.php @@ -30,7 +30,7 @@ namespace Espo\Core\Utils\Cron; use Espo\Core\{ - CronManager, + Job\JobManager, Utils\Config, ORM\EntityManager, Utils\System, @@ -73,7 +73,7 @@ class Job return false; } - return $job->get('status') === CronManager::PENDING; + return $job->get('status') === JobManager::PENDING; } public function getPendingJobList($queue = null, $limit = 0) @@ -92,7 +92,7 @@ class Job 'data', ], 'whereClause' => [ - 'status' => CronManager::PENDING, + 'status' => JobManager::PENDING, 'executeTime<=' => date('Y-m-d H:i:s'), 'queue' => $queue, ], @@ -113,7 +113,7 @@ class Job $where = [ 'scheduledJobId' => $scheduledJobId, - 'status' => [CronManager::RUNNING, CronManager::READY], + 'status' => [JobManager::RUNNING, JobManager::READY], ]; if ($targetId && $targetType) { @@ -173,7 +173,7 @@ class Job ->getRepository('Job') ->where([ 'scheduledJobId' => $scheduledJobId, - 'status' => CronManager::PENDING, + 'status' => JobManager::PENDING, ]) ->count(); @@ -209,7 +209,7 @@ class Job 'startedAt' ]) ->where([ - 'status' => CronManager::RUNNING, + 'status' => JobManager::RUNNING, 'startedAt<' => $dateTimeThreshold, ]) ->find(); @@ -244,7 +244,7 @@ class Job 'startedAt', ]) ->where([ - 'status' => CronManager::READY, + 'status' => JobManager::READY, 'startedAt<' => $dateTimeThreshold, ]) ->find(); @@ -276,7 +276,7 @@ class Job 'startedAt' ]) ->where([ - 'status' => CronManager::RUNNING, + 'status' => JobManager::RUNNING, 'executeTime<' => $dateTimeThreshold, ]) ->find(); @@ -310,7 +310,7 @@ class Job ->update() ->in('Job') ->set([ - 'status' => CronManager::FAILED, + 'status' => JobManager::FAILED, 'attempts' => 0, ]) ->where([ @@ -327,7 +327,7 @@ class Job $this->cronScheduledJob->addLogRecord( $job->get('scheduledJobId'), - CronManager::FAILED, + JobManager::FAILED, $job->get('startedAt'), $job->get('targetId'), $job->get('targetType') @@ -345,7 +345,7 @@ class Job ->select(['scheduledJobId']) ->where([ 'scheduledJobId!=' => null, - 'status' => CronManager::PENDING, + 'status' => JobManager::PENDING, 'executeTime<=' => date('Y-m-d H:i:s'), 'targetId' => null, ]) @@ -372,7 +372,7 @@ class Job ->select(['id']) ->where([ 'scheduledJobId' => $scheduledJobId, - 'status' => CronManager::PENDING, + 'status' => JobManager::PENDING, ]) ->order('executeTime') ->limit(0, 1000) @@ -408,7 +408,7 @@ class Job $jobList = $this->entityManager->getRepository('Job') ->select(['id', 'attempts', 'failedAttempts']) ->where([ - 'status' => CronManager::FAILED, + 'status' => JobManager::FAILED, 'executeTime<=' => date('Y-m-d H:i:s'), 'attempts>' => 0, ]) @@ -422,7 +422,7 @@ class Job $failedAttempts = $failedAttempts + 1; $job->set([ - 'status' => CronManager::PENDING, + 'status' => JobManager::PENDING, 'attempts' => $attempts, 'failedAttempts' => $failedAttempts, ]); diff --git a/application/Espo/Jobs/CheckEmailAccounts.php b/application/Espo/Jobs/CheckEmailAccounts.php index fc4f32ff5c..13d2b9724b 100644 --- a/application/Espo/Jobs/CheckEmailAccounts.php +++ b/application/Espo/Jobs/CheckEmailAccounts.php @@ -32,7 +32,7 @@ namespace Espo\Jobs; use Espo\Core\Exceptions\Error; use Espo\Core\{ - CronManager, + Job\JobManager, ServiceFactory, ORM\EntityManager, Jobs\JobTargeted, @@ -97,7 +97,7 @@ class CheckEmailAccounts implements JobTargeted ->getRepository('Job') ->where([ 'scheduledJobId' => $scheduledJob->id, - 'status' => [CronManager::RUNNING, CronManager::READY], + 'status' => [JobManager::RUNNING, JobManager::READY], 'targetType' => 'EmailAccount', 'targetId' => $entity->id, ]) @@ -111,7 +111,7 @@ class CheckEmailAccounts implements JobTargeted ->getRepository('Job') ->where([ 'scheduledJobId' => $scheduledJob->id, - 'status' => CronManager::PENDING, + 'status' => JobManager::PENDING, 'targetType' => 'EmailAccount', 'targetId' => $entity->id, ]) diff --git a/application/Espo/Jobs/CheckInboundEmails.php b/application/Espo/Jobs/CheckInboundEmails.php index 18ce11e7ff..a89303e533 100644 --- a/application/Espo/Jobs/CheckInboundEmails.php +++ b/application/Espo/Jobs/CheckInboundEmails.php @@ -32,7 +32,7 @@ namespace Espo\Jobs; use Espo\Core\Exceptions\Error; use Espo\Core\{ - CronManager, + Job\JobManager, ServiceFactory, ORM\EntityManager, Jobs\JobTargeted, @@ -95,7 +95,7 @@ class CheckInboundEmails implements JobTargeted ->getRepository('Job') ->where([ 'scheduledJobId' => $scheduledJob->id, - 'status' => [CronManager::RUNNING, CronManager::READY], + 'status' => [JobManager::RUNNING, JobManager::READY], 'targetType' => 'InboundEmail', 'targetId' => $entity->id, ]) @@ -109,7 +109,7 @@ class CheckInboundEmails implements JobTargeted ->getRepository('Job') ->where([ 'scheduledJobId' => $scheduledJob->id, - 'status' => CronManager::PENDING, + 'status' => JobManager::PENDING, 'targetType' => 'InboundEmail', 'targetId' => $entity->id, ]) diff --git a/application/Espo/Jobs/ProcessJobQueueE0.php b/application/Espo/Jobs/ProcessJobQueueE0.php index 7737aee992..2f1c98e1c1 100644 --- a/application/Espo/Jobs/ProcessJobQueueE0.php +++ b/application/Espo/Jobs/ProcessJobQueueE0.php @@ -30,19 +30,20 @@ namespace Espo\Jobs; use Espo\Core\{ - CronManager, + Job\JobManager, Utils\Config, Jobs\Job, }; class ProcessJobQueueE0 implements Job { - protected $cronManager; - protected $config; + private $jobManager; - public function __construct(CronManager $cronManager, Config $config) + private $config; + + public function __construct(JobManager $jobManager, Config $config) { - $this->cronManager = $cronManager; + $this->jobManager = $jobManager; $this->config = $config; } @@ -50,6 +51,6 @@ class ProcessJobQueueE0 implements Job { $limit = $this->config->get('jobE0MaxPortion', 100); - $this->cronManager->processPendingJobs('e0', $limit, true, true); + $this->jobManager->processQueue('e0', $limit); } } diff --git a/application/Espo/Jobs/ProcessJobQueueQ0.php b/application/Espo/Jobs/ProcessJobQueueQ0.php index 7b4c809ab1..ee487e8aa5 100644 --- a/application/Espo/Jobs/ProcessJobQueueQ0.php +++ b/application/Espo/Jobs/ProcessJobQueueQ0.php @@ -30,19 +30,20 @@ namespace Espo\Jobs; use Espo\Core\{ - CronManager, + Job\JobManager, Utils\Config, Jobs\Job, }; class ProcessJobQueueQ0 implements Job { - protected $cronManager; - protected $config; + private $jobManager; - public function __construct(CronManager $cronManager, Config $config) + private $config; + + public function __construct(JobManager $jobManager, Config $config) { - $this->cronManager = $cronManager; + $this->jobManager = $jobManager; $this->config = $config; } @@ -50,6 +51,6 @@ class ProcessJobQueueQ0 implements Job { $limit = $this->config->get('jobQ0MaxPortion', 200); - $this->cronManager->processPendingJobs('q0', $limit, true, true); + $this->jobManager->processQueue('q0', $limit); } } diff --git a/application/Espo/Jobs/ProcessJobQueueQ1.php b/application/Espo/Jobs/ProcessJobQueueQ1.php index ae44ecaa82..bfa80dcfca 100644 --- a/application/Espo/Jobs/ProcessJobQueueQ1.php +++ b/application/Espo/Jobs/ProcessJobQueueQ1.php @@ -30,19 +30,20 @@ namespace Espo\Jobs; use Espo\Core\{ - CronManager, + Job\JobManager, Utils\Config, Jobs\Job, }; class ProcessJobQueueQ1 implements Job { - protected $cronManager; - protected $config; + private $jobManager; - public function __construct(CronManager $cronManager, Config $config) + private $config; + + public function __construct(JobManager $jobManager, Config $config) { - $this->cronManager = $cronManager; + $this->jobManager = $jobManager; $this->config = $config; } @@ -50,6 +51,6 @@ class ProcessJobQueueQ1 implements Job { $limit = $this->config->get('jobQ1MaxPortion', 500); - $this->cronManager->processPendingJobs('q1', $limit, true, true); + $this->jobManager->processQueue('q1', $limit); } } diff --git a/application/Espo/Repositories/ScheduledJob.php b/application/Espo/Repositories/ScheduledJob.php index 6937647107..f026314eaa 100644 --- a/application/Espo/Repositories/ScheduledJob.php +++ b/application/Espo/Repositories/ScheduledJob.php @@ -31,7 +31,7 @@ namespace Espo\Repositories; use Espo\ORM\Entity; -use Espo\Core\CronManager; +use Espo\Core\Job\JobManager; class ScheduledJob extends \Espo\Core\Repositories\Database { @@ -46,10 +46,13 @@ class ScheduledJob extends \Espo\Core\Repositories\Database parent::afterSave($entity, $options); if ($entity->isAttributeChanged('scheduling')) { - $jobList = $this->getEntityManager()->getRepository('Job')->where([ - 'scheduledJobId' => $entity->id, - 'status' => CronManager::PENDING, - ])->find(); + $jobList = $this->getEntityManager() + ->getRepository('Job') + ->where([ + 'scheduledJobId' => $entity->id, + 'status' => JobManager::PENDING, + ]) + ->find(); foreach ($jobList as $job) { $this->getEntityManager()->removeEntity($job); diff --git a/application/Espo/Resources/metadata/app/containerServices.json b/application/Espo/Resources/metadata/app/containerServices.json index 4bfea26ed3..731ac12d28 100644 --- a/application/Espo/Resources/metadata/app/containerServices.json +++ b/application/Espo/Resources/metadata/app/containerServices.json @@ -17,8 +17,8 @@ "fileStorageManager": { "className": "Espo\\Core\\FileStorage\\Manager" }, - "cronManager": { - "className": "Espo\\Core\\CronManager" + "jobManager": { + "className": "Espo\\Core\\Job\\JobManager" }, "webSocketSubmission": { "className": "Espo\\Core\\WebSocket\\Submission" diff --git a/tests/unit/Espo/Core/CronManagerTest.php b/tests/unit/Espo/Core/Job/JobManagerTest.php similarity index 55% rename from tests/unit/Espo/Core/CronManagerTest.php rename to tests/unit/Espo/Core/Job/JobManagerTest.php index 6e7fb51478..c10e21595c 100644 --- a/tests/unit/Espo/Core/CronManagerTest.php +++ b/tests/unit/Espo/Core/Job/JobManagerTest.php @@ -27,93 +27,113 @@ * these Appropriate Legal Notices must retain the display of the "EspoCRM" word. ************************************************************************/ -namespace tests\unit\Espo\Core; +namespace tests\unit\Espo\Core\Job; use tests\unit\ReflectionHelper; -use Espo\Core\CronManager; +use Espo\Core\{ + Job\JobManager, + ServiceFactory, + Utils\Config, + Utils\File\Manager as FileManager, + Utils\ScheduledJob, + ORM\EntityManager, + InjectableFactory, + Utils\Log, +}; -class CronManagerTest extends \PHPUnit\Framework\TestCase +class JobManagerTest extends \PHPUnit\Framework\TestCase { - protected $object; - - protected $objects; - - protected $filesPath= 'tests/unit/testData/EntryPoints'; - protected function setUp() : void { - $this->objects['serviceFactory'] = $this->getMockBuilder('Espo\\Core\\ServiceFactory')->disableOriginalConstructor()->getMock(); - $this->objects['config'] = $this->getMockBuilder('Espo\\Core\\Utils\\Config')->disableOriginalConstructor()->getMock(); - $this->objects['fileManager'] = $this->getMockBuilder('Espo\\Core\\Utils\\File\\Manager')->disableOriginalConstructor()->getMock(); - $this->objects['scheduledJob'] = $this->getMockBuilder('Espo\\Core\\Utils\\ScheduledJob')->disableOriginalConstructor()->getMock(); - $this->objects['entityManager'] = $this->getMockBuilder('Espo\\Core\\ORM\\EntityManager')->disableOriginalConstructor()->getMock(); + $this->serviceFactory = $this->getMockBuilder(ServiceFactory::class) + ->disableOriginalConstructor()->getMock(); - $this->objects['injectableFactory'] = $this->getMockBuilder('Espo\\Core\\InjectableFactory')->disableOriginalConstructor()->getMock(); + $this->config = $this->getMockBuilder(Config::class) + ->disableOriginalConstructor()->getMock(); - $this->object = new CronManager( - $this->objects['config'], - $this->objects['fileManager'], - $this->objects['entityManager'], - $this->objects['serviceFactory'], - $this->objects['injectableFactory'], - $this->objects['scheduledJob'] + $this->fileManager = $this->getMockBuilder(FileManager::class) + ->disableOriginalConstructor()->getMock(); + + $this->scheduledJob = $this->getMockBuilder(ScheduledJob::class) + ->disableOriginalConstructor()->getMock(); + + $this->entityManager = $this->getMockBuilder(EntityManager::class) + ->disableOriginalConstructor()->getMock(); + + $this->injectableFactory = $this->getMockBuilder(InjectableFactory::class) + ->disableOriginalConstructor()->getMock(); + + $this->log = $this->createMock(Log::class); + + $this->manager = new JobManager( + $this->config, + $this->fileManager, + $this->entityManager, + $this->serviceFactory, + $this->injectableFactory, + $this->scheduledJob, + $this->log ); - $this->reflection = new ReflectionHelper($this->object); + $this->reflection = new ReflectionHelper($this->manager); } protected function tearDown() : void { - $this->object = NULL; + $this->manager = NULL; } - function testCheckLastRunTimeFileDoesnotExist() + public function testCheckLastRunTimeFileDoesnotExist() { - $this->objects['fileManager'] + $this->fileManager ->expects($this->once()) ->method('getPhpContents') ->will($this->returnValue(false)); - $this->objects['config'] + $this->config ->expects($this->any()) ->method('get') ->will($this->returnValue(50)); - $this->assertTrue( $this->reflection->invokeMethod('checkLastRunTime', array())); + $this->assertTrue($this->reflection->invokeMethod('checkLastRunTime', [])); } public function testCheckLastRunTime() { - $this->objects['fileManager'] + $this->fileManager ->expects($this->once()) ->method('getPhpContents') - ->will($this->returnValue(array( + ->will( + $this->returnValue([ 'time' => time() - 60, - ))); + ]) + ); - $this->objects['config'] + $this->config ->expects($this->any()) ->method('get') ->will($this->returnValue(50)); - $this->assertTrue( $this->reflection->invokeMethod('checkLastRunTime', array())); + $this->assertTrue( $this->reflection->invokeMethod('checkLastRunTime', [])); } public function testCheckLastRunTimeTooFrequency() { - $this->objects['fileManager'] + $this->fileManager ->expects($this->once()) ->method('getPhpContents') - ->will($this->returnValue(array( + ->will( + $this->returnValue([ 'time' => time() - 49, - ))); + ]) + ); - $this->objects['config'] + $this->config ->expects($this->exactly(1)) ->method('get') ->will($this->returnValue(50)); - $this->assertFalse($this->reflection->invokeMethod('checkLastRunTime', array())); + $this->assertFalse($this->reflection->invokeMethod('checkLastRunTime', [])); } }