using System.Diagnostics;
using System.IO;
using XFEToolBox.Tools.SpaceEngineers;
using XFEToolBox.Tools.SpaceEngineers.ViewModels;
namespace SpaceEngineersPluginManager.Validation;
internal static partial class Program
{
private static async Task TestViewPollingAsync(LoaderFixture fixture, LoaderInstallation built)
{
string source = Path.Combine(fixture.Root, "VM Source"); Directory.CreateDirectory(source);
string entry = Path.Combine(source, "VmPlugin.dll"); File.Copy(fixture.Plugins[0], entry);
File.Copy(Path.Combine(Path.GetDirectoryName(fixture.Plugins[0])!, "FixtureDependency.dll"), Path.Combine(source, "FixtureDependency.dll"));
string options = Path.Combine(source, "options.json"); File.WriteAllText(options, "1");
var imported = PluginFiles.Import(entry, Path.Combine(fixture.Root, "VM Library"));
var host = new FixtureProcessHost(new(93, built.LauncherPath, DateTime.UtcNow)) { Alive = true, ExitOnClose = false };
using var service = CreateService("vm-polling", host, out _);
service.Settings.Bin64Path = fixture.Bin64; service.Settings.LauncherPath = built.LauncherPath; service.Settings.BridgePath = built.BridgePath;
service.Settings.RestartOnLocalChanges = true;
var profiles = new PluginProfileStore(); profiles.Save(profiles.Load(service.Settings.ProfilePath), [imported]);
var vm = new MainPageViewModel(service, pollingEnabled: false);
try
{
await vm.InitializeAsync(); await vm.PollOnceAsync();
File.WriteAllText(options, "2"); await vm.PollOnceAsync(); await Task.Delay(3150);
var synchronization = vm.PollOnceAsync();
var wait = Stopwatch.StartNew();
while (host.CloseRequests == 0) { if (wait.Elapsed > TimeSpan.FromSeconds(5)) throw new TimeoutException("VM watcher did not begin graceful close"); await Task.Delay(15); }
Check(vm.IsPolling && !vm.CanEdit && !vm.ApplyCommand.CanExecute(null) && !vm.LaunchCommand.CanExecute(null) && !vm.CloseGameCommand.CanExecute(null), "background synchronization disables editing and conflicting launch/close controls");
host.Alive = false; await synchronization;
string synchronized = profiles.Load(service.Settings.ProfilePath).Plugins.Single().AssemblyPath;
Check(synchronized != imported.AssemblyPath && vm.Plugins.Single().Location == synchronized, "view model refreshes managed DLL path after source synchronization commits");
vm.Plugins.Single().IsEnabled = false;
await vm.ApplyCommand.ExecuteAsync(null);
Check(profiles.Load(service.Settings.ProfilePath).Plugins.Single().AssemblyPath == synchronized && !vm.IsDirty, "subsequent UI apply cannot restore stale pre-synchronization DLL version");
vm.Plugins.Single().IsEnabled = true; await vm.ApplyCommand.ExecuteAsync(null); await vm.PollOnceAsync();
byte[] clean = File.ReadAllBytes(service.Settings.ProfilePath);
vm.Plugins.Single().IsEnabled = false;
File.WriteAllText(options, "3"); await vm.PollOnceAsync(); await Task.Delay(3150); await vm.PollOnceAsync();
Check(vm.IsDirty && File.ReadAllBytes(service.Settings.ProfilePath).SequenceEqual(clean), "pending UI checkbox edits pause automatic source synchronization without replacing draft");
vm.IsDirty = false;
File.Delete(entry); await vm.PollOnceAsync(); await Task.Delay(3150); await vm.PollOnceAsync();
Check(!service.Settings.RestartOnLocalChanges && !vm.RestartOnLocalChanges, "failed source synchronization pauses both service watcher and visible UI checkbox");
}
finally { await vm.ShutdownAsync(); }
}
}
using System.Diagnostics;
using System.IO;
using XFEToolBox.Tools.SpaceEngineers;
using XFEToolBox.Tools.SpaceEngineers.ViewModels;
namespace SpaceEngineersPluginManager.Validation;
internal static partial class Program
{
private static async Task TestViewPollingAsync(LoaderFixture fixture, LoaderInstallation built)
{
string source = Path.Combine(fixture.Root, "VM Source"); Directory.CreateDirectory(source);
string entry = Path.Combine(source, "VmPlugin.dll"); File.Copy(fixture.Plugins[0], entry);
File.Copy(Path.Combine(Path.GetDirectoryName(fixture.Plugins[0])!, "FixtureDependency.dll"), Path.Combine(source, "FixtureDependency.dll"));
string options = Path.Combine(source, "options.json"); File.WriteAllText(options, "1");
var imported = PluginFiles.Import(entry, Path.Combine(fixture.Root, "VM Library"));
var host = new FixtureProcessHost(new(93, built.LauncherPath, DateTime.UtcNow)) { Alive = true, ExitOnClose = false };
using var service = CreateService("vm-polling", host, out _);
service.Settings.Bin64Path = fixture.Bin64; service.Settings.LauncherPath = built.LauncherPath; service.Settings.BridgePath = built.BridgePath;
service.Settings.RestartOnLocalChanges = true;
var profiles = new PluginProfileStore(); profiles.Save(profiles.Load(service.Settings.ProfilePath), [imported]);
var vm = new MainPageViewModel(service, pollingEnabled: false);
try
{
await vm.InitializeAsync(); await vm.PollOnceAsync();
File.WriteAllText(options, "2"); await vm.PollOnceAsync(); await Task.Delay(3150);
var synchronization = vm.PollOnceAsync();
var wait = Stopwatch.StartNew();
while (host.CloseRequests == 0) { if (wait.Elapsed > TimeSpan.FromSeconds(5)) throw new TimeoutException("VM watcher did not begin graceful close"); await Task.Delay(15); }
Check(vm.IsPolling && !vm.CanEdit && !vm.ApplyCommand.CanExecute(null) && !vm.LaunchCommand.CanExecute(null) && !vm.CloseGameCommand.CanExecute(null), "background synchronization disables editing and conflicting launch/close controls");
host.Alive = false; await synchronization;
string synchronized = profiles.Load(service.Settings.ProfilePath).Plugins.Single().AssemblyPath;
Check(synchronized != imported.AssemblyPath && vm.Plugins.Single().Location == synchronized, "view model refreshes managed DLL path after source synchronization commits");
vm.Plugins.Single().IsEnabled = false;
await vm.ApplyCommand.ExecuteAsync(null);
Check(profiles.Load(service.Settings.ProfilePath).Plugins.Single().AssemblyPath == synchronized && !vm.IsDirty, "subsequent UI apply cannot restore stale pre-synchronization DLL version");
vm.Plugins.Single().IsEnabled = true; await vm.ApplyCommand.ExecuteAsync(null); await vm.PollOnceAsync();
byte[] clean = File.ReadAllBytes(service.Settings.ProfilePath);
vm.Plugins.Single().IsEnabled = false;
File.WriteAllText(options, "3"); await vm.PollOnceAsync(); await Task.Delay(3150); await vm.PollOnceAsync();
Check(vm.IsDirty && File.ReadAllBytes(service.Settings.ProfilePath).SequenceEqual(clean), "pending UI checkbox edits pause automatic source synchronization without replacing draft");
vm.IsDirty = false;
File.Delete(entry); await vm.PollOnceAsync(); await Task.Delay(3150); await vm.PollOnceAsync();
Check(!service.Settings.RestartOnLocalChanges && !vm.RestartOnLocalChanges, "failed source synchronization pauses both service watcher and visible UI checkbox");
}
finally { await vm.ShutdownAsync(); }
}
}