58 lines
2.8 KiB
C#
58 lines
2.8 KiB
C#
using System.Text;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using Shouldly;
|
|
using Xunit;
|
|
using ZB.MOM.WW.OtOpcUa.AdminUI.Deployments;
|
|
using ZB.MOM.WW.OtOpcUa.Configuration.Entities;
|
|
using ZB.MOM.WW.OtOpcUa.Configuration.Enums;
|
|
|
|
namespace ZB.MOM.WW.OtOpcUa.AdminUI.Tests.Deployments;
|
|
|
|
/// <summary>
|
|
/// The SQL-Server-backed half of <see cref="CredentialReferencePreflightTests"/> (lmxopcua#815). EF InMemory runs
|
|
/// <c>ScanAsync</c>'s deployment query as LINQ-to-Objects, so an untranslatable predicate passes there and throws on
|
|
/// every real boot — exactly what the #815 live gate found (<c>ArtifactBlob.Length > 0</c>). Here it must translate.
|
|
/// </summary>
|
|
[Collection(nameof(AdminUiSqlServerCollection))]
|
|
public sealed class CredentialReferencePreflightSqlServerTests(AdminUiSqlServerFixture sql)
|
|
{
|
|
[SqlServerFact]
|
|
public async Task ScanAsync_translates_and_reads_the_latest_sealed_artifact()
|
|
{
|
|
// Far-future timestamps so this test's rows are the latest whatever else the shared database holds.
|
|
var anchor = new DateTime(2999, 1, 1, 0, 0, 0, DateTimeKind.Utc);
|
|
var sealedId = Guid.NewGuid();
|
|
var failedId = Guid.NewGuid();
|
|
const string artifact = """
|
|
{"DriverInstances":[{"DriverInstanceId":"ouc-sql","Name":"UpstreamSql","DriverType":"OpcUaClient",
|
|
"DriverConfig":"{\"Password\":\"secret:plant/opcua-pw\"}"}]}
|
|
""";
|
|
await using (var db = await sql.Factory.CreateDbContextAsync(TestContext.Current.CancellationToken))
|
|
{
|
|
db.Deployments.Add(new Deployment
|
|
{
|
|
DeploymentId = sealedId, RevisionHash = "preflight-sealed", CreatedBy = "t", Status = DeploymentStatus.Sealed,
|
|
CreatedAtUtc = anchor, ArtifactBlob = Encoding.UTF8.GetBytes(artifact),
|
|
});
|
|
db.Deployments.Add(new Deployment
|
|
{
|
|
DeploymentId = failedId, RevisionHash = "preflight-failed", CreatedBy = "t", Status = DeploymentStatus.PartiallyFailed,
|
|
CreatedAtUtc = anchor.AddMinutes(1), ArtifactBlob = Encoding.UTF8.GetBytes("""{"DriverInstances":[]}"""),
|
|
});
|
|
await db.SaveChangesAsync(TestContext.Current.CancellationToken);
|
|
}
|
|
|
|
try
|
|
{
|
|
var findings = await new CredentialReferencePreflight(sql.Factory).ScanAsync(TestContext.Current.CancellationToken);
|
|
|
|
findings.ShouldContain(f => f.Source == CredentialFindingSource.Deployed && f.DriverName == "UpstreamSql");
|
|
}
|
|
finally
|
|
{
|
|
await using var db = await sql.Factory.CreateDbContextAsync(CancellationToken.None);
|
|
await db.Deployments.Where(d => d.DeploymentId == sealedId || d.DeploymentId == failedId).ExecuteDeleteAsync(CancellationToken.None);
|
|
}
|
|
}
|
|
}
|