Skip to content

Commit

Permalink
feat: detail
Browse files Browse the repository at this point in the history
  • Loading branch information
nunomaduro committed Nov 4, 2023
1 parent aa5d1e7 commit 99e7c5f
Show file tree
Hide file tree
Showing 11 changed files with 285 additions and 21 deletions.
8 changes: 7 additions & 1 deletion src/Blocks/NetworkDuration.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,13 @@ public function value(): string
+ $array['metrics']['http_req_duration']['values']['avg']
- $array['metrics']['http_req_waiting']['values']['avg'];

return sprintf('%4.2f ms', $duration);
$duration = sprintf('%4.2f ms', $duration);

if (strlen($duration) < 9) {
$duration = str_pad($duration, 9, ' ', STR_PAD_BOTH);
}

return $duration;
}

/**
Expand Down
8 changes: 7 additions & 1 deletion src/Blocks/ResponseDuration.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,13 @@ public function value(): string
+ $array['metrics']['http_req_tls_handshaking']['values']['avg']
+ $array['metrics']['http_req_duration']['values']['avg'];

return sprintf('%4.2f ms', $duration);
$duration = sprintf('%4.2f ms', $duration);

if (strlen($duration) < 9) {
$duration = str_pad($duration, 9, ' ', STR_PAD_BOTH);
}

return $duration;
}

/**
Expand Down
8 changes: 7 additions & 1 deletion src/Blocks/ServerDuration.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,13 @@ public function value(): string

$duration = $array['metrics']['http_req_waiting']['values']['avg'];

return sprintf('%4.2f ms', $duration);
$duration = sprintf('%4.2f ms', $duration);

if (strlen($duration) < 9) {
$duration = str_pad($duration, 9, ' ', STR_PAD_BOTH);
}

return $duration;
}

/**
Expand Down
4 changes: 4 additions & 0 deletions src/Blocks/SuccessRate.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ public function value(): string

$percentage = (float) ($array['metrics']['http_req_failed']['values']['fails'] * 100 / $array['metrics']['http_reqs']['values']['count']);

if ($percentage === 100.0) {
return '100 %';
}

return sprintf('%4.1f %%', $percentage);
}

Expand Down
35 changes: 21 additions & 14 deletions src/ResultPrinters/Blocks.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@

private const SUCCESS_RATE = <<<'EOD'
<%success_rate_color%>%block_size%</>
<fg=white;options=bold;%success_rate_color%> %success_rate% </>
<fg=white;options=bold;%success_rate_color%> %success_rate% </>
<%success_rate_color%>%block_size%</>
EOD;

Expand All @@ -43,9 +43,9 @@
EOD;

private const NETWORK_DURATION = <<<'EOD'
<%ttfb_color%>%block_size%</>
<fg=white;options=bold;%ttfb_color%> %ttfb% </>
<%ttfb_color%>%block_size%</>
<%network_color%>%block_size%</>
<fg=white;options=bold;%network_color%> %network% </>
<%network_color%>%block_size%</>
EOD;

private const SERVER_DURATION = <<<'EOD'
Expand All @@ -57,13 +57,9 @@
public function print(Result $result): void
{
render(<<<'HTML'
<div class="mx-2 my-1 text-gray">
<span class="text-red">■</span>
<span class="ml-1">0-49</span>
<span class="text-yellow ml-2">■</span>
<span class="ml-1">50-89</span>
<span class="text-green ml-2">■</span>
<span class="ml-1">90-100</span>
<div class="flex mt-1">
<span></span>
<span class="flex-1 content-repeat-[─] text-gray mx-2"></span>
</div>
HTML);

Expand All @@ -77,11 +73,11 @@ public function print(Result $result): void
'%success_rate_color%' => "bg={$successRate->color()}",
'%response_time%' => $responseDuration->value(),
'%response_time_color%' => "bg={$responseDuration->color()}",
'%ttfb%' => $networkDuration->value(),
'%ttfb_color%' => "bg={$networkDuration->color()}",
'%network%' => $networkDuration->value(),
'%network_color%' => "bg={$networkDuration->color()}",
'%server_duration%' => $serverDuration->value(),
'%server_duration_color%' => "bg={$serverDuration->color()}",
'%subtitle%' => 'fg=white;options=bold;fg=white',
'%subtitle%' => 'options=bold',
];
$disposition = self::ALL_BLOCKS_IN_ROW;
$spaceWidth = $this->getSpaceWidth(terminal()->width(), self::BLOCK_SIZE, $disposition);
Expand Down Expand Up @@ -154,6 +150,17 @@ public function print(Result $result): void
}

$table->render();

render(<<<'HTML'
<div class="mx-2 my-1 text-gray">
<span class="text-red">■</span>
<span class="ml-1">0-49</span>
<span class="text-yellow ml-2">■</span>
<span class="ml-1">50-89</span>
<span class="text-green ml-2">■</span>
<span class="ml-1">90-100</span>
</div>
HTML);
}

/**
Expand Down
201 changes: 201 additions & 0 deletions src/ResultPrinters/Detail.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,201 @@
<?php

declare(strict_types=1);

namespace Pest\Stressless\ResultPrinters;

use Pest\Stressless\ValueObjects\Result;

use function Termwind\render;

/**
* @internal
*/
final readonly class Detail
{
/**
* Prints the blocks.
*/
public function print(Result $result): void
{
/**
* data_received..................: 22 kB 5.7 kB/s
* data_sent......................: 742 B 198 B/s
* http_req_blocked...............: avg=1.05s min=1.05s med=1.05s max=1.05s p(90)=1.05s p(95)=1.05s
* http_req_connecting............: avg=334.26ms min=334.26ms med=334.26ms max=334.26ms p(90)=334.26ms p(95)=334.26ms
* http_req_duration..............: avg=2.7s min=2.7s med=2.7s max=2.7s p(90)=2.7s p(95)=2.7s
* { expected_response:true }...: avg=2.7s min=2.7s med=2.7s max=2.7s p(90)=2.7s p(95)=2.7s
* http_req_failed................: 0.00% ✓ 0 ✗ 1
* http_req_receiving.............: avg=112.41µs min=112.41µs med=112.41µs max=112.41µs p(90)=112.41µs p(95)=112.41µs
* http_req_sending...............: avg=294.48µs min=294.48µs med=294.48µs max=294.48µs p(90)=294.48µs p(95)=294.48µs
* http_req_tls_handshaking.......: avg=700.6ms min=700.6ms med=700.6ms max=700.6ms p(90)=700.6ms p(95)=700.6ms
* http_req_waiting...............: avg=2.7s min=2.7s med=2.7s max=2.7s p(90)=2.7s p(95)=2.7s
* http_reqs......................: 1 0.266167/s
* iteration_duration.............: avg=3.75s min=3.75s med=3.75s max=3.75s p(90)=3.75s p(95)=3.75s
* iterations.....................: 1 0.266167/s
* vus............................: 1 min=1 max=1
* vus_max........................: 1 min=1 max=1
*/
$metrics = $result->toArray()['metrics'];

$this->overview($result, $metrics);
$this->server($metrics);
$this->network($metrics);
}

/**
* Prints the overview's detail.
*/
private function overview(Result $result, array $metrics): void
{
render(<<<'HTML'
<div class="flex mx-2 max-w-150"">
<span class="font-bold"></span>
<span class="flex-1"></span>
<span class="text-gray">
<span class="text-red">■</span>
<span class="ml-1"></span>
<span class="text-yellow ml-2">■</span>
<span class="ml-1">50-89</span>
<span class="text-green ml-2">■</span>
<span class="ml-1">90-100</span>
</span>
</div>);
HTML);

$testRunDuration = $result->testRunDuration();
$testRunDuration = sprintf('%4.2f', $testRunDuration / 1000);

$this->twoColumnDetail('Test Duration', "$testRunDuration s");

$requestsTotal = $metrics['http_reqs']['values']['count'];
$requestsRate = round($metrics['http_reqs']['values']['rate'], 2);
$testRunConcurrentUsers = $result->testRunConcurrentUsers();

$this->twoColumnDetail('Total Requests', <<<HTML
<span class="text-gray mr-1">$requestsRate reqs/second │ $testRunConcurrentUsers concurrent users</span>
<span>$requestsTotal requests</span>
HTML);

$successRate = (float) ($metrics['http_req_failed']['values']['fails'] * 100 / $metrics['http_reqs']['values']['count']);
$successRate = sprintf('%4.1f', $successRate);
$successRateColor = $metrics['http_req_failed']['values']['fails'] === $metrics['http_reqs']['values']['count']
? 'green'
: 'red';

$this->twoColumnDetail('Success Rate', <<<HTML
<span class="font-bold text-$successRateColor">$successRate %</span>
HTML);

$responseDuration = $metrics['http_req_connecting']['values']['avg']
+ $metrics['http_req_tls_handshaking']['values']['avg']
+ $metrics['http_req_duration']['values']['avg'];

$responseDurationColor = match (true) {
$responseDuration < 200 => 'green',
$responseDuration < 400 => 'yellow',
default => 'red',
};

$responseDuration = sprintf('%4.2f', $responseDuration);

$this->twoColumnDetail('Response Duration', <<<HTML
<span class="text-$responseDurationColor font-bold">$responseDuration ms</span>
HTML);
}

