public async Task DropsMessageAfterMissingPackageRetryCountIsReached()
        {
            var validationTrackingId = Guid.NewGuid();
            var messageData          = PackageValidationMessageData.NewProcessValidationSet(
                "packageId",
                "1.2.3",
                validationTrackingId,
                ValidatingType.SymbolPackage,
                entityKey: null);

            CoreSymbolPackageServiceMock
            .Setup(ps => ps.FindPackageByIdAndVersionStrict("packageId", "1.2.3"))
            .Returns <SymbolPackage>(null)
            .Verifiable();

            TelemetryServiceMock
            .Setup(t => t.TrackMissingPackageForValidationMessage("packageId", "1.2.3", validationTrackingId.ToString()))
            .Verifiable();

            var handler = CreateHandler();

            Assert.False(await handler.HandleAsync(OverrideDeliveryCount(messageData, deliveryCount: 1)));
            Assert.False(await handler.HandleAsync(OverrideDeliveryCount(messageData, deliveryCount: 2)));
            Assert.True(await handler.HandleAsync(OverrideDeliveryCount(messageData, deliveryCount: 3)));

            CoreSymbolPackageServiceMock.Verify(ps => ps.FindPackageByIdAndVersionStrict("packageId", "1.2.3"), Times.Exactly(3));
            TelemetryServiceMock.Verify(t => t.TrackMissingPackageForValidationMessage("packageId", "1.2.3", validationTrackingId.ToString()), Times.Once);
        }
        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);
        }
Beispiel #3
0
            public async Task SetsPackageStreamMetadataIfChanged()
            {
                var content                  = "Hello, world.";
                var expectedHash             = "rQw3wx1psxXzqB8TyM3nAQlK2RcluhsNwxmcqXE2YbgoDW735o8TPmIR4uWpoxUERddvFwjgRSGw7gNPCwuvJg==";
                var stream                   = new MemoryStream(Encoding.ASCII.GetBytes(content));
                PackageStreamMetadata actual = null;

                PackageFileServiceMock
                .Setup(x => x.DownloadPackageFileToDiskAsync(Package))
                .ReturnsAsync(stream);
                PackageServiceMock
                .Setup(x => x.UpdatePackageStreamMetadataAsync(Package, It.IsAny <PackageStreamMetadata>(), false))
                .Returns(Task.CompletedTask)
                .Callback <Package, PackageStreamMetadata, bool>((_, m, __) => actual = m);

                await Target.SetPackageStatusAsync(Package, ValidationSet, PackageStatus.Available);

                Assert.NotNull(actual);
                Assert.Equal(content.Length, actual.Size);
                Assert.Equal(expectedHash, actual.Hash);
                Assert.Equal("SHA512", actual.HashAlgorithm);
                PackageServiceMock.Verify(
                    x => x.UpdatePackageStreamMetadataAsync(Package, actual, false),
                    Times.Once);
                TelemetryServiceMock.Verify(
                    x => x.TrackDurationToHashPackage(
                        It.Is <TimeSpan>(y => y > TimeSpan.Zero),
                        Package.PackageRegistration.Id,
                        Package.NormalizedVersion,
                        "SHA512",
                        "System.IO.MemoryStream"),
                    Times.Once);
            }
        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 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 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 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);
        }
Beispiel #9
0
        private List <string> RecordOperationOrder()
        {
            var operations = new List <string>();

            PackageStateProcessorMock
            .Setup(x => x.SetStatusAsync(It.IsAny <IValidatingEntity <Package> >(), It.IsAny <PackageValidationSet>(), It.IsAny <PackageStatus>()))
            .Returns(Task.CompletedTask)
            .Callback(() => operations.Add(nameof(IStatusProcessor <Package> .SetStatusAsync)));
            ValidationStorageServiceMock
            .Setup(x => x.UpdateValidationSetAsync(It.IsAny <PackageValidationSet>()))
            .Returns(Task.CompletedTask)
            .Callback(() => operations.Add(nameof(IValidationStorageService.UpdateValidationSetAsync)));
            MessageServiceMock
            .Setup(x => x.SendPublishedMessageAsync(It.IsAny <Package>()))
            .Returns(Task.CompletedTask)
            .Callback(() => operations.Add(nameof(IMessageService <Package> .SendPublishedMessageAsync)));
            MessageServiceMock
            .Setup(x => x.SendValidationFailedMessageAsync(It.IsAny <Package>(), It.IsAny <PackageValidationSet>()))
            .Returns(Task.CompletedTask)
            .Callback(() => operations.Add(nameof(IMessageService <Package> .SendValidationFailedMessageAsync)));
            TelemetryServiceMock
            .Setup(x => x.TrackTotalValidationDuration(It.IsAny <string>(), It.IsAny <string>(), It.IsAny <Guid>(), It.IsAny <TimeSpan>(), It.IsAny <bool>()))
            .Callback(() => operations.Add(nameof(ITelemetryService.TrackTotalValidationDuration)));
            PackageFileServiceMock
            .Setup(x => x.DeletePackageForValidationSetAsync(It.IsAny <PackageValidationSet>()))
            .Returns(Task.CompletedTask)
            .Callback(() => operations.Add(nameof(IValidationFileService.DeletePackageForValidationSetAsync)));
            return(operations);
        }
