From 88194dae1efee7f2e91eac21f3951dc161645296 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Deniz=20=C4=B0rgin?= Date: Sun, 18 Oct 2026 01:51:38 +0300 Subject: [PATCH] test: a live service starts on the caller's config dir and serves the saved one after startup At the 2.0.32 pin the service re-applies its saved service-config env once it has started: the port comes from the caller's config directory, read at startup, while config discovery after startup uses the saved directory. --- .../Ensure/OpenCodeServerEnsureLiveTests.cs | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/tests/OpenCode.Sdk.Tests/Hosting/BackgroundService/Ensure/OpenCodeServerEnsureLiveTests.cs b/tests/OpenCode.Sdk.Tests/Hosting/BackgroundService/Ensure/OpenCodeServerEnsureLiveTests.cs index 35174262..a23cba07 100644 --- a/tests/OpenCode.Sdk.Tests/Hosting/BackgroundService/Ensure/OpenCodeServerEnsureLiveTests.cs +++ b/tests/OpenCode.Sdk.Tests/Hosting/BackgroundService/Ensure/OpenCodeServerEnsureLiveTests.cs @@ -1,5 +1,7 @@ using System.Text; +using System.Text.Json.Nodes; using OpenCode.Sdk.Internal; +using OpenCode.Sdk.Models; using OpenCode.Sdk.Tests.Harness; using OpenCode.Sdk.Tests.Hosting.BackgroundService.Support; using OpenCode.Sdk.Tests.Support; @@ -168,6 +170,43 @@ await Assert.That(result.StandardOutput.Trim()) await Assert.That(await context.ReadLiveContendersAsync(cancellationToken)).IsNotEmpty(); } + [Test] + [Timeout(180_000)] + public async Task EnsureAsync_Should_Start_On_The_Callers_Config_Dir_And_Serve_The_Saved_One_After_Startup(CancellationToken cancellationToken) + { + var context = Context; + var callerDirectory = context.Environment["OPENCODE_CONFIG_DIR"]; + var savedDirectory = FileSystem.Path.Combine(context.RunRoot, "saved-config"); + var channelFile = FileSystem.Path.GetFileName(context.RegistrationFile); + var ports = LoopbackPortReservation.ReservePair(); + var savedPort = EnsureServiceContext.RefuseRealDaemonPort(ports.First != context.Port ? ports.First : ports.Second); + + await SeedAsync(FileSystem.Path.Combine(callerDirectory, channelFile), new JsonObject + { + ["port"] = context.Port, + ["env"] = new JsonObject { ["OPENCODE_CONFIG_DIR"] = savedDirectory }, + }.ToJsonString()); + await SeedAsync(FileSystem.Path.Combine(savedDirectory, channelFile), new JsonObject + { + ["port"] = savedPort, + }.ToJsonString()); + + await using var server = await context.EnsureAsync(EnsureOptions(context), cancellationToken); + + // The service config is selected before the saved environment is applied. + await Assert.That(server.Endpoint.Port).IsEqualTo(context.Port); + + using var client = server.CreateClient(options => + options.Location = new LocationSelector { Directory = context.RunRoot }); + var response = await client.Config.GetConfigAsync(cancellationToken: cancellationToken); + var directories = response.Config.OfType() + .Select(directory => FileSystem.Path.GetFullPath(directory.Path)).ToList(); + + // Application config discovery reads the saved environment after startup. + await Assert.That(directories).Contains(FileSystem.Path.GetFullPath(savedDirectory)); + await Assert.That(directories).DoesNotContain(FileSystem.Path.GetFullPath(callerDirectory)); + } + [Test] [Timeout(180_000)] public async Task EnsureAsync_Should_Elect_One_Service_Across_Ten_Concurrent_Callers(CancellationToken cancellationToken)