Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
0af69a7
feat: add HTTP timeout configuration for requests
elwafa Apr 11, 2026
957ead0
version to 1.2.0-dev in composer.json
elwafa Apr 17, 2026
a53ec7a
feat: implement stages for load profile configuration and validation
elwafa Apr 17, 2026
4089eb7
feat: update CI configuration to include release branches for push an…
elwafa Apr 17, 2026
70389b3
feat: implement cloud execution features with stages and error handling
elwafa Apr 18, 2026
fbef112
feat: update base URL for CloudClient to use production endpoint
elwafa Apr 18, 2026
76e6a20
feat: update DASHBOARD_BASE_URL to use the correct production endpoint
elwafa Apr 18, 2026
0cca212
feat: update dashboard URL to use the correct production endpoint
elwafa Apr 18, 2026
902154b
Merge pull request #30 from volt-test/feat/Stages
elwafa Apr 18, 2026
572a3eb
feat: update engine version to v1.2.0-dev
elwafa Apr 18, 2026
9ad03b4
feat: implement cloud execution features with error handling and resp…
elwafa Apr 24, 2026
f811ae2
feat: bump version to 1.2.1-dev in composer.json and Platform.php
elwafa Apr 24, 2026
f21a70a
feat: add conflict handling for cloud test execution with user prompt
elwafa May 8, 2026
6953039
feat: bump version to 1.2.2-dev in composer.json
elwafa May 8, 2026
96fbe6a
feat: add region distribution configuration for cloud execution
elwafa May 20, 2026
b67ee81
fix: update parameter type hint for regions in Configuration.php
elwafa May 20, 2026
e9e1719
fix: remove phpstan ignore comment for region weight type validation …
elwafa May 20, 2026
e51d984
feat: add setName and setDescription methods to Configuration and Vol…
elwafa May 22, 2026
db5abb0
feat: add clearConstantLoad method and update stage handling in VoltTest
elwafa May 22, 2026
e4d889a
fix: improve error handling in ProcessManager by checking stderr content
elwafa May 28, 2026
f169c6f
fix: enhance stderr handling in ProcessManager and add tests for non-…
elwafa May 28, 2026
c4600d7
feat: add target URL configuration with validation and idle timeout s…
elwafa Jun 5, 2026
48a7da1
fix: add validation and error handling for regex extraction in Step c…
elwafa Jun 5, 2026
ec7167a
Merge pull request #31 from volt-test/release/v1.2.x-dev
elwafa Jun 5, 2026
b42c033
fix: update version number to 1.2.0 in composer.json
elwafa Jun 5, 2026
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
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ name: CI