/**
* Prints the network's detail.
*/
private function network(array $metrics): void
{
$responseDuration = $metrics['http_req_connecting']['values']['avg']
+ $metrics['http_req_tls_handshaking']['values']['avg']
+ $metrics['http_req_duration']['values']['avg'];

$responseNetworkDuration = $metrics['http_req_connecting']['values']['avg']
+ $metrics['http_req_tls_handshaking']['values']['avg']
+ $metrics['http_req_duration']['values']['avg']
- $metrics['http_req_waiting']['values']['avg'];
$responseNetworkDurationPercentage = $responseDuration > 0.00 ? round($responseNetworkDuration * 100 / $responseDuration, 2) : 0.00;
$responseNetworkDurationColor = match (true) {
$responseNetworkDuration < 100 => 'green',
$responseNetworkDuration < 200 => 'yellow',
default => 'red',
};

$responseNetworkDuration = sprintf('%4.2f', $responseNetworkDuration);

$this->twoColumnDetail(<<<HTML
<span class="text-gray mr-1">├</span><span>Network</span>
<span class="text-gray ml-1">$responseNetworkDurationPercentage %</span>
HTML, <<<HTML
<span class="text-$responseNetworkDurationColor">$responseNetworkDuration ms </span>
HTML);

$tlsHandshakingTime = $metrics['http_req_tls_handshaking']['values']['avg'];
$tlsHandshakingTime = sprintf('%4.2f', $tlsHandshakingTime);

$dnsLookupTime = $metrics['http_req_connecting']['values']['avg'];
$dnsLookupTime = sprintf('%4.2f', $dnsLookupTime);

$uploadTime = $metrics['http_req_sending']['values']['avg'];
$uploadTime = sprintf('%4.2f', $uploadTime);

$downloadTime = $metrics['http_req_receiving']['values']['avg'];
$downloadTime = sprintf('%4.2f', $downloadTime);

foreach ([
'TLS Handshaking' => "$tlsHandshakingTime ms",
'DNS Lookup' => "$dnsLookupTime ms",
'Upload' => "$uploadTime ms",
'Download' => "$downloadTime ms",
] as $title => $value) {
$this->twoColumnDetail('<span class="text-gray mr-1">│ ├</span>'.$title, $value);
}
}

