fix: enhance getRequiredPort to support map-style environment variables for SERVICE_URL and SERVICE_FQDN
This commit is contained in:
parent
85b73a8c00
commit
2edf2338de
2 changed files with 135 additions and 3 deletions
|
|
@ -208,10 +208,25 @@ public function getRequiredPort(): ?int
|
|||
// Extract SERVICE_URL and SERVICE_FQDN variables DIRECTLY DECLARED in this service's environment
|
||||
// (not variables that are merely referenced with ${VAR} syntax)
|
||||
$portFound = null;
|
||||
foreach ($environment as $envVar) {
|
||||
if (is_string($envVar)) {
|
||||
foreach ($environment as $key => $value) {
|
||||
if (is_int($key) && is_string($value)) {
|
||||
// List-style: "- SERVICE_URL_APP_3000" or "- SERVICE_URL_APP_3000=value"
|
||||
// Extract variable name (before '=' if present)
|
||||
$envVarName = str($envVar)->before('=')->trim();
|
||||
$envVarName = str($value)->before('=')->trim();
|
||||
|
||||
// Only process direct declarations
|
||||
if ($envVarName->startsWith('SERVICE_FQDN_') || $envVarName->startsWith('SERVICE_URL_')) {
|
||||
// Parse to check if it has a port suffix
|
||||
$parsed = parseServiceEnvironmentVariable($envVarName->value());
|
||||
if ($parsed['has_port'] && $parsed['port']) {
|
||||
// Found a port-specific variable for this service
|
||||
$portFound = (int) $parsed['port'];
|
||||
break;
|
||||
}
|
||||
}
|
||||
} elseif (is_string($key)) {
|
||||
// Map-style: "SERVICE_URL_APP_3000: value" or "SERVICE_FQDN_DB: localhost"
|
||||
$envVarName = str($key);
|
||||
|
||||
// Only process direct declarations
|
||||
if ($envVarName->startsWith('SERVICE_FQDN_') || $envVarName->startsWith('SERVICE_URL_')) {
|
||||
|
|
|
|||
|
|
@ -151,3 +151,120 @@
|
|||
|
||||
expect($result)->toBeFalse();
|
||||
});
|
||||
|
||||
it('detects port from map-style SERVICE_URL environment variable', function () {
|
||||
$yaml = <<<'YAML'
|
||||
services:
|
||||
trigger:
|
||||
environment:
|
||||
SERVICE_URL_TRIGGER_3000: ""
|
||||
OTHER_VAR: value
|
||||
YAML;
|
||||
|
||||
$service = Mockery::mock(Service::class)->makePartial();
|
||||
$service->docker_compose_raw = $yaml;
|
||||
$service->shouldReceive('getRequiredPort')->andReturn(null);
|
||||
|
||||
$app = Mockery::mock(ServiceApplication::class)->makePartial();
|
||||
$app->name = 'trigger';
|
||||
$app->shouldReceive('getAttribute')->with('service')->andReturn($service);
|
||||
$app->service = $service;
|
||||
|
||||
// Call the actual getRequiredPort method
|
||||
$result = $app->getRequiredPort();
|
||||
|
||||
expect($result)->toBe(3000);
|
||||
});
|
||||
|
||||
it('detects port from map-style SERVICE_FQDN environment variable', function () {
|
||||
$yaml = <<<'YAML'
|
||||
services:
|
||||
langfuse:
|
||||
environment:
|
||||
SERVICE_FQDN_LANGFUSE_3000: localhost
|
||||
DATABASE_URL: postgres://...
|
||||
YAML;
|
||||
|
||||
$service = Mockery::mock(Service::class)->makePartial();
|
||||
$service->docker_compose_raw = $yaml;
|
||||
$service->shouldReceive('getRequiredPort')->andReturn(null);
|
||||
|
||||
$app = Mockery::mock(ServiceApplication::class)->makePartial();
|
||||
$app->name = 'langfuse';
|
||||
$app->shouldReceive('getAttribute')->with('service')->andReturn($service);
|
||||
$app->service = $service;
|
||||
|
||||
$result = $app->getRequiredPort();
|
||||
|
||||
expect($result)->toBe(3000);
|
||||
});
|
||||
|
||||
it('returns null for map-style environment without port', function () {
|
||||
$yaml = <<<'YAML'
|
||||
services:
|
||||
db:
|
||||
environment:
|
||||
SERVICE_FQDN_DB: localhost
|
||||
SERVICE_URL_DB: http://localhost
|
||||
YAML;
|
||||
|
||||
$service = Mockery::mock(Service::class)->makePartial();
|
||||
$service->docker_compose_raw = $yaml;
|
||||
$service->shouldReceive('getRequiredPort')->andReturn(null);
|
||||
|
||||
$app = Mockery::mock(ServiceApplication::class)->makePartial();
|
||||
$app->name = 'db';
|
||||
$app->shouldReceive('getAttribute')->with('service')->andReturn($service);
|
||||
$app->service = $service;
|
||||
|
||||
$result = $app->getRequiredPort();
|
||||
|
||||
expect($result)->toBeNull();
|
||||
});
|
||||
|
||||
it('handles list-style environment with port', function () {
|
||||
$yaml = <<<'YAML'
|
||||
services:
|
||||
umami:
|
||||
environment:
|
||||
- SERVICE_URL_UMAMI_3000
|
||||
- DATABASE_URL=postgres://db/umami
|
||||
YAML;
|
||||
|
||||
$service = Mockery::mock(Service::class)->makePartial();
|
||||
$service->docker_compose_raw = $yaml;
|
||||
$service->shouldReceive('getRequiredPort')->andReturn(null);
|
||||
|
||||
$app = Mockery::mock(ServiceApplication::class)->makePartial();
|
||||
$app->name = 'umami';
|
||||
$app->shouldReceive('getAttribute')->with('service')->andReturn($service);
|
||||
$app->service = $service;
|
||||
|
||||
$result = $app->getRequiredPort();
|
||||
|
||||
expect($result)->toBe(3000);
|
||||
});
|
||||
|
||||
it('prioritizes first port found in environment', function () {
|
||||
$yaml = <<<'YAML'
|
||||
services:
|
||||
multi:
|
||||
environment:
|
||||
SERVICE_URL_MULTI_3000: ""
|
||||
SERVICE_URL_MULTI_8080: ""
|
||||
YAML;
|
||||
|
||||
$service = Mockery::mock(Service::class)->makePartial();
|
||||
$service->docker_compose_raw = $yaml;
|
||||
$service->shouldReceive('getRequiredPort')->andReturn(null);
|
||||
|
||||
$app = Mockery::mock(ServiceApplication::class)->makePartial();
|
||||
$app->name = 'multi';
|
||||
$app->shouldReceive('getAttribute')->with('service')->andReturn($service);
|
||||
$app->service = $service;
|
||||
|
||||
$result = $app->getRequiredPort();
|
||||
|
||||
// Should return one of the ports (depends on array iteration order)
|
||||
expect($result)->toBeIn([3000, 8080]);
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in a new issue