public async Task GetCatalogPropertiesAsync_ThrowsIfCancelled() { await Assert.ThrowsAsync <OperationCanceledException>( () => FeedHelpers.GetCatalogPropertiesAsync( Mock.Of <IStorage>(), Mock.Of <ITelemetryService>(), new CancellationToken(canceled: true))); }
public async Task GetCatalogPropertiesAsync_ThrowsForNullTelemetryService() { var exception = await Assert.ThrowsAsync <ArgumentNullException>( () => FeedHelpers.GetCatalogPropertiesAsync( storage: Mock.Of <IStorage>(), telemetryService: null, cancellationToken: CancellationToken.None)); Assert.Equal("telemetryService", exception.ParamName); }
private static async Task VerifyPropertyAsync(string json, Action <CatalogProperties> propertyVerifier) { var storage = CreateStorageMock(json); var catalogProperties = await FeedHelpers.GetCatalogPropertiesAsync( storage.Object, Mock.Of <ITelemetryService>(), CancellationToken.None); Assert.NotNull(catalogProperties); propertyVerifier(catalogProperties); storage.Verify(); }
public async Task GetCatalogPropertiesAsync_ReturnsNullPropertiesIfPropertiesMissing() { var storage = CreateStorageMock(json: "{}"); var catalogProperties = await FeedHelpers.GetCatalogPropertiesAsync( storage.Object, Mock.Of <ITelemetryService>(), CancellationToken.None); Assert.NotNull(catalogProperties); Assert.Null(catalogProperties.LastCreated); Assert.Null(catalogProperties.LastDeleted); Assert.Null(catalogProperties.LastEdited); storage.Verify(); }
protected override async Task RunInternalAsync(CancellationToken cancellationToken) { var timeout = TimeSpan.FromSeconds(300); using (var client = CreateHttpClient()) { client.Timeout = timeout; // if the version is specified a single package is processed otherwise all the packages corresponding to that id are processed var uri = (_version == null) ? MakePackageUri(_gallery, _id) : MakePackageUri(_gallery, _id, _version); var packages = await FeedHelpers.GetPackagesInOrder(client, uri, package => package.CreatedDate); Logger.LogInformation($"Downloading {packages.Select(t => t.Value.Count).Sum()} packages"); // the idea here is to leave the lastCreated, lastEdited and lastDeleted values exactly as they were var catalogProperties = await FeedHelpers.GetCatalogPropertiesAsync(_storage, TelemetryService, cancellationToken); var lastCreated = catalogProperties.LastCreated ?? DateTime.MinValue.ToUniversalTime(); var lastEdited = catalogProperties.LastEdited ?? DateTime.MinValue.ToUniversalTime(); var lastDeleted = catalogProperties.LastDeleted ?? DateTime.MinValue.ToUniversalTime(); var packageCatalogItemCreator = PackageCatalogItemCreator.Create( client, TelemetryService, Logger, storage: null); await FeedHelpers.DownloadMetadata2CatalogAsync( packageCatalogItemCreator, packages, _storage, lastCreated, lastEdited, lastDeleted, MaxDegreeOfParallelism, createdPackages : null, updateCreatedFromEdited : false, cancellationToken : cancellationToken, telemetryService : TelemetryService, logger : Logger); } }
public async Task GetCatalogPropertiesAsync_ReturnsAllPropertiesIfAllPropertiesSet() { var datetimeOffset = CreateDateTimeOffset(TimeSpan.Zero); var json = $"{{\"nuget:lastCreated\":\"{(datetimeOffset.ToString("O"))}\"," + $"\"nuget:lastDeleted\":\"{(datetimeOffset.ToString("O"))}\"," + $"\"nuget:lastEdited\":\"{(datetimeOffset.ToString("O"))}\"}}"; var storage = CreateStorageMock(json); var catalogProperties = await FeedHelpers.GetCatalogPropertiesAsync( storage.Object, Mock.Of <ITelemetryService>(), CancellationToken.None); Assert.NotNull(catalogProperties); Assert.NotNull(catalogProperties.LastCreated); Assert.NotNull(catalogProperties.LastDeleted); Assert.NotNull(catalogProperties.LastEdited); Assert.Equal(datetimeOffset, catalogProperties.LastCreated.Value); Assert.Equal(datetimeOffset, catalogProperties.LastDeleted.Value); Assert.Equal(datetimeOffset, catalogProperties.LastEdited.Value); storage.Verify(); }
protected override async Task RunInternalAsync(CancellationToken cancellationToken) { using (Logger.BeginScope($"Logging for {{{TelemetryConstants.Destination}}}", Destination.AbsoluteUri)) using (TelemetryService.TrackDuration(TelemetryConstants.JobLoopSeconds)) using (var client = CreateHttpClient()) { uint packagesDeleted; uint packagesCreated; uint packagesEdited; client.Timeout = Timeout; var packageCatalogItemCreator = PackageCatalogItemCreator.Create( client, TelemetryService, Logger, PreferredPackageSourceStorage); do { packagesDeleted = 0; packagesCreated = 0; packagesEdited = 0; // baseline timestamps var catalogProperties = await FeedHelpers.GetCatalogPropertiesAsync(CatalogStorage, TelemetryService, cancellationToken); var lastCreated = catalogProperties.LastCreated ?? (StartDate ?? Constants.DateTimeMinValueUtc); var lastEdited = catalogProperties.LastEdited ?? lastCreated; var lastDeleted = catalogProperties.LastDeleted ?? lastCreated; if (lastDeleted == Constants.DateTimeMinValueUtc) { lastDeleted = SkipCreatedPackagesProcessing ? lastEdited : lastCreated; } try { if (lastDeleted > Constants.DateTimeMinValueUtc) { using (TelemetryService.TrackDuration(TelemetryConstants.DeletedPackagesSeconds)) { Logger.LogInformation("CATALOG LastDeleted: {CatalogDeletedTime}", lastDeleted.ToString("O")); var deletedPackages = await GetDeletedPackages(AuditingStorage, lastDeleted); packagesDeleted = (uint)deletedPackages.SelectMany(x => x.Value).Count(); Logger.LogInformation("FEED DeletedPackages: {DeletedPackagesCount}", packagesDeleted); // We want to ensure a commit only contains each package once at most. // Therefore we segment by package id + version. var deletedPackagesSegments = SegmentPackageDeletes(deletedPackages); foreach (var deletedPackagesSegment in deletedPackagesSegments) { lastDeleted = await Deletes2Catalog( deletedPackagesSegment, CatalogStorage, lastCreated, lastEdited, lastDeleted, cancellationToken); // Wait for one second to ensure the next catalog commit gets a new timestamp Thread.Sleep(TimeSpan.FromSeconds(1)); } } } if (!SkipCreatedPackagesProcessing) { using (TelemetryService.TrackDuration(TelemetryConstants.CreatedPackagesSeconds)) { Logger.LogInformation("CATALOG LastCreated: {CatalogLastCreatedTime}", lastCreated.ToString("O")); var createdPackages = await GetCreatedPackages(client, Gallery, lastCreated, Top); packagesCreated = (uint)createdPackages.SelectMany(x => x.Value).Count(); Logger.LogInformation("FEED CreatedPackages: {CreatedPackagesCount}", packagesCreated); lastCreated = await FeedHelpers.DownloadMetadata2CatalogAsync( packageCatalogItemCreator, createdPackages, CatalogStorage, lastCreated, lastEdited, lastDeleted, MaxDegreeOfParallelism, createdPackages : true, updateCreatedFromEdited : false, cancellationToken : cancellationToken, telemetryService : TelemetryService, logger : Logger); } } using (TelemetryService.TrackDuration(TelemetryConstants.EditedPackagesSeconds)) { Logger.LogInformation("CATALOG LastEdited: {CatalogLastEditedTime}", lastEdited.ToString("O")); var editedPackages = await GetEditedPackages(client, Gallery, lastEdited, Top); packagesEdited = (uint)editedPackages.SelectMany(x => x.Value).Count(); Logger.LogInformation("FEED EditedPackages: {EditedPackagesCount}", packagesEdited); lastEdited = await FeedHelpers.DownloadMetadata2CatalogAsync( packageCatalogItemCreator, editedPackages, CatalogStorage, lastCreated, lastEdited, lastDeleted, MaxDegreeOfParallelism, createdPackages : false, updateCreatedFromEdited : SkipCreatedPackagesProcessing, cancellationToken : cancellationToken, telemetryService : TelemetryService, logger : Logger); } } finally { TelemetryService.TrackMetric(TelemetryConstants.DeletedPackagesCount, packagesDeleted); if (!SkipCreatedPackagesProcessing) { TelemetryService.TrackMetric(TelemetryConstants.CreatedPackagesCount, packagesCreated); } TelemetryService.TrackMetric(TelemetryConstants.EditedPackagesCount, packagesEdited); } } while (packagesDeleted > 0 || packagesCreated > 0 || packagesEdited > 0); } }