Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "volt-test/php-sdk",
"description": "Volt Test PHP SDK - A performance testing tool for PHP applications",
"type": "library",
"version": "0.1.0",
"version": "0.1.1",
"keywords": [
"volt-test",
"php-sdk",
Expand Down
1 change: 1 addition & 0 deletions src/Configuration.php
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ public function setTarget(string $idleTimeout = '30s'): self
throw new VoltTestException('Invalid idle timeout format. Use <number>[s|m|h]');
}
$this->target['idle_timeout'] = $idleTimeout;

return $this;
}

Expand Down
20 changes: 11 additions & 9 deletions src/Platform.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ class Platform
{
private const BINARY_NAME = 'volt-test';

private const CURRENT_VERSION = 'v0.0.1-beta';
private const ENGINE_CURRENT_VERSION = 'v0.0.1';
private const BASE_DOWNLOAD_URL = 'https://github.com/volt-test/binaries/releases/download';
private const SUPPORTED_PLATFORMS = [
'linux-amd64' => 'volt-test-linux-amd64',
Expand Down Expand Up @@ -67,7 +67,7 @@ private static function getBinaryDir(): string

private static function getCurrentVersion(): string
{
return self::CURRENT_VERSION;
return self::ENGINE_CURRENT_VERSION;
}

private static function detectPlatform($testing = false): string
Expand Down Expand Up @@ -99,7 +99,7 @@ public static function installBinary($testing = false): void
{
$platform = self::detectPlatform($testing);

if (!array_key_exists($platform, self::SUPPORTED_PLATFORMS)) {
if (! array_key_exists($platform, self::SUPPORTED_PLATFORMS)) {
throw new \RuntimeException("Platform $platform is not supported");
}

Expand All @@ -113,8 +113,8 @@ public static function installBinary($testing = false): void
$targetFile .= '.exe';
}

if (!is_dir($binDir)) {
if (!mkdir($binDir, 0755, true)) {
if (! is_dir($binDir)) {
if (! mkdir($binDir, 0755, true)) {
throw new \RuntimeException("Failed to create directory: $binDir");
}
}
Expand All @@ -135,6 +135,7 @@ public static function installBinary($testing = false): void
$fp = fopen($tempFile, 'w');
if ($fp === false) {
curl_close($ch);

throw new \RuntimeException("Failed to open temporary file for writing");
}

Expand All @@ -145,7 +146,7 @@ public static function installBinary($testing = false): void
CURLOPT_FAILONERROR => true,
CURLOPT_TIMEOUT => 300,
CURLOPT_CONNECTTIMEOUT => 30,
CURLOPT_HTTPHEADER => ['User-Agent: volt-test-php-sdk']
CURLOPT_HTTPHEADER => ['User-Agent: volt-test-php-sdk'],
]);

if (curl_exec($ch) === false) {
Expand All @@ -160,15 +161,15 @@ public static function installBinary($testing = false): void
curl_close($ch);
fclose($fp);

if (!file_exists($tempFile) || filesize($tempFile) === 0) {
if (! file_exists($tempFile) || filesize($tempFile) === 0) {
throw new \RuntimeException("Downloaded file is empty or missing");
}

if (!rename($tempFile, $targetFile)) {
if (! rename($tempFile, $targetFile)) {
throw new \RuntimeException("Failed to move downloaded binary to: $targetFile");
}

if (!chmod($targetFile, 0755)) {
if (! chmod($targetFile, 0755)) {
throw new \RuntimeException("Failed to set executable permissions on binary");
}

Expand All @@ -179,6 +180,7 @@ public static function installBinary($testing = false): void
if (file_exists($tempFile)) {
unlink($tempFile);
}

throw $e;
}
}
Expand Down
29 changes: 24 additions & 5 deletions src/ProcessManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ class ProcessManager
public function __construct(string $binaryPath)
{
$this->binaryPath = $binaryPath;
// Enable async signals
if (function_exists('pcntl_async_signals')) {
pcntl_async_signals(true);
pcntl_signal(SIGINT, [$this, 'handleSignal']);
Expand Down Expand Up @@ -44,7 +43,14 @@ public function execute(array $config, bool $streamOutput): string
fclose($pipes[0]);

$output = $this->handleProcess($pipes, $streamOutput);
} finally {

// Store stderr content before closing
$stderrContent = '';
if (isset($pipes[2]) && is_resource($pipes[2])) {
rewind($pipes[2]);
$stderrContent = stream_get_contents($pipes[2]);
}

// Clean up pipes
foreach ($pipes as $pipe) {
if (is_resource($pipe)) {
Expand All @@ -56,12 +62,24 @@ public function execute(array $config, bool $streamOutput): string
$exitCode = $this->closeProcess($process);
$this->currentProcess = null;
if ($exitCode !== 0) {
throw new RuntimeException('Process failed with exit code ' . $exitCode);
echo "\nError: " . trim($stderrContent) . "\n";

return '';
}
}
}

return $output;
return $output;
} finally {
foreach ($pipes as $pipe) {
if (is_resource($pipe)) {
fclose($pipe);
}
}
if (is_resource($process)) {
$this->closeProcess($process);
$this->currentProcess = null;
}
}
}

protected function openProcess(): array
Expand Down Expand Up @@ -149,6 +167,7 @@ protected function closeProcess($process): int
proc_terminate($process);
}


return proc_close($process);
}
}
1 change: 1 addition & 0 deletions src/Request.php
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ public function toArray(): array
if (count($this->headers) > 0) {
$array['header'] = $this->headers;
}

return $array;
}

Expand Down
32 changes: 0 additions & 32 deletions tests/Units/ProcessManagerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -63,38 +63,6 @@ public static function outputProvider(): array
];
}

#[DataProvider('errorScenarioProvider')]
public function testErrorScenarios(
bool $failStart,
int $exitCode,
string $errorOutput,
string $expectedMessage
): void {
$this->processManager->setFailProcessStart($failStart);
$this->processManager->setMockExitCode($exitCode);
$this->processManager->setMockStderr($errorOutput);

$this->expectException(\RuntimeException::class);
$this->expectExceptionMessage($expectedMessage);

$this->processManager->execute(['test' => true], false);
}

public static function errorScenarioProvider(): array
{
return [
'process start failure' => [
true, 0, '', 'Failed to start process',
],
'non-zero exit code' => [
false, 1, 'Error occurred', 'Process failed with exit code 1',
],
'permission error' => [
false, 126, 'Permission denied', 'Process failed with exit code 126',
],
];
}

public function testLongRunningProcess(): void
{
$longOutput = str_repeat("Output line\n", 100);
Expand Down
Loading