Skip to content

Commit

Permalink
Add package tests for JobWithChildJobs (#103)
Browse files Browse the repository at this point in the history
* Add package tests for JobWithChildJobs

* Add documentation for JobWithChildJobs factory method

* Fixed code style
  • Loading branch information
yann-eugone authored Sep 21, 2023
1 parent 6155350 commit 06ced2c
Show file tree
Hide file tree
Showing 2 changed files with 142 additions and 0 deletions.
20 changes: 20 additions & 0 deletions src/batch/src/Job/JobWithChildJobs.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@

namespace Yokai\Batch\Job;

use Psr\EventDispatcher\EventDispatcherInterface;
use Yokai\Batch\BatchStatus;
use Yokai\Batch\JobExecution;
use Yokai\Batch\Registry\JobRegistry;
use Yokai\Batch\Storage\JobExecutionStorageInterface;

/**
Expand All @@ -26,6 +28,24 @@ public function __construct(
) {
}

/**
* When creating {@see JobWithChildJobs}, you might prefer that child jobs are not available from the outside.
* You can do it by yourself, but this method will do it for you in one line.
*
* @param array<string, JobInterface> $children
*/
public static function withAnonymousChildren(
array $children,
JobExecutionStorageInterface $executionStorage,
EventDispatcherInterface $eventDispatcher = null,
): self {
return new self(
$executionStorage,
new JobExecutor(JobRegistry::fromJobArray($children), $executionStorage, $eventDispatcher),
\array_keys($children),
);
}

final public function execute(JobExecution $jobExecution): void
{
$logger = $jobExecution->getLogger();
Expand Down
122 changes: 122 additions & 0 deletions src/batch/tests/Job/JobWithChildJobsTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
<?php

declare(strict_types=1);

namespace Yokai\Batch\Tests\Job;

use PHPUnit\Framework\TestCase;
use Yokai\Batch\BatchStatus;
use Yokai\Batch\Job\JobExecutor;
use Yokai\Batch\Job\JobInterface;
use Yokai\Batch\Job\JobWithChildJobs;
use Yokai\Batch\JobExecution;
use Yokai\Batch\Registry\JobRegistry;
use Yokai\Batch\Test\Storage\InMemoryJobExecutionStorage;

class JobWithChildJobsTest extends TestCase
{
private InMemoryJobExecutionStorage $storage;

protected function setUp(): void
{
$this->storage = new InMemoryJobExecutionStorage();
}

public function test(): void
{
$execution = $this->execute([
'import' => new class() implements JobInterface {
public function execute(JobExecution $jobExecution): void
{
$jobExecution->getSummary()->set('executed', true);
}
},
'report' => new class() implements JobInterface {
public function execute(JobExecution $jobExecution): void
{
$jobExecution->getSummary()->set('executed', true);
}
},
]);

self::assertStatusSame(BatchStatus::COMPLETED, $execution);
self::assertCount(2, $execution->getChildExecutions());
self::assertNotNull($import = $execution->getChildExecution('import'));
self::assertStatusSame(BatchStatus::COMPLETED, $import);
self::assertTrue($import->getSummary()->get('executed'));
self::assertLogsContains('DEBUG: Starting child job {"job":"import"}', $execution);
self::assertLogsContains('INFO: Child job executed successfully {"job":"import"}', $execution);
self::assertNotNull($report = $execution->getChildExecution('report'));
self::assertStatusSame(BatchStatus::COMPLETED, $report);
self::assertTrue($report->getSummary()->get('executed'));
self::assertLogsContains('DEBUG: Starting child job {"job":"report"}', $execution);
self::assertLogsContains('INFO: Child job executed successfully {"job":"report"}', $execution);
}

public function testNoChildren(): void
{
$execution = $this->execute([
]);

self::assertStatusSame(BatchStatus::COMPLETED, $execution);
self::assertCount(0, $execution->getChildExecutions());
self::assertLogsNotContains('Child job executed successfully', $execution);
self::assertLogsNotContains('Child job did not executed successfully', $execution);
}

public function testFirstChildFailing(): void
{
$execution = $this->execute([
'import' => new class() implements JobInterface {
public function execute(JobExecution $jobExecution): void
{
throw new \RuntimeException('Expected failure');
}
},
'report' => new class() implements JobInterface {
public function execute(JobExecution $jobExecution): void
{
throw new \LogicException('Should never be executed');
}
},
]);

self::assertStatusSame(BatchStatus::FAILED, $execution);
self::assertCount(2, $execution->getChildExecutions());
self::assertNotNull($import = $execution->getChildExecution('import'));
self::assertStatusSame(BatchStatus::FAILED, $import);
self::assertLogsContains('ERROR: Child job did not executed successfully {"job":"import"', $execution);
self::assertNotNull($report = $execution->getChildExecution('report'));
self::assertStatusSame(BatchStatus::ABANDONED, $report);
self::assertLogsContains('WARNING: Child job will not be executed {"job":"report"}', $execution);
}

/**
* @param array<string, JobInterface> $children
*/
private function execute(array $children): JobExecution
{
(new JobExecutor(
JobRegistry::fromJobArray(['test' => JobWithChildJobs::withAnonymousChildren($children, $this->storage)]),
$this->storage,
null,
))->execute($execution = JobExecution::createRoot('650c0f7907774', 'test'));

return $execution;
}

private static function assertStatusSame(int $expected, JobExecution $execution): void
{
self::assertSame($expected, $execution->getStatus()->getValue());
}

private static function assertLogsContains(string $expected, JobExecution $execution): void
{
self::assertStringContainsString($expected, (string)$execution->getLogs());
}

private static function assertLogsNotContains(string $expected, JobExecution $execution): void
{
self::assertStringNotContainsString($expected, (string)$execution->getLogs());
}
}

0 comments on commit 06ced2c

Please sign in to comment.