public async Task DoesNotReEnqueueProcessingIfValidationSetTimesOut() { const int postponeMinutes = 1; AddValidation("validation1", ValidationStatus.Incomplete); Configuration.TimeoutValidationSetAfter = TimeSpan.FromDays(1); Configuration.ValidationMessageRecheckPeriod = TimeSpan.FromMinutes(postponeMinutes); ValidationSet.Created = DateTime.UtcNow - TimeSpan.FromDays(1) - TimeSpan.FromHours(1); ValidationStorageServiceMock .Setup(s => s.UpdateValidationSetAsync(It.IsAny <PackageValidationSet>())) .Callback <PackageValidationSet>(s => s.Updated = DateTime.UtcNow) .Returns(Task.FromResult(0)); var processor = CreateProcessor(); await processor.ProcessValidationOutcomeAsync(ValidationSet, PackageValidatingEntity, ProcessorStats); TelemetryServiceMock .Verify(t => t.TrackValidationSetTimeout(Package.PackageRegistration.Id, Package.NormalizedVersion, ValidationSet.ValidationTrackingId)); ValidationEnqueuerMock .Verify(ve => ve.StartValidationAsync(It.IsAny <PackageValidationMessageData>(), It.IsAny <DateTimeOffset>()), Times.Never); PackageFileServiceMock .Verify(x => x.DeletePackageForValidationSetAsync(It.IsAny <PackageValidationSet>()), Times.Never); }
public async Task MarksPackageStatusBasedOnValidatorResults( ValidationStatus validation, PackageStatus fromStatus, PackageStatus toStatus, bool expectedSetPackageStatusCall) { AddValidation("validation1", validation); Package.PackageStatusKey = fromStatus; TimeSpan duration = default(TimeSpan); TelemetryServiceMock .Setup(ts => ts.TrackTotalValidationDuration(It.IsAny <string>(), It.IsAny <string>(), It.IsAny <Guid>(), It.IsAny <TimeSpan>(), It.IsAny <bool>())) .Callback <string, string, Guid, TimeSpan, bool>((_1, _2, _3, t, _4) => duration = t); ProcessorStats.AnyRequiredValidationSucceeded = true; ProcessorStats.AnyValidationSucceeded = true; var processor = CreateProcessor(); var before = DateTime.UtcNow; await processor.ProcessValidationOutcomeAsync(ValidationSet, PackageValidatingEntity, ProcessorStats); var after = DateTime.UtcNow; if (expectedSetPackageStatusCall) { PackageStateProcessorMock.Verify( x => x.SetStatusAsync(PackageValidatingEntity, ValidationSet, toStatus), Times.Once); PackageStateProcessorMock.Verify( x => x.SetStatusAsync(It.IsAny <PackageValidatingEntity>(), It.IsAny <PackageValidationSet>(), It.IsAny <PackageStatus>()), Times.Once); } else { PackageStateProcessorMock.Verify( x => x.SetStatusAsync(It.IsAny <PackageValidatingEntity>(), It.IsAny <PackageValidationSet>(), It.IsAny <PackageStatus>()), Times.Never); } if (validation != ValidationStatus.Failed) { PackageFileServiceMock.Verify( x => x.DeletePackageForValidationSetAsync(ValidationSet), Times.Never); } else { PackageFileServiceMock.Verify( x => x.DeletePackageForValidationSetAsync(ValidationSet), Times.Once); } TelemetryServiceMock .Verify(ts => ts.TrackTotalValidationDuration(It.IsAny <string>(), It.IsAny <string>(), It.IsAny <Guid>(), It.IsAny <TimeSpan>(), It.IsAny <bool>()), Times.Once()); Assert.InRange(duration, before - ValidationSet.Created, after - ValidationSet.Created); Assert.Equal(ValidationSetStatus.Completed, ValidationSet.ValidationSetStatus); }
public async Task AllowsPackageAlreadyInPublicContainerWhenValidationSetPackageDoesNotExist() { PackageFileServiceMock .Setup(x => x.DoesValidationSetPackageExistAsync(It.IsAny <PackageValidationSet>())) .ReturnsAsync(false); PackageFileServiceMock .Setup(x => x.CopyValidationPackageToPackageFileAsync(It.IsAny <PackageValidationSet>())) .Throws(new InvalidOperationException("Duplicate!")); await Target.SetStatusAsync(PackageValidatingEntity, ValidationSet, PackageStatus.Available); PackageFileServiceMock.Verify( x => x.UpdatePackageBlobMetadataInValidationAsync(It.IsAny <PackageValidationSet>()), Times.Once); PackageFileServiceMock.Verify( x => x.CopyValidationPackageToPackageFileAsync(ValidationSet), Times.Once); PackageServiceMock.Verify( x => x.UpdateStatusAsync(Package, PackageStatus.Available, true), Times.Once); PackageFileServiceMock.Verify( x => x.DeleteValidationPackageFileAsync(ValidationSet), Times.Once); PackageFileServiceMock.Verify( x => x.DeletePackageForValidationSetAsync(ValidationSet), Times.Never); }
public async Task TracksTimedOutValidators() { const int postponeMinutes = 1; AddValidation( "IncompleteAndNotTimedOut", ValidationStatus.Incomplete, validationStart: DateTime.UtcNow, trackAfter: TimeSpan.FromDays(1)); AddValidation( "IncompleteButTimedOut", ValidationStatus.Incomplete, validationStart: DateTime.UtcNow + TimeSpan.FromDays(-5), trackAfter: TimeSpan.FromDays(1)); Configuration.TimeoutValidationSetAfter = TimeSpan.FromDays(1); Configuration.ValidationMessageRecheckPeriod = TimeSpan.FromMinutes(postponeMinutes); var processor = CreateProcessor(); await processor.ProcessValidationOutcomeAsync(ValidationSet, PackageValidatingEntity, ProcessorStats); TelemetryServiceMock .Verify(t => t.TrackValidatorTimeout("IncompleteButTimedOut")); ValidationEnqueuerMock .Verify(ve => ve.StartValidationAsync(It.IsAny <PackageValidationMessageData>(), It.IsAny <DateTimeOffset>()), Times.Once); PackageFileServiceMock .Verify(x => x.DeletePackageForValidationSetAsync(It.IsAny <PackageValidationSet>()), Times.Never); }
public async Task DoesNotSendValidatingTooLongMessageOnRevalidations() { const int postponeMinutes = 1; AddValidation("validation1", ValidationStatus.Incomplete); Configuration.TimeoutValidationSetAfter = TimeSpan.FromDays(1); Configuration.ValidationSetNotificationTimeout = TimeSpan.FromMinutes(20); Configuration.ValidationMessageRecheckPeriod = TimeSpan.FromMinutes(postponeMinutes); ValidationSet.Created = DateTime.UtcNow - TimeSpan.FromMinutes(21); ValidationSet.Updated = DateTime.UtcNow - TimeSpan.FromMinutes(15); ValidationStorageServiceMock .Setup(s => s.UpdateValidationSetAsync(It.IsAny <PackageValidationSet>())) .Callback <PackageValidationSet>(s => s.Updated = DateTime.UtcNow) .Returns(Task.FromResult(0)); ValidationStorageServiceMock .Setup(s => s.GetValidationSetCountAsync(PackageValidatingEntity)) .Returns(Task.FromResult(2)); // Process the outcome once - the "too long to validate" message should NOT be sent. var processor = CreateProcessor(); await processor.ProcessValidationOutcomeAsync(ValidationSet, PackageValidatingEntity, ProcessorStats); TelemetryServiceMock .Verify(t => t.TrackSentValidationTakingTooLongMessage(Package.PackageRegistration.Id, Package.NormalizedVersion, ValidationSet.ValidationTrackingId), Times.Never); MessageServiceMock .Verify(m => m.SendValidationTakingTooLongMessageAsync(Package), Times.Never); ValidationEnqueuerMock .Verify(ve => ve.StartValidationAsync(It.IsAny <PackageValidationMessageData>(), It.IsAny <DateTimeOffset>()), Times.Once); PackageFileServiceMock .Verify(x => x.DeletePackageForValidationSetAsync(It.IsAny <PackageValidationSet>()), Times.Never); }
public async Task GetOrCreateValidationSetAsyncDoesNotCreateDuplicateValidationSet() { Guid validationTrackingId = Guid.NewGuid(); ValidationStorageMock .Setup(vs => vs.GetValidationSetAsync(validationTrackingId)) .ReturnsAsync((PackageValidationSet)null); ValidationStorageMock .Setup(vs => vs.OtherRecentValidationSetForPackageExists( Package.Key, It.IsAny <TimeSpan>(), validationTrackingId)) .ReturnsAsync(true); var provider = CreateProvider(); var result = await provider.TryGetOrCreateValidationSetAsync(validationTrackingId, Package); Assert.Null(result); ValidationStorageMock .Verify( vs => vs.OtherRecentValidationSetForPackageExists( Package.Key, It.IsAny <TimeSpan>(), validationTrackingId), Times.Once); ValidationStorageMock .Verify(vs => vs.CreateValidationSetAsync(It.IsAny <PackageValidationSet>()), Times.Never); PackageFileServiceMock.Verify( x => x.CopyPackageFileForValidationSetAsync(It.IsAny <PackageValidationSet>()), Times.Never); PackageFileServiceMock.Verify( x => x.CopyValidationPackageForValidationSetAsync(It.IsAny <PackageValidationSet>()), Times.Never); }
public async Task ThrowsExceptionWhenValidationSetPackageAndDestinationPackageBothExist(PackageStatus packageStatus) { ValidationSet.PackageETag = null; Package.PackageStatusKey = packageStatus; var expected = new InvalidOperationException("Duplicate!"); PackageFileServiceMock .Setup(x => x.DoesValidationSetPackageExistAsync(It.IsAny <PackageValidationSet>())) .ReturnsAsync(true); PackageFileServiceMock .Setup(x => x.CopyValidationSetPackageToPackageFileAsync(It.IsAny <PackageValidationSet>(), It.IsAny <IAccessCondition>())) .Throws(expected); var actual = await Assert.ThrowsAsync <InvalidOperationException>( () => Target.SetPackageStatusAsync(Package, ValidationSet, PackageStatus.Available)); Assert.Same(expected, actual); PackageFileServiceMock.Verify( x => x.CopyValidationSetPackageToPackageFileAsync(ValidationSet, It.Is <IAccessCondition>(y => y.IfNoneMatchETag == "*")), Times.Once); PackageServiceMock.Verify( x => x.UpdatePackageStatusAsync(It.IsAny <Package>(), It.IsAny <PackageStatus>(), It.IsAny <bool>()), Times.Never); PackageFileServiceMock.Verify( x => x.DeleteValidationPackageFileAsync(It.IsAny <string>(), It.IsAny <string>()), Times.Never); PackageFileServiceMock.Verify( x => x.DeletePackageForValidationSetAsync(It.IsAny <PackageValidationSet>()), Times.Never); }
public async Task TriesToGetValidationSetFirst() { ValidationStorageMock .Setup(vs => vs.GetValidationSetAsync(ValidationSet.ValidationTrackingId)) .ReturnsAsync(ValidationSet) .Verifiable(); var provider = CreateProvider(); var set = await provider.TryGetOrCreateValidationSetAsync(PackageValidationMessageData, PackageValidatingEntity); ValidationStorageMock .Verify(vs => vs.GetValidationSetAsync(ValidationSet.ValidationTrackingId), Times.Once()); Assert.Same(ValidationSet, set); PackageFileServiceMock.Verify( x => x.CopyPackageFileForValidationSetAsync(It.IsAny <PackageValidationSet>()), Times.Never); PackageFileServiceMock.Verify( x => x.CopyValidationPackageForValidationSetAsync(It.IsAny <PackageValidationSet>()), Times.Never); PackageFileServiceMock.Verify( x => x.BackupPackageFileFromValidationSetPackageAsync(It.IsAny <PackageValidationSet>()), Times.Never); TelemetryServiceMock.Verify( x => x.TrackDurationToValidationSetCreation(It.IsAny <string>(), It.IsAny <string>(), It.IsAny <Guid>(), It.IsAny <TimeSpan>()), Times.Never); }
public async Task CopiesPackageToPublicStorageAndSendsEmailUponSuccess() { AddValidation("validation1", ValidationStatus.Succeeded); Package.PackageStatusKey = PackageStatus.Validating; var stream = new MemoryStream(); PackageFileServiceMock .Setup(pfs => pfs.DownloadValidationPackageFileAsync(Package)) .ReturnsAsync(stream) .Verifiable(); PackageFileServiceMock .Setup(pfs => pfs.SavePackageFileAsync(Package, stream)) .Returns(Task.FromResult(0)) .Verifiable(); var processor = CreateProcessor(); await processor.ProcessValidationOutcomeAsync(ValidationSet, Package); PackageFileServiceMock .Verify(pfs => pfs.DownloadValidationPackageFileAsync(Package), Times.Once()); PackageFileServiceMock .Verify(pfs => pfs.DownloadValidationPackageFileAsync(It.IsAny <Package>()), Times.Once()); PackageFileServiceMock .Verify(pfs => pfs.SavePackageFileAsync(Package, stream), Times.Once()); PackageFileServiceMock .Verify(pfs => pfs.SavePackageFileAsync(It.IsAny <Package>(), It.IsAny <Stream>()), Times.Once()); MessageServiceMock .Verify(ms => ms.SendPackagePublishedMessage(Package), Times.Once()); MessageServiceMock .Verify(ms => ms.SendPackagePublishedMessage(It.IsAny <Package>()), Times.Once()); }
public async Task ThrowsExceptionWhenValidationSetPackageAndDestinationPackageDoesNotMatchETag() { ValidationSet.PackageETag = "\"some-etag\""; Package.PackageStatusKey = PackageStatus.Available; var expected = new StorageException(new RequestResult { HttpStatusCode = (int)HttpStatusCode.PreconditionFailed }, "Changed!", null); PackageFileServiceMock .Setup(x => x.DoesValidationSetPackageExistAsync(It.IsAny <PackageValidationSet>())) .ReturnsAsync(true); PackageFileServiceMock .Setup(x => x.CopyValidationSetPackageToPackageFileAsync(It.IsAny <PackageValidationSet>(), It.IsAny <IAccessCondition>())) .Throws(expected); var actual = await Assert.ThrowsAsync <StorageException>( () => Target.SetPackageStatusAsync(Package, ValidationSet, PackageStatus.Available)); Assert.Same(expected, actual); PackageFileServiceMock.Verify( x => x.CopyValidationSetPackageToPackageFileAsync(ValidationSet, It.Is <IAccessCondition>(y => y.IfMatchETag == "\"some-etag\"")), Times.Once); PackageServiceMock.Verify( x => x.UpdatePackageStatusAsync(It.IsAny <Package>(), It.IsAny <PackageStatus>(), It.IsAny <bool>()), Times.Never); PackageFileServiceMock.Verify( x => x.DeleteValidationPackageFileAsync(It.IsAny <string>(), It.IsAny <string>()), Times.Never); PackageFileServiceMock.Verify( x => x.DeletePackageForValidationSetAsync(It.IsAny <PackageValidationSet>()), Times.Never); }
public async Task CopiesPackageFromValidationContainerWhenNotAvailable(PackageStatus packageStatus) { const string validation1 = "validation1"; Configuration.Validations = new List <ValidationConfigurationItem> { new ValidationConfigurationItem() { Name = validation1, TrackAfter = TimeSpan.FromDays(1), RequiredValidations = new List <string>(), ShouldStart = true, } }; Package.PackageStatusKey = packageStatus; Guid validationTrackingId = Guid.NewGuid(); ValidationStorageMock .Setup(vs => vs.GetValidationSetAsync(validationTrackingId)) .ReturnsAsync((PackageValidationSet)null) .Verifiable(); ValidationStorageMock .Setup(vs => vs.OtherRecentValidationSetForPackageExists(It.IsAny <IValidatingEntity <Package> >(), It.IsAny <TimeSpan>(), validationTrackingId)) .ReturnsAsync(false); PackageValidationSet createdSet = null; ValidationStorageMock .Setup(vs => vs.CreateValidationSetAsync(It.IsAny <PackageValidationSet>())) .Returns <PackageValidationSet>(pvs => Task.FromResult(pvs)) .Callback <PackageValidationSet>(pvs => createdSet = pvs) .Verifiable(); ValidationStorageMock .Setup(vs => vs.GetValidationSetCountAsync(It.IsAny <IValidatingEntity <Package> >())) .ReturnsAsync(1); var provider = CreateProvider(); var packageValidationMessageData = new ProcessValidationSetData( Package.PackageRegistration.Id, Package.NormalizedVersion, validationTrackingId, ValidatingType.Package, Package.Key); var actual = await provider.TryGetOrCreateValidationSetAsync(packageValidationMessageData, PackageValidatingEntity); PackageFileServiceMock.Verify(x => x.CopyPackageFileForValidationSetAsync(It.IsAny <PackageValidationSet>()), Times.Never); PackageFileServiceMock.Verify(x => x.CopyValidationPackageForValidationSetAsync(createdSet), Times.Once); PackageFileServiceMock.Verify(x => x.CopyValidationPackageForValidationSetAsync(It.IsAny <PackageValidationSet>()), Times.Once); PackageFileServiceMock.Verify(x => x.BackupPackageFileFromValidationSetPackageAsync(createdSet), Times.Once); Assert.Null(actual.PackageETag); }
public async Task AlwaysUsesValidationSetPackageWhenHasAnyProcessor() { ValidationSet.PackageValidations = new List <PackageValidation> { new PackageValidation { Type = "SomeValidatorA" }, new PackageValidation { Type = "SomeValidatorB" }, new PackageValidation { Type = "SomeProcessorA" }, new PackageValidation { Type = "SomeProcessorB" }, }; var expected = new StorageException("Validation set package not found!"); ValidatorProviderMock .Setup(x => x.IsNuGetProcessor(It.Is <string>(n => n.Contains("Processor")))) .Returns(true); PackageFileServiceMock .Setup(x => x.CopyValidationSetPackageToPackageFileAsync(ValidationSet, It.IsAny <IAccessCondition>())) .Throws(expected); var actual = await Assert.ThrowsAsync <StorageException>( () => Target.SetStatusAsync(PackageValidatingEntity, ValidationSet, PackageStatus.Available)); Assert.Same(expected, actual); PackageFileServiceMock.Verify( x => x.UpdatePackageBlobMetadataInValidationSetAsync(It.IsAny <PackageValidationSet>()), Times.Once); PackageFileServiceMock.Verify( x => x.UpdatePackageBlobMetadataInValidationAsync(It.IsAny <PackageValidationSet>()), Times.Never); PackageFileServiceMock.Verify( x => x.CopyValidationPackageToPackageFileAsync(It.IsAny <PackageValidationSet>()), Times.Never); PackageFileServiceMock.Verify( x => x.DoesValidationSetPackageExistAsync(It.IsAny <PackageValidationSet>()), Times.Never); ValidatorProviderMock.Verify( x => x.IsNuGetProcessor("SomeValidatorA"), Times.Once); ValidatorProviderMock.Verify( x => x.IsNuGetProcessor("SomeValidatorB"), Times.Once); ValidatorProviderMock.Verify( x => x.IsNuGetProcessor("SomeProcessorA"), Times.Once); ValidatorProviderMock.Verify( x => x.IsNuGetProcessor("SomeProcessorB"), Times.Never); // Never checked, since SomeProcessorA was found. }
public async Task DoesNotBackUpThePackageWhenThereAreNoValidators() { const string validation1 = "validation1"; Configuration.Validations = new List <ValidationConfigurationItem> { new ValidationConfigurationItem() { Name = validation1, TrackAfter = TimeSpan.FromDays(1), RequiredValidations = new List <string> { } } }; ValidatorProvider .Setup(x => x.IsNuGetProcessor(validation1)) .Returns(false); Guid validationTrackingId = Guid.NewGuid(); ValidationStorageMock .Setup(vs => vs.GetValidationSetAsync(validationTrackingId)) .ReturnsAsync((PackageValidationSet)null) .Verifiable(); ValidationStorageMock .Setup(vs => vs.OtherRecentValidationSetForPackageExists(It.IsAny <IValidatingEntity <Package> >(), It.IsAny <TimeSpan>(), validationTrackingId)) .ReturnsAsync(false); PackageValidationSet createdSet = null; ValidationStorageMock .Setup(vs => vs.CreateValidationSetAsync(It.IsAny <PackageValidationSet>())) .Returns <PackageValidationSet>(pvs => Task.FromResult(pvs)) .Callback <PackageValidationSet>(pvs => createdSet = pvs) .Verifiable(); ValidationStorageMock .Setup(vs => vs.GetValidationSetCountAsync(It.IsAny <IValidatingEntity <Package> >())) .ReturnsAsync(1); var provider = CreateProvider(); var packageValidationMessageData = new ProcessValidationSetData( Package.PackageRegistration.Id, Package.NormalizedVersion, validationTrackingId, ValidatingType.Package, Package.Key); var actual = await provider.TryGetOrCreateValidationSetAsync(packageValidationMessageData, PackageValidatingEntity); PackageFileServiceMock.Verify( x => x.BackupPackageFileFromValidationSetPackageAsync(It.IsAny <PackageValidationSet>()), Times.Never); }
public async Task ProcessesFailedValidationAccordingToFailureBehavior(ValidationFailureBehavior failureBehavior, PackageStatus expectedPackageStatus) { AddValidation("validation1", ValidationStatus.Failed, failureBehavior); var processor = CreateProcessor(); await processor.ProcessValidationOutcomeAsync(ValidationSet, PackageValidatingEntity, ProcessorStats); PackageStateProcessorMock.Verify( x => x.SetStatusAsync(PackageValidatingEntity, ValidationSet, expectedPackageStatus), Times.Once); PackageFileServiceMock.Verify( x => x.DeletePackageForValidationSetAsync(ValidationSet), Times.Once); }
public async Task DoesNotCopyPackageIfItsAvailable() { AddValidation("validation1", ValidationStatus.Succeeded); Package.PackageStatusKey = PackageStatus.Available; var processor = CreateProcessor(); await processor.ProcessValidationOutcomeAsync(ValidationSet, Package); PackageFileServiceMock .Verify(pfs => pfs.DownloadValidationPackageFileAsync(It.IsAny <Package>()), Times.Never()); PackageFileServiceMock .Verify(pfs => pfs.SavePackageFileAsync(It.IsAny <Package>(), It.IsAny <Stream>()), Times.Never()); }
public async Task CopiesPackageFromPackagesContainerWhenAvailable() { const string validation1 = "validation1"; Configuration.Validations = new List <ValidationConfigurationItem> { new ValidationConfigurationItem() { Name = validation1, TrackAfter = TimeSpan.FromDays(1), RequiredValidations = new List <string> { } } }; Package.PackageStatusKey = PackageStatus.Available; Guid validationTrackingId = Guid.NewGuid(); ValidationStorageMock .Setup(vs => vs.GetValidationSetAsync(validationTrackingId)) .ReturnsAsync((PackageValidationSet)null) .Verifiable(); ValidationStorageMock .Setup(vs => vs.OtherRecentValidationSetForPackageExists(It.IsAny <int>(), It.IsAny <TimeSpan>(), validationTrackingId)) .ReturnsAsync(false); PackageValidationSet createdSet = null; ValidationStorageMock .Setup(vs => vs.CreateValidationSetAsync(It.IsAny <PackageValidationSet>())) .Returns <PackageValidationSet>(pvs => Task.FromResult(pvs)) .Callback <PackageValidationSet>(pvs => createdSet = pvs) .Verifiable(); ValidationStorageMock .Setup(vs => vs.GetValidationSetCountAsync(It.IsAny <int>())) .ReturnsAsync(1); var provider = CreateProvider(); var actual = await provider.TryGetOrCreateValidationSetAsync(validationTrackingId, Package); PackageFileServiceMock.Verify(x => x.CopyPackageFileForValidationSetAsync(createdSet), Times.Once); PackageFileServiceMock.Verify(x => x.CopyPackageFileForValidationSetAsync(It.IsAny <PackageValidationSet>()), Times.Once); PackageFileServiceMock.Verify(x => x.CopyValidationPackageForValidationSetAsync(It.IsAny <PackageValidationSet>()), Times.Never); PackageFileServiceMock.Verify(x => x.BackupPackageFileFromValidationSetPackageAsync(Package, createdSet), Times.Once); Assert.Equal(ETag, actual.PackageETag); }
public async Task DeletesValidationPackageOnSuccess(PackageStatus fromStatus, bool delete) { Package.PackageStatusKey = fromStatus; await Target.SetPackageStatusAsync(Package, ValidationSet, PackageStatus.Available); PackageFileServiceMock.Verify( x => x.DeleteValidationPackageFileAsync(Package.PackageRegistration.Id, Package.Version), delete ? Times.Once() : Times.Never()); PackageFileServiceMock.Verify( x => x.DeleteValidationPackageFileAsync(It.IsAny <string>(), It.IsAny <string>()), delete ? Times.Once() : Times.Never()); PackageFileServiceMock.Verify( x => x.DeletePackageForValidationSetAsync(ValidationSet), Times.Never); }
public async Task ReEnqueuesProcessingIfNotAllComplete() { const int postponeMinutes = 1; AddValidation("validation1", ValidationStatus.Incomplete); Configuration.ValidationMessageRecheckPeriod = TimeSpan.FromMinutes(postponeMinutes); Configuration.TimeoutValidationSetAfter = TimeSpan.FromDays(1); PackageValidationMessageData messageData = null; DateTimeOffset postponeTill = DateTimeOffset.MinValue; ValidationEnqueuerMock .Setup(ve => ve.SendMessageAsync(It.IsAny <PackageValidationMessageData>(), It.IsAny <DateTimeOffset>())) .Returns(Task.FromResult(0)) .Callback <PackageValidationMessageData, DateTimeOffset>((pv, pt) => { messageData = pv; postponeTill = pt; }); var processor = CreateProcessor(); var startTime = DateTimeOffset.Now; await processor.ProcessValidationOutcomeAsync(ValidationSet, PackageValidatingEntity, ProcessorStats, ScheduleNextCheck); ValidationStorageServiceMock .Verify(s => s.UpdateValidationSetAsync(ValidationSet), Times.Once); ValidationEnqueuerMock .Verify(ve => ve.SendMessageAsync(It.IsAny <PackageValidationMessageData>(), It.IsAny <DateTimeOffset>()), Times.Once()); PackageStateProcessorMock.Verify( x => x.SetStatusAsync(It.IsAny <PackageValidatingEntity>(), It.IsAny <PackageValidationSet>(), It.IsAny <PackageStatus>()), Times.Never); PackageFileServiceMock.Verify( x => x.DeletePackageForValidationSetAsync(It.IsAny <PackageValidationSet>()), Times.Never); Assert.NotNull(messageData); Assert.Equal(PackageValidationMessageType.ProcessValidationSet, messageData.Type); Assert.Equal(ValidationSet.ValidationTrackingId, messageData.ProcessValidationSet.ValidationTrackingId); Assert.Equal(ValidationSet.PackageId, messageData.ProcessValidationSet.PackageId); Assert.Equal(Package.NormalizedVersion, messageData.ProcessValidationSet.PackageVersion); Assert.Equal(ValidationSet.ValidatingType, messageData.ProcessValidationSet.ValidatingType); Assert.Equal(ValidationSet.PackageKey, messageData.ProcessValidationSet.EntityKey); Assert.Equal(postponeMinutes, (postponeTill - startTime).TotalMinutes, 0); Assert.Equal(ValidationSetStatus.InProgress, ValidationSet.ValidationSetStatus); }
public async Task SetsPackageStatusToFailedValidation() { await Target.SetPackageStatusAsync(Package, ValidationSet, PackageStatus.FailedValidation); PackageServiceMock.Verify( x => x.UpdatePackageStatusAsync(Package, PackageStatus.FailedValidation, true), Times.Once); PackageServiceMock.Verify( x => x.UpdatePackageStatusAsync(It.IsAny <Package>(), It.IsAny <PackageStatus>(), It.IsAny <bool>()), Times.Once); TelemetryServiceMock.Verify( x => x.TrackPackageStatusChange(PackageStatus.Validating, PackageStatus.FailedValidation), Times.Once); PackageFileServiceMock.Verify( x => x.DeletePackageForValidationSetAsync(ValidationSet), Times.Never); }
public async Task MarksPackageStatusBasedOnValidatorResults( ValidationStatus validation, PackageStatus fromStatus, PackageStatus toStatus, bool setPackageStatus) { AddValidation("validation1", validation); Package.PackageStatusKey = fromStatus; TimeSpan duration = default(TimeSpan); TelemetryServiceMock .Setup(ts => ts.TrackTotalValidationDuration(It.IsAny <TimeSpan>(), It.IsAny <bool>())) .Callback <TimeSpan, bool>((t, _) => duration = t); var processor = CreateProcessor(); var before = DateTime.UtcNow; await processor.ProcessValidationOutcomeAsync(ValidationSet, Package); var after = DateTime.UtcNow; if (setPackageStatus) { PackageStateProcessorMock.Verify( x => x.SetPackageStatusAsync(Package, ValidationSet, toStatus), Times.Once); PackageStateProcessorMock.Verify( x => x.SetPackageStatusAsync(It.IsAny <Package>(), It.IsAny <PackageValidationSet>(), It.IsAny <PackageStatus>()), Times.Once); } else { PackageStateProcessorMock.Verify( x => x.SetPackageStatusAsync(It.IsAny <Package>(), It.IsAny <PackageValidationSet>(), It.IsAny <PackageStatus>()), Times.Never); } PackageFileServiceMock.Verify( x => x.DeletePackageForValidationSetAsync(ValidationSet), Times.Once); TelemetryServiceMock .Verify(ts => ts.TrackTotalValidationDuration(It.IsAny <TimeSpan>(), It.IsAny <bool>()), Times.Once()); Assert.InRange(duration, before - ValidationSet.Created, after - ValidationSet.Created); }
public async Task DeletesValidationPackageOnSuccess() { AddValidation("validation1", ValidationStatus.Succeeded); Package.PackageStatusKey = PackageStatus.Validating; PackageFileServiceMock .Setup(pfs => pfs.DeleteValidationPackageFileAsync(Package.PackageRegistration.Id, Package.Version)) .Returns(Task.FromResult(0)) .Verifiable(); var procecssor = CreateProcessor(); await procecssor.ProcessValidationOutcomeAsync(ValidationSet, Package); PackageFileServiceMock .Verify(pfs => pfs.DeleteValidationPackageFileAsync(Package.PackageRegistration.Id, Package.Version), Times.Once()); PackageFileServiceMock .Verify(pfs => pfs.DeleteValidationPackageFileAsync(It.IsAny <string>(), It.IsAny <string>()), Times.Once()); }
public async Task MakesPackageAvailableAndSendsEmailUponSuccess() { AddValidation("validation1", ValidationStatus.Succeeded); Package.PackageStatusKey = PackageStatus.Validating; var processor = CreateProcessor(); await processor.ProcessValidationOutcomeAsync(ValidationSet, PackageValidatingEntity, ProcessorStats); PackageStateProcessorMock.Verify( x => x.SetStatusAsync(PackageValidatingEntity, ValidationSet, PackageStatus.Available), Times.Once); PackageFileServiceMock.Verify( x => x.DeletePackageForValidationSetAsync(ValidationSet), Times.Once); MessageServiceMock .Verify(ms => ms.SendPublishedMessageAsync(Package), Times.Once()); MessageServiceMock .Verify(ms => ms.SendPublishedMessageAsync(It.IsAny <Package>()), Times.Once()); }
public async Task DoesNotTakeDownAvailablePackages() { AddValidation("validation1", ValidationStatus.Failed); Package.PackageStatusKey = PackageStatus.Available; var processor = CreateProcessor(); await processor.ProcessValidationOutcomeAsync(ValidationSet, PackageValidatingEntity, ProcessorStats); PackageFileServiceMock.Verify( x => x.DeletePackageForValidationSetAsync(ValidationSet), Times.Once); PackageStateProcessorMock.Verify( x => x.SetStatusAsync(It.IsAny <PackageValidatingEntity>(), It.IsAny <PackageValidationSet>(), It.IsAny <PackageStatus>()), Times.Never); MessageServiceMock.Verify( x => x.SendValidationFailedMessageAsync(It.IsAny <Package>(), It.IsAny <PackageValidationSet>()), Times.Never); MessageServiceMock.Verify( x => x.SendPublishedMessageAsync(It.IsAny <Package>()), Times.Never); }
public async Task PackageStillBecomesAvailableIfPublishedMessageFails() { var exception = new Exception("Something baaad happened"); MessageServiceMock .Setup(ms => ms.SendPublishedMessageAsync(It.IsAny <Package>())) .Throws(exception); Package.PackageStatusKey = PackageStatus.Validating; var processor = CreateProcessor(); var thrownException = await Record.ExceptionAsync( async() => await processor.ProcessValidationOutcomeAsync(ValidationSet, PackageValidatingEntity, ProcessorStats)); Assert.NotNull(thrownException); PackageStateProcessorMock.Verify( x => x.SetStatusAsync(PackageValidatingEntity, ValidationSet, PackageStatus.Available), Times.Once); PackageFileServiceMock.Verify( x => x.DeletePackageForValidationSetAsync(It.IsAny <PackageValidationSet>()), Times.Never); }
public async Task DoesNotDeletePackageFromPublicStorageOnDbUpdateFailureIfCopiedAndOriginallyAvailable() { Package.PackageStatusKey = PackageStatus.Available; var expected = new Exception("Everything failed"); PackageServiceMock .Setup(ps => ps.UpdatePackageStatusAsync(Package, PackageStatus.Available, true)) .Throws(expected); var actual = await Assert.ThrowsAsync <Exception>( () => Target.SetPackageStatusAsync(Package, ValidationSet, PackageStatus.Available)); Assert.Same(expected, actual); PackageFileServiceMock.Verify( x => x.DeletePackageFileAsync(It.IsAny <string>(), It.IsAny <string>()), Times.Never); PackageFileServiceMock.Verify( x => x.DeletePackageForValidationSetAsync(ValidationSet), Times.Never); }
public async Task UsesProperNupkgUrlWithSasDefinition() { UseDefaultValidatorProvider(); SasDefinitionConfiguration.ValidationSetProcessorSasDefinition = "ValidationSetProcessorSasDefinition"; var validator = AddValidation("validation1", TimeSpan.FromDays(1)); INuGetValidationRequest validationRequest = null; validator .Setup(v => v.GetResponseAsync(It.IsAny <INuGetValidationRequest>())) .ReturnsAsync(NuGetValidationResponse.NotStarted) .Callback <INuGetValidationRequest>(vr => validationRequest = vr); validator .Setup(v => v.StartAsync(It.IsAny <INuGetValidationRequest>())) .ReturnsAsync(NuGetValidationResponse.Incomplete); var processor = CreateProcessor(); var expectedEndOfAccessLower = DateTimeOffset.UtcNow.Add(Configuration.TimeoutValidationSetAfter); await processor.ProcessValidationsAsync(ValidationSet); var expectedEndOfAccessUpper = DateTimeOffset.UtcNow.Add(Configuration.TimeoutValidationSetAfter); validator .Verify(v => v.GetResponseAsync(It.IsAny <INuGetValidationRequest>()), Times.AtLeastOnce()); PackageFileServiceMock .Verify(s => s.GetPackageForValidationSetReadUriAsync( ValidationSet, SasDefinitionConfiguration.ValidationSetProcessorSasDefinition, It.IsAny <DateTimeOffset>()), Times.Once); Assert.NotNull(validationRequest); Assert.Contains(ValidationSet.ValidationTrackingId.ToString(), validationRequest.NupkgUrl); Assert.Contains(ValidationContainerName, validationRequest.NupkgUrl); Assert.Equal(Package.PackageRegistration.Id, validationRequest.PackageId); Assert.Equal(Package.NormalizedVersion, validationRequest.PackageVersion); }
public async Task DoesNotDeletePackageFromPublicStorageOnDbUpdateFailureIfNotCopied() { var expected = new Exception("Everything failed"); PackageServiceMock .Setup(ps => ps.UpdateStatusAsync(Package, PackageStatus.Available, true)) .Throws(expected); PackageFileServiceMock .Setup(x => x.CopyValidationPackageToPackageFileAsync(It.IsAny <PackageValidationSet>())) .Throws(new InvalidOperationException("Duplicate!")); var actual = await Assert.ThrowsAsync <Exception>( () => Target.SetStatusAsync(PackageValidatingEntity, ValidationSet, PackageStatus.Available)); Assert.Same(expected, actual); PackageFileServiceMock.Verify( x => x.DeletePackageFileAsync(It.IsAny <PackageValidationSet>()), Times.Never); PackageFileServiceMock.Verify( x => x.DeletePackageForValidationSetAsync(ValidationSet), Times.Never); }
public async Task DeletesPackageFromPublicStorageOnDbUpdateFailure() { AddValidation("validation1", ValidationStatus.Succeeded); Package.PackageStatusKey = PackageStatus.Validating; const string exceptionText = "Everything failed"; PackageServiceMock .Setup(ps => ps.UpdatePackageStatusAsync(Package, PackageStatus.Available, true)) .Throws(new Exception(exceptionText)) .Verifiable(); PackageFileServiceMock .Setup(pfs => pfs.DeletePackageFileAsync(Package.PackageRegistration.Id, Package.Version)) .Returns(Task.FromResult(0)) .Verifiable(); var procecssor = CreateProcessor(); var exception = await Assert.ThrowsAsync <Exception>(() => procecssor.ProcessValidationOutcomeAsync(ValidationSet, Package)); PackageFileServiceMock .Verify(pfs => pfs.DeletePackageFileAsync(Package.PackageRegistration.Id, Package.Version), Times.AtLeastOnce()); Assert.Equal(exceptionText, exception.Message); }
public void ThrowsIfNupkgDoesNotExist() { UseDefaultValidatorProvider(); var validator = AddValidation("validation1", TimeSpan.FromDays(1)); PackageFileServiceMock .Setup(pfs => pfs.DoesPackageFileExistAsync(Package)) .ReturnsAsync(false); PackageFileServiceMock .Setup(pfs => pfs.DoesValidationPackageFileExistAsync(Package)) .ReturnsAsync(false); var processor = CreateProcessor(); var ex = Assert.ThrowsAsync <Exception>(() => processor.ProcessValidationsAsync(ValidationSet, Package)); PackageFileServiceMock .Verify(pfs => pfs.DoesPackageFileExistAsync(Package), Times.Once()); PackageFileServiceMock .Verify(pfs => pfs.DoesPackageFileExistAsync(It.IsAny <Package>()), Times.Once()); PackageFileServiceMock .Verify(pfs => pfs.DoesValidationPackageFileExistAsync(Package), Times.Once()); PackageFileServiceMock .Verify(pfs => pfs.DoesValidationPackageFileExistAsync(It.IsAny <Package>()), Times.Once()); }
public async Task DoesNotCreateValidationsWhenShouldStartFalse() { const string validation1 = "validation1"; const string validation2 = "validation2"; Configuration.Validations = new List <ValidationConfigurationItem> { new ValidationConfigurationItem() { Name = validation1, TrackAfter = TimeSpan.FromDays(1), RequiredValidations = new List <string>(), ShouldStart = true, }, new ValidationConfigurationItem() { Name = validation2, TrackAfter = TimeSpan.FromDays(1), RequiredValidations = new List <string>(), ShouldStart = false, } }; Guid validationTrackingId = Guid.NewGuid(); ValidationStorageMock .Setup(vs => vs.GetValidationSetAsync(validationTrackingId)) .ReturnsAsync((PackageValidationSet)null) .Verifiable(); ValidationStorageMock .Setup(vs => vs.OtherRecentValidationSetForPackageExists(It.IsAny <IValidatingEntity <Package> >(), It.IsAny <TimeSpan>(), validationTrackingId)) .ReturnsAsync(false); PackageValidationSet createdSet = null; ValidationStorageMock .Setup(vs => vs.CreateValidationSetAsync(It.IsAny <PackageValidationSet>())) .Returns <PackageValidationSet>(pvs => Task.FromResult(pvs)) .Callback <PackageValidationSet>(pvs => createdSet = pvs) .Verifiable(); ValidationStorageMock .Setup(vs => vs.GetValidationSetCountAsync(It.IsAny <IValidatingEntity <Package> >())) .ReturnsAsync(1); var provider = new ValidationSetProvider <Package>( ValidationStorageMock.Object, PackageFileServiceMock.Object, ValidatorProvider.Object, ConfigurationAccessorMock.Object, TelemetryServiceMock.Object, LoggerMock.Object); var packageValidationMessageData = new ProcessValidationSetData( Package.PackageRegistration.Id, Package.NormalizedVersion, validationTrackingId, ValidatingType.Package, Package.Key); var returnedSet = await provider.TryGetOrCreateValidationSetAsync(packageValidationMessageData, PackageValidatingEntity); var endOfCallTimestamp = DateTime.UtcNow; ValidationStorageMock .Verify(vs => vs.CreateValidationSetAsync(It.IsAny <PackageValidationSet>()), Times.Once); Assert.NotNull(returnedSet); Assert.NotNull(createdSet); Assert.Same(createdSet, returnedSet); Assert.Equal(Package.PackageRegistration.Id, createdSet.PackageId); Assert.Equal(Package.NormalizedVersion, createdSet.PackageNormalizedVersion); Assert.Equal(Package.Key, createdSet.PackageKey); Assert.Equal(validationTrackingId, createdSet.ValidationTrackingId); Assert.True(createdSet.Created.Kind == DateTimeKind.Utc); Assert.True(createdSet.Updated.Kind == DateTimeKind.Utc); var allowedTimeDifference = TimeSpan.FromSeconds(5); Assert.True(endOfCallTimestamp - createdSet.Created < allowedTimeDifference); Assert.True(endOfCallTimestamp - createdSet.Updated < allowedTimeDifference); Assert.All(createdSet.PackageValidations, v => Assert.Same(createdSet, v.PackageValidationSet)); Assert.All(createdSet.PackageValidations, v => Assert.Equal(ValidationStatus.NotStarted, v.ValidationStatus)); Assert.All(createdSet.PackageValidations, v => Assert.True(endOfCallTimestamp - v.ValidationStatusTimestamp < allowedTimeDifference)); Assert.Contains(createdSet.PackageValidations, v => v.Type == validation1); Assert.DoesNotContain(createdSet.PackageValidations, v => v.Type == validation2); PackageFileServiceMock.Verify( x => x.CopyValidationPackageForValidationSetAsync(returnedSet), Times.Once); TelemetryServiceMock.Verify( x => x.TrackDurationToValidationSetCreation(createdSet.PackageId, createdSet.PackageNormalizedVersion, createdSet.ValidationTrackingId, createdSet.Created - Package.Created), Times.Once); }