Пример #1
0
 protected IEnumerable <DicomTagAnonymisation> SegmentationAnonymisationProtocol()
 {
     using (var segmentationClient = TestGatewayProcessorConfigProvider.CreateInnerEyeSegmentationClient().Invoke())
     {
         return(segmentationClient.SegmentationAnonymisationProtocol);
     }
 }
        public void TestBadProductKeyStart()
        {
            var processorSettings  = TestGatewayProcessorConfigProvider.ProcessorSettings();
            var existingLicenseKey = processorSettings.LicenseKey;

            try
            {
                // Note that Visual Studio must be running as Administrator in order to set the environment variable,
                // otherwise there will be a SecurityException.
                TestGatewayProcessorConfigProvider.SetProcessorSettings(licenseKey: Guid.NewGuid().ToString());

                using (var configurationService = CreateConfigurationService(
                           null,
                           null,
                           CreateDownloadService(),
                           CreateUploadService()))
                {
                    configurationService.Start();

                    SpinWait.SpinUntil(() => !configurationService.IsExecutionThreadRunning, TimeSpan.FromSeconds(10));

                    Assert.IsFalse(configurationService.IsExecutionThreadRunning);
                }
            }
            finally
            {
                TestGatewayProcessorConfigProvider.SetProcessorSettings(licenseKey: existingLicenseKey);
            }
        }
Пример #3
0
 /// <summary>
 /// Create a new instance of the <see cref="ConfigurationService"/> class.
 /// </summary>
 /// <param name="innerEyeSegmentationClient">Optional InnerEye segmentation client.</param>
 /// <param name="getConfigurationServiceConfig">Configuration service config callback.</param>
 /// <param name="services">The services.</param>
 /// <returns>New ConfigurationService<T>.</returns>
 protected ConfigurationService CreateConfigurationService(
     IInnerEyeSegmentationClient innerEyeSegmentationClient          = null,
     Func <ConfigurationServiceConfig> getConfigurationServiceConfig = null,
     params IService[] services) =>
 new ConfigurationService(
     innerEyeSegmentationClient != null ? () => innerEyeSegmentationClient : TestGatewayProcessorConfigProvider.CreateInnerEyeSegmentationClient(),
     getConfigurationServiceConfig ?? TestGatewayProcessorConfigProvider.ConfigurationServiceConfig,
     _loggerFactory.CreateLogger("ConfigurationService"),
     services);
Пример #4
0
 /// <summary>
 /// Creates a new instance of the <see cref="UploadService"/> class.
 /// </summary>
 /// <param name="innerEyeSegmentationClient">Optional InnerEye segmentation client.</param>
 /// <param name="aetConfigProvider">AET configuration provider.</param>
 /// <param name="instances">The number of concurrent execution instances we should have.</param>
 /// <returns>New UploadService.</returns>
 protected UploadService CreateUploadService(
     IInnerEyeSegmentationClient innerEyeSegmentationClient = null,
     Func <IEnumerable <AETConfigModel> > aetConfigProvider = null,
     int instances = 1) =>
 new UploadService(
     innerEyeSegmentationClient != null ? () => innerEyeSegmentationClient : TestGatewayProcessorConfigProvider.CreateInnerEyeSegmentationClient(),
     aetConfigProvider ?? _testAETConfigProvider.AETConfigModels,
     TestUploadQueuePath,
     TestDownloadQueuePath,
     TestDeleteQueuePath,
     TestGatewayProcessorConfigProvider.DequeueServiceConfig,
     _loggerFactory.CreateLogger("UploadService"),
     instances);
