Example #1
0
        public async Task OnNDeleteRequestAsync_ShouldRespond()
        {
            var port = Ports.GetNext();

            using (DicomServer.Create <AsyncDicomNServiceProvider>(port, logger: _logger.IncludePrefix("DicomServer")))
            {
                var client = new Network.Client.DicomClient("127.0.0.1", port, false, "SCU", "ANY-SCP")
                {
                    Logger = _logger.IncludePrefix(typeof(DicomClient).Name)
                };

                DicomNDeleteResponse            response = null;
                DicomRequest.OnTimeoutEventArgs timeout  = null;
                var request = new DicomNDeleteRequest(
                    DicomUID.BasicFilmSession,
                    new DicomUID("1.2.3", null, DicomUidType.SOPInstance))
                {
                    OnResponseReceived = (req, res) => response = res,
                    OnTimeout          = (sender, args) => timeout = args
                };

                await client.AddRequestAsync(request).ConfigureAwait(false);

                await client.SendAsync().ConfigureAwait(false);

                Assert.NotNull(response);
                Assert.Equal(DicomStatus.Success, response.Status);
                Assert.Null(timeout);
            }
        }
        public async Task SendingMoveRequestToServerThatSendsPendingResponsesTooSlowlyShouldTimeout()
        {
            var port = Ports.GetNext();

            using (CreateServer <SlowPendingResponsesDicomServer>(port))
            {
                var client = CreateClient(port);

                client.ServiceOptions.RequestTimeout = TimeSpan.FromSeconds(2);

                var request = new DicomCMoveRequest("another-AE", "study123");

                DicomRequest.OnTimeoutEventArgs onTimeoutEventArgs = null;
                request.OnTimeout += (sender, args) => onTimeoutEventArgs = args;
                RequestTimedOutEventArgs eventArgsFromDicomClientRequestTimedOut = null;
                client.RequestTimedOut += (sender, args) => eventArgsFromDicomClientRequestTimedOut = args;

                await client.AddRequestAsync(request).ConfigureAwait(false);

                var sendTask = client.SendAsync();
                var sendTimeoutCancellationTokenSource = new CancellationTokenSource();
                var sendTimeout = Task.Delay(TimeSpan.FromSeconds(10), sendTimeoutCancellationTokenSource.Token);

                var winner = await Task.WhenAny(sendTask, sendTimeout).ConfigureAwait(false);

                sendTimeoutCancellationTokenSource.Cancel();
                sendTimeoutCancellationTokenSource.Dispose();

                Assert.Equal(winner, sendTask);
                Assert.NotNull(onTimeoutEventArgs);
                Assert.NotNull(eventArgsFromDicomClientRequestTimedOut);
                Assert.Equal(request, eventArgsFromDicomClientRequestTimedOut.Request);
                Assert.Equal(client.ServiceOptions.RequestTimeout, eventArgsFromDicomClientRequestTimedOut.Timeout);
            }
        }
Example #3
0
        public async Task OnCEchoRequestAsync_ShouldRespond()
        {
            var port = Ports.GetNext();

            using (DicomServerFactory.Create <AsyncDicomCEchoProvider>(port, logger: _logger.IncludePrefix("DicomServer")))
            {
                var client = DicomClientFactory.Create("127.0.0.1", port, false, "SCU", "ANY-SCP");
                client.Logger = _logger.IncludePrefix(typeof(DicomClient).Name);

                DicomCEchoResponse response             = null;
                DicomRequest.OnTimeoutEventArgs timeout = null;
                var request = new DicomCEchoRequest
                {
                    OnResponseReceived = (req, res) => response = res,
                    OnTimeout          = (sender, args) => timeout = args
                };

                await client.AddRequestAsync(request).ConfigureAwait(false);

                await client.SendAsync().ConfigureAwait(false);

                Assert.NotNull(response);
                Assert.Equal(DicomStatus.Success, response.Status);
                Assert.Null(timeout);
            }
        }
        public async Task OnCGetRequestAsync_Pending_ShouldRespond()
        {
            var port = Ports.GetNext();

            using (DicomServerFactory.Create <PendingAsyncDicomCGetProvider>(port, logger: _logger.IncludePrefix("DicomServer")))
            {
                var client = DicomClientFactory.Create("127.0.0.1", port, false, "SCU", "ANY-SCP");
                client.Logger = _logger.IncludePrefix(typeof(DicomClient).Name);

                var responses = new ConcurrentQueue <DicomCGetResponse>();
                DicomRequest.OnTimeoutEventArgs timeout = null;
                var studyInstanceUID = DicomUIDGenerator.GenerateDerivedFromUUID().ToString();
                var request          = new DicomCGetRequest(studyInstanceUID)
                {
                    OnResponseReceived = (req, res) => responses.Enqueue(res),
                    OnTimeout          = (sender, args) => timeout = args
                };

                await client.AddRequestAsync(request).ConfigureAwait(false);

                await client.SendAsync().ConfigureAwait(false);

                Assert.Collection(
                    responses,
                    response1 => Assert.Equal(DicomStatus.Pending, response1.Status),
                    response2 => Assert.Equal(DicomStatus.Pending, response2.Status),
                    response3 => Assert.Equal(DicomStatus.Success, response3.Status)
                    );
                Assert.Null(timeout);
            }
        }
