コード例 #1
0
        public async Task <ValidationSetProcessorResult> ProcessValidationsAsync(PackageValidationSet validationSet)
        {
            _logger.LogInformation("Starting processing validation request for {PackageId} {PackageVersion}, validation set {ValidationSetId}",
                                   validationSet.PackageId,
                                   validationSet.PackageNormalizedVersion,
                                   validationSet.ValidationTrackingId);
            var processorStats = new ValidationSetProcessorResult();
            int loopLimit      = MaxProcessAttempts;

            await ProcessIncompleteValidations(validationSet, processorStats);

            bool hadSucceededValidations = false;

            do
            {
                // we will try to start more validations in case previous validation start attempts
                // result in Succeeded validation immediately (i.e. the validation was synchronous).
                // If no validation start attempts resulted in succeeded validation (ProcessNotStartedValidations
                // returns false) we move on and will check on progress later.
                // loopLimit is there to prevent looping here infinitely if there are any bugs that
                // cause ProcessNotStartedValidations to always return true.
                hadSucceededValidations = await ProcessNotStartedValidations(validationSet, processorStats);
            } while (hadSucceededValidations && loopLimit-- > 0);
            if (loopLimit <= 0)
            {
                _logger.LogWarning("Too many processing attempts ({NumAttempts}) for {PackageId} {PackageVersion}, validation set {ValidationSetId}",
                                   MaxProcessAttempts,
                                   validationSet.PackageId,
                                   validationSet.PackageNormalizedVersion,
                                   validationSet.ValidationTrackingId);
            }

            return(processorStats);
        }
コード例 #2
0
        public ValidationOutcomeProcessorFacts()
        {
            PackageServiceMock        = new Mock <ICorePackageService>();
            PackageFileServiceMock    = new Mock <ICorePackageFileService>();
            ValidationEnqueuerMock    = new Mock <IPackageValidationEnqueuer>();
            ConfigurationAccessorMock = new Mock <IOptionsSnapshot <ValidationConfiguration> >();
            MessageServiceMock        = new Mock <IMessageService>();
            LoggerMock = new Mock <ILogger <ValidationOutcomeProcessor> >();

            Configuration             = new ValidationConfiguration();
            Configuration.Validations = new List <ValidationConfigurationItem>();
            Package = new Package
            {
                PackageRegistration = new PackageRegistration {
                    Id = "package"
                },
                Version           = "1.2.3.456",
                NormalizedVersion = "1.2.3",
                PackageStatusKey  = PackageStatus.Validating
            };
            Package.PackageRegistration.Packages.Add(Package);

            ValidationSet = new PackageValidationSet();
            ValidationSet.PackageValidations = new List <PackageValidation>();

            ValidationSet.PackageId = Package.PackageRegistration.Id;
            ValidationSet.PackageNormalizedVersion = Package.NormalizedVersion;
            ValidationSet.ValidationTrackingId     = Guid.NewGuid();

            ConfigurationAccessorMock
            .SetupGet(ca => ca.Value)
            .Returns(Configuration);
        }
コード例 #3
0
 private static string BuildValidationSetPackageFileName(PackageValidationSet validationSet)
 {
     return($"validation-sets/{validationSet.ValidationTrackingId}/" +
            $"{validationSet.PackageId.ToLowerInvariant()}." +
            $"{validationSet.PackageNormalizedVersion.ToLowerInvariant()}" +
            CoreConstants.NuGetPackageFileExtension);
 }
コード例 #4
0
            public void ItShouldProceedWhenFromFailedStateWithNoValidationInProgress()
            {
                // Arrange
                IValidatingEntity <SymbolPackage> validatingSymbolPackage = null;

                SymbolsPackageServiceMock.Setup(sp => sp.FindPackageByIdAndVersionStrict(PackageId, PackageVersion))
                .Returns(validatingSymbolPackage);

                var validationSet = new PackageValidationSet
                {
                    PackageId = FailedSymbolPackage.Id,
                    PackageNormalizedVersion = FailedSymbolPackage.Version,
                    PackageKey         = FailedSymbolPackageValidatingEntity.Key,
                    PackageValidations = new List <PackageValidation>
                    {
                        new PackageValidation {
                            Type = "SomeValidator"
                        },
                    }
                };

                // Act
                bool result = Target.CanProceedToMakePackageAvailable(FailedSymbolPackageValidatingEntity, validationSet);

                Target.SetStatusAsync(FailedSymbolPackageValidatingEntity, validationSet, PackageStatus.Available);

                // Assert
                Assert.True(result);
                SymbolPackageFileServiceMock.Verify(spfs => spfs.DoesValidationSetPackageExistAsync(It.IsAny <PackageValidationSet>()), Times.Once);
            }
