diff --git a/src/Plugins/Shard.php b/src/Plugins/Shard.php index f6cb3ac1..e47920d4 100644 --- a/src/Plugins/Shard.php +++ b/src/Plugins/Shard.php @@ -50,6 +50,11 @@ final class Shard implements AddsOutput, HandlesArguments, Terminable */ private static bool $timeBalanced = false; + /** + * Whether the shards.json file is outdated. + */ + private static bool $shardsOutdated = false; + /** * Collected timings from workers or subscribers. * @@ -110,15 +115,18 @@ final class Shard implements AddsOutput, HandlesArguments, Terminable $timings = $this->loadShardsFile(); if ($timings !== null) { - $missingTests = array_diff($tests, array_keys($timings)); + $knownTests = array_values(array_filter($tests, fn (string $test): bool => isset($timings[$test]))); + $newTests = array_values(array_diff($tests, $knownTests)); - if ($missingTests !== []) { - throw new InvalidOption('The [tests/.pest/shards.json] file is out of date. Run [--update-shards] to update it.'); + $partitions = $this->partitionByTime($knownTests, $timings, $total); + + foreach ($newTests as $i => $test) { + $partitions[$i % $total][] = $test; } - $partitions = $this->partitionByTime($tests, $timings, $total); $testsToRun = $partitions[$index - 1] ?? []; self::$timeBalanced = true; + self::$shardsOutdated = $newTests !== []; } else { $testsToRun = (array_chunk($tests, max(1, (int) ceil(count($tests) / $total))))[$index - 1] ?? []; } @@ -250,6 +258,10 @@ final class Shard implements AddsOutput, HandlesArguments, Terminable $suffix, )); + if (self::$shardsOutdated) { + $this->output->writeln(' WARN The [tests/.pest/shards.json] file is out of date. Run [--update-shards] to update it.'); + } + return $exitCode; } diff --git a/tests/Arch.php b/tests/Arch.php index 40bd9b89..d0565216 100644 --- a/tests/Arch.php +++ b/tests/Arch.php @@ -19,6 +19,7 @@ arch()->preset()->security()->ignoring([ 'exec', 'md5', 'unserialize', + 'uniqid', 'extract', 'assert', ]);