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.
89 lines
3.6 KiB
C#
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);
|
|
}
|
|
}
|