chore: organize solution into module folders (Core/Server/Drivers/Client/Tooling)
Group all 69 projects into category subfolders under src/ and tests/ so the Rider Solution Explorer mirrors the module structure. Folders: Core, Server, Drivers (with a nested Driver CLIs subfolder), Client, Tooling. - Move every project folder on disk with git mv (history preserved as renames). - Recompute relative paths in 57 .csproj files: cross-category ProjectReferences, the lib/ HintPath+None refs in Driver.Historian.Wonderware, and the external mxaccessgw refs in Driver.Galaxy and its test project. - Rebuild ZB.MOM.WW.OtOpcUa.slnx with nested solution folders. - Re-prefix project paths in functional scripts (e2e, compliance, smoke SQL, integration, install). Build green (0 errors); unit tests pass. Docs left for a separate pass. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,59 @@
|
||||
using System.Security.Cryptography;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using Shouldly;
|
||||
using Xunit;
|
||||
|
||||
namespace ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.Tests;
|
||||
|
||||
[Trait("Category", "Unit")]
|
||||
public sealed class OpcUaClientCertAuthTests
|
||||
{
|
||||
[Fact]
|
||||
public void BuildCertificateIdentity_rejects_missing_path()
|
||||
{
|
||||
var opts = new OpcUaClientDriverOptions { AuthType = OpcUaAuthType.Certificate };
|
||||
Should.Throw<InvalidOperationException>(() => OpcUaClientDriver.BuildCertificateIdentity(opts))
|
||||
.Message.ShouldContain("UserCertificatePath");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void BuildCertificateIdentity_rejects_nonexistent_file()
|
||||
{
|
||||
var opts = new OpcUaClientDriverOptions
|
||||
{
|
||||
AuthType = OpcUaAuthType.Certificate,
|
||||
UserCertificatePath = Path.Combine(Path.GetTempPath(), $"does-not-exist-{Guid.NewGuid():N}.pfx"),
|
||||
};
|
||||
Should.Throw<FileNotFoundException>(() => OpcUaClientDriver.BuildCertificateIdentity(opts));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void BuildCertificateIdentity_loads_a_valid_PFX_with_private_key()
|
||||
{
|
||||
// Generate a self-signed cert on the fly so the test doesn't ship a static PFX.
|
||||
// The driver doesn't care about the issuer — just needs a cert with a private key.
|
||||
using var rsa = RSA.Create(2048);
|
||||
var req = new CertificateRequest("CN=OpcUaClientCertAuthTests", rsa,
|
||||
HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
|
||||
var cert = req.CreateSelfSigned(DateTimeOffset.UtcNow.AddMinutes(-5), DateTimeOffset.UtcNow.AddHours(1));
|
||||
|
||||
var tmpPath = Path.Combine(Path.GetTempPath(), $"opcua-cert-test-{Guid.NewGuid():N}.pfx");
|
||||
File.WriteAllBytes(tmpPath, cert.Export(X509ContentType.Pfx, "testpw"));
|
||||
try
|
||||
{
|
||||
var opts = new OpcUaClientDriverOptions
|
||||
{
|
||||
AuthType = OpcUaAuthType.Certificate,
|
||||
UserCertificatePath = tmpPath,
|
||||
UserCertificatePassword = "testpw",
|
||||
};
|
||||
var identity = OpcUaClientDriver.BuildCertificateIdentity(opts);
|
||||
identity.ShouldNotBeNull();
|
||||
identity.TokenType.ShouldBe(Opc.Ua.UserTokenType.Certificate);
|
||||
}
|
||||
finally
|
||||
{
|
||||
try { File.Delete(tmpPath); } catch { /* best-effort */ }
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user