Skip to content

Commit 980284d

Browse files
Restart feature queue workers around migrations
1 parent 4a524f8 commit 980284d

1 file changed

Lines changed: 55 additions & 40 deletions

File tree

tests/TestCase.php

Lines changed: 55 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -39,57 +39,27 @@ public static function setUpBeforeClass(): void
3939
}
4040

4141
self::flushRedis();
42-
43-
if ($currentSuite !== 'feature') {
44-
return;
45-
}
46-
47-
// The first feature test's migrate:fresh runs before setUp() can write
48-
// the Cache facade throttle keys, so prime Redis directly before the
49-
// background queue workers start polling.
50-
self::primeWatchdogThrottle();
51-
52-
// Explicitly hand our env to Process. testbench/laravel/.env hardcodes
53-
// CACHE_DRIVER=file; without an inherited env (or when Symfony Process
54-
// ignores the parent's env on some runners) the worker bootstraps its
55-
// own file-backed cache and cannot see the LOOP_THROTTLE_KEY the test
56-
// process writes to redis — original CI shape under #427. Merging
57-
// $_ENV + $_SERVER + getenv() rather than relying on Process's
58-
// default null-env inherit covers every environment variable source
59-
// GitHub Actions, Orchestra, and the loaded .env.feature might have
60-
// populated by this point.
61-
$workerEnv = array_merge(array_filter($_SERVER, 'is_string'), array_filter($_ENV, 'is_string'));
62-
63-
for ($i = 0; $i < self::NUMBER_OF_WORKERS; $i++) {
64-
self::$workers[$i] = new Process(
65-
['php', __DIR__ . '/../vendor/bin/testbench', 'queue:work'],
66-
null,
67-
$workerEnv,
68-
);
69-
self::$workers[$i]->disableOutput();
70-
self::$workers[$i]->start();
71-
}
7242
}
7343

7444
public static function tearDownAfterClass(): void
7545
{
76-
foreach (self::$workers as $worker) {
77-
$worker->stop();
78-
}
79-
80-
self::$workers = [];
81-
46+
self::stopWorkers();
8247
self::flushRedis();
8348
}
8449

8550
protected function setUp(): void
8651
{
87-
if (TestSuiteSubscriber::getCurrentSuite() === 'feature') {
52+
$currentSuite = TestSuiteSubscriber::getCurrentSuite();
53+
54+
if ($currentSuite === 'feature') {
8855
Dotenv::createImmutable(__DIR__, '.env.feature')->safeLoad();
89-
} elseif (TestSuiteSubscriber::getCurrentSuite() === 'unit') {
56+
} elseif ($currentSuite === 'unit') {
9057
Dotenv::createImmutable(__DIR__, '.env.unit')->safeLoad();
9158
}
9259

60+
self::stopWorkers();
61+
self::flushRedis();
62+
9363
parent::setUp();
9464

9565
Queue::swap($this->app->make('queue'));
@@ -98,10 +68,10 @@ protected function setUp(): void
9868

9969
self::flushRedis();
10070

101-
if (TestSuiteSubscriber::getCurrentSuite() === 'feature') {
71+
if ($currentSuite === 'feature') {
10272
// Block BOTH the V2 TaskWatchdog and the V1 Watchdog for the
10373
// duration of every feature test. The two testbench queue
104-
// workers spawned in setUpBeforeClass run both wake()s on every
74+
// workers spawned after the per-test migration run both wake()s on every
10575
// Looping event in separate PHP processes.
10676
//
10777
// V2: almost every V2 feature test uses Queue::fake() with
@@ -128,6 +98,18 @@ protected function setUp(): void
12898
// key and calls runPass(respectThrottle: false) directly.
12999
Cache::put(TaskWatchdog::LOOP_THROTTLE_KEY, true, self::WATCHDOG_THROTTLE_TTL_SECONDS);
130100
Cache::put(self::V1_WATCHDOG_LOOP_THROTTLE_KEY, true, self::WATCHDOG_THROTTLE_TTL_SECONDS);
101+
self::primeWatchdogThrottle();
102+
self::startWorkers();
103+
}
104+
}
105+
106+
protected function tearDown(): void
107+
{
108+
try {
109+
self::stopWorkers();
110+
self::flushRedis();
111+
} finally {
112+
parent::tearDown();
131113
}
132114
}
133115

@@ -170,6 +152,39 @@ private static function normalizeJsonObject(array $value): array
170152
return $normalized;
171153
}
172154

155+
private static function startWorkers(): void
156+
{
157+
if (self::$workers !== []) {
158+
return;
159+
}
160+
161+
$environment = getenv();
162+
$workerEnv = array_merge(
163+
is_array($environment) ? array_filter($environment, 'is_string') : [],
164+
array_filter($_SERVER, 'is_string'),
165+
array_filter($_ENV, 'is_string'),
166+
);
167+
168+
for ($i = 0; $i < self::NUMBER_OF_WORKERS; $i++) {
169+
self::$workers[$i] = new Process(
170+
['php', __DIR__ . '/../vendor/bin/testbench', 'queue:work'],
171+
null,
172+
$workerEnv,
173+
);
174+
self::$workers[$i]->disableOutput();
175+
self::$workers[$i]->start();
176+
}
177+
}
178+
179+
private static function stopWorkers(): void
180+
{
181+
foreach (self::$workers as $worker) {
182+
$worker->stop(3);
183+
}
184+
185+
self::$workers = [];
186+
}
187+
173188
private static function flushRedis(): void
174189
{
175190
$redis = self::redisConnection();

0 commit comments

Comments
 (0)