public void WillSkipAnyTimestampThatWouldResultInPageOverflow()
            {
                // Arrange
                const int top      = 20;
                var       utcNow   = DateTime.UtcNow;
                var       packages = new List <FeedPackageDetails>();

                // Ensure the top 10 timestamps have a package each.
                for (int i = 10; i < top; i++)
                {
                    packages.Add(new FeedPackageDetails(
                                     new Uri($"https://unittest.org/packages/Package.Id{i}/1.0.{i}"),
                                     createdDate: utcNow.AddDays(-i),
                                     lastEditedDate: utcNow.AddDays(-i),
                                     publishedDate: utcNow.AddDays(-i),
                                     packageId: $"Package.Id{i}",
                                     packageNormalizedVersion: $"1.0.{i}",
                                     packageFullVersion: $"1.0.{i}"));
                }

                // Ensure the next timestamp has enough packages to have it reach the max page size.
                // This simulates encountering bulk changes at timestamp 11.
                var timestampForBulkChanges = utcNow.AddHours(-8);

                for (int i = 0; i < CatalogConstants.MaxPageSize - top + 10; i++)
                {
                    packages.Add(new FeedPackageDetails(
                                     new Uri($"https://unittest.org/packages/BatchUpdatedPackage.Id/1.0.{i}"),
                                     createdDate: utcNow.AddHours(-9),
                                     lastEditedDate: timestampForBulkChanges,
                                     publishedDate: utcNow.AddHours(-9),
                                     packageId: "BatchUpdatedPackage.Id",
                                     packageNormalizedVersion: $"1.0.{i}",
                                     packageFullVersion: $"1.0.{i}"));
                }

                // Add some more timestamps with a package each to the end of the top 20 resultset.
                for (int i = top - 10 + 1; i < top; i++)
                {
                    packages.Add(new FeedPackageDetails(
                                     new Uri($"https://unittest.org/packages/Another.Package.Id{i}/1.0.{i}"),
                                     createdDate: utcNow.AddDays(-i),
                                     lastEditedDate: utcNow.AddMinutes(-i),
                                     publishedDate: utcNow.AddDays(-i),
                                     packageId: $"Another.Package.Id{i}",
                                     packageNormalizedVersion: $"1.0.{i}",
                                     packageFullVersion: $"1.0.{i}"));
                }

                // Act
                var orderedByLastEditedDate = GalleryDatabaseQueryService.OrderPackagesByKeyDate(packages, p => p.LastEditedDate);

                // Assert
                Assert.Equal(top - 10 + 1, orderedByLastEditedDate.Count);
                Assert.Contains(timestampForBulkChanges, orderedByLastEditedDate.Keys);
                Assert.True(orderedByLastEditedDate.Values.Sum(v => v.Count) <= CatalogConstants.MaxPageSize);
            }
            public void OnlyConsidersPackagesWithAvailableStatus()
            {
                // Arrange
                var cursor = Db2CatalogCursor.ByCreated(DateTime.UtcNow, 20);

                // Act
                var queryString = GalleryDatabaseQueryService.BuildDb2CatalogSqlQuery(cursor);

                // Assert
                Assert.Contains($"WHERE P.[PackageStatusKey] = {(int)PackageStatus.Available}", queryString);
            }
            public void JoinsWithPackageRegistrationsTable()
            {
                // Arrange
                var cursor = Db2CatalogCursor.ByCreated(DateTime.UtcNow, 20);

                // Act
                var queryString = GalleryDatabaseQueryService.BuildDb2CatalogSqlQuery(cursor);

                // Assert
                Assert.Contains("INNER JOIN [dbo].[PackageRegistrations] AS PR ON P.[PackageRegistrationKey] = PR.[Key]", queryString);
            }
            public void SelectsFromPackagesTable()
            {
                // Arrange
                var cursor = Db2CatalogCursor.ByCreated(DateTime.UtcNow, 20);

                // Act
                var queryString = GalleryDatabaseQueryService.BuildDb2CatalogSqlQuery(cursor);

                // Assert
                Assert.Contains("FROM [dbo].[Packages] AS P", queryString);
            }
            public void OrdersByCursorColumnName_LastEdited()
            {
                // Arrange
                var cursor = Db2CatalogCursor.ByLastEdited(DateTime.UtcNow, 20);

                // Act
                var queryString = GalleryDatabaseQueryService.BuildDb2CatalogSqlQuery(cursor);

                // Assert
                Assert.EndsWith($"ORDER BY P.[{cursor.ColumnName}]", queryString);
            }
            public void SelectsTopWithTies()
            {
                // Arrange
                var cursor = Db2CatalogCursor.ByCreated(DateTime.UtcNow, 10);

                // Act
                var queryString = GalleryDatabaseQueryService.BuildDb2CatalogSqlQuery(cursor);

                // Assert
                Assert.StartsWith($"SELECT TOP {cursor.Top} WITH TIES", queryString);
            }
