public async Task AssertDeviceConnectionOpenAsyncMutualExclusion()

in DeviceBridgeTests/Services/ConnectionManagerTests.cs [31:74]


        public async Task AssertDeviceConnectionOpenAsyncMutualExclusion()
        {
            using (ShimsContext.Create())
            {
                var connectionManager = CreateConnectionManager();

                // Check that client open and close operations for the same device block on the same mutex.
                SemaphoreSlim openSemaphore = null, closeSemaphore = null;
                TestUtils.CaptureSemaphoreOnWait((semaphore) => openSemaphore = semaphore);
                ShimDps("test-hub.azure.devices.net");
                ShimDeviceClient();
                await connectionManager.AssertDeviceConnectionOpenAsync("test-device-id");
                TestUtils.CaptureSemaphoreOnWait((semaphore) => closeSemaphore = semaphore);
                await connectionManager.AssertDeviceConnectionClosedAsync("test-device-id");
                Assert.IsNotNull(openSemaphore);
                Assert.AreEqual(openSemaphore, closeSemaphore);

                // Check that client open operations for different devices block on different mutexes.
                SemaphoreSlim anotherDeviceOpenSemaphore = null;
                TestUtils.CaptureSemaphoreOnWait((semaphore) => anotherDeviceOpenSemaphore = semaphore);
                await connectionManager.AssertDeviceConnectionOpenAsync("another-test-device-id");
                Assert.IsNotNull(anotherDeviceOpenSemaphore);
                Assert.AreNotEqual(openSemaphore, anotherDeviceOpenSemaphore);

                // Check that the mutex is unlocked on failure
                ShimDeviceClientToFail();
                SemaphoreSlim openFailSemaphore = null;
                TestUtils.CaptureSemaphoreOnWait((semaphore) => openFailSemaphore = semaphore);
                await ExpectToThrow(() => connectionManager.AssertDeviceConnectionOpenAsync("device-to-fail-id"));
                Assert.AreEqual(1, openFailSemaphore.CurrentCount);

                // Check that a device connection attempt time is registered before it enters the critical section.
                var startTime = DateTime.Now;
                SemaphoreSlim connectionTimeSemaphore = null;
                ShimDeviceClient();
                TestUtils.CaptureSemaphoreOnWait((semaphore) =>
                {
                    connectionTimeSemaphore = semaphore;
                    Assert.IsNotNull(connectionManager.GetDevicesThatConnectedSince(startTime).Find(id => id == "connection-time-test-id"));
                });
                await connectionManager.AssertDeviceConnectionOpenAsync("connection-time-test-id");
                Assert.NotNull(connectionTimeSemaphore);
            }
        }