コード例 #5
0
            public void ItShouldNotProceedWhenFromFailedStateWithValidationInProgress()
            {
                // Arrange
                SymbolsPackageServiceMock.Setup(sp => sp.FindPackageByIdAndVersionStrict(PackageId, PackageVersion))
                .Returns(ValidatingSymbolPackageValidatingEntity);

                var validationSet = new PackageValidationSet
                {
                    PackageId = FailedSymbolPackage.Id,
                    PackageNormalizedVersion = FailedSymbolPackage.Version,
                    PackageKey         = FailedSymbolPackageValidatingEntity.Key,
                    PackageValidations = new List <PackageValidation>
                    {
                        new PackageValidation {
                            Type = "SomeValidator"
                        },
                    }
                };

                // Act
                bool result = Target.CanProceedToMakePackageAvailable(FailedSymbolPackageValidatingEntity, validationSet);

                Target.SetStatusAsync(FailedSymbolPackageValidatingEntity, validationSet, PackageStatus.Available);

                // Assert
                Assert.False(result);
                SymbolPackageFileServiceMock.Verify(spfs => spfs.DoesValidationSetPackageExistAsync(It.IsAny <PackageValidationSet>()), Times.Never);
                SymbolPackageFileServiceMock.Verify(spfs => spfs.CopyValidationSetPackageToPackageFileAsync(It.IsAny <PackageValidationSet>(), It.IsAny <IAccessCondition>()), Times.Never);
                SymbolPackageFileServiceMock.Verify(spfs => spfs.CopyValidationPackageToPackageFileAsync(It.IsAny <PackageValidationSet>()), Times.Never);
                SymbolPackageFileServiceMock.Verify(spfs => spfs.UpdatePackageBlobMetadataInValidationSetAsync(It.IsAny <PackageValidationSet>()), Times.Never);
                SymbolPackageFileServiceMock.Verify(spfs => spfs.UpdatePackageBlobMetadataInValidationAsync(It.IsAny <PackageValidationSet>()), Times.Never);
                SymbolsPackageServiceMock.Verify(sps => sps.UpdateStatusAsync(It.IsAny <SymbolPackage>(), It.IsAny <PackageStatus>(), It.IsAny <bool>()), Times.Never);
            }
コード例 #6
0
        protected override async Task OnCleanupAfterDatabaseUpdateFailure(
            IValidatingEntity <Package> validatingEntity,
            PackageValidationSet validationSet)
        {
            if (validatingEntity.EntityRecord.EmbeddedLicenseType != EmbeddedLicenseFileType.Absent)
            {
                using (_telemetryService.TrackDurationToDeleteLicenseFile(validationSet.PackageId, validationSet.PackageNormalizedVersion, validationSet.ValidationTrackingId.ToString()))
                {
                    _logger.LogInformation("Cleaning up the license file for the package {PackageId} {PackageVersion}", validationSet.PackageId, validationSet.PackageNormalizedVersion);
                    await _coreLicenseFileService.DeleteLicenseFileAsync(validationSet.PackageId, validationSet.PackageNormalizedVersion);

                    _logger.LogInformation("Deleted the license file for the package {PackageId} {PackageVersion}", validationSet.PackageId, validationSet.PackageNormalizedVersion);
                }
            }

            if (validatingEntity.EntityRecord.HasEmbeddedReadme)
            {
                using (_telemetryService.TrackDurationToDeleteReadmeFile(validationSet.PackageId, validationSet.PackageNormalizedVersion, validationSet.ValidationTrackingId.ToString()))
                {
                    _logger.LogInformation("Cleaning up the readme file for the package {PackageId} {PackageVersion}", validationSet.PackageId, validationSet.PackageNormalizedVersion);
                    await _coreReadmeFileService.DeleteReadmeFileAsync(validationSet.PackageId, validationSet.PackageNormalizedVersion);

                    _logger.LogInformation("Deleted the readme file for the package {PackageId} {PackageVersion}", validationSet.PackageId, validationSet.PackageNormalizedVersion);
                }
            }
        }
