mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-06-07 18:44:08 +00:00
When a cronjob is executed, it may return an array of data. This data will be passed as parameter on the next execution
204 lines
6.6 KiB
PHP
204 lines
6.6 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
/*
|
|
* Chill is a software for social workers
|
|
*
|
|
* For the full copyright and license information, please view
|
|
* the LICENSE file that was distributed with this source code.
|
|
*/
|
|
|
|
namespace Chill\MainBundle\Tests\Cron;
|
|
|
|
use ArrayObject;
|
|
use Chill\MainBundle\Cron\CronJobInterface;
|
|
use Chill\MainBundle\Cron\CronManager;
|
|
use Chill\MainBundle\Entity\CronJobExecution;
|
|
use Chill\MainBundle\Repository\CronJobExecutionRepositoryInterface;
|
|
use DateTimeImmutable;
|
|
use Doctrine\ORM\AbstractQuery;
|
|
use Doctrine\ORM\EntityManagerInterface;
|
|
use PHPUnit\Framework\TestCase;
|
|
use Prophecy\Argument;
|
|
use Prophecy\PhpUnit\ProphecyTrait;
|
|
use Psr\Log\NullLogger;
|
|
use function array_key_exists;
|
|
|
|
/**
|
|
* @internal
|
|
* @coversNothing
|
|
*/
|
|
final class CronManagerTest extends TestCase
|
|
{
|
|
use ProphecyTrait;
|
|
|
|
public function testScheduleMostOldExecutedJob()
|
|
{
|
|
$jobOld1 = new JobCanRun('k');
|
|
$jobOld2 = new JobCanRun('l');
|
|
$jobToExecute = $this->prophesize(CronJobInterface::class);
|
|
$jobToExecute->getKey()->willReturn('to-exec');
|
|
$jobToExecute->canRun(Argument::type(CronJobExecution::class))->willReturn(true);
|
|
$jobToExecute->run([])->shouldBeCalled();
|
|
|
|
$executions = [
|
|
['key' => $jobOld1->getKey(), 'lastStart' => new DateTimeImmutable('yesterday'), 'lastEnd' => new DateTimeImmutable('1 hours ago'), 'lastStatus' => CronJobExecution::SUCCESS],
|
|
['key' => $jobOld2->getKey(), 'lastStart' => new DateTimeImmutable('3 days ago'), 'lastEnd' => new DateTimeImmutable('36 hours ago'), 'lastStatus' => CronJobExecution::SUCCESS],
|
|
// this is the oldest one
|
|
['key' => 'to-exec', 'lastStart' => new DateTimeImmutable('1 month ago'), 'lastEnd' => new DateTimeImmutable('10 days ago'), 'lastStatus' => CronJobExecution::SUCCESS],
|
|
];
|
|
|
|
$cronManager = new CronManager(
|
|
$this->buildCronJobExecutionRepository($executions),
|
|
$this->buildEntityManager([]),
|
|
new ArrayObject([$jobOld1, $jobToExecute->reveal(), $jobOld2]),
|
|
new NullLogger()
|
|
);
|
|
|
|
$cronManager->run();
|
|
}
|
|
|
|
public function testSelectNewJobFirstAndNewJobIsFirstInList(): void
|
|
{
|
|
$jobAlreadyExecuted = new JobCanRun('k');
|
|
$jobNeverExecuted = $this->prophesize(CronJobInterface::class);
|
|
$jobNeverExecuted->getKey()->willReturn('never-executed');
|
|
$jobNeverExecuted->run([])->shouldBeCalled();
|
|
$jobNeverExecuted->canRun(null)->willReturn(true);
|
|
|
|
$executions = [
|
|
['key' => $jobAlreadyExecuted->getKey(), 'lastStart' => new DateTimeImmutable('yesterday'), 'lastEnd' => new DateTimeImmutable('1 hours ago'), 'lastStatus' => CronJobExecution::SUCCESS],
|
|
];
|
|
|
|
$cronManager = new CronManager(
|
|
$this->buildCronJobExecutionRepository($executions),
|
|
$this->buildEntityManager([Argument::type(CronJobExecution::class)]),
|
|
new ArrayObject([$jobNeverExecuted->reveal(), $jobAlreadyExecuted]),
|
|
new NullLogger()
|
|
);
|
|
|
|
$cronManager->run();
|
|
}
|
|
|
|
public function testSelectNewJobFirstAndNewJobIsLastInList(): void
|
|
{
|
|
$jobAlreadyExecuted = new JobCanRun('k');
|
|
$jobNeverExecuted = $this->prophesize(CronJobInterface::class);
|
|
$jobNeverExecuted->getKey()->willReturn('never-executed');
|
|
$jobNeverExecuted->run([])->shouldBeCalled();
|
|
$jobNeverExecuted->canRun(null)->willReturn(true);
|
|
|
|
$executions = [
|
|
['key' => $jobAlreadyExecuted->getKey(), 'lastStart' => new DateTimeImmutable('yesterday'), 'lastEnd' => new DateTimeImmutable('1 hours ago'), 'lastStatus' => CronJobExecution::SUCCESS],
|
|
];
|
|
|
|
$cronManager = new CronManager(
|
|
$this->buildCronJobExecutionRepository($executions),
|
|
$this->buildEntityManager([Argument::type(CronJobExecution::class)]),
|
|
new ArrayObject([$jobAlreadyExecuted, $jobNeverExecuted->reveal()]),
|
|
new NullLogger()
|
|
);
|
|
|
|
$cronManager->run();
|
|
}
|
|
|
|
/**
|
|
* @param array<array{key: string, ?lastEnd: ?DateTimeImmutable, lastStart: DateTimeImmutable, ?lastStatus: ?int}> $executions
|
|
*/
|
|
private function buildCronJobExecutionRepository(array $executions): CronJobExecutionRepositoryInterface
|
|
{
|
|
$repository = $this->prophesize(CronJobExecutionRepositoryInterface::class);
|
|
|
|
$repository->findAll()->willReturn(
|
|
array_map(
|
|
static function (array $exec): CronJobExecution {
|
|
$e = new CronJobExecution($exec['key']);
|
|
$e->setLastStart($exec['lastStart']);
|
|
|
|
if (array_key_exists('lastEnd', $exec)) {
|
|
$e->setLastEnd($exec['lastEnd']);
|
|
}
|
|
|
|
if (array_key_exists('lastStatus', $exec)) {
|
|
$e->setLastStatus($exec['lastStatus']);
|
|
}
|
|
|
|
return $e;
|
|
},
|
|
$executions
|
|
)
|
|
);
|
|
|
|
return $repository->reveal();
|
|
}
|
|
|
|
private function buildEntityManager(array $persistArgsShouldBeCalled = []): EntityManagerInterface
|
|
{
|
|
$em = $this->prophesize(EntityManagerInterface::class);
|
|
|
|
if ([] === $persistArgsShouldBeCalled) {
|
|
$em->persist(Argument::any())->shouldNotBeCalled();
|
|
} else {
|
|
foreach ($persistArgsShouldBeCalled as $arg) {
|
|
$em->persist($arg)->shouldBeCalled();
|
|
}
|
|
$em->flush()->shouldBeCalled();
|
|
}
|
|
|
|
// other methods
|
|
$em->clear()->shouldBeCalled();
|
|
|
|
$query = $this->prophesize(AbstractQuery::class);
|
|
$query->setParameters(Argument::type('array'))->willReturn($query->reveal());
|
|
$query->execute()->shouldBeCalled();
|
|
|
|
$em->createQuery(Argument::type('string'))->willReturn($query->reveal());
|
|
|
|
return $em->reveal();
|
|
}
|
|
}
|
|
|
|
class JobCanRun implements CronJobInterface
|
|
{
|
|
private string $key;
|
|
|
|
public function __construct(string $key)
|
|
{
|
|
$this->key = $key;
|
|
}
|
|
|
|
public function canRun(?CronJobExecution $cronJobExecution): bool
|
|
{
|
|
return true;
|
|
}
|
|
|
|
public function getKey(): string
|
|
{
|
|
return $this->key;
|
|
}
|
|
|
|
public function run(array $lastExecutionData): null|array
|
|
{
|
|
return null;
|
|
}
|
|
}
|
|
|
|
class JobCannotRun implements CronJobInterface
|
|
{
|
|
public function canRun(?CronJobExecution $cronJobExecution): bool
|
|
{
|
|
return false;
|
|
}
|
|
|
|
public function getKey(): string
|
|
{
|
|
return 'job-b';
|
|
}
|
|
|
|
public function run(array $lastExecutionData): null|array
|
|
{
|
|
return null;
|
|
}
|
|
}
|