|
24 | 24 | use Enqueue\Null\NullMessage; |
25 | 25 | use Interop\Queue\Processor; |
26 | 26 | use ReflectionClass; |
| 27 | +use TestApp\Job\MultilineLogJob; |
27 | 28 | use TestApp\TestProcessor; |
28 | 29 |
|
29 | 30 | class SubprocessJobRunnerCommandTest extends TestCase |
@@ -252,4 +253,67 @@ public function testOutputResult(): void |
252 | 253 |
|
253 | 254 | $method->invoke($command, $io, ['success' => true, 'result' => 'ack']); |
254 | 255 | } |
| 256 | + |
| 257 | + /** |
| 258 | + * Test that subprocess jobs with multiple log lines properly separate logs from JSON output |
| 259 | + */ |
| 260 | + public function testLogsRedirectedToStderr(): void |
| 261 | + { |
| 262 | + $jobData = [ |
| 263 | + 'messageClass' => NullMessage::class, |
| 264 | + 'body' => [ |
| 265 | + 'class' => [MultilineLogJob::class, 'execute'], |
| 266 | + 'args' => [], |
| 267 | + ], |
| 268 | + 'properties' => [], |
| 269 | + 'logger' => 'debug', |
| 270 | + ]; |
| 271 | + |
| 272 | + $command = 'php ' . ROOT . 'bin/cake.php queue subprocess-runner'; |
| 273 | + |
| 274 | + $descriptors = [ |
| 275 | + 0 => ['pipe', 'r'], |
| 276 | + 1 => ['pipe', 'w'], |
| 277 | + 2 => ['pipe', 'w'], |
| 278 | + ]; |
| 279 | + |
| 280 | + $process = proc_open($command, $descriptors, $pipes); |
| 281 | + $this->assertIsResource($process); |
| 282 | + |
| 283 | + // Write job data to STDIN |
| 284 | + $jobDataJson = json_encode($jobData); |
| 285 | + if ($jobDataJson !== false) { |
| 286 | + fwrite($pipes[0], $jobDataJson); |
| 287 | + } |
| 288 | + |
| 289 | + fclose($pipes[0]); |
| 290 | + |
| 291 | + // Read STDOUT and STDERR |
| 292 | + $stdout = stream_get_contents($pipes[1]); |
| 293 | + fclose($pipes[1]); |
| 294 | + |
| 295 | + $stderr = stream_get_contents($pipes[2]); |
| 296 | + fclose($pipes[2]); |
| 297 | + |
| 298 | + proc_close($process); |
| 299 | + |
| 300 | + // STDOUT should be valid JSON without any log messages |
| 301 | + $result = json_decode($stdout, true); |
| 302 | + $this->assertIsArray($result, 'STDOUT should contain valid JSON: ' . $stdout); |
| 303 | + $this->assertArrayHasKey('success', $result); |
| 304 | + $this->assertTrue($result['success']); |
| 305 | + $this->assertSame(Processor::ACK, $result['result']); |
| 306 | + |
| 307 | + // STDOUT should not contain any job log messages |
| 308 | + $this->assertStringNotContainsString('Job execution started', $stdout); |
| 309 | + $this->assertStringNotContainsString('Processing step', $stdout); |
| 310 | + $this->assertStringNotContainsString('Job execution finished', $stdout); |
| 311 | + |
| 312 | + // All log messages should be in STDERR |
| 313 | + $this->assertStringContainsString('Job execution started', $stderr); |
| 314 | + $this->assertStringContainsString('Processing step 1 completed', $stderr); |
| 315 | + $this->assertStringContainsString('Processing step 2 completed', $stderr); |
| 316 | + $this->assertStringContainsString('Processing step 3 completed', $stderr); |
| 317 | + $this->assertStringContainsString('Job execution finished', $stderr); |
| 318 | + } |
255 | 319 | } |
0 commit comments