Skip to content

Commit

Permalink
feat(binary-download): refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
nunomaduro committed Nov 8, 2023
1 parent 82b4e6a commit cb398d8
Show file tree
Hide file tree
Showing 9 changed files with 93 additions and 188 deletions.
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
/bin/summary.json
/bin/k6*
/bin/*_summary.json
/bin/*_progress.json
.idea/*
.idea/codeStyleSettings.xml
composer.lock
Expand Down
1 change: 0 additions & 1 deletion phpstan.neon
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,3 @@ parameters:
ignoreErrors:
- "#Undefined variable: \\$this#"
- "#Short ternary operator is not allowed#"
- "#Class \"Pest\\\\Stressless\\\\Binaries\\\\K6\" is not allowed to extend \"Pest\\\\Stressless\\\\Contracts\\\\Binary\"#"
81 changes: 0 additions & 81 deletions src/Contracts/Binary.php

This file was deleted.

21 changes: 0 additions & 21 deletions src/Contracts/Block.php

This file was deleted.

114 changes: 70 additions & 44 deletions src/Binaries/K6.php → src/K6.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,94 +2,89 @@

declare(strict_types=1);

namespace Pest\Stressless\Binaries;
namespace Pest\Stressless;

use PharData;
use RuntimeException;
use Stringable;
use ZipArchive;
use Pest\Stressless\Contracts\Binary;

final class K6 extends Binary
final readonly class K6 implements Stringable
{
/**
* The k6 version to use.
* The path to the bin directory.
*/
protected const BIN_DIR = __DIR__.'/../bin/';

/**
* The version of k6 to download.
*/
public const K6_VERSION = 'v0.47.0';

/**
* The k6 binary name format.
* The order of the arguments is (version, os, arch, extension).
* The path where the k6 binary is stored relative to the root
* directory. The arguments are (version, os, arch, extension).
*/
private const K6 = 'k6-%s-%s-%s/k6%s';

/**
* The k6 binary url format.
* The order of the arguments is (version, version, os, arch, extension).
* The URL to the k6 binary. The arguments are (version, version, os, arch, extension).
*/
private const K6_URL = 'https://github.com/grafana/k6/releases/download/%s/k6-%s-%s-%s.%s';

/**
* @inheritDoc
* Creates a new binary instance.
*/
public static function new(): self
private function __construct(private string $path)
{
//
}

/**
* Creates a new binary instance from the environment.
*/
public static function make(): self
{
/**
* Get the path to the binary
*/
$path = self::path();

/**
* If the file does not exist, download it
*/
if (!self::exists()) {
if (! self::exists()) {
self::download();
}

return new self((string) realpath($path));
}

/**
* @inheritDoc
*/
protected static function path(): string
private static function path(): string
{
$os = self::os();
$os = self::os();
$arch = self::arch();

return self::BIN_DIR.sprintf(self::K6, self::K6_VERSION, $os, $arch, ($os === 'windows' ? '.exe' : ''));
}

/**
* @inheritDoc
*/
public static function exists(): bool
{
return file_exists(self::path());
}

/**
* @inheritDoc
*/
public static function download(): void
{
if(self::exists()) {
if (self::exists()) {
return;
}

$os = self::os();
$os = self::os();
$arch = self::arch();

$extension = ($os === 'linux' ? 'tar.gz' : 'zip');
$url = sprintf(self::K6_URL, self::K6_VERSION, self::K6_VERSION, $os, $arch, $extension);
$fileName = basename($url);
$url = sprintf(self::K6_URL, self::K6_VERSION, self::K6_VERSION, $os, $arch, $extension);
$fileName = basename($url);

/**
* Download the archive
*/
if (false === ($binary = file_get_contents($url))) {
throw new RuntimeException('Unable to download k6 binary.');
}
if (false === file_put_contents(self::BIN_DIR.$fileName, $binary)) {

if (file_put_contents(self::BIN_DIR.$fileName, $binary) === false) {
throw new RuntimeException('Unable to save k6 binary.');
}

Expand All @@ -98,7 +93,7 @@ public static function download(): void
'zip' => self::extractZip($fileName)
};

if (!self::executable(self::path())) {
if (! self::ensureExecutable(self::path())) {
throw new RuntimeException('Unable to make k6 binary executable.');
}
}
Expand All @@ -114,9 +109,6 @@ private static function extractTarGz(string $fileName): void
$tar = new PharData(self::BIN_DIR.str_replace('.gz', '', $fileName));
$tar->extractTo(self::BIN_DIR);

/**
* Remove the archive
*/
unlink(self::BIN_DIR.str_replace('.gz', '', $fileName));
unlink(self::BIN_DIR.$fileName);
}
Expand All @@ -128,16 +120,50 @@ private static function extractZip(string $fileName): void
{
$zip = new ZipArchive();

if (true !== $zip->open(self::BIN_DIR.$fileName)) {
if ($zip->open(self::BIN_DIR.$fileName) !== true) {
throw new RuntimeException('Unable to open k6 zip archive.');
}

$zip->extractTo(self::BIN_DIR);
$zip->close();

/**
* Remove the archive
*/
unlink(self::BIN_DIR.$fileName);
}

/**
* Returns the computer's architecture.
*/
private static function arch(): string
{
return str_contains(php_uname('m'), 'arm') ? 'arm64' : 'amd64';
}

/**
* Returns the operating system.
*/
private static function os(): string
{
return match (PHP_OS_FAMILY) {
'Darwin' => 'macos',
'Linux' => 'linux',
'Windows' => 'windows',
default => throw new RuntimeException('Unsupported OS.'),
};
}

/**
* Make the binary executable.
*/
private static function ensureExecutable(string $binary): bool
{
return chmod($binary, 0755);
}

/**
* The string representation of the binary.
*/
public function __toString(): string
{
return $this->path;
}
}
11 changes: 6 additions & 5 deletions src/Printers/Detail.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
use Pest\Stressless\Result;

use function Termwind\render;
use function Termwind\terminal;

/**
* @internal
Expand All @@ -31,18 +30,20 @@ public function print(Result $result): void
$color = $this->color($result->requests->dnsLookup->duration->avg, 20.0, 50.0, 100.0);
$value = $this->ms($result->requests->dnsLookup->duration->avg);

// map all IPv4 and IPv6 addresses of the given domain
$domain = $result->url();
$domain = (string) parse_url($domain, PHP_URL_HOST);
$dnsRecords = dns_get_record($domain, DNS_AAAA + DNS_A);
$dnsRecords = array_map(fn (array $record): string => $record['ipv6'] ?? $record['ip'], $dnsRecords ?: []);
$dnsRecords = array_unique($dnsRecords);
$dnsRecords = implode(', ', $dnsRecords);

if (strlen($dnsRecords) > 0 && strlen($dnsRecords) > ($size = terminal()->width() - 30)) {
$dnsRecords = substr($dnsRecords, 0, $size).'(…)';
if (count($dnsRecords) > 2) {
$lastDnsRecord = '(+ '.(count($dnsRecords) - 2).' more)';
$dnsRecords = array_slice($dnsRecords, 0, 2);
$dnsRecords[] = $lastDnsRecord;
}

$dnsRecords = implode(', ', $dnsRecords);

$this->twoColumnDetail('DNS Lookup Duration', <<<HTML
<span class="text-gray mr-1">$dnsRecords</span>
<span class="$color">$value</span>
Expand Down
26 changes: 0 additions & 26 deletions src/Printers/Info.php

This file was deleted.

Loading

0 comments on commit cb398d8

Please sign in to comment.