public async Task DoesNotEmitTelemetryIfMultipleValidationSetsExist()
        {
            const string validation1 = "validation1";

            Configuration.Validations = new List <ValidationConfigurationItem>
            {
                new ValidationConfigurationItem()
                {
                    Name = validation1, TrackAfter = TimeSpan.FromDays(1), RequiredValidations = new List <string> {
                    }
                }
            };

            Guid validationTrackingId = Guid.NewGuid();

            ValidationStorageMock
            .Setup(vs => vs.GetValidationSetAsync(validationTrackingId))
            .ReturnsAsync((PackageValidationSet)null)
            .Verifiable();

            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(2);

            ValidationStorageMock
            .Setup(vs => vs.OtherRecentValidationSetForPackageExists(It.IsAny <IValidatingEntity <Package> >(), It.IsAny <TimeSpan>(), It.IsAny <Guid>()))
            .ReturnsAsync(false);

            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);

            ValidationStorageMock
            .Verify(vs => vs.CreateValidationSetAsync(It.IsAny <PackageValidationSet>()), Times.Once);

            TelemetryServiceMock.Verify(
                x => x.TrackDurationToValidationSetCreation(It.IsAny <string>(), It.IsAny <string>(), It.IsAny <Guid>(), It.IsAny <TimeSpan>()),
                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 HandlesTerminalStatusOnUpdate(ValidationStatus targetStatus)
        {
            UseDefaultValidatorProvider();
            var validator  = AddValidation("validation1", TimeSpan.FromDays(1), validationStatus: ValidationStatus.Incomplete);
            var validation = ValidationSet.PackageValidations.First();

            var validationResult = new ValidationResult(targetStatus, new List <IValidationIssue>
            {
                ValidationIssue.PackageIsSigned,
            });

            validator
            .Setup(v => v.GetResultAsync(It.IsAny <IValidationRequest>()))
            .ReturnsAsync(validationResult)
            .Verifiable();

            ValidationStorageMock
            .Setup(vs => vs.UpdateValidationStatusAsync(
                       validation,
                       It.Is <IValidationResult>(r => r.Status == targetStatus && r.Issues.Any())))
            .Returns(Task.FromResult(0));

            var processor = CreateProcessor();
            await processor.ProcessValidationsAsync(ValidationSet, Package);

            ValidationStorageMock
            .Verify(vs => vs.UpdateValidationStatusAsync(
                        validation,
                        It.Is <IValidationResult>(r => r.Status == targetStatus && r.Issues.Any())),
                    Times.Once());
            validator.Verify(
                x => x.CleanUpAsync(It.Is <IValidationRequest>(y => y != null)),
                Times.Once);
        }
Exemple #4
0
        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);
        }
Exemple #5
0
        public async Task HandlesTerminalStatusOnStart(ValidationStatus targetStatus)
        {
            UseDefaultValidatorProvider();
            var validator  = AddValidation("validation1", TimeSpan.FromDays(1), validationStatus: ValidationStatus.NotStarted);
            var validation = ValidationSet.PackageValidations.First();

            var validationResponse = new NuGetValidationResponse(targetStatus, new List <IValidationIssue>
            {
                ValidationIssue.PackageIsSigned,
            });

            validator
            .Setup(v => v.GetResponseAsync(It.IsAny <INuGetValidationRequest>()))
            .ReturnsAsync(validationResponse)
            .Verifiable();

            ValidationStorageMock
            .Setup(vs => vs.MarkValidationStartedAsync(
                       validation,
                       It.Is <INuGetValidationResponse>(r => r.Status == targetStatus && r.Issues.Any())))
            .Callback <PackageValidation, INuGetValidationResponse>((v, vr) => v.ValidationStatus = vr.Status)
            .Returns(Task.FromResult(0));

            var processor = CreateProcessor();
            await processor.ProcessValidationsAsync(ValidationSet);

            ValidationStorageMock
            .Verify(vs => vs.MarkValidationStartedAsync(
                        validation,
                        It.Is <INuGetValidationResponse>(r => r.Status == targetStatus && r.Issues.Any())),
                    Times.Once());
            validator.Verify(
                x => x.CleanUpAsync(It.Is <INuGetValidationRequest>(y => y != null)),
                Times.Once);
        }
