using System; using System.Threading.Tasks; using MxGateway.Contracts.Proto; using MxGateway.Worker.MxAccess; using MxGateway.Worker.Sta; namespace MxGateway.Worker.Tests.MxAccess; public sealed class MxAccessLiveComCreationTests { private const string LiveClientName = "MxGateway.Worker.Tests"; private const string DefaultLiveAddItemReference = "TestChildObject.TestInt"; private const string DefaultLiveAddItem2Definition = "TestInt"; private const string DefaultLiveAddItem2Context = "TestChildObject"; [Fact] public async Task StartAsync_WhenOptedIn_CreatesInstalledMxAccessComObjectOnSta() { if (!string.Equals( Environment.GetEnvironmentVariable("MXGATEWAY_RUN_LIVE_MXACCESS_TESTS"), "1", StringComparison.Ordinal)) { return; } using MxAccessStaSession session = new(); await session.StartAsync(workerProcessId: 1234); } [Fact] public async Task RegisterAndUnregister_WhenOptedIn_RoundTripsInstalledMxAccessServerHandle() { if (!RunLiveMxAccessTests()) { return; } using MxAccessStaSession session = new(); await session.StartAsync(workerProcessId: 1234); MxCommandReply registerReply = await session.DispatchAsync(new StaCommand( "session-1", "live-register", new MxCommand { Kind = MxCommandKind.Register, Register = new RegisterCommand { ClientName = LiveClientName, }, })); Assert.Equal(ProtocolStatusCode.Ok, registerReply.ProtocolStatus.Code); Assert.True(registerReply.Register.ServerHandle > 0); MxCommandReply unregisterReply = await session.DispatchAsync(new StaCommand( "session-1", "live-unregister", new MxCommand { Kind = MxCommandKind.Unregister, Unregister = new UnregisterCommand { ServerHandle = registerReply.Register.ServerHandle, }, })); Assert.Equal(ProtocolStatusCode.Ok, unregisterReply.ProtocolStatus.Code); } [Fact] public async Task AddItemAndRemoveItem_WhenOptedIn_RoundTripsInstalledMxAccessItemHandle() { if (!RunLiveMxAccessTests()) { return; } using MxAccessStaSession session = new(); await session.StartAsync(workerProcessId: 1234); MxCommandReply registerReply = await RegisterLiveSessionAsync(session, "live-add-register"); int serverHandle = registerReply.Register.ServerHandle; int itemHandle = 0; try { MxCommandReply addItemReply = await session.DispatchAsync(new StaCommand( "session-1", "live-add-item", new MxCommand { Kind = MxCommandKind.AddItem, AddItem = new AddItemCommand { ServerHandle = serverHandle, ItemDefinition = GetLiveAddItemReference(), }, })); Assert.Equal(ProtocolStatusCode.Ok, addItemReply.ProtocolStatus.Code); Assert.True(addItemReply.AddItem.ItemHandle > 0); itemHandle = addItemReply.AddItem.ItemHandle; MxCommandReply removeItemReply = await session.DispatchAsync(new StaCommand( "session-1", "live-remove-item", new MxCommand { Kind = MxCommandKind.RemoveItem, RemoveItem = new RemoveItemCommand { ServerHandle = serverHandle, ItemHandle = itemHandle, }, })); Assert.Equal(ProtocolStatusCode.Ok, removeItemReply.ProtocolStatus.Code); itemHandle = 0; } finally { if (itemHandle > 0) { await session.DispatchAsync(new StaCommand( "session-1", "live-remove-item-cleanup", new MxCommand { Kind = MxCommandKind.RemoveItem, RemoveItem = new RemoveItemCommand { ServerHandle = serverHandle, ItemHandle = itemHandle, }, })); } await UnregisterLiveSessionAsync(session, serverHandle, "live-add-unregister"); } } [Fact] public async Task AddItem2AndRemoveItem_WhenOptedIn_PreservesContextForInstalledMxAccess() { if (!RunLiveMxAccessTests()) { return; } using MxAccessStaSession session = new(); await session.StartAsync(workerProcessId: 1234); MxCommandReply registerReply = await RegisterLiveSessionAsync(session, "live-add2-register"); int serverHandle = registerReply.Register.ServerHandle; int itemHandle = 0; try { MxCommandReply addItem2Reply = await session.DispatchAsync(new StaCommand( "session-1", "live-add-item2", new MxCommand { Kind = MxCommandKind.AddItem2, AddItem2 = new AddItem2Command { ServerHandle = serverHandle, ItemDefinition = DefaultLiveAddItem2Definition, ItemContext = DefaultLiveAddItem2Context, }, })); Assert.Equal(ProtocolStatusCode.Ok, addItem2Reply.ProtocolStatus.Code); Assert.True(addItem2Reply.AddItem2.ItemHandle > 0); itemHandle = addItem2Reply.AddItem2.ItemHandle; MxCommandReply removeItemReply = await session.DispatchAsync(new StaCommand( "session-1", "live-remove-item2", new MxCommand { Kind = MxCommandKind.RemoveItem, RemoveItem = new RemoveItemCommand { ServerHandle = serverHandle, ItemHandle = itemHandle, }, })); Assert.Equal(ProtocolStatusCode.Ok, removeItemReply.ProtocolStatus.Code); itemHandle = 0; } finally { if (itemHandle > 0) { await session.DispatchAsync(new StaCommand( "session-1", "live-remove-item2-cleanup", new MxCommand { Kind = MxCommandKind.RemoveItem, RemoveItem = new RemoveItemCommand { ServerHandle = serverHandle, ItemHandle = itemHandle, }, })); } await UnregisterLiveSessionAsync(session, serverHandle, "live-add2-unregister"); } } [Fact] public async Task AdviseAndUnAdvise_WhenOptedIn_RoundTripsInstalledMxAccessSubscription() { if (!RunLiveMxAccessTests()) { return; } using MxAccessStaSession session = new(); await session.StartAsync(workerProcessId: 1234); MxCommandReply registerReply = await RegisterLiveSessionAsync(session, "live-advise-register"); int serverHandle = registerReply.Register.ServerHandle; int itemHandle = 0; bool advised = false; try { MxCommandReply addItemReply = await session.DispatchAsync(new StaCommand( "session-1", "live-advise-add-item", new MxCommand { Kind = MxCommandKind.AddItem, AddItem = new AddItemCommand { ServerHandle = serverHandle, ItemDefinition = GetLiveAddItemReference(), }, })); Assert.Equal(ProtocolStatusCode.Ok, addItemReply.ProtocolStatus.Code); Assert.True(addItemReply.AddItem.ItemHandle > 0); itemHandle = addItemReply.AddItem.ItemHandle; MxCommandReply adviseReply = await session.DispatchAsync(new StaCommand( "session-1", "live-advise", new MxCommand { Kind = MxCommandKind.Advise, Advise = new AdviseCommand { ServerHandle = serverHandle, ItemHandle = itemHandle, }, })); Assert.Equal(ProtocolStatusCode.Ok, adviseReply.ProtocolStatus.Code); advised = true; MxCommandReply unAdviseReply = await session.DispatchAsync(new StaCommand( "session-1", "live-unadvise", new MxCommand { Kind = MxCommandKind.UnAdvise, UnAdvise = new UnAdviseCommand { ServerHandle = serverHandle, ItemHandle = itemHandle, }, })); Assert.Equal(ProtocolStatusCode.Ok, unAdviseReply.ProtocolStatus.Code); advised = false; MxCommandReply removeItemReply = await session.DispatchAsync(new StaCommand( "session-1", "live-advise-remove-item", new MxCommand { Kind = MxCommandKind.RemoveItem, RemoveItem = new RemoveItemCommand { ServerHandle = serverHandle, ItemHandle = itemHandle, }, })); Assert.Equal(ProtocolStatusCode.Ok, removeItemReply.ProtocolStatus.Code); itemHandle = 0; } finally { if (advised && itemHandle > 0) { await session.DispatchAsync(new StaCommand( "session-1", "live-unadvise-cleanup", new MxCommand { Kind = MxCommandKind.UnAdvise, UnAdvise = new UnAdviseCommand { ServerHandle = serverHandle, ItemHandle = itemHandle, }, })); } if (itemHandle > 0) { await session.DispatchAsync(new StaCommand( "session-1", "live-advise-remove-item-cleanup", new MxCommand { Kind = MxCommandKind.RemoveItem, RemoveItem = new RemoveItemCommand { ServerHandle = serverHandle, ItemHandle = itemHandle, }, })); } await UnregisterLiveSessionAsync(session, serverHandle, "live-advise-unregister"); } } private static bool RunLiveMxAccessTests() { return string.Equals( Environment.GetEnvironmentVariable("MXGATEWAY_RUN_LIVE_MXACCESS_TESTS"), "1", StringComparison.Ordinal); } private static string GetLiveAddItemReference() { string itemReference = Environment.GetEnvironmentVariable("MXGATEWAY_LIVE_MXACCESS_ITEM"); return string.IsNullOrWhiteSpace(itemReference) ? DefaultLiveAddItemReference : itemReference; } private static async Task RegisterLiveSessionAsync( MxAccessStaSession session, string correlationId) { MxCommandReply reply = await session.DispatchAsync(new StaCommand( "session-1", correlationId, new MxCommand { Kind = MxCommandKind.Register, Register = new RegisterCommand { ClientName = LiveClientName, }, })); Assert.Equal(ProtocolStatusCode.Ok, reply.ProtocolStatus.Code); Assert.True(reply.Register.ServerHandle > 0); return reply; } private static async Task UnregisterLiveSessionAsync( MxAccessStaSession session, int serverHandle, string correlationId) { MxCommandReply unregisterReply = await session.DispatchAsync(new StaCommand( "session-1", correlationId, new MxCommand { Kind = MxCommandKind.Unregister, Unregister = new UnregisterCommand { ServerHandle = serverHandle, }, })); Assert.Equal(ProtocolStatusCode.Ok, unregisterReply.ProtocolStatus.Code); } }