Пример #5
0
 /// <summary>
 /// Creates a new instance of the <see cref="DownloadService"/> class.
 /// </summary>
 /// <param name="innerEyeSegmentationClient">Optional InnerEye segmentation client.</param>
 /// <param name="dequeueServiceConfig">Optional dequeue service config.</param>
 /// <param name="instances">The number of concurrent execution instances we should have.</param>
 /// <returns>New DownloadService.</returns>
 protected DownloadService CreateDownloadService(
     IInnerEyeSegmentationClient innerEyeSegmentationClient = null,
     DequeueServiceConfig dequeueServiceConfig = null,
     int instances = 1) =>
 new DownloadService(
     innerEyeSegmentationClient != null ? () => innerEyeSegmentationClient : TestGatewayProcessorConfigProvider.CreateInnerEyeSegmentationClient(),
     TestDownloadQueuePath,
     TestPushQueuePath,
     TestDeleteQueuePath,
     () => new DownloadServiceConfig(),
     dequeueServiceConfig != null ? (Func <DequeueServiceConfig>)(() => dequeueServiceConfig) : TestGatewayProcessorConfigProvider.DequeueServiceConfig,
     _loggerFactory.CreateLogger("DownloadService"),
     instances);
Пример #6
0
        /// <summary>
        /// Test anonymization/deanonymization preserves some of the tags, replaces some others and drops the rest.
        /// </summary>
        /// <param name="random">Random.</param>
        /// <param name="sourceImageFileName">Source file name.</param>
        /// <param name="tagReplacements">Tag replacements.</param>
        /// <returns>Awaitable task.</returns>
        public async Task TestDataSetAnonymizeDeanonymize(
            Random random,
            string sourceImageFileName,
            IEnumerable <TagReplacement> tagReplacements)
        {
            var originalDicomFile = await DicomFile.OpenAsync(sourceImageFileName, FileReadOption.ReadAll);

            // Make a copy of the existing DicomDataset
            var originalDataset = originalDicomFile.Dataset.Clone();

            AddRandomTags(random, new[] { originalDicomFile });
            var sourceDataset = originalDicomFile.Dataset;

            // Check that the randomisation of the DicomDataset has actually changed the tags
            foreach (var dicomTagRandomiserPair in DicomTagRandomisers)
            {
                foreach (var dicomTag in dicomTagRandomiserPair.Item1)
                {
                    // Value may not even exist in the original dataset
                    var originalValue = originalDataset.GetSingleValueOrDefault(dicomTag, string.Empty);
                    // But should always exist after randomisation
                    var sourceValue = sourceDataset.GetSingleValue <string>(dicomTag);

                    // Check they are different, as strings.
                    Assert.IsFalse(string.IsNullOrEmpty(sourceValue));
                    Assert.AreNotEqual(originalValue, sourceValue);
                }
            }

            var innerEyeSegmentationClient = TestGatewayProcessorConfigProvider.CreateInnerEyeSegmentationClient()();

            // Anonymize the original DICOM file
            var anonymizedDicomFile = innerEyeSegmentationClient.AnonymizeDicomFile(originalDicomFile, innerEyeSegmentationClient.SegmentationAnonymisationProtocolId, innerEyeSegmentationClient.SegmentationAnonymisationProtocol);

            anonymizedDicomFile.Dataset.AddOrUpdate(DicomTag.SoftwareVersions, "Microsoft InnerEye Gateway:");

            // Check it has been anonymized
            AssertDicomFileIsAnonymised(anonymizedDicomFile);

            // And then deanonymize it using the original
            var deanonymizedDicomFile = innerEyeSegmentationClient.DeanonymizeDicomFile(
                anonymizedDicomFile,
                new[] { originalDicomFile },
                innerEyeSegmentationClient.TopLevelReplacements,
                tagReplacements,
                innerEyeSegmentationClient.SegmentationAnonymisationProtocolId,
                innerEyeSegmentationClient.SegmentationAnonymisationProtocol);

            AssertDeanonymizedFile(originalDicomFile, deanonymizedDicomFile, innerEyeSegmentationClient.TopLevelReplacements, tagReplacements, true);
        }
Пример #7
0
        /// <summary>
        /// Disposes of all managed resources.
        /// </summary>
        /// <param name="disposing">If we are disposing.</param>
        protected virtual void Dispose(bool disposing)
        {
            if (disposedValue)
            {
                return;
            }

            if (disposing)
            {
                _loggerFactory.Dispose();
                debugOutStream.Dispose();
                _testAETConfigProvider.Dispose();
                TestGatewayProcessorConfigProvider.Dispose();
                TestGatewayReceiveConfigProvider.Dispose();
            }

            disposedValue = true;
        }
