964b40dcbc
MxAccessInteropReference_ExistsOnlyInWorkerProject asserted the MXAccess COM interop was referenced only by MxGateway.Worker. The worker test project now legitimately references ArchestrA.MxAccess and Interop.WNWRAPCONSUMERLib so it can exercise the COM-facing worker code (WnWrapAlarmConsumer, the alarm tests). Renamed to ..._ExistsOnlyInWorkerAndWorkerTestProjects, updated the assertion to expect both projects, and made it order-independent. The architecture invariant the test protects — the gateway/contracts never reference MXAccess COM — still holds. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
108 lines
4.3 KiB
C#
108 lines
4.3 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Xml.Linq;
|
|
|
|
namespace MxGateway.Worker.Tests.ProjectStructure;
|
|
|
|
public sealed class WorkerProjectReferenceTests
|
|
{
|
|
/// <summary>Verifies that the worker project targets .NET Framework 4.8 with x86 platform.</summary>
|
|
[Fact]
|
|
public void WorkerProject_TargetsNet48AndX86()
|
|
{
|
|
XDocument project = LoadProject("MxGateway.Worker");
|
|
|
|
Assert.Equal("net48", ElementValue(project, "TargetFramework"));
|
|
Assert.Equal("x86", ElementValue(project, "PlatformTarget"));
|
|
Assert.Equal("true", ElementValue(project, "Prefer32Bit"));
|
|
}
|
|
|
|
/// <summary>Verifies that the worker test project targets .NET Framework 4.8 with x86 platform.</summary>
|
|
[Fact]
|
|
public void WorkerTestProject_TargetsNet48AndX86()
|
|
{
|
|
XDocument project = LoadProject("MxGateway.Worker.Tests");
|
|
|
|
Assert.Equal("net48", ElementValue(project, "TargetFramework"));
|
|
Assert.Equal("x86", ElementValue(project, "PlatformTarget"));
|
|
}
|
|
|
|
/// <summary>
|
|
/// Verifies that the MXAccess COM interop is referenced only by the
|
|
/// worker project and its test project — never by the gateway server
|
|
/// or the contracts project. The gateway must never load MXAccess COM
|
|
/// directly (see <c>gateway.md</c>); the worker test project
|
|
/// legitimately references the interop so it can exercise the
|
|
/// COM-facing worker code (e.g. <c>WnWrapAlarmConsumer</c>).
|
|
/// </summary>
|
|
[Fact]
|
|
public void MxAccessInteropReference_ExistsOnlyInWorkerAndWorkerTestProjects()
|
|
{
|
|
DirectoryInfo repositoryRoot = FindRepositoryRoot();
|
|
string[] projectFiles = Directory.GetFiles(repositoryRoot.FullName, "*.csproj", SearchOption.AllDirectories)
|
|
.Where(path => path.IndexOf($"{Path.DirectorySeparatorChar}bin{Path.DirectorySeparatorChar}", StringComparison.OrdinalIgnoreCase) < 0)
|
|
.Where(path => path.IndexOf($"{Path.DirectorySeparatorChar}obj{Path.DirectorySeparatorChar}", StringComparison.OrdinalIgnoreCase) < 0)
|
|
.ToArray();
|
|
|
|
IReadOnlyList<string> projectsWithMxAccessReference = projectFiles
|
|
.Where(ProjectReferencesMxAccess)
|
|
.Select(path => Path.GetFileNameWithoutExtension(path))
|
|
.OrderBy(name => name, StringComparer.Ordinal)
|
|
.ToArray();
|
|
|
|
Assert.Equal(
|
|
["MxGateway.Worker", "MxGateway.Worker.Tests"],
|
|
projectsWithMxAccessReference);
|
|
}
|
|
|
|
private static bool ProjectReferencesMxAccess(string projectPath)
|
|
{
|
|
XDocument project = XDocument.Load(projectPath);
|
|
|
|
return project
|
|
.Descendants()
|
|
.Where(element => element.Name.LocalName is "Reference" or "COMReference" or "COMFileReference" or "PackageReference")
|
|
.Select(element => (string?)element.Attribute("Include") ?? string.Empty)
|
|
.Concat(project.Descendants().Where(element => element.Name.LocalName == "HintPath").Select(element => element.Value))
|
|
.Any(reference =>
|
|
reference.IndexOf("MxAccess", StringComparison.OrdinalIgnoreCase) >= 0
|
|
|| reference.IndexOf("ArchestrA.MXAccess", StringComparison.OrdinalIgnoreCase) >= 0
|
|
|| reference.IndexOf("LMXProxy", StringComparison.OrdinalIgnoreCase) >= 0);
|
|
}
|
|
|
|
private static XDocument LoadProject(string projectName)
|
|
{
|
|
DirectoryInfo repositoryRoot = FindRepositoryRoot();
|
|
string projectPath = Path.Combine(repositoryRoot.FullName, projectName, $"{projectName}.csproj");
|
|
|
|
return XDocument.Load(projectPath);
|
|
}
|
|
|
|
private static string ElementValue(XDocument project, string elementName)
|
|
{
|
|
return project
|
|
.Descendants()
|
|
.Single(element => element.Name.LocalName == elementName)
|
|
.Value;
|
|
}
|
|
|
|
private static DirectoryInfo FindRepositoryRoot()
|
|
{
|
|
DirectoryInfo? current = new(AppContext.BaseDirectory);
|
|
|
|
while (current is not null)
|
|
{
|
|
if (File.Exists(Path.Combine(current.FullName, "MxGateway.sln")))
|
|
{
|
|
return current;
|
|
}
|
|
|
|
current = current.Parent;
|
|
}
|
|
|
|
throw new DirectoryNotFoundException("Could not locate src/MxGateway.sln from the test output directory.");
|
|
}
|
|
}
|