Files
git.stella-ops.org/src/__Libraries/__Tests/StellaOps.TestKit.Tests/InteropTests.cs
2026-01-28 02:30:48 +02:00

361 lines
10 KiB
C#

using FluentAssertions;
using StellaOps.TestKit.Interop;
using Xunit;
namespace StellaOps.TestKit.Tests;
/// <summary>
/// Unit tests for cross-version interoperability testing infrastructure.
/// </summary>
[Trait("Category", TestCategories.Unit)]
public sealed class InteropTests
{
#region SchemaVersionMatrix Tests
[Fact]
public void SchemaVersionMatrix_AddVersion_StoresSchema()
{
// Arrange
var matrix = new SchemaVersionMatrix();
var schema = new SchemaDefinition
{
RequiredFields = ["id", "name"]
};
// Act
matrix.AddVersion("1.0", schema);
// Assert
matrix.Versions.Should().Contain("1.0");
matrix.GetVersion("1.0").Should().Be(schema);
}
[Fact]
public void SchemaVersionMatrix_IsBackwardCompatible_ReturnsTrueWhenNoFieldsRemoved()
{
// Arrange
var matrix = new SchemaVersionMatrix();
matrix.AddVersion("1.0", new SchemaDefinition
{
RequiredFields = ["id", "name"]
});
matrix.AddVersion("2.0", new SchemaDefinition
{
RequiredFields = ["id", "name", "type"], // Added field, none removed
OptionalFields = ["description"]
});
// Act & Assert
matrix.IsBackwardCompatible("1.0", "2.0").Should().BeTrue();
}
[Fact]
public void SchemaVersionMatrix_IsBackwardCompatible_ReturnsFalseWhenFieldsRemoved()
{
// Arrange
var matrix = new SchemaVersionMatrix();
matrix.AddVersion("1.0", new SchemaDefinition
{
RequiredFields = ["id", "name", "oldField"]
});
matrix.AddVersion("2.0", new SchemaDefinition
{
RequiredFields = ["id", "name"] // oldField removed
});
// Act & Assert
matrix.IsBackwardCompatible("1.0", "2.0").Should().BeFalse();
}
[Fact]
public void SchemaVersionMatrix_IsForwardCompatible_ReturnsTrueWhenNewFieldsHaveDefaults()
{
// Arrange
var matrix = new SchemaVersionMatrix();
matrix.AddVersion("1.0", new SchemaDefinition
{
RequiredFields = ["id", "name"]
});
matrix.AddVersion("2.0", new SchemaDefinition
{
RequiredFields = ["id", "name", "type"],
FieldDefaults = new() { ["type"] = "default" }
});
// Act & Assert
matrix.IsForwardCompatible("1.0", "2.0").Should().BeTrue();
}
[Fact]
public void SchemaVersionMatrix_IsForwardCompatible_ReturnsFalseWhenNewRequiredFieldsHaveNoDefaults()
{
// Arrange
var matrix = new SchemaVersionMatrix();
matrix.AddVersion("1.0", new SchemaDefinition
{
RequiredFields = ["id", "name"]
});
matrix.AddVersion("2.0", new SchemaDefinition
{
RequiredFields = ["id", "name", "type"] // No default for "type"
});
// Act & Assert
matrix.IsForwardCompatible("1.0", "2.0").Should().BeFalse();
}
[Fact]
public void SchemaVersionMatrix_Analyze_GeneratesReport()
{
// Arrange
var matrix = new SchemaVersionMatrix();
matrix.AddVersion("1.0", new SchemaDefinition { RequiredFields = ["id"] });
matrix.AddVersion("2.0", new SchemaDefinition { RequiredFields = ["id", "name"] });
// Act
var report = matrix.Analyze();
// Assert
report.Versions.Should().Contain(["1.0", "2.0"]);
report.Pairs.Should().HaveCount(2); // 1.0->2.0 and 2.0->1.0
report.GeneratedAt.Should().BeCloseTo(DateTimeOffset.UtcNow, TimeSpan.FromSeconds(5));
}
[Fact]
public void SchemaVersionMatrix_Analyze_DetectsTypeChanges()
{
// Arrange
var matrix = new SchemaVersionMatrix();
matrix.AddVersion("1.0", new SchemaDefinition
{
RequiredFields = ["id"],
FieldTypes = new() { ["id"] = "int" }
});
matrix.AddVersion("2.0", new SchemaDefinition
{
RequiredFields = ["id"],
FieldTypes = new() { ["id"] = "string" } // Type changed
});
// Act
var report = matrix.Analyze();
// Assert
var pair = report.Pairs.First(p => p.FromVersion == "1.0" && p.ToVersion == "2.0");
pair.IsBackwardCompatible.Should().BeFalse();
pair.BackwardIssues.Should().Contain(i => i.Contains("Type changed"));
}
[Fact]
public void CompatibilityReport_ToMarkdown_ProducesValidMarkdown()
{
// Arrange
var matrix = new SchemaVersionMatrix();
matrix.AddVersion("1.0", new SchemaDefinition { RequiredFields = ["id"] });
matrix.AddVersion("2.0", new SchemaDefinition { RequiredFields = ["id"] });
var report = matrix.Analyze();
// Act
var markdown = report.ToMarkdown();
// Assert
markdown.Should().Contain("# Schema Compatibility Report");
markdown.Should().Contain("| From | To |");
markdown.Should().Contain("1.0");
markdown.Should().Contain("2.0");
}
[Fact]
public void CompatibilityReport_ToJson_ProducesValidJson()
{
// Arrange
var matrix = new SchemaVersionMatrix();
matrix.AddVersion("1.0", new SchemaDefinition { RequiredFields = ["id"] });
var report = matrix.Analyze();
// Act
var json = report.ToJson();
// Assert
json.Should().Contain("\"generatedAt\"");
json.Should().Contain("\"versions\"");
}
#endregion
#region VersionCompatibilityFixture Tests
[Fact]
public async Task VersionCompatibilityFixture_Initialize_CreatesCurrentEndpoint()
{
// Arrange
var fixture = new VersionCompatibilityFixture
{
Config = new VersionCompatibilityConfig { CurrentVersion = "3.0" }
};
// Act
await fixture.InitializeAsync();
// Assert
fixture.CurrentEndpoint.Should().NotBeNull();
fixture.CurrentEndpoint!.Version.Should().Be("3.0");
fixture.CurrentEndpoint.IsHealthy.Should().BeTrue();
// Cleanup
await fixture.DisposeAsync();
}
[Fact]
public async Task VersionCompatibilityFixture_StartVersion_CreatesEndpoint()
{
// Arrange
var fixture = new VersionCompatibilityFixture();
await fixture.InitializeAsync();
// Act
var endpoint = await fixture.StartVersion("1.0", "EvidenceLocker");
// Assert
endpoint.Should().NotBeNull();
endpoint.Version.Should().Be("1.0");
endpoint.ServiceName.Should().Be("EvidenceLocker");
// Cleanup
await fixture.DisposeAsync();
}
[Fact]
public async Task VersionCompatibilityFixture_StartVersion_ReturnsSameEndpointForSameVersion()
{
// Arrange
var fixture = new VersionCompatibilityFixture();
await fixture.InitializeAsync();
// Act
var endpoint1 = await fixture.StartVersion("1.0", "Service");
var endpoint2 = await fixture.StartVersion("1.0", "Service");
// Assert
endpoint1.Should().BeSameAs(endpoint2);
// Cleanup
await fixture.DisposeAsync();
}
[Fact]
public async Task VersionCompatibilityFixture_TestHandshake_ReturnsSuccess()
{
// Arrange
var fixture = new VersionCompatibilityFixture();
await fixture.InitializeAsync();
var server = await fixture.StartVersion("1.0", "Service");
// Act
var result = await fixture.TestHandshake(fixture.CurrentEndpoint!, server);
// Assert
result.IsSuccess.Should().BeTrue();
result.ClientVersion.Should().Be(fixture.CurrentEndpoint!.Version);
result.ServerVersion.Should().Be("1.0");
// Cleanup
await fixture.DisposeAsync();
}
[Fact]
public async Task VersionCompatibilityFixture_TestMessageFormat_ReturnsSuccess()
{
// Arrange
var fixture = new VersionCompatibilityFixture();
await fixture.InitializeAsync();
var producer = await fixture.StartVersion("1.0", "Producer");
var consumer = await fixture.StartVersion("2.0", "Consumer");
// Act
var result = await fixture.TestMessageFormat(producer, consumer, "EvidenceBundle");
// Assert
result.IsSuccess.Should().BeTrue();
result.Message.Should().Contain("EvidenceBundle");
// Cleanup
await fixture.DisposeAsync();
}
[Fact]
public async Task VersionCompatibilityFixture_TestSchemaMigration_ReturnsSuccess()
{
// Arrange
var fixture = new VersionCompatibilityFixture();
await fixture.InitializeAsync();
// Act
var result = await fixture.TestSchemaMigration("1.0", "2.0", new { id = 1 });
// Assert
result.IsSuccess.Should().BeTrue();
result.FromVersion.Should().Be("1.0");
result.ToVersion.Should().Be("2.0");
result.DataPreserved.Should().BeTrue();
result.RollbackSupported.Should().BeTrue();
// Cleanup
await fixture.DisposeAsync();
}
[Fact]
public async Task VersionCompatibilityFixture_StopVersion_RemovesEndpoint()
{
// Arrange
var fixture = new VersionCompatibilityFixture();
await fixture.InitializeAsync();
await fixture.StartVersion("1.0", "Service");
// Act
await fixture.StopVersion("1.0", "Service");
var newEndpoint = await fixture.StartVersion("1.0", "Service");
// Assert - new endpoint should be created (different base URL due to increment)
newEndpoint.Should().NotBeNull();
// Cleanup
await fixture.DisposeAsync();
}
#endregion
#region ServiceEndpoint Tests
[Fact]
public void ServiceEndpoint_DefaultValues_AreSet()
{
// Arrange & Act
var endpoint = new ServiceEndpoint();
// Assert
endpoint.ServiceName.Should().BeEmpty();
endpoint.Version.Should().BeEmpty();
endpoint.BaseUrl.Should().BeEmpty();
endpoint.IsHealthy.Should().BeFalse();
}
#endregion
#region CompatibilityResult Tests
[Fact]
public void CompatibilityResult_DefaultValues_AreSet()
{
// Arrange & Act
var result = new CompatibilityResult();
// Assert
result.IsSuccess.Should().BeFalse();
result.Errors.Should().BeEmpty();
result.Warnings.Should().BeEmpty();
}
#endregion
}