//
// Copyright (c) StellaOps. Licensed under AGPL-3.0-or-later.
//
// Sprint: SPRINT_20260105_002_005_TEST_cross_cutting
// Task: CCUT-020
using System.Collections.Immutable;
using FluentAssertions;
using Microsoft.Extensions.Logging.Abstractions;
using StellaOps.TestKit;
using StellaOps.Testing.ConfigDiff;
using Xunit;
namespace StellaOps.Concelier.ConfigDiff.Tests;
///
/// Config-diff tests for the Concelier module.
/// Verifies that configuration changes produce only expected behavioral deltas.
///
[Trait("Category", TestCategories.ConfigDiff)]
[Trait("Category", TestCategories.Integration)]
[Trait("BlastRadius", TestCategories.BlastRadius.Advisories)]
public class ConcelierConfigDiffTests : ConfigDiffTestBase
{
///
/// Initializes a new instance of the class.
///
public ConcelierConfigDiffTests()
: base(
new ConfigDiffTestConfig(StrictMode: true),
NullLogger.Instance)
{
}
///
/// Verifies that changing cache timeout only affects cache behavior.
///
[Fact]
public async Task ChangingCacheTimeout_OnlyAffectsCacheBehavior()
{
// Arrange
var baselineConfig = new ConcelierTestConfig
{
CacheTimeoutMinutes = 30,
MaxConcurrentDownloads = 10,
RetryCount = 3
};
var changedConfig = baselineConfig with
{
CacheTimeoutMinutes = 60
};
// Act
var result = await TestConfigIsolationAsync(
baselineConfig,
changedConfig,
changedSetting: "CacheTimeoutMinutes",
unrelatedBehaviors:
[
async config => await GetDownloadBehaviorAsync(config),
async config => await GetRetryBehaviorAsync(config),
async config => await GetParseBehaviorAsync(config)
]);
// Assert
result.IsSuccess.Should().BeTrue(
because: "changing cache timeout should not affect other behaviors");
}
///
/// Verifies that changing retry count produces expected behavioral delta.
///
[Fact]
public async Task ChangingRetryCount_ProducesExpectedDelta()
{
// Arrange
var baselineConfig = new ConcelierTestConfig { RetryCount = 3 };
var changedConfig = new ConcelierTestConfig { RetryCount = 5 };
var expectedDelta = new ConfigDelta(
ChangedBehaviors: ["MaxRetryAttempts", "FailureRecoveryWindow"],
BehaviorDeltas:
[
new BehaviorDelta("MaxRetryAttempts", "3", "5", null),
new BehaviorDelta("FailureRecoveryWindow", "increase", null,
"More retries extend recovery window")
]);
// Act
var result = await TestConfigBehavioralDeltaAsync(
baselineConfig,
changedConfig,
getBehavior: async config => await CaptureRetryBehaviorAsync(config),
computeDelta: ComputeBehaviorSnapshotDelta,
expectedDelta: expectedDelta);
// Assert
result.IsSuccess.Should().BeTrue(
because: "retry count change should produce expected behavioral delta");
}
///
/// Verifies that changing max concurrent downloads only affects concurrency.
///
[Fact]
public async Task ChangingMaxConcurrentDownloads_OnlyAffectsConcurrency()
{
// Arrange
var baselineConfig = new ConcelierTestConfig { MaxConcurrentDownloads = 5 };
var changedConfig = new ConcelierTestConfig { MaxConcurrentDownloads = 20 };
// Act
var result = await TestConfigIsolationAsync(
baselineConfig,
changedConfig,
changedSetting: "MaxConcurrentDownloads",
unrelatedBehaviors:
[
async config => await GetCacheBehaviorAsync(config),
async config => await GetRetryBehaviorAsync(config),
async config => await GetParseBehaviorAsync(config)
]);
// Assert
result.IsSuccess.Should().BeTrue(
because: "changing concurrency should not affect cache, retry, or parsing");
}
///
/// Verifies that enabling strict validation produces expected changes.
///
[Fact]
public async Task EnablingStrictValidation_ProducesExpectedDelta()
{
// Arrange
var baselineConfig = new ConcelierTestConfig { StrictValidation = false };
var changedConfig = new ConcelierTestConfig { StrictValidation = true };
var expectedDelta = new ConfigDelta(
ChangedBehaviors: ["ValidationStrictness", "RejectionRate"],
BehaviorDeltas:
[
new BehaviorDelta("ValidationStrictness", "relaxed", "strict", null),
new BehaviorDelta("RejectionRate", "increase", null,
"Strict validation rejects more malformed advisories")
]);
// Act
var result = await TestConfigBehavioralDeltaAsync(
baselineConfig,
changedConfig,
getBehavior: async config => await CaptureValidationBehaviorAsync(config),
computeDelta: ComputeBehaviorSnapshotDelta,
expectedDelta: expectedDelta);
// Assert
result.IsSuccess.Should().BeTrue();
}
// Helper methods to capture behaviors
private static Task