acdream/tests/AcDream.Launcher.Core.Tests/Updates/LiveGiteaReleaseInstallTests.cs
Erik 657ac6baca
Some checks failed
CI / windows-gate (push) Has been cancelled
CI / linux-portable (push) Has been cancelled
CI / release (push) Has been cancelled
test: prove a launcher installs the client from the live Gitea release
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.
2026-08-19 13:43:12 +02:00

89 lines
3.6 KiB
C#

using AcDream.Launcher.Core.Orchestration;
using AcDream.Launcher.Core.Profiles;
using AcDream.Launcher.Core.Updates;
using AcDream.Platform;
namespace AcDream.Launcher.Core.Tests.Updates;
/// <summary>
/// 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
/// <see cref="ReleaseManifestClient.ProductionManifestUri"/>, real network,
/// real SHA-256/size verification, real ZIP extraction and atomic activation.
///
/// <para>
/// Lane=Live: it needs the public feed to be reachable, so the bounded gate
/// excludes it. Run it deliberately after a release lands:
/// <c>dotnet test tests/AcDream.Launcher.Core.Tests --filter Lane=Live</c>.
/// Everything is written under an isolated temporary path set, never the
/// caller's real launcher data directory.
/// </para>
/// </summary>
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);
}
}