on:
push:
branches: [ main, develop ]
branches: [ main, develop, release/* ]
pull_request:
branches: [ main, develop ]
branches: [ main, develop , release/* ]

jobs:
test:
Expand Down
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 Developers",
"type": "library",
"version": "1.1.1",
"version": "1.2.0",
"keywords": [
"volt-test",
"php-sdk",
Expand Down
46 changes: 46 additions & 0 deletions src/CloudRun.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<?php

namespace VoltTest;

class CloudRun
{
private const DASHBOARD_BASE_URL = 'https://volt-test.com';

private string $runId;

private string $testId;

private string $status;

public function __construct(string $runId, string $testId, string $status)
{
$this->runId = $runId;
$this->testId = $testId;
$this->status = $status;
}

public function getRunId(): string
{
return $this->runId;
}

public function getTestId(): string
{
return $this->testId;
}

public function getStatus(): string
{
return $this->status;
}

public function getDashboardUrl(): string
{
return self::DASHBOARD_BASE_URL . '/runs/' . $this->runId;
}

public function isSuccessful(): bool
{
return $this->status === 'completed';
}
}
154 changes: 148 additions & 6 deletions src/Configuration.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,16 @@ class Configuration

private array $target;

private string $httpTimeout = '';

private bool $httpDebug = false;

/** @var Stage[] */
private array $stages = [];

/** @var array<string, int> */
private array $regionConfig = [];

public function __construct(string $name, string $description = '')
{
$this->name = $name;
Expand All @@ -38,15 +46,34 @@ public function toArray(): array
$array = [
'name' => $this->name,
'description' => $this->description,
'virtual_users' => $this->virtualUsers,
'target' => $this->target,
'http_debug' => $this->httpDebug,
];
if (trim($this->rampUp) !== '') {
$array['ramp_up'] = $this->rampUp;

if (count($this->stages) > 0) {
// Stages mode: omit virtual_users, duration, ramp_up
$array['stages'] = array_map(fn (Stage $s) => $s->toArray(), $this->stages);
} else {
// Constant mode
$array['virtual_users'] = $this->virtualUsers;
if (trim($this->rampUp) !== '') {
$array['ramp_up'] = $this->rampUp;
}
if (trim($this->duration) !== '') {
$array['duration'] = $this->duration;
}
}
if (trim($this->duration) !== '') {
$array['duration'] = $this->duration;

if (trim($this->httpTimeout) !== '') {
$array['http_timeout'] = $this->httpTimeout;
}

if (count($this->regionConfig) > 0) {
$array['region_config'] = array_map(
fn (string $region, int $weight) => ['region' => $region, 'weight' => $weight],
array_keys($this->regionConfig),
array_values($this->regionConfig)
);
}

return $array;
Expand Down Expand Up @@ -82,7 +109,21 @@ public function setRampUp(string $rampUp): self
return $this;
}

public function setTarget(string $idleTimeout = '30s'): self
public function setTargetUrl(string $url): self
{
if (! preg_match('/^https?:\/\//', $url)) {
throw new VoltTestException('Target URL must start with http:// or https://');
}
$parsed = parse_url($url);
if ($parsed === false || ! isset($parsed['host'])) {
throw new VoltTestException('Invalid target URL');
}
$this->target['url'] = $url;

return $this;
}

public function setIdleTimeout(string $idleTimeout = '30s'): self
{
if (! preg_match('/^\d+[smh]$/', $idleTimeout)) {
throw new VoltTestException('Invalid idle timeout format. Use <number>[s|m|h]');
Expand All @@ -92,10 +133,111 @@ public function setTarget(string $idleTimeout = '30s'): self
return $this;
}

/**
* @deprecated Use setIdleTimeout() instead
*/
public function setTarget(string $idleTimeout = '30s'): self
{
return $this->setIdleTimeout($idleTimeout);
}

public function setHttpTimeout(string $httpTimeout): self
{
if (! preg_match('/^\d+[smh]$/', $httpTimeout)) {
throw new VoltTestException('Invalid HTTP timeout format. Use <number>[s|m|h]');
}
$this->httpTimeout = $httpTimeout;

return $this;
}

public function setHttpDebug(bool $httpDebug): self
{
$this->httpDebug = $httpDebug;

return $this;
}

/**
* @throws VoltTestException
*/
public function addStage(string $duration, int $target): self
{
$this->stages[] = new Stage($duration, $target);

return $this;
}

public function hasStages(): bool
{
return count($this->stages) > 0;
}

public function hasConstantLoad(): bool
{
return $this->virtualUsers > 1 || trim($this->duration) !== '' || trim($this->rampUp) !== '';
}

public function clearConstantLoad(): self
{
$this->virtualUsers = 1;
$this->duration = '';
$this->rampUp = '';

return $this;
}

/**
* @param array $regions Region code => weight (e.g., ['us-east-1' => 60, 'eu-west-1' => 40])
*
* @throws VoltTestException
*/
public function setRegions(array $regions): self
{
if (empty($regions)) {
throw new VoltTestException('Region distribution cannot be empty');
}

foreach ($regions as $region => $weight) {
if (! is_string($region) || trim($region) === '') {
throw new VoltTestException('Region code must be a non-empty string');
}

if (! is_int($weight)) {
throw new VoltTestException('Region weight must be an integer');
}

if ($weight <= 0) {
throw new VoltTestException('Region weight must be greater than 0');
}
}

$sum = array_sum($regions);
if ($sum !== 100) {
throw new VoltTestException("Region weights must sum to 100, got {$sum}");
}

$this->regionConfig = $regions;

return $this;
}

public function hasRegions(): bool
{
return count($this->regionConfig) > 0;
}

public function setName(string $name): self
{
$this->name = $name;

return $this;
}

public function setDescription(string $description): self
{
$this->description = $description;

return $this;
}
}
7 changes: 7 additions & 0 deletions src/Exceptions/AuthenticationException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?php

namespace VoltTest\Exceptions;

class AuthenticationException extends CloudException
{
}
7 changes: 7 additions & 0 deletions src/Exceptions/CloudConnectionException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?php

namespace VoltTest\Exceptions;

class CloudConnectionException extends CloudException
{
}
7 changes: 7 additions & 0 deletions src/Exceptions/CloudException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?php

namespace VoltTest\Exceptions;

class CloudException extends VoltTestException
{
}
7 changes: 7 additions & 0 deletions src/Exceptions/CloudTimeoutException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?php

namespace VoltTest\Exceptions;

class CloudTimeoutException extends CloudException
{
}
7 changes: 7 additions & 0 deletions src/Exceptions/PlanLimitException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?php

namespace VoltTest\Exceptions;

class PlanLimitException extends CloudException
{
}
7 changes: 7 additions & 0 deletions src/Exceptions/RunFailedException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?php

namespace VoltTest\Exceptions;

class RunFailedException extends CloudException
{
}
1 change: 0 additions & 1 deletion src/Extractors/HtmlExtractor.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@

class HtmlExtractor implements Extractor
{

private string $variableName;

private string $selector;
Expand Down
2 changes: 1 addition & 1 deletion 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 ENGINE_CURRENT_VERSION = 'v1.1.0';
private const ENGINE_CURRENT_VERSION = 'v1.2.0';
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
Loading
Loading