Esempio n. 7
0
            public void OrdersByCursorColumnName_Created()
            {
                // Arrange
                var cursor = Db2CatalogCursor.ByCreated(DateTime.UtcNow, 20);

                // Act
                var queryString = GalleryDatabaseQueryService.BuildDb2CatalogSqlQuery(cursor);

                // Assert
                Assert.EndsWith($"ORDER BY P_EXT.[{cursor.ColumnName}], P_EXT.[{Db2CatalogProjectionColumnNames.Key}]", queryString);
            }
Esempio n. 8
0
            public void JoinsWithPackageVulnerabilitiesTables()
            {
                // Arrange
                var cursor = Db2CatalogCursor.ByCreated(DateTime.UtcNow, 20);

                // Act
                var queryString = GalleryDatabaseQueryService.BuildDb2CatalogSqlQuery(cursor);

                // Assert
                Assert.Contains("LEFT JOIN [dbo].[VulnerablePackageVersionRangePackages] AS VPVRP ON VPVRP.[Package_Key] = P_EXT.[Key]", queryString);
                Assert.Contains("LEFT JOIN [dbo].[VulnerablePackageVersionRanges] AS VPVR ON VPVR.[Key] = VPVRP.[VulnerablePackageVersionRange_Key]", queryString);
                Assert.Contains("LEFT JOIN [dbo].[PackageVulnerabilities] AS PV ON PV.[Key] = VPVR.[VulnerabilityKey]", queryString);
            }
            public void WillSkipLastTimestampIfItWouldResultInPageOverflow()
            {
                // Arrange
                const int top      = 20;
                var       utcNow   = DateTime.UtcNow;
                var       packages = new List <FeedPackageDetails>();

                // Ensure the top 19 timestamps have a package each.
                for (int i = 1; i < top; i++)
                {
                    packages.Add(new FeedPackageDetails(
                                     new Uri($"https://unittest.org/packages/Package.Id{i}/1.0.{i}"),
                                     createdDate: utcNow.AddDays(-i),
                                     lastEditedDate: utcNow.AddDays(-i),
                                     publishedDate: utcNow.AddDays(-i),
                                     packageId: $"Package.Id{i}",
                                     packageNormalizedVersion: $"1.0.{i}",
                                     packageFullVersion: $"1.0.{i}"));
                }

                // Ensure the last timestamp has enough packages to have it exceed the max page size.
                // This simulates TOP 20 WITH TIES behavior encountering bulk changes to these packages
                var lastTimestamp = utcNow.AddHours(-8);

                for (int i = 0; i < CatalogConstants.MaxPageSize - top + 2; i++)
                {
                    packages.Add(new FeedPackageDetails(
                                     new Uri($"https://unittest.org/packages/BatchUpdatedPackage.Id/1.0.{i}"),
                                     createdDate: utcNow.AddHours(-9),
                                     lastEditedDate: lastTimestamp,
                                     publishedDate: utcNow.AddHours(-9),
                                     packageId: "BatchUpdatedPackage.Id",
                                     packageNormalizedVersion: $"1.0.{i}",
                                     packageFullVersion: $"1.0.{i}"));
                }

                // Act
                var orderedByLastEditedDate = GalleryDatabaseQueryService.OrderPackagesByKeyDate(packages, p => p.LastEditedDate);

                // Assert
                Assert.Equal(top - 1, orderedByLastEditedDate.Count);
                Assert.DoesNotContain(lastTimestamp, orderedByLastEditedDate.Keys);
                Assert.True(orderedByLastEditedDate.Values.Sum(v => v.Count) <= CatalogConstants.MaxPageSize);
            }
            public void WillNotSkipSingleTimestampIfThatWouldResultInPageOverflow()
            {
                // Arrange
                var utcNow   = DateTime.UtcNow;
                var packages = new List <FeedPackageDetails>();

                // Ensure the first timestamp has enough packages to overflow.
                var timestampForBulkChanges = utcNow.AddHours(-8);

                for (int i = 0; i < CatalogConstants.MaxPageSize + 1; i++)
                {
                    packages.Add(new FeedPackageDetails(
                                     new Uri($"https://unittest.org/packages/BatchUpdatedPackage.Id{i}/1.0.{i}"),
                                     createdDate: utcNow.AddDays(-i),
                                     lastEditedDate: timestampForBulkChanges,
                                     publishedDate: utcNow.AddDays(-i),
                                     packageId: $"BatchUpdatedPackage.Id{i}",
                                     packageNormalizedVersion: $"1.0.{i}",
                                     packageFullVersion: $"1.0.{i}"));
                }

                // Add 19 more timestamps to simulate top 20.
                for (int i = 0; i < 19; i++)
                {
                    packages.Add(new FeedPackageDetails(
                                     new Uri($"https://unittest.org/packages/Package.Id/1.0.{i}"),
                                     createdDate: utcNow.AddHours(-9),
                                     lastEditedDate: utcNow.AddMinutes(-i),
                                     publishedDate: utcNow.AddHours(-9),
                                     packageId: "Package.Id",
                                     packageNormalizedVersion: $"1.0.{i}",
                                     packageFullVersion: $"1.0.{i}"));
                }

                // Act
                var orderedByLastEditedDate = GalleryDatabaseQueryService.OrderPackagesByKeyDate(packages, p => p.LastEditedDate);

                // Assert
                Assert.Single(orderedByLastEditedDate);
                Assert.Equal(timestampForBulkChanges, orderedByLastEditedDate.Single().Key);
                Assert.True(orderedByLastEditedDate.Values.Sum(v => v.Count) >= CatalogConstants.MaxPageSize);
            }
            public void OrdersBySelectedPropertyDescending()
            {
                // Arrange
                var utcNow = DateTime.UtcNow;
                var firstCreatedPackage = new FeedPackageDetails(
                    new Uri("https://unittest.org/packages/Package.Id/1.0.1"),
                    createdDate: utcNow.AddDays(-2),
                    lastEditedDate: utcNow,
                    publishedDate: utcNow.AddDays(-2),
                    packageId: "Package.Id",
                    packageNormalizedVersion: "1.0.1",
                    packageFullVersion: "1.0.1");
                var firstEditedPackage = new FeedPackageDetails(
                    new Uri("https://unittest.org/packages/Package.Id/1.0.0"),
                    createdDate: utcNow.AddDays(-1),
                    lastEditedDate: utcNow.AddHours(-8),
                    publishedDate: utcNow.AddDays(-1),
                    packageId: "Package.Id",
                    packageNormalizedVersion: "1.0.0",
                    packageFullVersion: "1.0.0");

                var packages = new List <FeedPackageDetails>
                {
                    firstCreatedPackage,
                    firstEditedPackage
                };

                // Act
                var orderedByCreatedDate    = GalleryDatabaseQueryService.OrderPackagesByKeyDate(packages, p => p.CreatedDate);
                var orderedByLastEditedDate = GalleryDatabaseQueryService.OrderPackagesByKeyDate(packages, p => p.LastEditedDate);

                // Assert
                Assert.Equal(firstCreatedPackage.CreatedDate, orderedByCreatedDate.First().Key);
                Assert.Equal(1, orderedByCreatedDate.First().Value.Count);
                Assert.Contains(firstCreatedPackage, orderedByCreatedDate.First().Value);

                Assert.Equal(firstEditedPackage.LastEditedDate, orderedByLastEditedDate.First().Key);
                Assert.Equal(1, orderedByLastEditedDate.First().Value.Count);
                Assert.Contains(firstEditedPackage, orderedByLastEditedDate.First().Value);
            }
