namespace Zcbot.WindowsNode.Tests; public sealed class WorkspaceCompatibilityTests : IDisposable { private readonly string root = Path.Combine( Path.GetTempPath(), "zcbot-workspace-tests", Guid.NewGuid().ToString("N")); [Fact] public void NewWorkspacePromotesOutputAndPersistsHeadMetadata() { var workspaceId = Guid.NewGuid(); var job = CreateJob(workspaceId, sourceJobId: null, mode: "new"); var paths = Paths(); var store = new WorkspaceStore(paths); store.Prepare(job, "origin.plot@v2"); var output = Path.Combine(paths.JobsDirectory, job.JobId.ToString("D"), "output"); Directory.CreateDirectory(output); File.WriteAllText(Path.Combine(output, "project.opju"), "workspace-state"); var size = store.Promote(job, "origin.plot@v2", "project.opju"); Assert.True(size > 0); Assert.True(File.Exists(Path.Combine( paths.WorkspacesDirectory, workspaceId.ToString("D"), "current", "project.opju"))); Assert.True(File.Exists(Path.Combine( paths.JobsDirectory, job.JobId.ToString("D"), "workspace-result.json"))); } [Fact] public void FailedContinuationRestoresThePreviousCurrentDirectory() { var workspaceId = Guid.NewGuid(); var first = CreateJob(workspaceId, sourceJobId: null, mode: "new"); var paths = Paths(); var store = new WorkspaceStore(paths); store.Prepare(first, "origin.plot@v2"); var firstOutput = Path.Combine( paths.JobsDirectory, first.JobId.ToString("D"), "output"); Directory.CreateDirectory(firstOutput); File.WriteAllText(Path.Combine(firstOutput, "project.opju"), "stable-state"); store.Promote(first, "origin.plot@v2", "project.opju"); var continued = CreateJob(workspaceId, first.JobId, "continue"); store.Prepare(continued, "origin.plot@v2"); store.Restore(continued); var current = store.CurrentDirectory(continued); Assert.Equal("stable-state", File.ReadAllText(Path.Combine(current, "project.opju"))); Assert.False(Directory.Exists(Path.Combine( paths.WorkspacesDirectory, workspaceId.ToString("D"), "rollback"))); } public void Dispose() { if (Directory.Exists(root)) { Directory.Delete(root, recursive: true); } } private NodePaths Paths() => new( root, Path.Combine(root, "node.json"), Path.Combine(root, "jobs"), Path.Combine(root, "workspaces")); private static RecoverableJob CreateJob( Guid workspaceId, Guid? sourceJobId, string mode) => new( Guid.NewGuid(), Guid.NewGuid(), new string('a', 64), "origin.plot@v2", new WorkspaceBinding(workspaceId, sourceJobId, mode), null, null, false, false); }