コード例 #7
0
        public static IReadOnlyList <ValidationIssue> GetValidationIssues(this PackageValidationSet validationSet)
        {
            IReadOnlyList <ValidationIssue> issues = null;

            if (validationSet != null)
            {
                // Get the failed validation set's validation issues. The issues are ordered by their
                // key so that it appears that issues are appended as more validations fail.
                issues = validationSet
                         .PackageValidations
                         .SelectMany(v => v.PackageValidationIssues)
                         .OrderBy(i => i.Key)
                         .Select(i => ValidationIssue.Deserialize(i.IssueCode, i.Data))
                         .ToList();

                // Filter out unknown issues and deduplicate the issues by code and data. This also deduplicates cases
                // where there is extraneous data in the serialized data field or if the issue code is unknown.
                issues = issues
                         .GroupBy(x => new { x.IssueCode, Data = x.Serialize() })
                         .Select(x => x.First())
                         .ToList();
            }

            // If the package failed validation but we could not find an issue that explains why, use a generic error message.
            if (issues == null || !issues.Any())
            {
                issues = new[] { ValidationIssue.Unknown };
            }

            return(issues);
        }
コード例 #8
0
        public async Task DownloadPackageFileToDiskAsync()
        {
            _fileStorageService
            .Setup(x => x.GetFileReadUriAsync(
                       _packagesContainerName,
                       _packageFileName,
                       null))
            .ReturnsAsync(_testUri)
            .Verifiable();

            _packageDownloader
            .Setup(x => x.DownloadAsync(_testUri, CancellationToken.None))
            .ReturnsAsync(_packageStream)
            .Verifiable();

            var validationSet = new PackageValidationSet()
            {
                PackageNormalizedVersion = _package.NormalizedVersion,
                PackageKey = _package.Key,
                PackageId  = _package.PackageRegistration.Id
            };

            var actual = await _target.DownloadPackageFileToDiskAsync(validationSet);

            Assert.Same(_packageStream, actual);
            _fileStorageService.Verify();
            _packageDownloader.Verify();
        }
コード例 #9
0
        public async Task SendValidationFailedMessageAsync(Package package, PackageValidationSet validationSet)
        {
            package       = package ?? throw new ArgumentNullException(nameof(package));
            validationSet = validationSet ?? throw new ArgumentNullException(nameof(validationSet));

            var galleryPackageUrl = _serviceConfiguration.GalleryPackageUrl(package.PackageRegistration.Id, package.NormalizedVersion);
            var packageSupportUrl = _serviceConfiguration.PackageSupportUrl(package.PackageRegistration.Id, package.NormalizedVersion);

            var packageValidationFailedMessage = new PackageValidationFailedMessage(
                _serviceConfiguration,
                package,
                validationSet,
                galleryPackageUrl,
                packageSupportUrl,
                _serviceConfiguration.EmailConfiguration.AnnouncementsUrl,
                _serviceConfiguration.EmailConfiguration.TwitterUrl);

            _logger.LogInformation(
                "The validation failed email will be sent for the package {PackageId} {PackageVersion} and " +
                "{ValidationSetId}",
                package.Id,
                package.NormalizedVersion,
                validationSet.ValidationTrackingId);
            await _messageService.SendMessageAsync(packageValidationFailedMessage);
        }
コード例 #10
0
 protected static string BuildValidationSetPackageFileName(PackageValidationSet validationSet, string extension)
 {
     return($"validation-sets/{validationSet.ValidationTrackingId}/" +
            $"{validationSet.PackageId.ToLowerInvariant()}." +
            $"{validationSet.PackageNormalizedVersion.ToLowerInvariant()}" +
            extension);
 }
コード例 #11
0
        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);
        }
