public async void GivenAllDifferentStudyInstanceUIDs_WhenStoringWithProvidedStudyInstanceUID_TheServerShouldReturnConflict() { DicomFile dicomFile1 = Samples.CreateRandomDicomFile(); DicomFile dicomFile2 = Samples.CreateRandomDicomFile(); var studyInstanceUID = TestUidGenerator.Generate(); DicomWebException <DicomDataset> exception = await Assert.ThrowsAsync <DicomWebException <DicomDataset> >(() => _client.StoreAsync( new[] { dicomFile1, dicomFile2 }, studyInstanceUID)); Assert.Equal(HttpStatusCode.Conflict, exception.StatusCode); Assert.NotNull(exception.Value); Assert.True(exception.Value.Count() == 1); ValidationHelpers.ValidateFailedSopSequence( exception.Value, ConvertToFailedSopSequenceEntry(dicomFile1.Dataset, MismatchStudyInstanceUidFailureCode), ConvertToFailedSopSequenceEntry(dicomFile2.Dataset, MismatchStudyInstanceUidFailureCode)); }
public async Task GivenUnsupportedInternalTransferSyntax_WhenRetrieveInstanceWithOriginalTransferSyntax_ThenServerShouldReturnOriginalContent() { var studyInstanceUid = TestUidGenerator.Generate(); var seriesInstanceUid = TestUidGenerator.Generate(); var sopInstanceUid = TestUidGenerator.Generate(); DicomFile dicomFile = Samples.CreateRandomDicomFileWith8BitPixelData( studyInstanceUid, seriesInstanceUid, sopInstanceUid, transferSyntax: DicomTransferSyntax.MPEG2.UID.UID, encode: false); await InternalStoreAsync(new[] { dicomFile }); using DicomWebResponse <DicomFile> instancesInStudy = await _client.RetrieveInstanceAsync(studyInstanceUid, seriesInstanceUid, sopInstanceUid, dicomTransferSyntax : "*"); Assert.Equal(dicomFile.ToByteArray(), (await instancesInStudy.GetValueAsync()).ToByteArray()); }
public async Task GivenRetrieveStudyMetadataRequest_WhenIfNoneMatchMatchesETag_ThenNotModifiedResponseIsReturned() { string studyInstanceUid = TestUidGenerator.Generate(); DicomDataset storedInstance = await PostDicomFileAsync(ResourceType.Study, studyInstanceUid, dataSet : GenerateNewDataSet()); string eTag; using (DicomWebAsyncEnumerableResponse <DicomDataset> response = await _client.RetrieveStudyMetadataAsync(studyInstanceUid)) { eTag = GetEtagFromResponse(response); } using (DicomWebAsyncEnumerableResponse <DicomDataset> response = await _client.RetrieveStudyMetadataAsync(studyInstanceUid, eTag)) { Assert.Equal(HttpStatusCode.NotModified, response.StatusCode); ValidateNoContent(response); } }
public async Task GivenMultipleSeriesInStudy_WhenDeletingSeries_TheServerShouldReturnNoContentAndOnlyTargetSeriesIsDeleted() { var studyInstanceUid = TestUidGenerator.Generate(); var seriesInstanceUid1 = TestUidGenerator.Generate(); var seriesInstanceUid2 = TestUidGenerator.Generate(); var sopInstanceUid1 = TestUidGenerator.Generate(); var sopInstanceUid2 = TestUidGenerator.Generate(); await CreateFile(studyInstanceUid, seriesInstanceUid1, sopInstanceUid1); await CreateFile(studyInstanceUid, seriesInstanceUid2, sopInstanceUid2); await _client.DeleteInstanceAsync(studyInstanceUid, seriesInstanceUid1, sopInstanceUid1); await VerifySopInstanceRemoval(studyInstanceUid, seriesInstanceUid1, sopInstanceUid1); await VerifySeriesRemoval(studyInstanceUid, seriesInstanceUid1); await VerifyRemainingSeries(studyInstanceUid, seriesInstanceUid2, 1); await VerifyRemainingStudy(studyInstanceUid, 1); }
public async Task GivenExistingStudyWithMultipleItemsInEachLevel_WhenDeletingStudy_TheServerShouldReturnNoContentAndAllLevelsShouldBeRemoved() { var studyInstanceUid = TestUidGenerator.Generate(); var seriesInstanceUid1 = TestUidGenerator.Generate(); var seriesInstanceUid2 = TestUidGenerator.Generate(); var sopInstanceUid1 = TestUidGenerator.Generate(); var sopInstanceUid2 = TestUidGenerator.Generate(); var sopInstanceUid3 = TestUidGenerator.Generate(); await CreateFile(studyInstanceUid, seriesInstanceUid1, sopInstanceUid1); await CreateFile(studyInstanceUid, seriesInstanceUid2, sopInstanceUid2); await CreateFile(studyInstanceUid, seriesInstanceUid2, sopInstanceUid3); await _client.DeleteStudyAsync(studyInstanceUid); await VerifyAllRemoval(studyInstanceUid, seriesInstanceUid1, sopInstanceUid1); await VerifyAllRemoval(studyInstanceUid, seriesInstanceUid2, sopInstanceUid2); await VerifyAllRemoval(studyInstanceUid, seriesInstanceUid2, sopInstanceUid3); }
public async Task GivenStudyWithMultileInstances_WhenDeleteStudy_ThenAssociatedErrorsShouldBeRemoved() { string studyUid1 = TestUidGenerator.Generate(); string seriesUid1 = TestUidGenerator.Generate(); string instanceUid1 = TestUidGenerator.Generate(); string seriesUid2 = TestUidGenerator.Generate(); string instanceUid2 = TestUidGenerator.Generate(); string studyUid3 = TestUidGenerator.Generate(); string seriesUid3 = TestUidGenerator.Generate(); string instanceUid3 = TestUidGenerator.Generate(); // add instances: instance1 and instance2 are in same study long watermark1 = await AddInstanceAsync(studyUid1, seriesUid1, instanceUid1); long watermark2 = await AddInstanceAsync(studyUid1, seriesUid2, instanceUid2); long watermark3 = await AddInstanceAsync(studyUid3, seriesUid3, instanceUid3); // add tag DicomTag tag = DicomTag.DeviceSerialNumber; int tagKey = await AddTagAsync(tag); // add errors ValidationErrorCode errorCode = ValidationErrorCode.DateIsInvalid; await _extendedQueryTagErrorStore.AddExtendedQueryTagErrorAsync(tagKey, errorCode, watermark1); await _extendedQueryTagErrorStore.AddExtendedQueryTagErrorAsync(tagKey, errorCode, watermark2); await _extendedQueryTagErrorStore.AddExtendedQueryTagErrorAsync(tagKey, errorCode, watermark3); // delete instance await _indexDataStore.DeleteStudyIndexAsync(DefaultPartition.Key, studyUid1, DateTime.UtcNow); // check errors var errors = await _extendedQueryTagErrorStore.GetExtendedQueryTagErrorsAsync(tag.GetPath(), int.MaxValue, 0); Assert.Single(errors); Assert.Equal(studyUid3, errors[0].StudyInstanceUid); Assert.Equal(seriesUid3, errors[0].SeriesInstanceUid); Assert.Equal(instanceUid3, errors[0].SopInstanceUid); }
public async Task GivenAnIncorrectAcceptHeader_WhenRetrievingResource_NotAcceptableIsReturned(string acceptHeader) { // Study await _client.ValidateResponseStatusCodeAsync( string.Format(DicomWebConstants.BasStudyUriFormat, TestUidGenerator.Generate()), acceptHeader, HttpStatusCode.NotAcceptable); // Series await _client.ValidateResponseStatusCodeAsync( string.Format(DicomWebConstants.BaseSeriesUriFormat, TestUidGenerator.Generate(), TestUidGenerator.Generate()), acceptHeader, HttpStatusCode.NotAcceptable); // Instance await _client.ValidateResponseStatusCodeAsync( string.Format(DicomWebConstants.BaseInstanceUriFormat, TestUidGenerator.Generate(), TestUidGenerator.Generate(), TestUidGenerator.Generate()), acceptHeader, HttpStatusCode.NotAcceptable); }
public async Task GivenExtendedQueryTagError_WhenAddExtendedQueryTagError_ThenErrorCountShouldIncrease() { string studyInstanceUid = TestUidGenerator.Generate(); string seriesInstanceUid = TestUidGenerator.Generate(); string sopInstanceUid = TestUidGenerator.Generate(); DicomTag tag = DicomTag.DeviceSerialNumber; long watermark = await AddInstanceAsync(studyInstanceUid, seriesInstanceUid, sopInstanceUid); int tagKey = await AddTagAsync(tag); await _extendedQueryTagErrorStore.AddExtendedQueryTagErrorAsync( tagKey, ValidationErrorCode.UidIsInvalid, watermark); var tagEntry = await _extendedQueryTagStore.GetExtendedQueryTagAsync(tag.GetPath()); Assert.Equal(1, tagEntry.ErrorCount); }
public async Task GivenRetrieveStudyMetadataRequest_WhenStudyIsUpdatedAndPreviousETagIsUsed_ThenResponseMetadataIsReturnedWithNewETag() { string studyInstanceUid = TestUidGenerator.Generate(); DicomDataset firstStoredInstance = await PostDicomFileAsync(ResourceType.Study, studyInstanceUid, dataSet : GenerateNewDataSet()); string eTag; using (DicomWebAsyncEnumerableResponse <DicomDataset> response = await _client.RetrieveStudyMetadataAsync(studyInstanceUid)) { eTag = GetEtagFromResponse(response); } DicomDataset secondStoredInstance = await PostDicomFileAsync(ResourceType.Study, studyInstanceUid, dataSet : GenerateNewDataSet()); using (DicomWebAsyncEnumerableResponse <DicomDataset> response = await _client.RetrieveStudyMetadataAsync(studyInstanceUid, eTag)) { await ValidateResponseMetadataDatasetAsync(response, firstStoredInstance, secondStoredInstance); } }
public async Task GivenFewDeletedInstances_NumMatchRetryCountShouldBeCorrect() { await _testHelper.ClearDeletedInstanceTable(); string studyInstanceUid = TestUidGenerator.Generate(); string seriesInstanceUid = TestUidGenerator.Generate(); string sopInstanceUid = TestUidGenerator.Generate(); Instance instance1 = await CreateIndexAndVerifyInstance(studyInstanceUid, seriesInstanceUid, sopInstanceUid); await _indexDataStore.DeleteInstanceIndexAsync(studyInstanceUid, seriesInstanceUid, sopInstanceUid, Clock.UtcNow); string sopInstanceUid2 = TestUidGenerator.Generate(); Instance instance2 = await CreateIndexAndVerifyInstance(studyInstanceUid, seriesInstanceUid, sopInstanceUid2); await _indexDataStore.DeleteInstanceIndexAsync(studyInstanceUid, seriesInstanceUid, sopInstanceUid2, Clock.UtcNow); var numMatchRetryCount = await _indexDataStore.RetrieveNumExhaustedDeletedInstanceAttemptsAsync(0); Assert.Equal(2, numMatchRetryCount); }
public async Task GivenAnExistingDicomInstance_WhenDeletedByInstanceId_AdditionalInstancesShouldBeMaintained() { string studyInstanceUid = TestUidGenerator.Generate(); string seriesInstanceUid = TestUidGenerator.Generate(); string sopInstanceUid = TestUidGenerator.Generate(); Instance instance = await CreateIndexAndVerifyInstance(studyInstanceUid, seriesInstanceUid, sopInstanceUid); string sopInstanceUid2 = TestUidGenerator.Generate(); await CreateIndexAndVerifyInstance(studyInstanceUid, seriesInstanceUid, sopInstanceUid2); await _indexDataStore.DeleteInstanceIndexAsync(studyInstanceUid, seriesInstanceUid, sopInstanceUid, Clock.UtcNow); Assert.Empty(await _testHelper.GetInstancesAsync(studyInstanceUid, seriesInstanceUid, sopInstanceUid)); Assert.NotEmpty(await _testHelper.GetInstancesAsync(studyInstanceUid, seriesInstanceUid, sopInstanceUid2)); Assert.NotEmpty(await _testHelper.GetSeriesMetadataAsync(seriesInstanceUid)); Assert.NotEmpty(await _testHelper.GetStudyMetadataAsync(studyInstanceUid)); Assert.Collection(await _testHelper.GetDeletedInstanceEntriesAsync(studyInstanceUid, seriesInstanceUid, null), ValidateSingleDeletedInstance(instance)); }
public async Task WhenRetrievingPartitions_TheServerShouldReturnAllPartitions() { var newPartition1 = TestUidGenerator.Generate(); var newPartition2 = TestUidGenerator.Generate(); DicomFile dicomFile = Samples.CreateRandomDicomFile(); using DicomWebResponse <DicomDataset> response1 = await _instancesManager.StoreAsync(new[] { dicomFile }, partitionName : newPartition1); using DicomWebResponse <DicomDataset> response2 = await _instancesManager.StoreAsync(new[] { dicomFile }, partitionName : newPartition2); using DicomWebResponse <IEnumerable <PartitionEntry> > response3 = await _client.GetPartitionsAsync(); Assert.True(response3.IsSuccessStatusCode); IEnumerable <PartitionEntry> values = await response3.GetValueAsync(); Assert.Contains(values, x => x.PartitionName == newPartition1); Assert.Contains(values, x => x.PartitionName == newPartition2); }
public async Task GivenMultipleInstancesWithMixTransferSyntax_WhenRetrieveStudy_ThenServerShouldReturnNotAcceptable() { var studyInstanceUid = TestUidGenerator.Generate(); DicomFile dicomFile1 = Samples.CreateRandomDicomFileWith8BitPixelData( studyInstanceUid, TestUidGenerator.Generate(), transferSyntax: DicomTransferSyntax.ExplicitVRLittleEndian.UID.UID); DicomFile dicomFile2 = Samples.CreateRandomDicomFileWith8BitPixelData( studyInstanceUid, TestUidGenerator.Generate(), transferSyntax: DicomTransferSyntax.MPEG2.UID.UID, encode: false); await _instancesManager.StoreAsync(new[] { dicomFile1, dicomFile2 }); DicomWebException exception = await Assert.ThrowsAsync <DicomWebException>(() => _client.RetrieveStudyAsync(studyInstanceUid, dicomTransferSyntax: DicomTransferSyntax.ExplicitVRLittleEndian.UID.UID)); Assert.Equal(HttpStatusCode.NotAcceptable, exception.StatusCode); }
public async Task GivenRetrieveSeriesMetadataRequest_WhenInstanceIsDeletedInSeriesAndPreviousETagIsUsed_ThenResponseMetadataIsReturnedWithNewETag() { string studyInstanceUid = TestUidGenerator.Generate(); string seriesInstanceUid = TestUidGenerator.Generate(); string firstSopInstanceUid = TestUidGenerator.Generate(); DicomDataset firstStoredInstance = await PostDicomFileAsync(ResourceType.Instance, studyInstanceUid, seriesInstanceUid, firstSopInstanceUid, dataSet : GenerateNewDataSet()); DicomDataset secondStoredInstance = await PostDicomFileAsync(ResourceType.Series, studyInstanceUid, seriesInstanceUid, dataSet : GenerateNewDataSet()); DicomWebResponse <IReadOnlyList <DicomDataset> > response = await _client.RetrieveSeriesMetadataAsync(studyInstanceUid, seriesInstanceUid); string eTag = GetEtagFromResponse(response); await _client.DeleteInstanceAsync(studyInstanceUid, seriesInstanceUid, firstSopInstanceUid); response = await _client.RetrieveSeriesMetadataAsync(studyInstanceUid, seriesInstanceUid, eTag); Assert.Single(response.Value); ValidateResponseMetadataDataset(secondStoredInstance, response.Value.First()); }
public async Task GivenDicomInstanceWithDifferentTypesOfExtendedQueryTags_WhenDeletedBySopInstanceId_ThenTagValuesShouldBeRemoved() { string studyInstanceUid = TestUidGenerator.Generate(); string seriesInstanceUid = TestUidGenerator.Generate(); string sopInstanceUid = TestUidGenerator.Generate(); string sopInstanceUid2 = TestUidGenerator.Generate(); try { // Store 5 tags, 1 study level datetime tag, 2 series level string and double tags and 2 instance level long and person name tags. IReadOnlyList <QueryTag> tags = await StoreTagsOfSuportedDataTypes(); // Create 2 instances in same series and same study. Instance instance1 = await StoreInstanceWithDifferentTagValues(studyInstanceUid, seriesInstanceUid, sopInstanceUid, 1, tags); Instance instance2 = await StoreInstanceWithDifferentTagValues(studyInstanceUid, seriesInstanceUid, sopInstanceUid2, 2, tags); var queryTags = tags.ToArray(); // Delete by instance uid. await _indexDataStore.DeleteInstanceIndexAsync(DefaultPartition.Key, studyInstanceUid, seriesInstanceUid, sopInstanceUid, Clock.UtcNow); // Study and series level tags should not be deleted. Assert.Single(await _extendedQueryTagStoreTestHelper.GetExtendedQueryTagDataAsync(ExtendedQueryTagDataType.DateTimeData, queryTags[0].ExtendedQueryTagStoreEntry.Key, instance1.StudyKey)); Assert.Single(await _extendedQueryTagStoreTestHelper.GetExtendedQueryTagDataAsync(ExtendedQueryTagDataType.StringData, queryTags[1].ExtendedQueryTagStoreEntry.Key, instance1.StudyKey, instance1.SeriesKey)); Assert.Single(await _extendedQueryTagStoreTestHelper.GetExtendedQueryTagDataAsync(ExtendedQueryTagDataType.DoubleData, queryTags[2].ExtendedQueryTagStoreEntry.Key, instance1.StudyKey, instance1.SeriesKey)); // Instance level tags under the deleted instance should be deleted. Assert.Empty(await _extendedQueryTagStoreTestHelper.GetExtendedQueryTagDataAsync(ExtendedQueryTagDataType.LongData, queryTags[3].ExtendedQueryTagStoreEntry.Key, instance1.StudyKey, instance1.SeriesKey, instance1.InstanceKey)); Assert.Empty(await _extendedQueryTagStoreTestHelper.GetExtendedQueryTagDataAsync(ExtendedQueryTagDataType.PersonNameData, queryTags[4].ExtendedQueryTagStoreEntry.Key, instance1.StudyKey, instance1.SeriesKey, instance1.InstanceKey)); // Instance level tags under the other instance should not be deleted. Assert.Single(await _extendedQueryTagStoreTestHelper.GetExtendedQueryTagDataAsync(ExtendedQueryTagDataType.LongData, queryTags[3].ExtendedQueryTagStoreEntry.Key, instance1.StudyKey, instance1.SeriesKey, instance2.InstanceKey)); Assert.Single(await _extendedQueryTagStoreTestHelper.GetExtendedQueryTagDataAsync(ExtendedQueryTagDataType.PersonNameData, queryTags[4].ExtendedQueryTagStoreEntry.Key, instance1.StudyKey, instance1.SeriesKey, instance2.InstanceKey)); } finally { await CleanupExtendedQueryTags(); } }
public async Task GivenAMultipartRequestWithAnInvalidMultipartSection_WhenStoring_TheServerShouldReturnAccepted() { var multiContent = new MultipartContent("related"); multiContent.Headers.ContentType.Parameters.Add(new System.Net.Http.Headers.NameValueHeaderValue("type", $"\"{DicomWebConstants.MediaTypeApplicationDicom.MediaType}\"")); var byteContent = new ByteArrayContent(Array.Empty <byte>()); byteContent.Headers.ContentType = DicomWebConstants.MediaTypeApplicationDicom; multiContent.Add(byteContent); string studyInstanceUID = TestUidGenerator.Generate(); try { DicomFile validFile = Samples.CreateRandomDicomFile(studyInstanceUID); await using (MemoryStream stream = _recyclableMemoryStreamManager.GetStream()) { await validFile.SaveAsync(stream); var validByteContent = new ByteArrayContent(stream.ToArray()); validByteContent.Headers.ContentType = DicomWebConstants.MediaTypeApplicationDicom; multiContent.Add(validByteContent); } using DicomWebResponse <DicomDataset> response = await _instancesManager.StoreAsync(multiContent, instanceId : DicomInstanceId.FromDicomFile(validFile)); Assert.Equal(HttpStatusCode.Accepted, response.StatusCode); await ValidateReferencedSopSequenceAsync( response, ConvertToReferencedSopSequenceEntry(validFile.Dataset)); } finally { await _client.DeleteStudyAsync(studyInstanceUID); } }
public async void GivenAMultipartRequestWithTypeParameterAndFirstSectionWithoutContentType_WhenStoring_TheServerShouldReturnOK() { var request = new HttpRequestMessage(HttpMethod.Post, "studies"); request.Headers.Add(HeaderNames.Accept, DicomWebClient.MediaTypeApplicationDicomJson.MediaType); var multiContent = new MultipartContent("related"); multiContent.Headers.ContentType.Parameters.Add(new System.Net.Http.Headers.NameValueHeaderValue("type", $"\"{DicomWebClient.MediaTypeApplicationDicom.MediaType}\"")); string studyInstanceUID = TestUidGenerator.Generate(); try { DicomFile dicomFile = Samples.CreateRandomDicomFile(studyInstanceUID); await using (MemoryStream stream = _recyclableMemoryStreamManager.GetStream()) { await dicomFile.SaveAsync(stream); var byteContent = new ByteArrayContent(stream.ToArray()); multiContent.Add(byteContent); } request.Content = multiContent; DicomWebResponse <DicomDataset> response = await _client.PostMultipartContentAsync(multiContent, "studies"); Assert.Equal(HttpStatusCode.OK, response.StatusCode); ValidationHelpers.ValidateReferencedSopSequence( response.Value, ConvertToReferencedSopSequenceEntry(dicomFile.Dataset)); } finally { await _client.DeleteStudyAsync(studyInstanceUID); } }
public async Task GivenASetOfDicomInstances_WhenRetrievingChangeFeed_ThenTheExpectedInstanceAreReturned() { var studyInstanceUid = TestUidGenerator.Generate(); var seriesInstanceUid = TestUidGenerator.Generate(); var sopInstanceUids = Enumerable.Range(1, 10).Select(x => TestUidGenerator.Generate()).ToArray(); long initialSequence = -1; for (int i = 0; i < 10; i++) { await CreateFile(studyInstanceUid, seriesInstanceUid, sopInstanceUids[i]); if (initialSequence == -1) { var result = await _client.GetChangeFeedLatest(); initialSequence = result.Value.Sequence; Assert.Equal(studyInstanceUid, result.Value.StudyInstanceUid); Assert.Equal(seriesInstanceUid, result.Value.SeriesInstanceUid); Assert.Equal(sopInstanceUids[i], result.Value.SopInstanceUid); Assert.Equal(ChangeFeedAction.Create, result.Value.Action); Assert.Equal(ChangeFeedState.Current, result.Value.State); } } var changeFeedResults = await _client.GetChangeFeed(); Assert.Equal(10, changeFeedResults.Value.Count); changeFeedResults = await _client.GetChangeFeed($"?offset={initialSequence - 1}"); Assert.Equal(10, changeFeedResults.Value.Count); for (int i = 0; i < 10; i++) { Assert.Equal(studyInstanceUid, changeFeedResults.Value[i].StudyInstanceUid); Assert.Equal(seriesInstanceUid, changeFeedResults.Value[i].SeriesInstanceUid); Assert.Equal(sopInstanceUids[i], changeFeedResults.Value[i].SopInstanceUid); Assert.NotNull(changeFeedResults.Value[i].Metadata); } }
public async void GivenRequestForStudies_WhenRetrievingQueriableExtendedQueryTags_ReturnsStudyTags(QueryResource resourceType) { var request = new QueryResourceRequest( Substitute.For <IEnumerable <KeyValuePair <string, StringValues> > >(), resourceType, TestUidGenerator.Generate(), TestUidGenerator.Generate()); List <ExtendedQueryTagStoreEntry> storeEntries = new List <ExtendedQueryTagStoreEntry>() { new ExtendedQueryTagStoreEntry(1, "00741000", "CS", null, QueryTagLevel.Instance, ExtendedQueryTagStatus.Ready), new ExtendedQueryTagStoreEntry(2, "0040A121", "DA", null, QueryTagLevel.Series, ExtendedQueryTagStatus.Ready), new ExtendedQueryTagStoreEntry(3, "00101005", "PN", null, QueryTagLevel.Study, ExtendedQueryTagStatus.Ready), }; var list = QueryTagService.CoreQueryTags.Concat(storeEntries.Select(item => new QueryTag(item))).ToList(); _queryStore.QueryAsync(Arg.Any <QueryExpression>(), Arg.Any <CancellationToken>()).ReturnsForAnyArgs(new QueryResult(new List <VersionedInstanceIdentifier>())); await _queryService.QueryAsync(request, CancellationToken.None); _queryParser.Received().Parse(request, Arg.Do <IReadOnlyCollection <QueryTag> >(x => Assert.Equal(x, list, QueryTagComparer.Default))); }
public async Task GivenMultipleDeletedInstances_OldestDeletedIsCorrect() { await _testHelper.ClearDeletedInstanceTable(); DateTimeOffset start = Clock.UtcNow; string studyInstanceUid = TestUidGenerator.Generate(); string seriesInstanceUid = TestUidGenerator.Generate(); string sopInstanceUid = TestUidGenerator.Generate(); Instance instance1 = await CreateIndexAndVerifyInstance(studyInstanceUid, seriesInstanceUid, sopInstanceUid); await _indexDataStore.DeleteInstanceIndexAsync(studyInstanceUid, seriesInstanceUid, sopInstanceUid, Clock.UtcNow); string sopInstanceUid2 = TestUidGenerator.Generate(); Instance instance2 = await CreateIndexAndVerifyInstance(studyInstanceUid, seriesInstanceUid, sopInstanceUid2); await Task.Delay(5000); await _indexDataStore.DeleteInstanceIndexAsync(studyInstanceUid, seriesInstanceUid, sopInstanceUid2, Clock.UtcNow); Assert.InRange(await _indexDataStore.GetOldestDeletedAsync(), start.AddSeconds(-1), start.AddSeconds(1)); }
public async Task GivenRetrieveStudyMetadataRequest_WhenIfNoneMatchDoesnotMatchETag_ThenResponseMetadataIsReturnedWithNewETag() { string studyInstanceUid = TestUidGenerator.Generate(); DicomDataset firstStoredInstance = await PostDicomFileAsync(ResourceType.Study, studyInstanceUid, dataSet : GenerateNewDataSet()); DicomDataset secondStoredInstance = await PostDicomFileAsync(ResourceType.Study, studyInstanceUid, dataSet : GenerateNewDataSet()); DicomWebResponse <IReadOnlyList <DicomDataset> > response = await _client.RetrieveStudyMetadataAsync(studyInstanceUid); string eTag = GetEtagFromResponse(response); string ifNoneMatch = null; if (!string.IsNullOrEmpty(eTag)) { ifNoneMatch = string.Concat("1", eTag); } response = await _client.RetrieveStudyMetadataAsync(studyInstanceUid, ifNoneMatch); ValidateResponseMetadataDataset(response, firstStoredInstance, secondStoredInstance); }
public async Task GivenMultipleDicomInstance_WhenDeletedByStudyInstanceUid_ThenItemsBeRemovedAndAddedToDeletedInstanceTable() { string studyInstanceUid = TestUidGenerator.Generate(); string seriesInstanceUid = TestUidGenerator.Generate(); string sopInstanceUid = TestUidGenerator.Generate(); Instance instance1 = await CreateIndexAndVerifyInstance(studyInstanceUid, seriesInstanceUid, sopInstanceUid); string sopInstanceUid2 = TestUidGenerator.Generate(); Instance instance2 = await CreateIndexAndVerifyInstance(studyInstanceUid, seriesInstanceUid, sopInstanceUid2); await _indexDataStore.DeleteStudyIndexAsync(studyInstanceUid, Clock.UtcNow); Assert.Empty(await _testHelper.GetInstancesAsync(studyInstanceUid, seriesInstanceUid, sopInstanceUid)); Assert.Empty(await _testHelper.GetInstancesAsync(studyInstanceUid, seriesInstanceUid, sopInstanceUid2)); Assert.Empty(await _testHelper.GetSeriesMetadataAsync(seriesInstanceUid)); Assert.Empty(await _testHelper.GetStudyMetadataAsync(seriesInstanceUid)); Assert.Collection( await _testHelper.GetDeletedInstanceEntriesAsync(studyInstanceUid, null, null), ValidateSingleDeletedInstance(instance1), ValidateSingleDeletedInstance(instance2)); }
public async Task GivenAnInstance_WhenRetrievingChangeFeedWithoutMetadata_ThenMetadataIsNotReturned() { var studyInstanceUid = TestUidGenerator.Generate(); var seriesInstanceUid = TestUidGenerator.Generate(); var sopInstanceUid = TestUidGenerator.Generate(); await CreateFile(studyInstanceUid, seriesInstanceUid, sopInstanceUid); var latestResult = await _client.GetChangeFeedLatest("?includemetadata=false"); long initialSequence = latestResult.Value.Sequence; Assert.Equal(studyInstanceUid, latestResult.Value.StudyInstanceUid); Assert.Equal(seriesInstanceUid, latestResult.Value.SeriesInstanceUid); Assert.Equal(sopInstanceUid, latestResult.Value.SopInstanceUid); Assert.Null(latestResult.Value.Metadata); var changeFeedResults = await _client.GetChangeFeed($"?offset={initialSequence - 1}&includemetadata=false"); Assert.Equal(1, changeFeedResults.Value.Count); Assert.Null(changeFeedResults.Value[0].Metadata); Assert.Equal(ChangeFeedState.Current, changeFeedResults.Value[0].State); }
public async Task WhenRetrievingWithPartitionName_TheServerShouldReturnOnlyTheSpecifiedPartition() { var newPartition1 = "partition1"; var newPartition2 = "partition2"; string studyInstanceUID = TestUidGenerator.Generate(); string seriesInstanceUID = TestUidGenerator.Generate(); string sopInstanceUID = TestUidGenerator.Generate(); DicomFile dicomFile = Samples.CreateRandomDicomFile(studyInstanceUID, seriesInstanceUID, sopInstanceUID); using DicomWebResponse <DicomDataset> response1 = await _instancesManager.StoreAsync(new[] { dicomFile }, partitionName : newPartition1); using DicomWebResponse <DicomDataset> response2 = await _instancesManager.StoreAsync(new[] { dicomFile }, partitionName : newPartition2); using DicomWebResponse <DicomFile> response3 = await _client.RetrieveInstanceAsync(studyInstanceUID, seriesInstanceUID, sopInstanceUID, partitionName : newPartition1); Assert.True(response3.IsSuccessStatusCode); using DicomWebResponse <DicomFile> response4 = await _client.RetrieveInstanceAsync(studyInstanceUID, seriesInstanceUID, sopInstanceUID, partitionName : newPartition2); Assert.True(response4.IsSuccessStatusCode); }
public async Task GivenANonExistingDicomInstance_WhenStatusIsUpdated_ThenDicomInstanceNotFoundExceptionShouldBeThrown() { string studyInstanceUid = TestUidGenerator.Generate(); string seriesInstanceUid = TestUidGenerator.Generate(); string sopInstanceUid = TestUidGenerator.Generate(); DicomDataset dataset = Samples.CreateRandomDicomFile(studyInstanceUid, seriesInstanceUid, sopInstanceUid).Dataset; long version = await _indexDataStore.CreateInstanceIndexAsync(dataset); VersionedInstanceIdentifier versionedInstanceIdentifier = new VersionedInstanceIdentifier( studyInstanceUid, seriesInstanceUid, sopInstanceUid, version); await _indexDataStore.DeleteInstanceIndexAsync(versionedInstanceIdentifier); await Assert.ThrowsAsync <InstanceNotFoundException>( () => _indexDataStore.UpdateInstanceIndexStatusAsync(versionedInstanceIdentifier, IndexStatus.Created)); Assert.Empty(await _testHelper.GetInstancesAsync(studyInstanceUid, seriesInstanceUid, sopInstanceUid)); }
public async Task GivenAnInstance_WhenRetrievingChangeFeedWithPartition_ThenPartitionNameIsReturned() { var newPartition = TestUidGenerator.Generate(); string studyInstanceUID = TestUidGenerator.Generate(); string seriesInstanceUID = TestUidGenerator.Generate(); string sopInstanceUID = TestUidGenerator.Generate(); DicomFile dicomFile = Samples.CreateRandomDicomFile(studyInstanceUID, seriesInstanceUID, sopInstanceUID); using DicomWebResponse <DicomDataset> response1 = await _instancesManager.StoreAsync(new[] { dicomFile }, partitionName : newPartition); Assert.True(response1.IsSuccessStatusCode); long initialSequence; using (DicomWebResponse <ChangeFeedEntry> response = await _client.GetChangeFeedLatest("?includemetadata=false")) { ChangeFeedEntry changeFeedEntry = await response.GetValueAsync(); initialSequence = changeFeedEntry.Sequence; Assert.Equal(newPartition, changeFeedEntry.PartitionName); Assert.Equal(studyInstanceUID, changeFeedEntry.StudyInstanceUid); Assert.Equal(seriesInstanceUID, changeFeedEntry.SeriesInstanceUid); Assert.Equal(sopInstanceUID, changeFeedEntry.SopInstanceUid); } using (DicomWebAsyncEnumerableResponse <ChangeFeedEntry> response = await _client.GetChangeFeed($"?offset={initialSequence - 1}&includemetadata=false")) { ChangeFeedEntry[] changeFeedResults = await response.ToArrayAsync(); Assert.Single(changeFeedResults); Assert.Null(changeFeedResults[0].Metadata); Assert.Equal(newPartition, changeFeedResults[0].PartitionName); Assert.Equal(ChangeFeedState.Current, changeFeedResults[0].State); } }
public async Task GivenAnExistingDicomInstance_WhenStatusIsUpdated_ThenStatusShouldBeUpdated() { string studyInstanceUid = TestUidGenerator.Generate(); string seriesInstanceUid = TestUidGenerator.Generate(); string sopInstanceUid = TestUidGenerator.Generate(); DicomDataset dataset = Samples.CreateRandomDicomFile(studyInstanceUid, seriesInstanceUid, sopInstanceUid).Dataset; long version = await _indexDataStore.CreateInstanceIndexAsync(dataset); Instance instance = await _testHelper.GetInstanceAsync(studyInstanceUid, seriesInstanceUid, sopInstanceUid, version); Assert.NotNull(instance); DateTimeOffset lastStatusUpdatedDate = instance.LastStatusUpdatedDate; // Make sure there is delay between. await Task.Delay(50); await _indexDataStore.UpdateInstanceIndexStatusAsync( new VersionedInstanceIdentifier( studyInstanceUid, seriesInstanceUid, sopInstanceUid, version), IndexStatus.Created); IReadOnlyList <Instance> instances = await _testHelper.GetInstancesAsync(studyInstanceUid, seriesInstanceUid, sopInstanceUid); Assert.NotNull(instances); Assert.Single(instances); Instance updatedInstance = instances[0]; Assert.Equal((byte)IndexStatus.Created, updatedInstance.Status); Assert.True(updatedInstance.LastStatusUpdatedDate > lastStatusUpdatedDate); }
public async Task GivenInstances_WhenDeleteInstance_ThenAssociatedErrorsShouldBeRemoved() { string studyUid1 = TestUidGenerator.Generate(); string seriesUid1 = TestUidGenerator.Generate(); string instanceUid1 = TestUidGenerator.Generate(); string studyUid2 = TestUidGenerator.Generate(); string seriesUid2 = TestUidGenerator.Generate(); string instanceUid2 = TestUidGenerator.Generate(); // add instances long watermark1 = await AddInstanceAsync(studyUid1, seriesUid1, instanceUid1); long watermark2 = await AddInstanceAsync(studyUid2, seriesUid2, instanceUid2); // add tag DicomTag tag1 = DicomTag.DeviceSerialNumber; int tagKey = await AddTagAsync(tag1); // add errors ValidationErrorCode errorCode = ValidationErrorCode.DateIsInvalid; await _extendedQueryTagErrorStore.AddExtendedQueryTagErrorAsync(tagKey, errorCode, watermark1); await _extendedQueryTagErrorStore.AddExtendedQueryTagErrorAsync(tagKey, errorCode, watermark2); // delete instance await _indexDataStore.DeleteInstanceIndexAsync(new InstanceIdentifier(studyUid1, seriesUid1, instanceUid1, DefaultPartition.Key)); // check errors var errors = await _extendedQueryTagErrorStore.GetExtendedQueryTagErrorsAsync(tag1.GetPath(), int.MaxValue, 0); Assert.Single(errors); Assert.Equal(studyUid2, errors[0].StudyInstanceUid); Assert.Equal(seriesUid2, errors[0].SeriesInstanceUid); Assert.Equal(instanceUid2, errors[0].SopInstanceUid); }
public async Task GivenUnsupportedTransferSyntax_WhenRetrieveFrame_ThenServerShouldReturnNotAcceptable() { string studyInstanceUid = TestUidGenerator.Generate(); string seriesInstanceUid = TestUidGenerator.Generate(); string sopInstanceUid = TestUidGenerator.Generate(); DicomFile dicomFile = Samples.CreateRandomDicomFileWith8BitPixelData( studyInstanceUid, seriesInstanceUid, sopInstanceUid, transferSyntax: DicomTransferSyntax.HEVCH265Main10ProfileLevel51.UID.UID, encode: false); await InternalStoreAsync(new[] { dicomFile }); DicomWebException exception = await Assert.ThrowsAsync <DicomWebException>(() => _client.RetrieveFramesAsync( studyInstanceUid, seriesInstanceUid, sopInstanceUid, dicomTransferSyntax: DicomTransferSyntax.JPEG2000Lossless.UID.UID, frames: new[] { 1 })); Assert.Equal(HttpStatusCode.NotAcceptable, exception.StatusCode); }
private async Task <List <DicomDataset> > GenerateDicomDatasets(string seriesInstanceUid, int instancesinSeries, bool storeInstanceFile) { List <DicomDataset> dicomDatasets = new List <DicomDataset>(); for (int i = 0; i < instancesinSeries; i++) { var ds = new DicomDataset(DicomTransferSyntax.ExplicitVRLittleEndian) { { DicomTag.StudyInstanceUID, _studyInstanceUid }, { DicomTag.SeriesInstanceUID, seriesInstanceUid }, { DicomTag.SOPInstanceUID, TestUidGenerator.Generate() }, { DicomTag.SOPClassUID, TestUidGenerator.Generate() }, { DicomTag.PatientID, TestUidGenerator.Generate() }, { DicomTag.BitsAllocated, (ushort)8 }, { DicomTag.PhotometricInterpretation, PhotometricInterpretation.Monochrome2.Value }, }; await StoreDatasetsAndInstances(ds, storeInstanceFile); dicomDatasets.Add(ds); } return(dicomDatasets); }