| 1 | using CascadeIDE.Cockpit.DataBus; |
| 2 | using CascadeIDE.Features.Agent.Environment; |
| 3 | using CascadeIDE.Models; |
| 4 | using Xunit; |
| 5 | |
| 6 | namespace CascadeIDE.Tests; |
| 7 | |
| 8 | public sealed class AgentAeeW3ToW6Tests |
| 9 | { |
| 10 | [Fact] |
| 11 | public void EpochTracker_MarksUiStaleOnWrite() |
| 12 | { |
| 13 | var tracker = new AgentVerifyEpochTracker(new InMemoryDataBus()); |
| 14 | tracker.Begin("run1", "snap1", @"C:\ws\s.sln"); |
| 15 | tracker.WatchPath(@"C:\ws\Foo.cs"); |
| 16 | |
| 17 | tracker.NotifyWrite(@"C:\ws\Foo.cs"); |
| 18 | |
| 19 | Assert.True(tracker.IsUiStale); |
| 20 | Assert.True(tracker.IsPathUiStale(@"C:\ws\Foo.cs")); |
| 21 | } |
| 22 | |
| 23 | [Fact] |
| 24 | public void DevServiceContractValidator_AcceptsEphemeralSubstrate() |
| 25 | { |
| 26 | var dir = Path.Combine(Path.GetTempPath(), "cide-dev-" + Guid.NewGuid().ToString("N")); |
| 27 | Directory.CreateDirectory(dir); |
| 28 | try |
| 29 | { |
| 30 | var bundle = AgentSandboxSubstrate.Allocate(dir); |
| 31 | var lease = new AgentSandboxLease("r", AgentSandboxProfile.AgentEphemeral, dir, dir, bundle); |
| 32 | var result = AgentDevServiceContractValidator.ValidateForTestScoped( |
| 33 | new AgentDevServiceContractSettings(), |
| 34 | AgentSandboxProfile.AgentEphemeral, |
| 35 | lease); |
| 36 | |
| 37 | Assert.True(result.Ok); |
| 38 | } |
| 39 | finally |
| 40 | { |
| 41 | try { Directory.Delete(dir, recursive: true); } catch { /* best-effort */ } |
| 42 | } |
| 43 | } |
| 44 | |
| 45 | [Fact] |
| 46 | public void DevServiceContractValidator_FailsWithoutSubstrateWhenGated() |
| 47 | { |
| 48 | var lease = new AgentSandboxLease("r", AgentSandboxProfile.AgentEphemeral, "x", "x", Substrate: null); |
| 49 | var result = AgentDevServiceContractValidator.ValidateForTestScoped( |
| 50 | new AgentDevServiceContractSettings { GateTestScopedOnViolation = true }, |
| 51 | AgentSandboxProfile.AgentEphemeral, |
| 52 | lease); |
| 53 | |
| 54 | Assert.False(result.Ok); |
| 55 | } |
| 56 | |
| 57 | [Fact] |
| 58 | public void SettingsToml_DeserializesDevServicesAndTestScopedFilter() |
| 59 | { |
| 60 | const string toml = """ |
| 61 | [agent.environment.dev_services] |
| 62 | require_config_override = false |
| 63 | gate_test_scoped_on_violation = false |
| 64 | |
| 65 | [agent.environment.ladder] |
| 66 | test_scoped_touched_tests_only = false |
| 67 | diagnose_files_enabled = true |
| 68 | """; |
| 69 | var s = CascadeIDE.Services.CascadeTomlSerializer.Deserialize<CascadeIdeSettings>(toml)!; |
| 70 | Assert.False(s.Agent.Environment.DevServices.RequireConfigOverride); |
| 71 | Assert.False(s.Agent.Environment.DevServices.GateTestScopedOnViolation); |
| 72 | Assert.False(s.Agent.Environment.Ladder.TestScopedTouchedTestsOnly); |
| 73 | Assert.True(s.Agent.Environment.Ladder.DiagnoseFilesEnabled); |
| 74 | } |
| 75 | |
| 76 | [Fact] |
| 77 | public void AgentOrchestrator_SkipsWithoutWrites() |
| 78 | { |
| 79 | var svc = new AgentEnvironmentService(new InMemoryDataBus(), new AgentEnvironmentSettings()); |
| 80 | var orch = svc.Orchestrator; |
| 81 | var result = orch.TryVerifyAfterStep(writesOccurred: false); |
| 82 | Assert.False(result.Accepted); |
| 83 | } |
| 84 | |
| 85 | [Fact] |
| 86 | public void IdleUserTracker_RecordsSliceOnFocusReturn() |
| 87 | { |
| 88 | var tracker = new AgentIdleUserTracker(); |
| 89 | tracker.NotifyCideFocus(false); |
| 90 | Thread.Sleep(60); |
| 91 | tracker.NotifyCideFocus(true); |
| 92 | var slices = tracker.DrainSlices(); |
| 93 | Assert.Contains(slices, s => s.Phase == AgentRunPhaseKind.IdleUser); |
| 94 | } |
| 95 | } |
| 96 | |