コード例 #12
0
        public SymbolsMessageServiceFacts()
        {
            EmailConfiguration = new EmailConfiguration
            {
                PackageUrlTemplate     = "https://example.com/package/{0}/{1}",
                PackageSupportTemplate = "https://example.com/packageSupport/{0}/{1}",
                EmailSettingsUrl       = ValidSettingsUrl,
                AnnouncementsUrl       = "https://announcements.com",
                TwitterUrl             = "https://twitter.com/nuget",
                GalleryNoReplyAddress  = "NuGet Gallery <*****@*****.**>",
                GalleryOwner           = "NuGet Gallery <*****@*****.**>"
            };

            EmailConfigurationAccessorMock
            .SetupGet(eca => eca.Value)
            .Returns(EmailConfiguration);

            var package = new Package
            {
                PackageRegistration = new PackageRegistration {
                    Id = "package"
                },
                Version           = "1.2.3.4",
                NormalizedVersion = "1.2.3"
            };

            SymbolPackage = new SymbolPackage()
            {
                Package = package
            };

            ValidationSet = new PackageValidationSet();
        }
コード例 #13
0
        public ValidationSetProviderFacts()
        {
            ValidationStorageMock     = new Mock <IValidationStorageService>(MockBehavior.Strict);
            ConfigurationAccessorMock = new Mock <IOptionsSnapshot <ValidationConfiguration> >();
            LoggerMock = new Mock <ILogger <ValidationSetProvider> >();

            Configuration = new ValidationConfiguration();
            ConfigurationAccessorMock
            .SetupGet(ca => ca.Value)
            .Returns(() => Configuration);

            Package = new Package
            {
                PackageRegistration = new PackageRegistration {
                    Id = "package1"
                },
                Version           = "1.2.3.456",
                NormalizedVersion = "1.2.3",
                Key = 42,
            };
            Package.PackageRegistration.Packages = new List <Package> {
                Package
            };

            ValidationSet = new PackageValidationSet
            {
                PackageId = Package.PackageRegistration.Id,
                PackageNormalizedVersion = Package.NormalizedVersion,
                ValidationTrackingId     = Guid.NewGuid()
            };
        }
コード例 #14
0
        public async Task BackupPackageFileFromValidationSetPackageAsync(PackageValidationSet validationSet, string sasDefinition)
        {
            if (validationSet.ValidatingType == ValidatingType.Generic)
            {
                throw new ArgumentException(
                          $"This method is not supported for validation sets of validating type {validationSet.ValidatingType}",
                          nameof(validationSet));
            }

            using (_telemetryService.TrackDurationToBackupPackage(validationSet))
            {
                _logger.LogInformation(
                    "Backing up package for validation set {ValidationTrackingId} ({PackageId} {PackageVersion}).",
                    validationSet.ValidationTrackingId,
                    validationSet.PackageId,
                    validationSet.PackageNormalizedVersion);

                var packageUri = await GetPackageForValidationSetReadUriAsync(
                    validationSet,
                    sasDefinition,
                    DateTimeOffset.UtcNow.Add(AccessDuration));

                using (var result = await _fileDownloader.DownloadAsync(packageUri, CancellationToken.None))
                {
                    await StorePackageFileInBackupLocationAsync(validationSet, result.GetStreamOrThrow());
                }
            }
        }
コード例 #15
0
        public async Task DropsMessageIfPackageIsSoftDeletedForCheckValidator()
        {
            var messageData             = PackageValidationMessageData.NewCheckValidator(Guid.NewGuid());
            var validationConfiguration = new ValidationConfiguration();
            var package = new Package {
                Key = 42, PackageStatusKey = PackageStatus.Deleted
            };
            var packageValidatingEntity = new PackageValidatingEntity(package);
            var validationSet           = new PackageValidationSet {
                PackageKey = package.Key, ValidatingType = ValidatingType.Package
            };

            ValidationSetProviderMock
            .Setup(ps => ps.TryGetParentValidationSetAsync(messageData.CheckValidator.ValidationId))
            .ReturnsAsync(validationSet)
            .Verifiable();
            CorePackageServiceMock
            .Setup(ps => ps.FindPackageByKey(package.Key))
            .Returns(packageValidatingEntity);

            var handler = CreateHandler();

            var result = await handler.HandleAsync(messageData);

            Assert.True(result);
            ValidationSetProviderMock.Verify(
                vsp => vsp.TryGetParentValidationSetAsync(messageData.CheckValidator.ValidationId),
                Times.Once);
            CorePackageServiceMock.Verify(
                ps => ps.FindPackageByKey(package.Key),
                Times.Once);
        }