Example #5
0
        public async Task OnCFindRequestAsync_Pending_ShouldRespond()
        {
            var port = Ports.GetNext();

            using (DicomServer.Create <PendingAsyncDicomCFindProvider>(port, logger: _logger.IncludePrefix("DicomServer")))
            {
                var client = new Client.DicomClient("127.0.0.1", port, false, "SCU", "ANY-SCP")
                {
                    Logger = _logger.IncludePrefix(typeof(DicomClient).Name)
                };

                var responses = new ConcurrentQueue <DicomCFindResponse>();
                DicomRequest.OnTimeoutEventArgs timeout = null;
                var request = new DicomCFindRequest(DicomQueryRetrieveLevel.Study)
                {
                    OnResponseReceived = (req, res) => responses.Enqueue(res),
                    OnTimeout          = (sender, args) => timeout = args
                };

                await client.AddRequestAsync(request).ConfigureAwait(false);

                await client.SendAsync().ConfigureAwait(false);

                Assert.Collection(
                    responses,
                    response1 => Assert.Equal(DicomStatus.Pending, response1.Status),
                    response2 => Assert.Equal(DicomStatus.Pending, response2.Status),
                    response3 => Assert.Equal(DicomStatus.Success, response3.Status)
                    );
                Assert.Null(timeout);
            }
        }