Beispiel #10
0
            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);
        }
Beispiel #12
0
            public async Task TracksMissingNupkgForAvailablePackage(bool validationFileExists)
            {
                Package.PackageStatusKey = PackageStatus.Available;
                PackageFileServiceMock
                .Setup(pfs => pfs.DoesPackageFileExistAsync(Package))
                .ReturnsAsync(false);
                PackageFileServiceMock
                .Setup(pfs => pfs.DoesValidationPackageFileExistAsync(Package))
                .ReturnsAsync(validationFileExists);

                await Target.SetPackageStatusAsync(Package, ValidationSet, PackageStatus.Available);

                TelemetryServiceMock.Verify(
                    x => x.TrackMissingNupkgForAvailablePackage(
                        ValidationSet.PackageId,
                        ValidationSet.PackageNormalizedVersion,
                        ValidationSet.ValidationTrackingId.ToString()),
                    Times.Once);
            }
Beispiel #13
0
            public async Task EmitsTelemetryOnStatusChange(PackageStatus fromStatus, PackageStatus toStatus)
            {
                Package.PackageStatusKey = fromStatus;

                await Target.SetPackageStatusAsync(Package, ValidationSet, toStatus);

                if (fromStatus != toStatus)
                {
                    TelemetryServiceMock.Verify(
                        x => x.TrackPackageStatusChange(fromStatus, toStatus),
                        Times.Once);
                    TelemetryServiceMock.Verify(
                        x => x.TrackPackageStatusChange(It.IsAny <PackageStatus>(), It.IsAny <PackageStatus>()),
                        Times.Once);
                }
                else
                {
                    TelemetryServiceMock.Verify(
                        x => x.TrackPackageStatusChange(It.IsAny <PackageStatus>(), It.IsAny <PackageStatus>()),
                        Times.Never);
                }
            }
Beispiel #14
0
            public async Task EmitsTelemetryOnStatusChange(PackageStatus fromStatus, PackageStatus toStatus)
            {
                Package.PackageStatusKey = fromStatus;

                await Target.SetStatusAsync(PackageValidatingEntity, ValidationSet, toStatus);

                if (fromStatus != toStatus)
                {
                    TelemetryServiceMock.Verify(
                        x => x.TrackPackageStatusChange(ValidationSet.PackageId, ValidationSet.PackageNormalizedVersion, ValidationSet.ValidationTrackingId, fromStatus, toStatus),
                        Times.Once);
                    TelemetryServiceMock.Verify(
                        x => x.TrackPackageStatusChange(It.IsAny <string>(), It.IsAny <string>(), It.IsAny <Guid>(), It.IsAny <PackageStatus>(), It.IsAny <PackageStatus>()),
                        Times.Once);
                }
                else
                {
                    TelemetryServiceMock.Verify(
                        x => x.TrackPackageStatusChange(It.IsAny <string>(), It.IsAny <string>(), It.IsAny <Guid>(), It.IsAny <PackageStatus>(), It.IsAny <PackageStatus>()),
                        Times.Never);
                }
            }
        public async Task TracksSuccessOnAllRequiredValidatorsFinished(bool requiredValidationSucceeded, bool expectedCompletionTracking)
        {
            AddValidation("requiredValidation", ValidationStatus.Succeeded, ValidationFailureBehavior.MustSucceed);
            AddValidation("optionalValidaiton", ValidationStatus.Incomplete, ValidationFailureBehavior.AllowedToFail);
            ProcessorStats.AnyRequiredValidationSucceeded = requiredValidationSucceeded;

            var processor = CreateProcessor();
            await processor.ProcessValidationOutcomeAsync(ValidationSet, PackageValidatingEntity, ProcessorStats);

            if (expectedCompletionTracking)
            {
                TelemetryServiceMock
                .Verify(ts => ts.TrackTotalValidationDuration(It.IsAny <TimeSpan>(), true), Times.Once());
                TelemetryServiceMock
                .Verify(ts => ts.TrackTotalValidationDuration(It.IsAny <TimeSpan>(), It.IsAny <bool>()), Times.Once());
            }
            else
            {
                TelemetryServiceMock
                .Verify(ts => ts.TrackTotalValidationDuration(It.IsAny <TimeSpan>(), It.IsAny <bool>()), Times.Never());
            }
        }
        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);
        }