Пример #8
0
 public async Task IntegrationTestLicenseKey()
 {
     try
     {
         using (var segmentationClient = TestGatewayProcessorConfigProvider.CreateInnerEyeSegmentationClient()())
         {
             await segmentationClient.PingAsync().ConfigureAwait(false);
         }
     }
     catch (AuthenticationException)
     {
         Assert.Fail("Invalid product key. Check ProcessorSettings.LicenseKeyEnvVar in TestConfigurations/GatewayProcessorConfig.json and the corresponding system environment variable.");
     }
     catch (InvalidOperationException)
     {
         Assert.Fail("Unable to connect to inference service uri. Check ProcessorSettings.InferenceUri in TestConfigurations/GatewayProcessorConfig.json.");
     }
 }
Пример #9
0
        protected async Task <(string SegmentationId, string ModelId, IEnumerable <byte[]> Data)> StartRealSegmentationAsync(string filesPath)
        {
            var dicomFiles = new DirectoryInfo(filesPath).GetFiles().Select(x => DicomFile.Open(x.FullName)).ToArray();

            using (var segmentationClient = TestGatewayProcessorConfigProvider.CreateInnerEyeSegmentationClient().Invoke())
            {
                var testAETConfigModel = GetTestAETConfigModel();

                var matchedModel = ApplyAETModelConfigProvider.ApplyAETModelConfig(testAETConfigModel.AETConfig.Config.ModelsConfig, dicomFiles);
                var modelId      = matchedModel.Result.ModelId;

                var(segmentationId, postedImages) = await segmentationClient.StartSegmentationAsync(
                    matchedModel.Result.ModelId,
                    matchedModel.Result.ChannelData).ConfigureAwait(false);

                var referenceDicomFiles = postedImages.CreateNewDicomFileWithoutPixelData(segmentationClient.SegmentationAnonymisationProtocol.Select(x => x.DicomTagIndex.DicomTag));
                return(segmentationId, modelId, referenceDicomFiles);
            }
        }
Пример #10
0
        protected MockInnerEyeSegmentationClient GetMockInnerEyeSegmentationClient()
        {
            var realClient = TestGatewayProcessorConfigProvider.CreateInnerEyeSegmentationClient().Invoke();

            return(new MockInnerEyeSegmentationClient(realClient));
        }