コード例 #16
0
        private async Task ProcessValidationSetAsync(
            IValidatingEntity <TEntity> entity,
            PackageValidationSet validationSet,
            bool scheduleNextCheck)
        {
            if (validationSet.ValidationSetStatus == ValidationSetStatus.Completed)
            {
                _logger.LogInformation(
                    "The validation set {ValidatingType} {PackageId} {PackageVersion} {Key} {ValidationSetId} is " +
                    "already completed. Discarding the message.",
                    ValidatingType,
                    validationSet.PackageId,
                    validationSet.PackageNormalizedVersion,
                    validationSet.PackageKey,
                    validationSet.ValidationTrackingId);
                return;
            }

            var processorStats = await _validationSetProcessor.ProcessValidationsAsync(validationSet);

            await _validationOutcomeProcessor.ProcessValidationOutcomeAsync(
                validationSet,
                entity,
                processorStats,
                scheduleNextCheck);
        }
コード例 #17
0
        private async Task ScheduleCheckIfNotTimedOut(PackageValidationSet validationSet, IValidatingEntity <T> validatingEntity, bool tooLongNotificationAllowed)
        {
            var validationSetDuration = await UpdateValidationDurationAsync(validationSet, validatingEntity, tooLongNotificationAllowed);

            // Schedule another check if we haven't reached the validation set timeout yet.
            if (validationSetDuration <= _validationConfiguration.TimeoutValidationSetAfter)
            {
                var messageData = new PackageValidationMessageData(
                    validationSet.PackageId,
                    validationSet.PackageNormalizedVersion,
                    validationSet.ValidationTrackingId,
                    validationSet.ValidatingType,
                    entityKey: validationSet.PackageKey);
                var postponeUntil = DateTimeOffset.UtcNow + _validationConfiguration.ValidationMessageRecheckPeriod;

                await _validationEnqueuer.StartValidationAsync(messageData, postponeUntil);
            }
            else
            {
                _logger.LogWarning("Abandoning checking status of validation set {ValidationTrackingId} for " +
                                   "package {PackageId} {PackageVersion} because it took too long (Duration: {Duration}, CutOffDuration: {CutOffDuration})",
                                   validationSet.ValidationTrackingId,
                                   validationSet.PackageId,
                                   validationSet.PackageNormalizedVersion,
                                   validationSetDuration,
                                   _validationConfiguration.TimeoutValidationSetAfter);
                _telemetryService.TrackValidationSetTimeout(validationSet.PackageId, validationSet.PackageNormalizedVersion, validationSet.ValidationTrackingId);
            }
        }
コード例 #18
0
            public void ReturnsSingleUnknownIssueIfNoneArePersisted()
            {
                // Arrange
                _package.Key = 123;
                _package.PackageStatusKey = PackageStatus.FailedValidation;

                var packageValidationSet = new PackageValidationSet
                {
                    PackageKey         = 123,
                    PackageValidations = new[]
                    {
                        new PackageValidation
                        {
                            ValidationStatus        = ValidationStatus.Failed,
                            PackageValidationIssues = new PackageValidationIssue[0],
                        }
                    }
                };

                _validationSets
                .Setup(x => x.GetAll())
                .Returns(new[] { packageValidationSet }.AsQueryable());

                // Act
                var issues = _target.GetLatestValidationIssues(_package);

                // Assert
                _validationSets.Verify(x => x.GetAll(), Times.Once);

                var issue = Assert.Single(issues);

                Assert.Equal(ValidationIssueCode.Unknown, issue.IssueCode);
            }
コード例 #19
0
 private bool AreOptionalValidationsRunning(PackageValidationSet packageValidationSet)
 {
     return(packageValidationSet
            .PackageValidations
            .Any(pv => pv.ValidationStatus == ValidationStatus.Incomplete &&
                 GetValidationConfigurationItemByName(pv.Type)?.FailureBehavior == ValidationFailureBehavior.AllowedToFail));
 }
