Example #1
0
            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 DoesNotSetPackageStreamMetadataIfNotChanged()
            {
                var content = "Hello, world.";

                Package.PackageFileSize = content.Length;
                Package.HashAlgorithm   = "SHA512";
                Package.Hash            = "rQw3wx1psxXzqB8TyM3nAQlK2RcluhsNwxmcqXE2YbgoDW735o8TPmIR4uWpoxUERddvFwjgRSGw7gNPCwuvJg==";
                var stream = new MemoryStream(Encoding.ASCII.GetBytes(content));

                var corePackageService          = new Mock <ICorePackageService>();
                var mockPackageEntityRepository = new Mock <IEntityRepository <Package> >();
                var entityPackageService        = new PackageEntityService(corePackageService.Object, mockPackageEntityRepository.Object);

                PackageFileServiceMock
                .Setup(x => x.DownloadPackageFileToDiskAsync(ValidationSet))
                .ReturnsAsync(stream);

                var streamMetadata = new PackageStreamMetadata()
                {
                    Size          = Package.PackageFileSize,
                    Hash          = Package.Hash,
                    HashAlgorithm = Package.HashAlgorithm
                };

                PackageFileServiceMock
                .Setup(x => x.UpdatePackageBlobMetadataAsync(It.IsAny <PackageValidationSet>()))
                .ReturnsAsync(streamMetadata);

                await Target.SetStatusAsync(PackageValidatingEntity, ValidationSet, PackageStatus.Available);

                corePackageService.Verify(
                    x => x.UpdatePackageStreamMetadataAsync(It.IsAny <Package>(), It.IsAny <PackageStreamMetadata>(), It.IsAny <bool>()),
                    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 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);
        }
Example #5
0
            public async Task SavesPackageLicenseFileWhenPresent(EmbeddedLicenseFileType licenseFileType, bool expectedSave)
            {
                var content = "Hello, world.";
                var stream  = new MemoryStream(Encoding.ASCII.GetBytes(content));

                Package.EmbeddedLicenseType = licenseFileType;
                PackageFileServiceMock
                .Setup(x => x.DownloadPackageFileToDiskAsync(ValidationSet))
                .ReturnsAsync(stream);

                await Target.SetStatusAsync(PackageValidatingEntity, ValidationSet, PackageStatus.Available);

                if (expectedSave)
                {
                    CoreLicenseFileServiceMock
                    .Verify(clfs => clfs.ExtractAndSaveLicenseFileAsync(PackageValidatingEntity.EntityRecord, stream), Times.Once);
                    CoreLicenseFileServiceMock
                    .Verify(clfs => clfs.ExtractAndSaveLicenseFileAsync(It.IsAny <Package>(), It.IsAny <Stream>()), Times.Once);
                }
                else
                {
                    CoreLicenseFileServiceMock
                    .Verify(clfs => clfs.ExtractAndSaveLicenseFileAsync(It.IsAny <Package>(), It.IsAny <Stream>()), Times.Never);
                }
            }
Example #6
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 CopyDbUpdateDeleteInCorrectOrderWhenValidationSetPackageExists()
            {
                var operations = new List <string>();

                PackageFileServiceMock
                .Setup(x => x.DoesValidationSetPackageExistAsync(ValidationSet))
                .ReturnsAsync(true)
                .Callback(() => operations.Add(nameof(IValidationFileService.DoesValidationSetPackageExistAsync)));
                PackageFileServiceMock
                .Setup(x => x.CopyValidationSetPackageToPackageFileAsync(ValidationSet, It.IsAny <IAccessCondition>()))
                .Returns(Task.CompletedTask)
                .Callback(() => operations.Add(nameof(IValidationFileService.CopyValidationSetPackageToPackageFileAsync)));
                PackageServiceMock
                .Setup(x => x.UpdateStatusAsync(Package, PackageStatus.Available, true))
                .Returns(Task.CompletedTask)
                .Callback(() => operations.Add(nameof(IEntityService <Package> .UpdateStatusAsync)));
                PackageFileServiceMock
                .Setup(x => x.DeleteValidationPackageFileAsync(ValidationSet))
                .Returns(Task.CompletedTask)
                .Callback(() => operations.Add(nameof(IValidationFileService.DeleteValidationPackageFileAsync)));

                await Target.SetStatusAsync(PackageValidatingEntity, ValidationSet, PackageStatus.Available);

                var expectedOrder = new[]
                {
                    nameof(IValidationFileService.DoesValidationSetPackageExistAsync),
                    nameof(IValidationFileService.CopyValidationSetPackageToPackageFileAsync),
                    nameof(IEntityService <Package> .UpdateStatusAsync),
                    nameof(IValidationFileService.DeleteValidationPackageFileAsync),
                };

                Assert.Equal(expectedOrder, operations);
            }
        public async Task UsesProperNupkgUrl(bool existsInPublicContainer, bool existsInValidationContainer, string expectedUrlSubstring)
        {
            UseDefaultValidatorProvider();
            var validator = AddValidation("validation1", TimeSpan.FromDays(1));

            PackageFileServiceMock
            .Setup(pfs => pfs.DoesPackageFileExistAsync(Package))
            .ReturnsAsync(existsInPublicContainer);
            PackageFileServiceMock
            .Setup(pfs => pfs.DoesValidationPackageFileExistAsync(Package))
            .ReturnsAsync(existsInValidationContainer);
            IValidationRequest validationRequest = null;

            validator
            .Setup(v => v.GetStatusAsync(It.IsAny <IValidationRequest>()))
            .ReturnsAsync(ValidationStatus.NotStarted)
            .Callback <IValidationRequest>(vr => validationRequest = vr);

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

            validator
            .Verify(v => v.GetStatusAsync(It.IsAny <IValidationRequest>()), Times.AtLeastOnce());
            Assert.NotNull(validationRequest);
            Assert.Contains(expectedUrlSubstring, validationRequest.NupkgUrl);
            Assert.Equal(Package.PackageRegistration.Id, validationRequest.PackageId);
            Assert.Equal(Package.NormalizedVersion, validationRequest.PackageVersion);
        }
        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);
        }
