Skip to content

Commit 06bd3f3

Browse files
committed
Fix: Make external LocalStack detection more lenient
Accept LocalStack instances that respond with HTTP 200 even if services aren't fully initialized yet. This prevents port conflicts when multiple tests try to start LocalStack simultaneously - they'll detect and reuse the existing container instead of trying to create new ones. The service readiness check is handled by WaitForServicesAsync with the proper 90s timeout for CI environments.
1 parent c85cb4e commit 06bd3f3

File tree

1 file changed

+21
-33
lines changed

1 file changed

+21
-33
lines changed

tests/SourceFlow.Cloud.AWS.Tests/TestHelpers/LocalStackManager.cs

Lines changed: 21 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -523,50 +523,38 @@ private async Task<bool> IsExternalLocalStackAvailableAsync(string endpoint)
523523
return false;
524524
}
525525

526-
// Parse JSON response to verify services are "available"
526+
// If we get HTTP 200, LocalStack is running - accept it even if services aren't fully ready yet
527+
// We'll wait for services to become ready in WaitForServicesAsync
527528
var content = await response.Content.ReadAsStringAsync();
528-
var healthData = JsonSerializer.Deserialize<LocalStackHealthResponse>(content);
529529

530-
if (healthData?.Services == null || healthData.Services.Count == 0)
530+
try
531531
{
532-
_logger.LogDebug("External LocalStack health check returned no services (attempt {Attempt}/{MaxAttempts})",
533-
attempt, maxAttempts);
532+
var healthData = JsonSerializer.Deserialize<LocalStackHealthResponse>(content);
534533

535-
if (attempt < maxAttempts)
534+
if (healthData?.Services != null && healthData.Services.Count > 0)
536535
{
537-
await Task.Delay(retryDelay);
538-
continue;
536+
var serviceStatus = healthData.Services
537+
.Select(s => $"{s.Key}:{s.Value}")
538+
.ToList();
539+
540+
_logger.LogInformation("Successfully detected external LocalStack instance at {Endpoint} with {ServiceCount} services: {Services} (response time: {ResponseTime}ms)",
541+
endpoint, healthData.Services.Count, string.Join(", ", serviceStatus), responseTime.TotalMilliseconds);
539542
}
540-
return false;
541-
}
542-
543-
// Check if all services are available or running
544-
var availableServices = healthData.Services
545-
.Where(s => s.Value == "available" || s.Value == "running")
546-
.Select(s => s.Key)
547-
.ToList();
548-
549-
var unavailableServices = healthData.Services
550-
.Where(s => s.Value != "available" && s.Value != "running")
551-
.Select(s => $"{s.Key}:{s.Value}")
552-
.ToList();
553-
554-
if (unavailableServices.Any())
555-
{
556-
_logger.LogDebug("External LocalStack has unavailable services: {UnavailableServices} (attempt {Attempt}/{MaxAttempts}, response time: {ResponseTime}ms)",
557-
string.Join(", ", unavailableServices), attempt, maxAttempts, responseTime.TotalMilliseconds);
558-
559-
if (attempt < maxAttempts)
543+
else
560544
{
561-
await Task.Delay(retryDelay);
562-
continue;
545+
_logger.LogInformation("Successfully detected external LocalStack instance at {Endpoint} (services still initializing, response time: {ResponseTime}ms)",
546+
endpoint, responseTime.TotalMilliseconds);
563547
}
564-
return false;
548+
}
549+
catch (JsonException)
550+
{
551+
// JSON parsing failed, but we got HTTP 200, so LocalStack is running
552+
_logger.LogInformation("Successfully detected external LocalStack instance at {Endpoint} (health endpoint responded, response time: {ResponseTime}ms)",
553+
endpoint, responseTime.TotalMilliseconds);
565554
}
566555

567556
var totalTime = DateTime.UtcNow - startTime;
568-
_logger.LogInformation("Successfully detected external LocalStack instance at {Endpoint} with {ServiceCount} available services: {Services} (total time: {TotalTime}ms, response time: {ResponseTime}ms)",
569-
endpoint, availableServices.Count, string.Join(", ", availableServices), totalTime.TotalMilliseconds, responseTime.TotalMilliseconds);
557+
_logger.LogDebug("External LocalStack detection succeeded after {TotalTime}ms", totalTime.TotalMilliseconds);
570558

571559
return true;
572560
}

0 commit comments

Comments
 (0)