215 lines
8.7 KiB
C#
215 lines
8.7 KiB
C#
using AcDream.Launcher.Core.Updates;
|
|
using AcDream.Platform;
|
|
|
|
namespace AcDream.Launcher.Core.Tests.Updates;
|
|
|
|
public sealed class LauncherUpdaterIntegrationTests : IDisposable
|
|
{
|
|
private readonly string _root = Path.Combine(
|
|
Path.GetTempPath(),
|
|
"acdream-updater-integration-tests",
|
|
Guid.NewGuid().ToString("N"));
|
|
private readonly ApplicationPathSet _paths;
|
|
private readonly string _rid = LauncherRuntimeIdentity.DetectRid();
|
|
|
|
public LauncherUpdaterIntegrationTests() => _paths = UpdateTestData.Paths(_root);
|
|
|
|
public void Dispose()
|
|
{
|
|
if (Directory.Exists(_root))
|
|
{
|
|
Directory.Delete(_root, recursive: true);
|
|
}
|
|
}
|
|
|
|
[Fact]
|
|
public async Task LocalHttpManifestDownloadExtractPromotionAndNextCheckAreCoherent()
|
|
{
|
|
using var server = new LocalHttpFixture();
|
|
byte[] client = UpdateTestData.ClientZip(_rid, "release-2");
|
|
byte[] launcher = UpdateTestData.LauncherZip(_rid, "release-2");
|
|
ConfigureRelease(server, "2.0.0", "1.0.0", _rid, client, launcher);
|
|
using var http = new HttpClient();
|
|
using var source = ReleaseManifestClient.CreateLoopbackFixture(
|
|
server.UriFor("manifest.json"));
|
|
var versions = new ClientVersionStore(_paths);
|
|
var updater = new LauncherUpdater(
|
|
source,
|
|
http,
|
|
versions,
|
|
new LauncherSelfUpdateManager(_paths, http),
|
|
LauncherVersion.Parse("1.0.0"),
|
|
_rid,
|
|
Path.Combine(_root, "launcher"));
|
|
_ = await updater.InitializeAsync();
|
|
var progress = new List<LauncherUpdateProgress>();
|
|
|
|
LauncherUpdateCheckResult check = await updater.CheckAsync();
|
|
ClientVersionResolution installed = await updater.InstallClientAsync(
|
|
check,
|
|
new ImmediateProgress(progress.Add));
|
|
LauncherUpdateCheckResult after = await updater.CheckAsync();
|
|
|
|
Assert.True(check.IsClientUpdateAvailable);
|
|
Assert.True(check.IsLauncherUpdateAvailable);
|
|
Assert.True(check.IsLauncherMinimumSatisfied);
|
|
Assert.True(installed.IsVerified);
|
|
Assert.Equal("2.0.0", installed.Version!.Value);
|
|
Assert.False(after.IsClientUpdateAvailable);
|
|
Assert.True(after.IsLauncherUpdateAvailable);
|
|
Assert.Contains(progress, item => item.Phase == LauncherUpdatePhase.DownloadingClient);
|
|
Assert.Contains(progress, item => item.Phase == LauncherUpdatePhase.ExtractingClient);
|
|
Assert.Contains(progress, item => item.Phase == LauncherUpdatePhase.ActivatingClient);
|
|
Assert.Equal(LauncherUpdatePhase.Completed, progress[^1].Phase);
|
|
Assert.Empty(Directory.EnumerateFiles(
|
|
versions.AppDirectory,
|
|
".client-download-*",
|
|
SearchOption.TopDirectoryOnly));
|
|
}
|
|
|
|
[Fact]
|
|
public async Task MinimumLauncherGateAndMissingRidFailBeforePublication()
|
|
{
|
|
using var server = new LocalHttpFixture();
|
|
byte[] client = UpdateTestData.ClientZip(_rid);
|
|
byte[] launcher = UpdateTestData.LauncherZip(_rid);
|
|
ConfigureRelease(server, "3.0.0", "2.0.0", _rid, client, launcher);
|
|
using var http = new HttpClient();
|
|
using var source = ReleaseManifestClient.CreateLoopbackFixture(
|
|
server.UriFor("manifest.json"));
|
|
var versions = new ClientVersionStore(_paths);
|
|
var updater = new LauncherUpdater(
|
|
source,
|
|
http,
|
|
versions,
|
|
new LauncherSelfUpdateManager(_paths, http),
|
|
LauncherVersion.Parse("1.0.0"),
|
|
_rid,
|
|
Path.Combine(_root, "launcher"));
|
|
_ = await updater.InitializeAsync();
|
|
|
|
LauncherUpdateCheckResult check = await updater.CheckAsync();
|
|
Assert.False(check.IsLauncherMinimumSatisfied);
|
|
await Assert.ThrowsAsync<LauncherUpdateException>(() =>
|
|
updater.InstallClientAsync(check));
|
|
Assert.False(File.Exists(versions.CurrentPointerPath));
|
|
|
|
string otherRid = _rid == "win-x64" ? "linux-x64" : "win-x64";
|
|
ConfigureRelease(server, "3.0.0", "1.0.0", otherRid,
|
|
UpdateTestData.ClientZip(otherRid), UpdateTestData.LauncherZip(otherRid));
|
|
LauncherUpdateException missingRid = await Assert.ThrowsAsync<LauncherUpdateException>(
|
|
() => updater.CheckAsync());
|
|
Assert.Contains(_rid, missingRid.Message, StringComparison.Ordinal);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task RunningPredicateAndCrossProcessBarrierRefuseUpdateWithoutNetworkMutation()
|
|
{
|
|
using var server = new LocalHttpFixture();
|
|
byte[] client = UpdateTestData.ClientZip(_rid);
|
|
byte[] launcher = UpdateTestData.LauncherZip(_rid);
|
|
ConfigureRelease(server, "2.0.0", "1.0.0", _rid, client, launcher);
|
|
using var http = new HttpClient();
|
|
using var source = ReleaseManifestClient.CreateLoopbackFixture(
|
|
server.UriFor("manifest.json"));
|
|
var versions = new ClientVersionStore(_paths);
|
|
bool running = true;
|
|
var updater = new LauncherUpdater(
|
|
source,
|
|
http,
|
|
versions,
|
|
new LauncherSelfUpdateManager(_paths, http),
|
|
LauncherVersion.Parse("1.0.0"),
|
|
_rid,
|
|
Path.Combine(_root, "launcher"),
|
|
() => running);
|
|
_ = await updater.InitializeAsync();
|
|
LauncherUpdateCheckResult check = await updater.CheckAsync();
|
|
|
|
LauncherUpdateException local = await Assert.ThrowsAsync<LauncherUpdateException>(() =>
|
|
updater.InstallClientAsync(check));
|
|
Assert.Contains("Stop every", local.Message, StringComparison.Ordinal);
|
|
Assert.False(File.Exists(versions.CurrentPointerPath));
|
|
|
|
running = false;
|
|
using UpdateSessionBarrier.SessionLease session = versions.Barrier.AcquireSession();
|
|
LauncherUpdateException shared = await Assert.ThrowsAsync<LauncherUpdateException>(() =>
|
|
updater.InstallClientAsync(check));
|
|
Assert.Contains("session", shared.Message, StringComparison.OrdinalIgnoreCase);
|
|
Assert.False(File.Exists(versions.CurrentPointerPath));
|
|
}
|
|
|
|
[Fact]
|
|
public async Task CancelledSlowClientDownloadLeavesNoPointerOrStaging()
|
|
{
|
|
using var server = new LocalHttpFixture();
|
|
byte[] client = UpdateTestData.ClientZip(_rid, new string('x', 1_000_000));
|
|
byte[] launcher = UpdateTestData.LauncherZip(_rid);
|
|
server.Add("client.zip", client, chunkSize: 1024, chunkDelay: TimeSpan.FromMilliseconds(2));
|
|
server.Add("launcher.zip", launcher);
|
|
server.Add(
|
|
"manifest.json",
|
|
UpdateTestData.Manifest(
|
|
"2.0.0",
|
|
"1.0.0",
|
|
_rid,
|
|
server.UriFor("client.zip"),
|
|
client,
|
|
server.UriFor("launcher.zip"),
|
|
launcher),
|
|
contentType: "application/json");
|
|
using var http = new HttpClient();
|
|
using var source = ReleaseManifestClient.CreateLoopbackFixture(
|
|
server.UriFor("manifest.json"));
|
|
var versions = new ClientVersionStore(_paths);
|
|
var updater = new LauncherUpdater(
|
|
source,
|
|
http,
|
|
versions,
|
|
new LauncherSelfUpdateManager(_paths, http),
|
|
LauncherVersion.Parse("1.0.0"),
|
|
_rid,
|
|
Path.Combine(_root, "launcher"));
|
|
_ = await updater.InitializeAsync();
|
|
LauncherUpdateCheckResult check = await updater.CheckAsync();
|
|
using var cancellation = new CancellationTokenSource(TimeSpan.FromMilliseconds(30));
|
|
|
|
await Assert.ThrowsAnyAsync<OperationCanceledException>(() =>
|
|
updater.InstallClientAsync(check, cancellationToken: cancellation.Token));
|
|
|
|
Assert.False(File.Exists(versions.CurrentPointerPath));
|
|
Assert.Empty(Directory.EnumerateFileSystemEntries(
|
|
versions.AppDirectory,
|
|
".client-*",
|
|
SearchOption.TopDirectoryOnly));
|
|
}
|
|
|
|
private static void ConfigureRelease(
|
|
LocalHttpFixture server,
|
|
string version,
|
|
string minimum,
|
|
string rid,
|
|
byte[] client,
|
|
byte[] launcher)
|
|
{
|
|
server.Add("client.zip", client);
|
|
server.Add("launcher.zip", launcher);
|
|
server.Add(
|
|
"manifest.json",
|
|
UpdateTestData.Manifest(
|
|
version,
|
|
minimum,
|
|
rid,
|
|
server.UriFor("client.zip"),
|
|
client,
|
|
server.UriFor("launcher.zip"),
|
|
launcher),
|
|
contentType: "application/json");
|
|
}
|
|
|
|
private sealed class ImmediateProgress(Action<LauncherUpdateProgress> callback)
|
|
: IProgress<LauncherUpdateProgress>
|
|
{
|
|
public void Report(LauncherUpdateProgress value) => callback(value);
|
|
}
|
|
}
|