|
<?php |
|
|
|
namespace App\Console\Commands; |
|
|
|
use GuzzleHttp\Client; |
|
use GuzzleHttp\Pool; |
|
use Illuminate\Console\Command; |
|
|
|
class LoadTestCommand extends Command |
|
{ |
|
/** |
|
* @var string |
|
*/ |
|
protected $signature = 'load-test {url} |
|
{connections=10}'; |
|
|
|
/** |
|
* @var string |
|
*/ |
|
protected $description = 'Perform load testing on a specified URL with a customizable number of concurrent connections.'; |
|
|
|
public function handle(): int |
|
{ |
|
$url = $this->argument('url'); |
|
$connections = $this->argument('connections'); |
|
|
|
$client = new Client([ |
|
'verify' => false, |
|
]); |
|
|
|
$results = collect([]); |
|
$progressBar = $this->output->createProgressBar($connections); |
|
$progressBar->start(); |
|
|
|
function convertToReadableFormat($size): string |
|
{ |
|
$unit = array('b', 'kb', 'mb', 'gb', 'tb', 'pb'); |
|
|
|
return @round($size / (1024 ** ($i = floor(log($size, 1024)))), 2) . ' ' . $unit[$i]; |
|
} |
|
|
|
$requests = static function () use ($client, $url, $connections, &$results, $progressBar) { |
|
for ($i = 0; $i < $connections; $i++) { |
|
yield static function () use ($client, $url, &$results, $i, $progressBar) { |
|
$start = microtime(true); |
|
$memoryUsageStart = memory_get_usage(true); |
|
|
|
return $client->getAsync($url)->then( |
|
function ($response) use (&$results, $i, $start, $memoryUsageStart, $progressBar) { |
|
$statusCode = $response->getStatusCode(); |
|
$responseTime = (microtime(true) - $start) * 1000; |
|
$memoryUsageEnd = memory_get_usage(true); |
|
$memoryUsageDelta = $memoryUsageEnd - $memoryUsageStart; |
|
|
|
$results->push([ |
|
'connection' => $i + 1, |
|
'status_code' => $statusCode, |
|
'memory_usage' => convertToReadableFormat($memoryUsageDelta), |
|
'response_time' => $responseTime . ' ms', |
|
]); |
|
|
|
$progressBar->advance(); |
|
}, |
|
function ($reason) use (&$results, $i, $progressBar) { |
|
$results->push([ |
|
'connection' => $i + 1, |
|
'status_code' => 'Failed', |
|
'memory_usage' => 'N/A', |
|
'error' => $reason->getMessage(), |
|
]); |
|
|
|
$progressBar->advance(); |
|
} |
|
); |
|
}; |
|
} |
|
}; |
|
|
|
$pool = new Pool($client, $requests(), [ |
|
'concurrency' => $connections, |
|
]); |
|
|
|
$promise = $pool->promise(); |
|
$promise->wait(); |
|
|
|
$progressBar->finish(); |
|
|
|
$this->newLine(); |
|
$this->table([ |
|
'Connection', |
|
'Status Code', |
|
'Memory Usage', |
|
'Response Time/Error' |
|
], $results->sortBy('status_code')->sortBy('response_time')); |
|
|
|
return 0; |
|
} |
|
} |