mirror of
https://github.com/karatektus/pl_mail.git
synced 2026-10-25 01:54:10 +00:00
Give the PHP time limit back after every test (#89)
A streaming controller's set_time_limit() outlived its test in the single PHPUnit process and killed slower runs part-way. A PHPUnit extension resets it after every test. Co-authored-by: pmdevelopment <4947485+pmdevelopment@users.noreply.github.com>
This commit is contained in:
1 parent
280f58b7b5
commit
55a6d67a48
3 files changed
+82
No files matched your search
@@ -53,5 +53,8 @@
|
|||||||
</source>
|
</source>
|
||||||
|
|
||||||
<extensions>
|
<extensions>
|
||||||
|
<!-- The streaming controllers call set_time_limit(), and in one
|
||||||
|
PHPUnit process that limit outlives their test. See the class. -->
|
||||||
|
<bootstrap class="App\Tests\Support\PhpUnit\ResetTimeLimitExtension"/>
|
||||||
</extensions>
|
</extensions>
|
||||||
</phpunit>
|
</phpunit>
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace App\Tests\Support\PhpUnit;
|
||||||
|
|
||||||
|
use PHPUnit\Event\Test\Finished;
|
||||||
|
use PHPUnit\Event\Test\FinishedSubscriber;
|
||||||
|
use PHPUnit\Runner\Extension\Extension;
|
||||||
|
use PHPUnit\Runner\Extension\Facade;
|
||||||
|
use PHPUnit\Runner\Extension\ParameterCollection;
|
||||||
|
use PHPUnit\TextUI\Configuration\Configuration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gives the time limit back after every test.
|
||||||
|
*
|
||||||
|
* Four controllers stream for longer than PHP's default allows and call
|
||||||
|
* set_time_limit() to say so — the JMAP event source, the thread summary, the
|
||||||
|
* compose assistant and the AI warm-up. In a web request that is right: the
|
||||||
|
* limit dies with the request. In the suite it does not, because every test
|
||||||
|
* runs in the one PHPUnit process, and a limit set by a controller test is
|
||||||
|
* still counting for every test after it. On a fast machine the rest of the
|
||||||
|
* suite finished inside it; on a slower one the run died part-way with
|
||||||
|
* "Maximum execution time of 300 seconds exceeded", in whichever unrelated
|
||||||
|
* test happened to be running — CalendarPullerTest one time, GraphFolderMoveTest
|
||||||
|
* the next — and passed again when that test was run on its own.
|
||||||
|
*
|
||||||
|
* In the suite rather than in the controllers: the four calls are correct, and
|
||||||
|
* a seam in production code to hide them from tests would be four places to
|
||||||
|
* get wrong for the sake of one place that is. ResetTimeLimitExtensionTest
|
||||||
|
* holds it.
|
||||||
|
*/
|
||||||
|
final class ResetTimeLimitExtension implements Extension
|
||||||
|
{
|
||||||
|
public function bootstrap(Configuration $configuration, Facade $facade, ParameterCollection $parameters): void
|
||||||
|
{
|
||||||
|
$facade->registerSubscriber(new class implements FinishedSubscriber {
|
||||||
|
public function notify(Finished $event): void
|
||||||
|
{
|
||||||
|
// 0 is the CLI default: no limit. set_time_limit() also
|
||||||
|
// restarts the clock, which is what a limit somebody else set
|
||||||
|
// needs.
|
||||||
|
set_time_limit(0);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace App\Tests\Support\PhpUnit;
|
||||||
|
|
||||||
|
use PHPUnit\Framework\Attributes\Depends;
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A time limit one test sets is gone by the next one.
|
||||||
|
*
|
||||||
|
* Two tests in a fixed order, because the claim is about what one test leaves
|
||||||
|
* behind for the next: the first does what a streaming controller does, the
|
||||||
|
* second looks. Without ResetTimeLimitExtension registered in phpunit.dist.xml
|
||||||
|
* the second sees the first's 300 seconds and fails.
|
||||||
|
*/
|
||||||
|
final class ResetTimeLimitExtensionTest extends TestCase
|
||||||
|
{
|
||||||
|
public function testAControllerTestSetsALimitTheWayTheStreamingEndpointsDo(): void
|
||||||
|
{
|
||||||
|
set_time_limit(300);
|
||||||
|
|
||||||
|
self::assertSame('300', ini_get('max_execution_time'));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[Depends('testAControllerTestSetsALimitTheWayTheStreamingEndpointsDo')]
|
||||||
|
public function testTheNextTestRunsWithoutIt(): void
|
||||||
|
{
|
||||||
|
self::assertSame('0', ini_get('max_execution_time'), 'a time limit set by one test is still counting in the next');
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in new issue
Block a user