コード例 #20
0
        protected override async Task OnBeforeUpdateDatabaseToMakePackageAvailable(
            IValidatingEntity <Package> validatingEntity,
            PackageValidationSet validationSet)
        {
            if (validatingEntity.EntityRecord.EmbeddedLicenseType != EmbeddedLicenseFileType.Absent || validatingEntity.EntityRecord.HasEmbeddedReadme)
            {
                using (_telemetryService.TrackDurationToExtractLicenseAndReadmeFile(validationSet.PackageId, validationSet.PackageNormalizedVersion, validationSet.ValidationTrackingId.ToString()))
                    using (var packageStream = await _packageFileService.DownloadPackageFileToDiskAsync(validationSet, _sasDefinitionConfiguration.PackageStatusProcessorSasDefinition))
                    {
                        if (validatingEntity.EntityRecord.EmbeddedLicenseType != EmbeddedLicenseFileType.Absent)
                        {
                            _logger.LogInformation("Extracting the license file of type {EmbeddedLicenseFileType} for the package {PackageId} {PackageVersion}",
                                                   validatingEntity.EntityRecord.EmbeddedLicenseType,
                                                   validationSet.PackageId,
                                                   validationSet.PackageNormalizedVersion);
                            await _coreLicenseFileService.ExtractAndSaveLicenseFileAsync(validatingEntity.EntityRecord, packageStream);

                            _logger.LogInformation("Successfully extracted the license file.");
                        }

                        if (validatingEntity.EntityRecord.HasEmbeddedReadme)
                        {
                            _logger.LogInformation("Extracting the readme file of type {EmbeddedReadmeType} for the package {PackageId} {PackageVersion}",
                                                   validatingEntity.EntityRecord.EmbeddedReadmeType,
                                                   validationSet.PackageId,
                                                   validationSet.PackageNormalizedVersion);
                            await _coreReadmeFileService.ExtractAndSaveReadmeFileAsync(validatingEntity.EntityRecord, packageStream);

                            _logger.LogInformation("Successfully extracted the readme file.");
                        }
                    }
            }
        }
コード例 #21
0
 private bool AllRequiredValidationsSucceeded(PackageValidationSet packageValidationSet)
 {
     return(packageValidationSet
            .PackageValidations
            .All(pv => pv.ValidationStatus == ValidationStatus.Succeeded ||
                 GetValidationConfigurationItemByName(pv.Type)?.FailureBehavior == ValidationFailureBehavior.AllowedToFail));
 }
コード例 #22
0
            public BaseFacts()
            {
                Package = new Package
                {
                    PackageRegistration = new PackageRegistration(),
                    PackageStatusKey    = PackageStatus.Validating,
                };
                ValidationSet = new PackageValidationSet
                {
                    PackageValidations = new List <PackageValidation>
                    {
                        new PackageValidation {
                            Type = "SomeValidator"
                        },
                    }
                };

                PackageServiceMock     = new Mock <ICorePackageService>();
                PackageFileServiceMock = new Mock <IValidationPackageFileService>();
                ValidatorProviderMock  = new Mock <IValidatorProvider>();
                TelemetryServiceMock   = new Mock <ITelemetryService>();
                LoggerMock             = new Mock <ILogger <PackageStatusProcessor> >();

                PackageFileServiceMock
                .Setup(x => x.DownloadPackageFileToDiskAsync(It.IsAny <Package>()))
                .ReturnsAsync(() => Stream.Null);

                Target = new PackageStatusProcessor(
                    PackageServiceMock.Object,
                    PackageFileServiceMock.Object,
                    ValidatorProviderMock.Object,
                    TelemetryServiceMock.Object,
                    LoggerMock.Object);
            }