Esempio n. 12
0
        protected override void Init(IDictionary <string, string> arguments, CancellationToken cancellationToken)
        {
            var gallery                    = arguments.GetOrThrow <string>(Arguments.Gallery);
            var index                      = arguments.GetOrThrow <string>(Arguments.Index);
            var packageBaseAddress         = arguments.GetOrThrow <string>(Arguments.ContentBaseAddress);
            var source                     = arguments.GetOrThrow <string>(Arguments.Source);
            var requireRepositorySignature = arguments.GetOrDefault(Arguments.RequireRepositorySignature, false);
            var verbose                    = arguments.GetOrDefault(Arguments.Verbose, false);

            var timeoutInSeconds = arguments.GetOrDefault(Arguments.SqlCommandTimeoutInSeconds, 300);
            var sqlTimeout       = TimeSpan.FromSeconds(timeoutInSeconds);

            var connectionString    = arguments.GetOrThrow <string>(Arguments.ConnectionString);
            var galleryDbConnection = new AzureSqlConnectionFactory(
                connectionString,
                SecretInjector,
                LoggerFactory.CreateLogger <AzureSqlConnectionFactory>());
            var packageContentUriBuilder = new PackageContentUriBuilder(
                arguments.GetOrThrow <string>(Arguments.PackageContentUrlFormat));
            var galleryDatabase = new GalleryDatabaseQueryService(
                galleryDbConnection,
                packageContentUriBuilder,
                TelemetryService,
                timeoutInSeconds);

            CommandHelpers.AssertAzureStorage(arguments);

            var monitoringStorageFactory = CommandHelpers.CreateStorageFactory(arguments, verbose);
            var auditingStorageFactory   = CommandHelpers.CreateSuffixedStorageFactory("Auditing", arguments, verbose);

            var endpointConfiguration = CommandHelpers.GetEndpointConfiguration(arguments);
            var messageHandlerFactory = CommandHelpers.GetHttpMessageHandlerFactory(TelemetryService, verbose);

            Logger.LogInformation(
                "CONFIG gallery: {Gallery} index: {Index} storage: {Storage} auditingStorage: {AuditingStorage} registration cursor uri: {RegistrationCursorUri} flat-container cursor uri: {FlatContainerCursorUri}",
                gallery, index, monitoringStorageFactory, auditingStorageFactory, endpointConfiguration.RegistrationCursorUri, endpointConfiguration.FlatContainerCursorUri);

            var validatorConfig = new ValidatorConfiguration(
                packageBaseAddress,
                requireRepositorySignature);

            _packageValidator = ValidationFactory.CreatePackageValidator(
                gallery,
                index,
                auditingStorageFactory,
                validatorConfig,
                endpointConfiguration,
                messageHandlerFactory,
                galleryDatabase,
                LoggerFactory);

            _queue = CommandHelpers.CreateStorageQueue <PackageValidatorContext>(arguments, PackageValidatorContext.Version);

            _statusService = CommandHelpers.GetPackageMonitoringStatusService(arguments, monitoringStorageFactory, LoggerFactory);

            _notificationService = new LoggerMonitoringNotificationService(LoggerFactory.CreateLogger <LoggerMonitoringNotificationService>());

            _client = new CollectorHttpClient(messageHandlerFactory());

            _queueLoopDuration = TimeSpan.FromHours(
                arguments.GetOrDefault(
                    Arguments.QueueLoopDurationHours,
                    DefaultQueueLoopDurationHours));

            _queueDelay = TimeSpan.FromSeconds(
                arguments.GetOrDefault(
                    Arguments.QueueDelaySeconds,
                    DefaultQueueDelaySeconds));

            _workerCount = arguments.GetOrDefault(Arguments.WorkerCount, DefaultWorkerCount);

            SetUserAgentString();
        }