Пример #11
0
        public async Task IntegrationTestEndToEnd()
        {
            var sourceDirectory = CreateTemporaryDirectory();
            var resultDirectory = CreateTemporaryDirectory();

            var random = new Random();

            // Get file names for all in directory
            var sourceDicomFileNames = new DirectoryInfo(@"Images\HN").GetFiles().ToArray();
            // Load all DICOM files
            var sourceDicomFiles = sourceDicomFileNames.Select(f => DicomFile.Open(f.FullName, FileReadOption.ReadAll)).ToArray();

            // Add/Update random tags for the source DICOM files.
            DicomAnonymisationTests.AddRandomTags(random, sourceDicomFiles);

            // Save them all to the sourceDirectory.
            var sourcePairs = sourceDicomFileNames.Zip(sourceDicomFiles, (f, d) => Tuple.Create(f, d)).ToArray();

            foreach (var sourcePair in sourcePairs)
            {
                var sourceImageFilePath = Path.Combine(sourceDirectory.FullName, sourcePair.Item1.Name);

                sourcePair.Item2.Save(sourceImageFilePath);
            }

            // Keep the first as a reference for deanonymization later.
            var originalSlice = sourceDicomFiles.First();

            var testAETConfigModel = GetTestAETConfigModel();

            var receivePort = 160;

            using (var dicomDataReceiver = new ListenerDataReceiver(new ListenerDicomSaver(resultDirectory.FullName)))
                using (var deleteService = CreateDeleteService())
                    using (var pushService = CreatePushService())
                        using (var downloadService = CreateDownloadService())
                            using (var uploadService = CreateUploadService())
                                using (var receiveService = CreateReceiveService(receivePort))
                                {
                                    // Start a DICOM receiver for the final DICOM-RT file
                                    var eventCount = new ConcurrentDictionary <DicomReceiveProgressCode, int>();
                                    var folderPath = string.Empty;

                                    dicomDataReceiver.DataReceived += (sender, e) =>
                                    {
                                        folderPath = e.FolderPath;
                                        eventCount.AddOrUpdate(e.ProgressCode, 1, (k, v) => v + 1);
                                    };

                                    StartDicomDataReceiver(dicomDataReceiver, testAETConfigModel.AETConfig.Destination.Port);

                                    // Start the services.
                                    deleteService.Start();
                                    pushService.Start();
                                    downloadService.Start();
                                    uploadService.Start();
                                    receiveService.Start();

                                    // Try a DICOM C-ECHO
                                    var dicomDataSender = new DicomDataSender();

                                    var echoResult = await dicomDataSender.DicomEchoAsync(
                                        testAETConfigModel.CallingAET,
                                        testAETConfigModel.CalledAET,
                                        receivePort,
                                        "127.0.0.1").ConfigureAwait(false);

                                    Assert.IsTrue(echoResult == DicomOperationResult.Success);

                                    // Send the image stack
                                    DcmtkHelpers.SendFolderUsingDCMTK(
                                        sourceDirectory.FullName,
                                        receivePort,
                                        ScuProfile.LEExplicitCT,
                                        TestContext,
                                        applicationEntityTitle: testAETConfigModel.CallingAET,
                                        calledAETitle: testAETConfigModel.CalledAET);

                                    // Wait for DICOM-RT file to be received.
                                    Func <DicomReceiveProgressCode, int, bool> TestEventCount = (progressCode, count) =>
                                                                                                eventCount.ContainsKey(progressCode) && eventCount[progressCode] == count;

                                    SpinWait.SpinUntil(() => TestEventCount(DicomReceiveProgressCode.AssociationEstablished, 1));
                                    SpinWait.SpinUntil(() => TestEventCount(DicomReceiveProgressCode.FileReceived, 1));
                                    SpinWait.SpinUntil(() => TestEventCount(DicomReceiveProgressCode.AssociationReleased, 1));
                                    SpinWait.SpinUntil(() => TestEventCount(DicomReceiveProgressCode.ConnectionClosed, 1));

                                    Assert.IsTrue(eventCount[DicomReceiveProgressCode.AssociationEstablished] == 1);
                                    Assert.IsTrue(eventCount[DicomReceiveProgressCode.FileReceived] == 1);
                                    Assert.IsTrue(eventCount[DicomReceiveProgressCode.AssociationReleased] == 1);
                                    Assert.IsTrue(eventCount[DicomReceiveProgressCode.ConnectionClosed] == 1);

                                    var receivedFiles = new DirectoryInfo(folderPath).GetFiles();
                                    Assert.AreEqual(1, receivedFiles.Length);

                                    var receivedFilePath = receivedFiles.First().FullName;

                                    var dicomFile = await DicomFile.OpenAsync(receivedFilePath, FileReadOption.ReadAll).ConfigureAwait(false);

                                    Assert.IsNotNull(dicomFile);

                                    var matchedModel = ApplyAETModelConfigProvider.ApplyAETModelConfig(testAETConfigModel.AETConfig.Config.ModelsConfig, sourceDicomFiles);

                                    var segmentationClient = TestGatewayProcessorConfigProvider.CreateInnerEyeSegmentationClient().Invoke();

                                    DicomAnonymisationTests.AssertDeanonymizedFile(
                                        originalSlice,
                                        dicomFile,
                                        segmentationClient.TopLevelReplacements,
                                        matchedModel.Result.TagReplacements,
                                        false);

                                    AssertIsDicomRtFile(DateTime.UtcNow, dicomFile, matchedModel.Result.ModelId);
                                }
        }