Example #6
0
        public async Task OnCFindRequestAsync_ImmediateSuccess_ShouldRespond()
        {
            var port = Ports.GetNext();

            using (DicomServer.Create <ImmediateSuccessAsyncDicomCFindProvider>(port, logger: _logger.IncludePrefix("DicomServer")))
            {
                var client = new Client.DicomClient("127.0.0.1", port, false, "SCU", "ANY-SCP")
                {
                    Logger = _logger.IncludePrefix(typeof(DicomClient).Name)
                };

                DicomCFindResponse response             = null;
                DicomRequest.OnTimeoutEventArgs timeout = null;
                var request = new DicomCFindRequest(DicomQueryRetrieveLevel.Study)
                {
                    OnResponseReceived = (req, res) => response = res,
                    OnTimeout          = (sender, args) => timeout = args
                };

                await client.AddRequestAsync(request).ConfigureAwait(false);

                await client.SendAsync().ConfigureAwait(false);

                Assert.NotNull(response);
                Assert.Equal(DicomStatus.Success, response.Status);
                Assert.Null(timeout);
            }
        }
        public async Task SendingLargeFileUsingVeryShortResponseTimeoutAndSendingTakesTooLongShouldFail()
        {
            var port = Ports.GetNext();

            using (CreateServer <InMemoryDicomCStoreProvider>(port))
            {
                var client = CreateClient(port);

                client.Options.RequestTimeout = TimeSpan.FromSeconds(1);
                client.Options.MaxPDULength   = 16 * 1024;

                TimeSpan streamWriteTimeout = TimeSpan.FromMilliseconds(1500);

                client.NetworkManager = new ConfigurableNetworkManager(() => Thread.Sleep(streamWriteTimeout));

                DicomResponse response = null;
                DicomRequest.OnTimeoutEventArgs onTimeoutEventArgs = null;

                // Size = 5 192 KB, one PDU = 16 KB, so this will result in 325 PDUs
                // If stream timeout = 1500ms, then total time to send will be 325 * 1500 = 487.5 seconds
                var request = new DicomCStoreRequest(@"./Test Data/10200904.dcm")
                {
                    OnResponseReceived = (req, res) => response = res,
                    OnTimeout          = (sender, args) => onTimeoutEventArgs = args
                };

                RequestTimedOutEventArgs eventArgsFromDicomClientRequestTimedOut = null;
                client.RequestTimedOut += (sender, args) => eventArgsFromDicomClientRequestTimedOut = args;
                await client.AddRequestAsync(request).ConfigureAwait(false);

                var sendTask = client.SendAsync();
                var sendTimeoutCancellationTokenSource = new CancellationTokenSource();
                var sendTimeout = Task.Delay(TimeSpan.FromSeconds(10), sendTimeoutCancellationTokenSource.Token);

                var winner = await Task.WhenAny(sendTask, sendTimeout).ConfigureAwait(false);

                sendTimeoutCancellationTokenSource.Cancel();
                sendTimeoutCancellationTokenSource.Dispose();

                Assert.Same(winner, sendTask);
                Assert.Null(response);
                Assert.NotNull(onTimeoutEventArgs);
                Assert.NotNull(eventArgsFromDicomClientRequestTimedOut);
                Assert.Equal(request, eventArgsFromDicomClientRequestTimedOut.Request);
                Assert.Equal(client.Options.RequestTimeout, eventArgsFromDicomClientRequestTimedOut.Timeout);
            }
        }
        public async Task SendingFindRequestToServerThatNeverRespondsShouldTimeout()
        {
            var port = Ports.GetNext();

            using (CreateServer <NeverRespondingDicomServer>(port))
            {
                var client = CreateClient(port);

                client.ServiceOptions.RequestTimeout = TimeSpan.FromSeconds(2);

                var request = new DicomCFindRequest(DicomQueryRetrieveLevel.Patient)
                {
                    Dataset = new DicomDataset
                    {
                        { DicomTag.PatientID, "PAT123" }
                    },
                    OnResponseReceived = (req, res) => throw new Exception("Did not expect a response"),
                };

                DicomRequest.OnTimeoutEventArgs eventArgsFromRequestTimeout = null;
                request.OnTimeout += (sender, args) => eventArgsFromRequestTimeout = args;
                RequestTimedOutEventArgs eventArgsFromDicomClientRequestTimedOut = null;
                client.RequestTimedOut += (sender, args) => eventArgsFromDicomClientRequestTimedOut = args;

                await client.AddRequestAsync(request).ConfigureAwait(false);

                var sendTask = client.SendAsync();
                var sendTimeoutCancellationTokenSource = new CancellationTokenSource();
                var sendTimeout = Task.Delay(TimeSpan.FromSeconds(10), sendTimeoutCancellationTokenSource.Token);

                var winner = await Task.WhenAny(sendTask, sendTimeout).ConfigureAwait(false);

                sendTimeoutCancellationTokenSource.Cancel();
                sendTimeoutCancellationTokenSource.Dispose();

                Assert.Equal(winner, sendTask);
                Assert.NotNull(eventArgsFromRequestTimeout);
                Assert.NotNull(eventArgsFromDicomClientRequestTimedOut);
                Assert.Equal(request, eventArgsFromDicomClientRequestTimedOut.Request);
                Assert.Equal(client.ServiceOptions.RequestTimeout, eventArgsFromDicomClientRequestTimedOut.Timeout);
            }
        }
        public async Task SendingFindRequestToServerThatSendsPendingResponsesWithinTimeoutShouldNotTimeout()
        {
            var port = Ports.GetNext();

            using (CreateServer <FastPendingResponsesDicomServer>(port))
            {
                var client = CreateClient(port);

                client.ServiceOptions.RequestTimeout = TimeSpan.FromSeconds(2);

                DicomCFindResponse lastResponse = null;
                var request = new DicomCFindRequest(DicomQueryRetrieveLevel.Patient)
                {
                    Dataset = new DicomDataset
                    {
                        { DicomTag.PatientID, "PAT123" }
                    },
                    OnResponseReceived = (req, res) => lastResponse = res
                };

                DicomRequest.OnTimeoutEventArgs onTimeoutEventArgs = null;
                request.OnTimeout += (sender, args) => onTimeoutEventArgs = args;

                await client.AddRequestAsync(request).ConfigureAwait(false);

                var sendTask = client.SendAsync();
                var sendTimeoutCancellationTokenSource = new CancellationTokenSource();
                var sendTimeout = Task.Delay(TimeSpan.FromSeconds(10), sendTimeoutCancellationTokenSource.Token);

                var winner = await Task.WhenAny(sendTask, sendTimeout).ConfigureAwait(false);

                sendTimeoutCancellationTokenSource.Cancel();
                sendTimeoutCancellationTokenSource.Dispose();

                Assert.Equal(winner, sendTask);
                Assert.NotNull(lastResponse);
                Assert.Equal(lastResponse.Status, DicomStatus.Success);
                Assert.Null(onTimeoutEventArgs);
            }
        }
        public async Task SendAsync_WithGenericStreamException_ShouldNotLoopInfinitely()
        {
            var port   = Ports.GetNext();
            var logger = _logger.IncludePrefix("UnitTest");

            DicomCStoreResponse response1 = null, response2 = null, response3 = null;

            DicomRequest.OnTimeoutEventArgs timeout1 = null, timeout2 = null, timeout3 = null;
            using (CreateServer <InMemoryDicomCStoreProvider>(port))
            {
                var request1HasArrived = false;
                var clientFactory      = CreateClientFactory(new ConfigurableNetworkManager(() =>
                {
                    if (request1HasArrived)
                    {
                        throw new Exception("Request 1 has arrived, we can no longer write to this stream!");
                    }
                }));
                var client = clientFactory.Create("127.0.0.1", port, false, "SCU", "ANY-SCP");
                client.Logger = _logger.IncludePrefix(typeof(DicomClient).Name).WithMinimumLevel(LogLevel.Debug);

                // Ensure requests are handled sequentially
                client.NegotiateAsyncOps(1, 1);

                // Size = 5 192 KB, one PDU = 16 KB, so this will result in 325 PDUs
                // If stream timeout = 1500ms, then total time to send will be 325 * 1500 = 487.5 seconds
                var request1 = new DicomCStoreRequest(@"./Test Data/10200904.dcm")
                {
                    OnResponseReceived = (req, res) =>
                    {
                        request1HasArrived = true;
                        response1          = res;
                    },
                    OnTimeout = (sender, args) => timeout1 = args
                };
                var request2 = new DicomCStoreRequest(@"./Test Data/10200904.dcm")
                {
                    OnResponseReceived = (req, res) => response2 = res,
                    OnTimeout          = (sender, args) => timeout2 = args
                };
                var request3 = new DicomCStoreRequest(@"./Test Data/10200904.dcm")
                {
                    OnResponseReceived = (req, res) => response3 = res,
                    OnTimeout          = (sender, args) => timeout3 = args
                };

                await client.AddRequestsAsync(new[] { request1, request2, request3 }).ConfigureAwait(false);

                using var cancellation = new CancellationTokenSource(TimeSpan.FromSeconds(30));

                Exception exception = null;
                try
                {
                    await client.SendAsync(cancellation.Token, DicomClientCancellationMode.ImmediatelyAbortAssociation).ConfigureAwait(false);
                }
                catch (Exception e)
                {
                    exception = e;
                }

                Assert.NotNull(exception);
                Assert.False(cancellation.IsCancellationRequested, "The DicomClient had to be cancelled, this indicates it was stuck in an infinite loop");
            }

            Assert.NotNull(response1);
            Assert.Null(response2);
            Assert.Null(response3);
            Assert.Null(timeout1);
            Assert.Null(timeout2);
            Assert.Null(timeout3);
        }
        public async Task SendAsync_WithSocketException_ShouldNotLoopInfinitely()
        {
            var port   = Ports.GetNext();
            var logger = _logger.IncludePrefix("UnitTest");

            IDicomServer        server = null;
            DicomCStoreResponse response1 = null, response2 = null, response3 = null;

            DicomRequest.OnTimeoutEventArgs timeout1 = null, timeout2 = null, timeout3 = null;
            using (CreateServer <InMemoryDicomCStoreProvider>(port))
            {
                var client = CreateClient(port);

                var request1HasArrived = false;
                client.NetworkManager = new ConfigurableNetworkManager(() =>
                {
                    if (request1HasArrived)
                    {
                        throw new IOException("Request 1 has arrived, we can no longer write to this stream!",
                                              new SocketException());
                    }
                });

                // Ensure requests are handled sequentially
                client.NegotiateAsyncOps(1, 1);

                // Size = 5 192 KB, one PDU = 16 KB, so this will result in 325 PDUs
                // If stream timeout = 1500ms, then total time to send will be 325 * 1500 = 487.5 seconds
                var request1 = new DicomCStoreRequest(@"./Test Data/10200904.dcm")
                {
                    OnResponseReceived = (req, res) =>
                    {
                        request1HasArrived = true;
                        response1          = res;
                    },
                    OnTimeout = (sender, args) => timeout1 = args
                };
                var request2 = new DicomCStoreRequest(@"./Test Data/10200904.dcm")
                {
                    OnResponseReceived = (req, res) => response2 = res,
                    OnTimeout          = (sender, args) => timeout2 = args
                };
                var request3 = new DicomCStoreRequest(@"./Test Data/10200904.dcm")
                {
                    OnResponseReceived = (req, res) => response3 = res,
                    OnTimeout          = (sender, args) => timeout3 = args
                };

                await client.AddRequestsAsync(request1, request2, request3).ConfigureAwait(false);

                using (var cancellation = new CancellationTokenSource(TimeSpan.FromMinutes(1)))
                {
                    Exception exception = null;
                    try
                    {
                        await client.SendAsync(cancellation.Token, DicomClientCancellationMode.ImmediatelyAbortAssociation).ConfigureAwait(false);
                    }
                    catch (Exception e)
                    {
                        exception = e;
                    }

                    Assert.NotNull(exception);

                    Assert.False(cancellation.IsCancellationRequested);
                }
            }

            Assert.NotNull(response1);
            Assert.Null(response2);
            Assert.Null(response3);
            Assert.Null(timeout1);
            Assert.Null(timeout2);
            Assert.Null(timeout3);
        }