Example #10
0
            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);
            }
Example #11
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);
        }
Example #12
0
            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);
            }
Example #13
0
        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());
        }
Example #14
0
            public async Task CopyDbUpdateDeleteInCorrectOrderWhenValidationSetPackageDoesNotExist()
            {
                var operations = new List <string>();

                PackageFileServiceMock
                .Setup(x => x.DoesValidationSetPackageExistAsync(ValidationSet))
                .ReturnsAsync(false)
                .Callback(() => operations.Add(nameof(IValidationPackageFileService.DoesValidationSetPackageExistAsync)));
                PackageFileServiceMock
                .Setup(x => x.CopyValidationPackageToPackageFileAsync(Package.PackageRegistration.Id, Package.NormalizedVersion))
                .Returns(Task.CompletedTask)
                .Callback(() => operations.Add(nameof(IValidationPackageFileService.CopyValidationPackageToPackageFileAsync)));
                PackageServiceMock
                .Setup(x => x.UpdatePackageStatusAsync(Package, PackageStatus.Available, true))
                .Returns(Task.CompletedTask)
                .Callback(() => operations.Add(nameof(ICorePackageService.UpdatePackageStatusAsync)));
                PackageFileServiceMock
                .Setup(x => x.DeleteValidationPackageFileAsync(Package.PackageRegistration.Id, Package.Version))
                .Returns(Task.CompletedTask)
                .Callback(() => operations.Add(nameof(IValidationPackageFileService.DeleteValidationPackageFileAsync)));

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

                var expectedOrder = new[]
                {
                    nameof(IValidationPackageFileService.DoesValidationSetPackageExistAsync),
                    nameof(IValidationPackageFileService.CopyValidationPackageToPackageFileAsync),
                    nameof(ICorePackageService.UpdatePackageStatusAsync),
                    nameof(IValidationPackageFileService.DeleteValidationPackageFileAsync),
                };

                Assert.Equal(expectedOrder, operations);
            }
Example #15
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);
        }
        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 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 SetsPackageStreamMetadataIfChanged()
            {
                var content                  = "Hello, world.";
                var expectedHash             = "rQw3wx1psxXzqB8TyM3nAQlK2RcluhsNwxmcqXE2YbgoDW735o8TPmIR4uWpoxUERddvFwjgRSGw7gNPCwuvJg==";
                var stream                   = new MemoryStream(Encoding.ASCII.GetBytes(content));
                PackageStreamMetadata actual = null;

                PackageFileServiceMock
                .Setup(x => x.DownloadPackageFileToDiskAsync(ValidationSet))
                .ReturnsAsync(stream);
                var streamMetadata = new PackageStreamMetadata()
                {
                    Size          = stream.Length,
                    Hash          = expectedHash,
                    HashAlgorithm = CoreConstants.Sha512HashAlgorithmId
                };

                PackageFileServiceMock
                .Setup(x => x.UpdatePackageBlobMetadataAsync(It.IsAny <PackageValidationSet>()))
                .ReturnsAsync(streamMetadata);
                PackageServiceMock
                .Setup(x => x.UpdateMetadataAsync(Package, It.IsAny <PackageStreamMetadata>(), false))
                .Returns(Task.CompletedTask)
                .Callback <Package, PackageStreamMetadata, bool>((_, m, __) => actual = m);

                await Target.SetStatusAsync(PackageValidatingEntity, 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.UpdateMetadataAsync(Package, actual, false),
                    Times.Once);
            }
Example #19
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);
        }
Example #21
0
            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);
        }
Example #24
0
        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());
        }
Example #25
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);
        }
Example #26
0
            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);
            }
Example #27
0
        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);
        }
Example #28
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);
        }
Example #30
0
        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());
        }