using Microsoft.Extensions.Options; namespace ZB.MOM.WW.ScadaBridge.DeploymentManager.Tests; /// /// Arch-review 08 ยง1.5: timeouts are /// applied as linked-CTS deadlines around lifecycle commands, per-site artifact /// deployment, and operation-lock acquisition. A zero/negative duration makes a /// deadline fire immediately (or a CancellationTokenSource constructor /// throw), so a misconfigured section must be rejected at startup with a clear, /// key-naming message rather than silently breaking deployments. /// public class DeploymentManagerOptionsValidatorTests { private static ValidateOptionsResult Validate(DeploymentManagerOptions options) => new DeploymentManagerOptionsValidator().Validate(Options.DefaultName, options); [Fact] public void DefaultOptions_AreValid() { var result = Validate(new DeploymentManagerOptions()); Assert.True(result.Succeeded, result.FailureMessage); } [Fact] public void ZeroLifecycleCommandTimeout_IsRejected() { var result = Validate(new DeploymentManagerOptions { LifecycleCommandTimeout = TimeSpan.Zero }); Assert.True(result.Failed); Assert.Contains("LifecycleCommandTimeout", result.FailureMessage); } [Fact] public void NegativeLifecycleCommandTimeout_IsRejected() { var result = Validate(new DeploymentManagerOptions { LifecycleCommandTimeout = TimeSpan.FromSeconds(-1) }); Assert.True(result.Failed); Assert.Contains("LifecycleCommandTimeout", result.FailureMessage); } [Fact] public void ZeroArtifactDeploymentTimeoutPerSite_IsRejected() { var result = Validate(new DeploymentManagerOptions { ArtifactDeploymentTimeoutPerSite = TimeSpan.Zero }); Assert.True(result.Failed); Assert.Contains("ArtifactDeploymentTimeoutPerSite", result.FailureMessage); } [Fact] public void ZeroOperationLockTimeout_IsRejected() { var result = Validate(new DeploymentManagerOptions { OperationLockTimeout = TimeSpan.Zero }); Assert.True(result.Failed); Assert.Contains("OperationLockTimeout", result.FailureMessage); } }