コード例 #23
0
            public Facts(ITestOutputHelper output)
            {
                Options                    = new Mock <IOptionsSnapshot <ValidationConfiguration> >();
                EntityService              = new Mock <IEntityService <TestEntity> >();
                ValidationSetProvider      = new Mock <IValidationSetProvider <TestEntity> >();
                ValidationSetProcessor     = new Mock <IValidationSetProcessor>();
                ValidationOutcomeProcessor = new Mock <IValidationOutcomeProcessor <TestEntity> >();
                LeaseService               = new Mock <ILeaseService>();
                PackageValidationEnqueuer  = new Mock <IPackageValidationEnqueuer>();
                FeatureFlagService         = new Mock <IFeatureFlagService>();
                TelemetryService           = new Mock <ITelemetryService>();
                Logger = new LoggerFactory().AddXunit(output).CreateLogger <SymbolValidationMessageHandler>();

                Config = new ValidationConfiguration
                {
                    MissingPackageRetryCount = 1,
                };
                ValidatingEntity = new Mock <IValidatingEntity <TestEntity> >();
                ValidationSet    = new PackageValidationSet
                {
                    PackageKey               = 42,
                    ValidationTrackingId     = new Guid("dc2aa638-a23c-4791-a4ff-c3e07b1320a4"),
                    PackageId                = "NuGet.Versioning",
                    PackageNormalizedVersion = "5.3.0-BETA",
                    ValidatingType           = ValidatingType.Package,
                    ValidationSetStatus      = ValidationSetStatus.InProgress,
                };
                LeaseResourceName            = "Package/nuget.versioning/5.3.0-beta";
                ValidationSetProcessorResult = new ValidationSetProcessorResult();
                LeaseResult = LeaseResult.Success("lease-id");

                Options.Setup(x => x.Value).Returns(() => Config);
                EntityService
                .Setup(x => x.FindPackageByKey(It.IsAny <int>()))
                .Returns(() => ValidatingEntity.Object);
                ValidationSetProcessor
                .Setup(x => x.ProcessValidationsAsync(It.IsAny <PackageValidationSet>()))
                .ReturnsAsync(() => ValidationSetProcessorResult);
                ValidatingEntity
                .Setup(x => x.Status)
                .Returns(PackageStatus.Validating);
                LeaseService
                .Setup(x => x.TryAcquireAsync(It.IsAny <string>(), It.IsAny <TimeSpan>(), It.IsAny <CancellationToken>()))
                .ReturnsAsync(() => LeaseResult);

                FeatureFlagService.Setup(x => x.IsQueueBackEnabled()).Returns(true);
                FeatureFlagService.Setup(x => x.IsOrchestratorLeaseEnabled()).Returns(true);

                Target = new TestHandler(
                    Options.Object,
                    EntityService.Object,
                    ValidationSetProvider.Object,
                    ValidationSetProcessor.Object,
                    ValidationOutcomeProcessor.Object,
                    LeaseService.Object,
                    PackageValidationEnqueuer.Object,
                    FeatureFlagService.Object,
                    TelemetryService.Object,
                    Logger);
            }
コード例 #24
0
        public static string BuildFileName(PackageValidationSet validationSet, string pathTemplate, string extension)
        {
            string id      = validationSet.PackageId;
            string version = validationSet.PackageNormalizedVersion;

            return(FileNameHelper.BuildFileName(id, version, pathTemplate, extension));
        }
コード例 #25
0
        public async Task WaitsForPackageAvailabilityInGalleryDBWithCheckValidator()
        {
            var messageData             = PackageValidationMessageData.NewCheckValidator(Guid.NewGuid());
            var validationConfiguration = new ValidationConfiguration();
            var validationSet           = new PackageValidationSet {
                PackageKey = 42, ValidatingType = ValidatingType.SymbolPackage
            };

            ValidationSetProviderMock
            .Setup(ps => ps.TryGetParentValidationSetAsync(messageData.CheckValidator.ValidationId))
            .ReturnsAsync(validationSet)
            .Verifiable();
            CoreSymbolPackageServiceMock
            .Setup(ps => ps.FindPackageByKey(validationSet.PackageKey))
            .Returns <SymbolPackage>(null)
            .Verifiable();

            var handler = CreateHandler();

            var result = await handler.HandleAsync(messageData);

            ValidationSetProviderMock.Verify(
                ps => ps.TryGetParentValidationSetAsync(messageData.CheckValidator.ValidationId),
                Times.Once);
            CoreSymbolPackageServiceMock.Verify(
                ps => ps.FindPackageByKey(validationSet.PackageKey),
                Times.Once);

            Assert.False(result, "The handler should not have succeeded.");
        }
