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>
55 lines
2.7 KiB
C#
55 lines
2.7 KiB
C#
using Shouldly;
|
|
using Xunit;
|
|
|
|
namespace ZB.MOM.WW.OtOpcUa.Driver.Modbus.IntegrationTests.S7;
|
|
|
|
/// <summary>
|
|
/// End-to-end smoke against the S7-1500 <c>MB_SERVER</c> pymodbus profile (or a real
|
|
/// S7-1500 + MB_SERVER deployment when <c>MODBUS_SIM_ENDPOINT</c> points at one). Drives
|
|
/// the full <see cref="ModbusDriver"/> + real <see cref="ModbusTcpTransport"/> stack —
|
|
/// no fake transport. Success proves the driver initializes against the S7 simulator,
|
|
/// writes a known value, and reads it back with the correct status and value, which is
|
|
/// the baseline every S7-specific test (PR 57+) builds on.
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// S7-specific quirk tests (MB_SERVER requires non-optimized DBs, ABCD word order
|
|
/// default, port-per-connection, FC23 Illegal Function, STOP-mode behaviour, etc.) land
|
|
/// as separate test classes in this directory as each quirk is validated in pymodbus.
|
|
/// Keep this smoke test deliberately narrow — filtering by device class
|
|
/// (<c>--filter DisplayName~S7</c>) should surface the quirk-specific failure mode when
|
|
/// something goes wrong, not a blanket smoke failure that could mean anything.
|
|
/// </remarks>
|
|
[Collection(ModbusSimulatorCollection.Name)]
|
|
[Trait("Category", "Integration")]
|
|
[Trait("Device", "S7")]
|
|
public sealed class S7_1500SmokeTests(ModbusSimulatorFixture sim)
|
|
{
|
|
[Fact]
|
|
public async Task S7_1500_roundtrip_write_then_read_of_holding_register()
|
|
{
|
|
if (sim.SkipReason is not null) Assert.Skip(sim.SkipReason);
|
|
if (!string.Equals(Environment.GetEnvironmentVariable("MODBUS_SIM_PROFILE"), "s7_1500",
|
|
StringComparison.OrdinalIgnoreCase))
|
|
{
|
|
Assert.Skip("MODBUS_SIM_PROFILE != s7_1500 — skipping (other profiles don't seed the S7 scratch range identically).");
|
|
}
|
|
|
|
var options = S7_1500Profile.BuildOptions(sim.Host, sim.Port);
|
|
await using var driver = new ModbusDriver(options, driverInstanceId: "s7-smoke");
|
|
await driver.InitializeAsync(driverConfigJson: "{}", TestContext.Current.CancellationToken);
|
|
|
|
var writeResults = await driver.WriteAsync(
|
|
[new(FullReference: "Smoke_HReg200", Value: (short)S7_1500Profile.SmokeHoldingValue)],
|
|
TestContext.Current.CancellationToken);
|
|
writeResults.Count.ShouldBe(1);
|
|
writeResults[0].StatusCode.ShouldBe(0u, "write must succeed against the S7-1500 MB_SERVER profile");
|
|
|
|
var readResults = await driver.ReadAsync(
|
|
["Smoke_HReg200"],
|
|
TestContext.Current.CancellationToken);
|
|
readResults.Count.ShouldBe(1);
|
|
readResults[0].StatusCode.ShouldBe(0u);
|
|
readResults[0].Value.ShouldBe((short)S7_1500Profile.SmokeHoldingValue);
|
|
}
|
|
}
|