Exemple #6
0
        public async Task CopiesToValidationSetContainerBeforeAddingDbRecord()
        {
            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;

            var operations = new List <string>();

            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);

            PackageFileServiceMock
            .Setup(x => x.CopyPackageFileForValidationSetAsync(It.IsAny <PackageValidationSet>()))
            .ReturnsAsync(ETag)
            .Callback <PackageValidationSet>(_ => operations.Add(nameof(IValidationPackageFileService.CopyPackageFileForValidationSetAsync)));
            PackageFileServiceMock
            .Setup(x => x.BackupPackageFileFromValidationSetPackageAsync(It.IsAny <Package>(), It.IsAny <PackageValidationSet>()))
            .Returns(Task.CompletedTask)
            .Callback(() => operations.Add(nameof(IValidationPackageFileService.BackupPackageFileFromValidationSetPackageAsync)));
            ValidationStorageMock
            .Setup(vs => vs.CreateValidationSetAsync(It.IsAny <PackageValidationSet>()))
            .Returns <PackageValidationSet>(pvs => Task.FromResult(pvs))
            .Callback <PackageValidationSet>(_ => operations.Add(nameof(IValidationStorageService.CreateValidationSetAsync)));

            ValidationStorageMock
            .Setup(vs => vs.GetValidationSetCountAsync(It.IsAny <int>()))
            .ReturnsAsync(1);

            var provider = CreateProvider();
            await provider.TryGetOrCreateValidationSetAsync(validationTrackingId, Package);

            Assert.Equal(new[]
            {
                nameof(IValidationPackageFileService.CopyPackageFileForValidationSetAsync),
                nameof(IValidationPackageFileService.BackupPackageFileFromValidationSetPackageAsync),
                nameof(IValidationStorageService.CreateValidationSetAsync),
            }, operations);
        }
        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 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 FailsUnknownValidations()
        {
            AddValidationToSet("validation1");
            ValidationStorageMock
            .Setup(vs => vs.UpdateValidationStatusAsync(ValidationSet.PackageValidations.First(), ValidationResult.Failed))
            .Returns(Task.FromResult(0))
            .Verifiable();

            var processor = CreateProcessor();
            await processor.ProcessValidationsAsync(ValidationSet, Package);

            ValidationStorageMock
            .Verify(vs => vs.UpdateValidationStatusAsync(ValidationSet.PackageValidations.First(), ValidationResult.Failed), Times.Once());
        }
        public async Task ThrowsIfPackageVersionDoesNotMatchValidationSet()
        {
            ValidationSet.PackageNormalizedVersion = ValidationSet.PackageNormalizedVersion + ".42";
            ValidationStorageMock
            .Setup(vs => vs.GetValidationSetAsync(ValidationSet.ValidationTrackingId))
            .ReturnsAsync(ValidationSet)
            .Verifiable();

            var provider = CreateProvider();

            var ex = await Assert.ThrowsAsync <Exception>(() => provider.GetOrCreateValidationSetAsync(ValidationSet.ValidationTrackingId, Package));

            Assert.Contains(ValidationSet.PackageNormalizedVersion, ex.Message);
            Assert.Contains(Package.NormalizedVersion, ex.Message);
        }
        public async Task ThrowsIfPackageIdDoesNotMatchValidationSet()
        {
            ValidationSet.PackageId = string.Join("", ValidationSet.PackageId.Reverse());
            ValidationStorageMock
            .Setup(vs => vs.GetValidationSetAsync(ValidationSet.ValidationTrackingId))
            .ReturnsAsync(ValidationSet)
            .Verifiable();

            var provider = CreateProvider();

            var ex = await Assert.ThrowsAsync <Exception>(() => provider.GetOrCreateValidationSetAsync(ValidationSet.ValidationTrackingId, Package));

            Assert.Contains(ValidationSet.PackageId, ex.Message);
            Assert.Contains(Package.PackageRegistration.Id, ex.Message);
        }
