From 657ac6baca13761fd8f3c1338c8831859ac4d832 Mon Sep 17 00:00:00 2001 From: Erik Date: Wed, 19 Aug 2026 13:43:12 +0200 Subject: [PATCH] test: prove a launcher installs the client from the live Gitea release MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Lane=Live end-to-end verification against the real feed, using the production updater the GUI button calls: ReleaseManifestClient.ProductionManifestUri, real network, real SHA-256/size verification, real ZIP extraction, real atomic activation. Asserts what the launcher actually does next — that LauncherExecutableSet can resolve BOTH hosts out of the activated directory, and that current.json names the installed version — rather than merely that files exist. Excluded from the bounded gate (Lane=Live needs the public feed reachable); run deliberately after a release lands. Writes only under an isolated temporary path set, never the caller's real launcher data directory. --- .../Updates/LiveGiteaReleaseInstallTests.cs | 89 +++++++++++++++++++ 1 file changed, 89 insertions(+) create mode 100644 tests/AcDream.Launcher.Core.Tests/Updates/LiveGiteaReleaseInstallTests.cs diff --git a/tests/AcDream.Launcher.Core.Tests/Updates/LiveGiteaReleaseInstallTests.cs b/tests/AcDream.Launcher.Core.Tests/Updates/LiveGiteaReleaseInstallTests.cs new file mode 100644 index 00000000..ebbc188c --- /dev/null +++ b/tests/AcDream.Launcher.Core.Tests/Updates/LiveGiteaReleaseInstallTests.cs @@ -0,0 +1,89 @@ +using AcDream.Launcher.Core.Orchestration; +using AcDream.Launcher.Core.Profiles; +using AcDream.Launcher.Core.Updates; +using AcDream.Platform; + +namespace AcDream.Launcher.Core.Tests.Updates; + +/// +/// End-to-end proof that a launcher installs the client from the real Gitea +/// alpha release, using the PRODUCTION updater the GUI button calls — the same +/// , real network, +/// real SHA-256/size verification, real ZIP extraction and atomic activation. +/// +/// +/// Lane=Live: it needs the public feed to be reachable, so the bounded gate +/// excludes it. Run it deliberately after a release lands: +/// dotnet test tests/AcDream.Launcher.Core.Tests --filter Lane=Live. +/// Everything is written under an isolated temporary path set, never the +/// caller's real launcher data directory. +/// +/// +public sealed class LiveGiteaReleaseInstallTests : IDisposable +{ + private readonly string _root = Path.Combine( + Path.GetTempPath(), + "acdream-live-release-install", + Guid.NewGuid().ToString("N")); + private readonly ApplicationPathSet _paths; + private readonly string _rid = LauncherRuntimeIdentity.DetectRid(); + + public LiveGiteaReleaseInstallTests() => _paths = UpdateTestData.Paths(_root); + + public void Dispose() + { + if (Directory.Exists(_root)) + { + try { Directory.Delete(_root, recursive: true); } catch (IOException) { } + } + } + + [Fact] + [Trait("Lane", "Live")] + public async Task InstallsTheAdvertisedClientFromTheLiveGiteaRelease() + { + using var http = new HttpClient(); + using var source = new ReleaseManifestClient(TimeSpan.FromSeconds(30)); + var versions = new ClientVersionStore(_paths); + var updater = new LauncherUpdater( + source, + http, + versions, + new LauncherSelfUpdateManager(_paths, http), + // Deliberately ancient so the feed always advertises something + // newer; this asserts the INSTALL path, not the version compare. + LauncherVersion.Parse("0.0.1"), + _rid, + Path.Combine(_root, "launcher")); + + _ = await updater.InitializeAsync(); + + LauncherUpdateCheckResult check = await updater.CheckAsync(); + Assert.True( + check.IsClientUpdateAvailable, + $"The live feed advertised no client for RID '{_rid}': {check.Status}"); + + ClientVersionResolution installed = await updater.InstallClientAsync(check); + + Assert.True(installed.IsVerified, installed.Status); + Assert.Equal(check.Manifest.Version, installed.Version); + Assert.NotNull(installed.Directory); + + // The launcher resolves its hosts out of the activated directory, so + // assert what it will actually look for rather than merely "files exist". + var executables = LauncherExecutableSet.FromCurrentVersionStore(versions); + Assert.True( + executables.GetAvailability(LaunchMode.Gui).IsAvailable, + "The graphical client is not launchable from the installed release."); + Assert.True( + executables.GetAvailability(LaunchMode.Headless).IsAvailable, + "The headless host is not launchable from the installed release."); + + // current.json must point at exactly what was just activated. + Assert.True(File.Exists(versions.CurrentPointerPath)); + Assert.Contains( + check.Manifest.Version.Value, + await File.ReadAllTextAsync(versions.CurrentPointerPath), + StringComparison.Ordinal); + } +}