Let's say in PHP I have a bunch of unit tests. Suppose they require some maintenance.
Ideally, I want my bootstrap script:
- run this service
- wait until the service reaches the desired state.
- manual control to select a unit of measure for running tests
- cleaning when tests end, gracefully ending the service for granted
- set up a way to capture all output from the service in the path for logging and debugging
Currently, I use proc_open()to initialize my service, capture output using the pipe mechanism, checking that the service goes to the state that I need, examining the output.
However, at the moment I am puzzled - how can I write the rest of the output (including STDERR) for the remainder of the duration of the script, while preserving my unit tests?
I can think of several potentially long-term solutions, but before investing time in investigating them, I would like to know if someone else had this problem and what solutions they found, if any, without affecting the answer.
Edit:
The following is the version of the class cutoff that I initialize in my bootstrap script (c new ServiceRunner), for reference:
<?php
namespace Tests;
class ServiceRunner
{
private $servicePipes;
private $serviceProc;
private $temp;
public function __construct()
{
$this->temp = fopen('php://temp', 'r+');
fputs(STDERR,"Launching Service.\n");
$this->serviceProc = proc_open('/path/to/service', [
0 => array("pipe", "r"),
1 => array("pipe", "w"),
2 => array("pipe", "w"),
], $this->servicePipes);
stream_set_blocking($this->servicePipes[1], false);
stream_set_blocking($this->servicePipes[2], false);
$readables = [$this->servicePipes[1], $this->servicePipes[2]);
while(false !== ($streams = stream_select($read = $readables, $w = [], $e = [], 1))) {
foreach($read as $stream) {
if($line = stream_get_line($stream, 8192, "\n")) {
fputs($this->temp, $line."\n");
}
if(strstr($line, 'The Service is Listening' ) !== false) {
break 2;
}
if($line === false && feof($stream)) {
$readables = array_diff($readables, [$stream]);
}
}
}
register_shutdown_function([$this, 'shutDown']);
}
public function shutDown()
{
fputs(STDERR,"Closing...\n");
fclose($this->servicePipes[0]);
proc_terminate($this->serviceProc, SIGINT);
fclose($this->servicePipes[1]);
fclose($this->servicePipes[2]);
proc_close($this->serviceProc);
fputs(STDERR,"Closed service\n");
$logFile = fopen('log.txt', 'w');
rewind($this->temp);
stream_copy_to_stream($this->temp, $logFile);
fclose($this->temp);
fclose($logFile);
}
}