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
41 changes: 40 additions & 1 deletion src/Runtimes/Runtime.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,52 @@ class Runtime
*/
protected $versions = [];

/** @var string[] */
protected array $services;

public const SERVICE_FUNCTIONS = 'functions';
public const SERVICE_SITES = 'sites';

/**
* Runtime that can contain different Versions.
*
* @param string[] $services
*/
public function __construct(string $key, string $name, string $startCommand)
public function __construct(string $key, string $name, string $startCommand, array $services = [self::SERVICE_FUNCTIONS, self::SERVICE_SITES])
{
$this->key = $key;
$this->name = $name;
$this->startCommand = $startCommand;
$this->setServices($services);
}

/**
* Get services.
*
* @return string[]
*/
public function getServices(): array
Comment thread
Meldiron marked this conversation as resolved.
{
return $this->services;
}

/**
* Set services.
*
* @param string[] $services
*/
public function setServices(array $services): void
{
if (empty($services)) {
throw new \InvalidArgumentException('Runtime must be associated with at least one service.');
}
$validServices = [self::SERVICE_FUNCTIONS, self::SERVICE_SITES];
foreach ($services as $service) {
if (!\in_array($service, $validServices, true)) {
throw new \InvalidArgumentException("Invalid runtime service: {$service}");
}
}
$this->services = $services;
}

/**
Expand Down Expand Up @@ -68,6 +106,7 @@ public function list(): array
'name' => $this->name,
'logo' => "{$this->key}.png",
'startCommand' => $this->startCommand,
'services' => $this->services,
],
$version->get()
);
Expand Down
4 changes: 2 additions & 2 deletions src/Runtimes/Runtimes.php
Original file line number Diff line number Diff line change
Expand Up @@ -171,11 +171,11 @@ public function __construct(string $version = '')
$rust->addVersion('1.83', 'rust:1.83.0-alpine3.21', 'openruntimes/rust:'.$this->version.'-1.83', [System::X86, System::ARM64]);
$this->runtimes['rust'] = $rust;

$static = new Runtime('static', 'Static', 'bash helpers/server.sh');
$static = new Runtime('static', 'Static', 'bash helpers/server.sh', [Runtime::SERVICE_SITES]);
$static->addVersion('1', 'joseluisq/static-web-server:2.33-alpine', 'openruntimes/static:'.$this->version.'-1', [System::X86, System::ARM64]);
$this->runtimes['static'] = $static;

$flutter = new Runtime('flutter', 'Flutter', 'bash helpers/server.sh');
$flutter = new Runtime('flutter', 'Flutter', 'bash helpers/server.sh', [Runtime::SERVICE_SITES]);
$flutter->addVersion('3.24', 'ghcr.io/cirruslabs/flutter:3.24.5', 'openruntimes/flutter:'.$this->version.'-3.24', [System::X86, System::ARM64]);
$flutter->addVersion('3.27', 'ghcr.io/cirruslabs/flutter:3.27.3', 'openruntimes/flutter:'.$this->version.'-3.27', [System::X86, System::ARM64]);
$flutter->addVersion('3.29', 'ghcr.io/cirruslabs/flutter:3.29.1', 'openruntimes/flutter:'.$this->version.'-3.29', [System::X86, System::ARM64]);
Expand Down
75 changes: 75 additions & 0 deletions tests/Runtimes/RuntimesTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace Appwrite\Tests;

use Appwrite\Runtimes\Runtime;
use Appwrite\Runtimes\Runtimes;
use PHPUnit\Framework\TestCase;

Expand Down Expand Up @@ -195,10 +196,84 @@ public function testGetRuntimes(): void
$this->assertArrayHasKey('image', $runtime, $runtime['name']);
$this->assertArrayHasKey('logo', $runtime, $runtime['name']);
$this->assertArrayHasKey('supports', $runtime, $runtime['name']);
$this->assertArrayHasKey('services', $runtime, $runtime['name']);
$this->assertStringContainsString('v1-', $runtime['image']);

$this->assertIsArray($runtime['supports']);
$this->assertNotEmpty($runtime['supports']);
$this->assertIsArray($runtime['services']);
$this->assertNotEmpty($runtime['services']);
}
}

public function testFlutterAndStaticAreSiteOnly(): void
{
$flutter = $this->instance->get('flutter');
$this->assertEquals([Runtime::SERVICE_SITES], $flutter->getServices());

$static = $this->instance->get('static');
$this->assertEquals([Runtime::SERVICE_SITES], $static->getServices());
}

public function testDefaultRuntimesAvailableForBothServices(): void
{
$node = $this->instance->get('node');
$this->assertContains(Runtime::SERVICE_FUNCTIONS, $node->getServices());
$this->assertContains(Runtime::SERVICE_SITES, $node->getServices());
}

public function testServicesFieldInListOutput(): void
{
$node = $this->instance->get('node');
$versions = $node->list();

$this->assertArrayHasKey('node-18.0', $versions);
$this->assertArrayHasKey('services', $versions['node-18.0']);
$this->assertContains(Runtime::SERVICE_FUNCTIONS, $versions['node-18.0']['services']);
$this->assertContains(Runtime::SERVICE_SITES, $versions['node-18.0']['services']);
}

public function testSetServices(): void
{
$runtime = $this->instance->get('node');

$runtime->setServices([Runtime::SERVICE_FUNCTIONS]);
$this->assertEquals([Runtime::SERVICE_FUNCTIONS], $runtime->getServices());

$runtime->setServices([Runtime::SERVICE_SITES]);
$this->assertEquals([Runtime::SERVICE_SITES], $runtime->getServices());

$runtime->setServices([Runtime::SERVICE_FUNCTIONS, Runtime::SERVICE_SITES]);
$this->assertEquals([Runtime::SERVICE_FUNCTIONS, Runtime::SERVICE_SITES], $runtime->getServices());
}

public function testConstructorThrowsOnInvalidService(): void
{
$this->expectException(\InvalidArgumentException::class);
$this->expectExceptionMessage('Invalid runtime service: invalid');
new Runtime('test', 'Test', 'bash helpers/server.sh', ['invalid']);
}

public function testConstructorThrowsOnEmptyServices(): void
{
$this->expectException(\InvalidArgumentException::class);
$this->expectExceptionMessage('Runtime must be associated with at least one service.');
new Runtime('test', 'Test', 'bash helpers/server.sh', []);
}

public function testSetServicesThrowsOnEmptyArray(): void
{
$this->expectException(\InvalidArgumentException::class);
$this->expectExceptionMessage('Runtime must be associated with at least one service.');
$runtime = $this->instance->get('node');
$runtime->setServices([]);
}

public function testSetServicesThrowsOnInvalidService(): void
{
$this->expectException(\InvalidArgumentException::class);
$this->expectExceptionMessage('Invalid runtime service: invalid');
$runtime = $this->instance->get('node');
$runtime->setServices(['invalid']);
}
}
Loading