コード例 #26
0
        protected ValidationSetProcessorFactsBase(
            MockBehavior validatorProviderMockBehavior     = MockBehavior.Default,
            MockBehavior validationStorageMockBehavior     = MockBehavior.Default,
            MockBehavior configurationAccessorMockBehavior = MockBehavior.Default,
            MockBehavior packageFileServiceMockBehavior    = MockBehavior.Default,
            MockBehavior loggerMockBehavior = MockBehavior.Default)
        {
            ValidatorProviderMock     = new Mock <IValidatorProvider>(validatorProviderMockBehavior);
            ValidationStorageMock     = new Mock <IValidationStorageService>(validationStorageMockBehavior);
            ConfigurationAccessorMock = new Mock <IOptionsSnapshot <ValidationConfiguration> >(configurationAccessorMockBehavior);
            PackageFileServiceMock    = new Mock <ICorePackageFileService>(packageFileServiceMockBehavior);
            LoggerMock    = new Mock <ILogger <ValidationSetProcessor> >(loggerMockBehavior);
            Configuration = new ValidationConfiguration
            {
                Validations = new List <ValidationConfigurationItem>
                {
                }
            };
            ConfigurationAccessorMock
            .SetupGet(ca => ca.Value)
            .Returns(Configuration);

            Package = new Package
            {
                PackageRegistration = new PackageRegistration {
                    Id = "packageId"
                },
                Version           = "1.2.3.456",
                NormalizedVersion = "1.2.3"
            };

            Package.PackageRegistration.Packages.Add(Package);

            ValidationSet = new PackageValidationSet
            {
                Key       = 238423,
                PackageId = Package.PackageRegistration.Id,
                PackageNormalizedVersion = Package.NormalizedVersion,
                PackageValidations       = new List <PackageValidation>
                {
                }
            };
            ValidationSet.PackageValidations.ToList().ForEach(v => v.PackageValidationSet = ValidationSet);
            Validators = new Dictionary <string, Mock <IValidator> >();

            PackageFileServiceMock
            .Setup(pfs => pfs.GetValidationPackageReadUriAsync(It.IsAny <Package>(), It.IsAny <DateTimeOffset>()))
            .Returns <Package, DateTimeOffset>(
                (p, e) => Task.FromResult(new Uri($"https://example.com/{ValidationContainerName}/{p.PackageRegistration.Id}/{p.NormalizedVersion}?e={e:yyyy-MM-dd-hh-mm-ss}")));

            PackageFileServiceMock
            .Setup(pfs => pfs.GetPackageReadUriAsync(It.IsAny <Package>()))
            .Returns <Package>(
                p => Task.FromResult(new Uri($"https://example.com/{PublicContainerName}/{p.PackageRegistration.Id}/{p.NormalizedVersion}")));

            PackageFileServiceMock
            .Setup(pfs => pfs.DoesValidationPackageFileExistAsync(Package))
            .ReturnsAsync(true);
        }
コード例 #27
0
 private List <PackageValidation> GetFailedValidations(PackageValidationSet packageValidationSet)
 {
     return(packageValidationSet
            .PackageValidations
            .Where(v => v.ValidationStatus == ValidationStatus.Failed)
            .Where(v => GetValidationConfigurationItemByName(v.Type)?.FailureBehavior == ValidationFailureBehavior.MustSucceed)
            .ToList());
 }
コード例 #28
0
        public async Task <string> GetPublicPackageBlobETagOrNullAsync(PackageValidationSet validationSet)
        {
            var fileName = BuildFileName(validationSet,
                                         _fileMetadataService.FileSavePathTemplate,
                                         _fileMetadataService.FileExtension);

            return(await _fileStorageService.GetETagOrNullAsync(_fileMetadataService.FileFolderName, fileName));
        }
コード例 #29
0
 private async Task MarkValidationSetAsCompletedAsync(PackageValidationSet validationSet)
 {
     // Move the validation set to the completed status. This operation is done using optimistic concurrency
     // meaning if another thread is processing this same validation set at the same time, one thread will win
     // and one thread will fail. In other words, subsequent steps will be executed at most one time. From
     validationSet.ValidationSetStatus = ValidationSetStatus.Completed;
     await _validationStorageService.UpdateValidationSetAsync(validationSet);
 }
コード例 #30
0
        public Task <Uri> GetPackageReadUriAsync(PackageValidationSet validationSet)
        {
            var fileName = BuildFileName(validationSet,
                                         _fileMetadataService.FileSavePathTemplate,
                                         _fileMetadataService.FileExtension);

            return(_fileStorageService.GetFileReadUriAsync(_fileMetadataService.FileFolderName, fileName, endOfAccess: null));
        }