/**
* Prints the server's detail.
*/
private function server(array $metrics): void
{
$responseDuration = $metrics['http_req_connecting']['values']['avg']
+ $metrics['http_req_tls_handshaking']['values']['avg']
+ $metrics['http_req_duration']['values']['avg'];
$responseServerDuration = $metrics['http_req_waiting']['values']['avg'];
$responseServerDurationColor = match (true) {
$responseDuration < 100 => 'green',
$responseDuration < 200 => 'yellow',
default => 'red',
};

$responseServerDurationPercentage = $responseDuration > 0.00 ? round($responseServerDuration * 100 / $responseDuration, 2) : 0.00;
$responseServerDuration = sprintf('%4.2f', $responseServerDuration);

$this->twoColumnDetail(<<<HTML
<span class="text-gray mr-1">├</span><span>Server</span>
<span class="text-gray ml-1">$responseServerDurationPercentage %</span>
HTML, <<<HTML
<span class="text-$responseServerDurationColor">$responseServerDuration ms </span>
HTML);
}

/**
* Prints a two column detail.
*/
private function twoColumnDetail(string $left, string $right): void
{
render(<<<HTML
<div class="flex max-w-150 mx-2">
<span>
$left
</span>
<span class="flex-1 content-repeat-[.] text-gray ml-1"></span>
<span class="ml-1">
$right
</span>
</div>
HTML);
}
}
10 changes: 7 additions & 3 deletions src/ResultPrinters/Progress.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public function tail(): void
<div class="flex mx-2">
<span class="text-gray">$date</span>
<span class="flex-1"></span>
<span class="text-gray">Running stress test on <span class="text-blue">$domain</span></span>
<span class="text-gray">Stress testing <span class="text-blue">$domain</span></span>
</div>
HTML);

Expand All @@ -55,7 +55,11 @@ public function tail(): void
$buffer = '';
$lastTime = null;
while ($this->process->isRunning()) {
$output = $tail->getIncrementalOutput();
$output = trim($tail->getIncrementalOutput());

if ($output === '') {
continue;
}

$output = $buffer.$output;
$buffer = '';
Expand All @@ -65,7 +69,7 @@ public function tail(): void
foreach ($lines as $line) {
if (str_starts_with($line, '{"metric":"http_req_duration","type":"Point"')) {
/** @var array{data: array{time: string, value: float}}|null $point */
$point = json_decode($line, true, 512, JSON_THROW_ON_ERROR);
$point = json_decode($line, true);

if (is_array($point)) {
$currentTime = substr($point['data']['time'], 0, 19);
Expand Down
5 changes: 5 additions & 0 deletions src/Run.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

use Pest\Exceptions\ShouldNotHappen;
use Pest\Stressless\ResultPrinters\Blocks;
use Pest\Stressless\ResultPrinters\Detail;
use Pest\Stressless\ResultPrinters\Progress;
use Pest\Stressless\ValueObjects\Binary;
use Pest\Stressless\ValueObjects\Result;
Expand Down Expand Up @@ -72,6 +73,10 @@ public function start(): Result
$blocks = new Blocks();

$blocks->print($result);

$detail = new Detail();

$detail->print($result);
}

$session->clean();
Expand Down
Loading

0 comments on commit 99e7c5f

Please sign in to comment.