Exemple #12
0
        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 TriesToGetValidationSetFirst()
        {
            ValidationStorageMock
            .Setup(vs => vs.GetValidationSetAsync(ValidationSet.ValidationTrackingId))
            .ReturnsAsync(ValidationSet)
            .Verifiable();

            var provider = CreateProvider();

            var set = await provider.GetOrCreateValidationSetAsync(ValidationSet.ValidationTrackingId, Package);

            ValidationStorageMock
            .Verify(vs => vs.GetValidationSetAsync(ValidationSet.ValidationTrackingId), Times.Once());

            Assert.Same(ValidationSet, set);
        }
        public async Task ThrowsIfPackageKeyDoesNotMatchValidationSet()
        {
            ValidationSet.PackageKey += 1111;
            ValidationStorageMock
            .Setup(vs => vs.GetValidationSetAsync(ValidationSet.ValidationTrackingId))
            .ReturnsAsync(ValidationSet)
            .Verifiable();

            var provider = CreateProvider();

            var ex = await Assert.ThrowsAsync <InvalidOperationException>(
                () => provider.TryGetOrCreateValidationSetAsync(PackageValidationMessageData, PackageValidatingEntity));

            Assert.Contains(ValidationSet.PackageKey.ToString(), ex.Message);
            Assert.Contains(Package.Key.ToString(), ex.Message);
        }
        public async Task StartsNotStartedValidations(ValidationStatus startStatus, bool expectStorageUdpate)
        {
            UseDefaultValidatorProvider();
            const string validationName = "validation1";
            var          validator      = AddValidation(validationName, TimeSpan.FromDays(1));
            var          validation     = ValidationSet.PackageValidations.First();

            ValidationStatus actualStatus = ValidationStatus.NotStarted;

            validator
            .Setup(v => v.GetStatusAsync(It.IsAny <IValidationRequest>()))
            .Returns(() => Task.FromResult(actualStatus))
            .Callback <IValidationRequest>(r => Assert.Equal(validation.Key, r.ValidationId));

            validator
            .Setup(v => v.StartValidationAsync(It.IsAny <IValidationRequest>()))
            .ReturnsAsync(startStatus)
            .Callback <IValidationRequest>(r => {
                Assert.Equal(validation.Key, r.ValidationId);
                actualStatus = startStatus;
            })
            .Verifiable();

            ValidationStorageMock
            .Setup(vs => vs.MarkValidationStartedAsync(validation, startStatus))
            .Returns(Task.FromResult(0))
            .Callback <PackageValidation, ValidationStatus>((pv, vs) => pv.ValidationStatus = vs)
            .Verifiable();

            var processor = CreateProcessor();
            await processor.ProcessValidationsAsync(ValidationSet, Package);

            validator.Verify(v => v.StartValidationAsync(It.IsAny <IValidationRequest>()), Times.AtLeastOnce());
            if (expectStorageUdpate)
            {
                ValidationStorageMock.Verify(
                    vs => vs.MarkValidationStartedAsync(validation, startStatus), Times.Once());
                ValidationStorageMock.Verify(
                    vs => vs.MarkValidationStartedAsync(It.IsAny <PackageValidation>(), It.IsAny <ValidationStatus>()), Times.Once());
            }
            else
            {
                ValidationStorageMock.Verify(
                    vs => vs.MarkValidationStartedAsync(It.IsAny <PackageValidation>(), It.IsAny <ValidationStatus>()), Times.Never());
            }
        }
        public async Task HandlesIncompleteValidationsStatusChanges(ValidationStatus targetStatus, bool shouldStart, ValidationFailureBehavior failureBehavior, bool expectStorageUdpate)
        {
            UseDefaultValidatorProvider();
            var validator  = AddValidation("validation1", TimeSpan.FromDays(1), validationStatus: ValidationStatus.Incomplete, shouldStart: shouldStart, failureBehavior: failureBehavior);
            var validation = ValidationSet.PackageValidations.First();

            validator
            .Setup(v => v.GetResultAsync(It.IsAny <IValidationRequest>()))
            .ReturnsAsync(new ValidationResult(targetStatus))
            .Verifiable();

            ValidationStorageMock
            .Setup(vs => vs.UpdateValidationStatusAsync(validation, It.Is <IValidationResult>(r => r.Status == targetStatus)))
            .Returns(Task.FromResult(0))
            .Callback <PackageValidation, IValidationResult>((pv, vr) => pv.ValidationStatus = vr.Status)
            .Verifiable();

            var processor = CreateProcessor();
            await processor.ProcessValidationsAsync(ValidationSet, Package);

            validator
            .Verify(v => v.GetResultAsync(It.IsAny <IValidationRequest>()), Times.AtLeastOnce());
            if (expectStorageUdpate)
            {
                ValidationStorageMock.Verify(
                    vs => vs.UpdateValidationStatusAsync(validation, It.Is <IValidationResult>(r => r.Status == targetStatus)), Times.Once());
                ValidationStorageMock.Verify(
                    vs => vs.UpdateValidationStatusAsync(It.IsAny <PackageValidation>(), It.IsAny <ValidationResult>()), Times.Once());
                validator.Verify(
                    x => x.CleanUpAsync(It.IsAny <IValidationRequest>()), Times.Once);
            }
            else
            {
                ValidationStorageMock.Verify(
                    vs => vs.UpdateValidationStatusAsync(It.IsAny <PackageValidation>(), It.IsAny <ValidationResult>()), Times.Never());
                validator.Verify(
                    x => x.CleanUpAsync(It.IsAny <IValidationRequest>()), Times.Never);
            }
            Assert.Equal(targetStatus, validation.ValidationStatus);
        }
        public async Task StartsNotStartedValidations(ValidationStatus startStatus, bool expectStorageUpdate, bool expectCleanup)
        {
            UseDefaultValidatorProvider();
            const string validationName = "validation1";
            var          validator      = AddValidation(validationName, TimeSpan.FromDays(1));
            var          validation     = ValidationSet.PackageValidations.First();

            ValidationStatus actualStatus = ValidationStatus.NotStarted;

            validator
            .Setup(v => v.GetResultAsync(It.IsAny <IValidationRequest>()))
            .ReturnsAsync(new ValidationResult(actualStatus))
            .Callback <IValidationRequest>(r => Assert.Equal(validation.Key, r.ValidationId));

            validator
            .Setup(v => v.StartAsync(It.IsAny <IValidationRequest>()))
            .ReturnsAsync(new ValidationResult(startStatus))
            .Callback <IValidationRequest>(r => {
                Assert.Equal(validation.Key, r.ValidationId);
                actualStatus = startStatus;
            })
            .Verifiable();

            ValidationStorageMock
            .Setup(vs => vs.MarkValidationStartedAsync(validation, It.Is <ValidationResult>(r => r.Status == startStatus)))
            .Returns(Task.FromResult(0))
            .Callback <PackageValidation, ValidationResult>((pv, vr) => pv.ValidationStatus = vr.Status)
            .Verifiable();

            var processor = CreateProcessor();
            await processor.ProcessValidationsAsync(ValidationSet, Package);

            validator.Verify(v => v.StartAsync(It.IsAny <IValidationRequest>()), Times.AtLeastOnce());
            if (expectStorageUpdate)
            {
                ValidationStorageMock.Verify(
                    vs => vs.MarkValidationStartedAsync(validation, It.Is <ValidationResult>(r => r.Status == startStatus)), Times.Once);
                ValidationStorageMock.Verify(
                    vs => vs.MarkValidationStartedAsync(It.IsAny <PackageValidation>(), It.IsAny <ValidationResult>()), Times.Once);
                TelemetryServiceMock.Verify(
                    ts => ts.TrackValidatorStarted(validationName), Times.Once);
                TelemetryServiceMock.Verify(
                    ts => ts.TrackValidatorStarted(It.IsAny <string>()), Times.Once);
            }
            else
            {
                ValidationStorageMock.Verify(
                    vs => vs.MarkValidationStartedAsync(It.IsAny <PackageValidation>(), It.IsAny <ValidationResult>()), Times.Never);
                TelemetryServiceMock.Verify(
                    ts => ts.TrackValidatorStarted(It.IsAny <string>()), Times.Never);
            }

            if (expectCleanup)
            {
                validator.Verify(
                    x => x.CleanUpAsync(It.IsAny <IValidationRequest>()),
                    Times.Once);
            }
            else
            {
                validator.Verify(
                    x => x.CleanUpAsync(It.IsAny <IValidationRequest>()),
                    Times.Never);
            }
        }
        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);
        }
        public async Task ProperlyConstructsValidationSet()
        {
            const string validation1 = "validation1";
            const string validation2 = "validation2";

            Configuration.Validations = new List <ValidationConfigurationItem>
            {
                new ValidationConfigurationItem()
                {
                    Name = validation1, FailAfter = TimeSpan.FromDays(1), RequiredValidations = new List <string> {
                        validation2
                    }
                },
                new ValidationConfigurationItem()
                {
                    Name = validation2, FailAfter = TimeSpan.FromDays(1), RequiredValidations = new List <string> {
                    }
                }
            };

            Guid validationTrackingId = Guid.NewGuid();

            ValidationStorageMock
            .Setup(vs => vs.GetValidationSetAsync(validationTrackingId))
            .ReturnsAsync(null)
            .Verifiable();

            PackageValidationSet createdSet = null;

            ValidationStorageMock
            .Setup(vs => vs.CreateValidationSetAsync(It.IsAny <PackageValidationSet>()))
            .Returns <PackageValidationSet>(pvs => Task.FromResult(pvs))
            .Callback <PackageValidationSet>(pvs => createdSet = pvs)
            .Verifiable();

            var provider = new ValidationSetProvider(
                ValidationStorageMock.Object,
                ConfigurationAccessorMock.Object,
                LoggerMock.Object);

            var returnedSet = await provider.GetOrCreateValidationSetAsync(validationTrackingId, Package);

            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.Contains(createdSet.PackageValidations, v => v.Type == validation2);
        }