From 45f07fe64b6af6fca7960d6e1c4bd5769e4ff617 Mon Sep 17 00:00:00 2001 From: Scott Bommarito Date: Fri, 14 Jun 2019 10:22:33 -0700 Subject: [PATCH] Add RegistrationDeprecationValidator to verify deprecation changes are properly consumed (#554) --- src/Catalog/Helpers/Db2CatalogProjection.cs | 3 +- .../Db2CatalogProjectionColumnNames.cs | 1 + src/Catalog/Helpers/FeedHelpers.cs | 100 ------------- src/Catalog/Helpers/FeedPackageDetails.cs | 8 +- .../Helpers/GalleryDatabaseQueryService.cs | 1 + src/Catalog/Helpers/JsonSort.cs | 2 - src/Catalog/Helpers/UriUtils.cs | 2 - src/Catalog/Helpers/XsltHelper.cs | 2 - src/Catalog/PackageCatalogItem.cs | 5 +- src/Catalog/SingleGraphPersistence.cs | 1 - .../VerboseFileSystemEmulatorHandler.cs | 1 - src/Ng/Jobs/Catalog2PackageFixupJob.cs | 1 - src/Ng/Jobs/ClearLuceneJob.cs | 1 - src/Ng/Jobs/MonitoringProcessorJob.cs | 2 +- .../ExceptionTrackingMiddleware.cs | 1 - src/NuGet.Indexing/ChainedFilter.cs | 2 - src/NuGet.Indexing/DescriptionAnalyzer.cs | 1 - src/NuGet.Indexing/DownloadsByVersion.cs | 1 - src/NuGet.Indexing/FileLoader.cs | 1 - src/NuGet.Indexing/IndexConsistencyReport.cs | 4 - .../IIndexDirectoryProvider.cs | 3 +- .../LocalIndexDirectoryProvider.cs | 3 +- src/NuGet.Indexing/KeyCollector.cs | 1 - src/NuGet.Indexing/OwnerAnalyzer.cs | 1 - src/NuGet.Indexing/PerfEventTracker.cs | 3 - src/NuGet.Indexing/SearcherManagerT.cs | 1 - src/NuGet.Indexing/SegmentInfoEventArgs.cs | 1 - src/NuGet.Indexing/TenantFilter.cs | 1 - src/NuGet.Indexing/TypeFilter.cs | 2 - .../Configuration/SecretReaderFactory.cs | 1 - ...ageRegistrationAlternatePackageMetadata.cs | 27 ++++ .../PackageRegistrationDeprecationMetadata.cs | 31 ++++ .../Model/PackageRegistrationIndexMetadata.cs | 52 +++---- .../Model/PackageRegistrationLeafMetadata.cs | 13 +- ...ervices.Metadata.Catalog.Monitoring.csproj | 12 +- ...rationMetadataResourceDatabaseProvider.cs} | 16 +-- ...estampMetadataResourceDatabaseProvider.cs} | 10 +- ...egistrationMetadataResourceDatabaseFeed.cs | 60 ++++++++ ...ckageRegistrationMetadataResourceV2Feed.cs | 70 --------- ...ckageTimestampMetadataResourceDatabase.cs} | 8 +- .../Utility/ContainerBuilderExtensions.cs | 7 +- ...AggregateMetadataInconsistencyException.cs | 22 +++ .../MetadataFieldInconsistencyException.cs | 13 +- .../MetadataInconsistencyException.cs | 14 +- .../TimestampComparisonException.cs | 8 +- .../RegistrationDeprecationValidator.cs | 135 ++++++++++++++++++ .../RegistrationExistsValidator.cs | 14 +- .../Registration/RegistrationIdValidator.cs | 6 +- .../RegistrationIndexValidator.cs | 16 +-- .../Registration/RegistrationLeafValidator.cs | 24 ++-- .../RegistrationListedValidator.cs | 10 +- ...rationRequireLicenseAcceptanceValidator.cs | 6 +- .../RegistrationVersionValidator.cs | 6 +- .../Validation/Test/ValidationContext.cs | 32 ++--- .../Validation/Test/Validator.cs | 24 ++-- .../Properties/AssemblyInfo.cs | 1 - tests/CatalogTests/CatalogTests.csproj | 1 - .../Helpers/Db2CatalogProjectionTests.cs | 14 +- tests/CatalogTests/Properties/AssemblyInfo.cs | 1 - .../RegistrationMakerCatalogItemTests.cs | 1 - tests/NgTests/Db2CatalogTests.cs | 6 +- tests/NgTests/NgTests.csproj | 1 + ...egistrationDeprecationValidatorTestData.cs | 113 +++++++++++++++ .../RegistrationVersionValidatorTestData.cs | 6 +- .../Validation/ValidationContextTests.cs | 18 +-- .../Properties/AssemblyInfo.cs | 1 - .../TestSupport/MockSearcher.cs | 1 - .../NuGet.IndexingTests/VersionResultTests.cs | 1 - .../CatalogClientFacts.cs | 1 - .../DictionaryConfigurationProvider.cs | 5 +- .../Properties/AssemblyInfo.cs | 1 - 71 files changed, 573 insertions(+), 392 deletions(-) create mode 100644 src/NuGet.Services.Metadata.Catalog.Monitoring/Model/PackageRegistrationAlternatePackageMetadata.cs create mode 100644 src/NuGet.Services.Metadata.Catalog.Monitoring/Model/PackageRegistrationDeprecationMetadata.cs rename src/NuGet.Services.Metadata.Catalog.Monitoring/Providers/{PackageRegistrationMetadataResourceV2FeedProvider.cs => PackageRegistrationMetadataResourceDatabaseProvider.cs} (64%) rename src/NuGet.Services.Metadata.Catalog.Monitoring/Providers/{PackageTimestampMetadataResourceV2Provider.cs => PackageTimestampMetadataResourceDatabaseProvider.cs} (81%) create mode 100644 src/NuGet.Services.Metadata.Catalog.Monitoring/Resources/PackageRegistrationMetadataResourceDatabaseFeed.cs delete mode 100644 src/NuGet.Services.Metadata.Catalog.Monitoring/Resources/PackageRegistrationMetadataResourceV2Feed.cs rename src/NuGet.Services.Metadata.Catalog.Monitoring/Resources/{PackageTimestampMetadataResourceV2.cs => PackageTimestampMetadataResourceDatabase.cs} (88%) create mode 100644 src/NuGet.Services.Metadata.Catalog.Monitoring/Validation/Test/Exceptions/AggregateMetadataInconsistencyException.cs create mode 100644 src/NuGet.Services.Metadata.Catalog.Monitoring/Validation/Test/Registration/RegistrationDeprecationValidator.cs create mode 100644 tests/NgTests/Validation/RegistrationDeprecationValidatorTestData.cs diff --git a/src/Catalog/Helpers/Db2CatalogProjection.cs b/src/Catalog/Helpers/Db2CatalogProjection.cs index 3243d2db1..b678dbf40 100644 --- a/src/Catalog/Helpers/Db2CatalogProjection.cs +++ b/src/Catalog/Helpers/Db2CatalogProjection.cs @@ -49,7 +49,8 @@ public FeedPackageDetails ReadFeedPackageDetailsFromDataReader(DbDataReader data normalizedPackageVersion, hideLicenseReport ? null : dataReader[Db2CatalogProjectionColumnNames.LicenseNames]?.ToString(), hideLicenseReport ? null : dataReader[Db2CatalogProjectionColumnNames.LicenseReportUrl]?.ToString(), - deprecationInfo); + deprecationInfo, + dataReader.GetBoolean(dataReader.GetOrdinal(Db2CatalogProjectionColumnNames.RequiresLicenseAcceptance))); } public PackageDeprecationItem ReadDeprecationInfoFromDataReader(DbDataReader dataReader) diff --git a/src/Catalog/Helpers/Db2CatalogProjectionColumnNames.cs b/src/Catalog/Helpers/Db2CatalogProjectionColumnNames.cs index 013048a3f..272b7f4cf 100644 --- a/src/Catalog/Helpers/Db2CatalogProjectionColumnNames.cs +++ b/src/Catalog/Helpers/Db2CatalogProjectionColumnNames.cs @@ -21,5 +21,6 @@ public static class Db2CatalogProjectionColumnNames public const string AlternatePackageVersion = "AlternatePackageVersion"; public const string DeprecationStatus = "DeprecationStatus"; public const string DeprecationMessage = "DeprecationMessage"; + public const string RequiresLicenseAcceptance = "RequiresLicenseAcceptance"; } } \ No newline at end of file diff --git a/src/Catalog/Helpers/FeedHelpers.cs b/src/Catalog/Helpers/FeedHelpers.cs index 62a48abfd..28be296c2 100644 --- a/src/Catalog/Helpers/FeedHelpers.cs +++ b/src/Catalog/Helpers/FeedHelpers.cs @@ -2,11 +2,7 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; -using System.Collections.Generic; using System.Net.Http; -using System.Threading.Tasks; -using System.Web; -using System.Xml.Linq; namespace NuGet.Services.Metadata.Catalog.Helpers { @@ -23,101 +19,5 @@ public static HttpClient CreateHttpClient(Func handlerFunc) var handler = (handlerFunc != null) ? handlerFunc() : new WebRequestHandler { AllowPipelining = true }; return new HttpClient(handler); } - - /// - /// Builds a for accessing the metadata of a specific package on the feed. - /// - public static Uri MakeUriForPackage(string source, string id, string version) - { - var uri = new Uri($"{source.Trim('/')}/Packages(Id='{HttpUtility.UrlEncode(id)}',Version='{HttpUtility.UrlEncode(version)}')"); - return UriUtils.GetNonhijackableUri(uri); - } - - /// - /// Asynchronously gets a from the feed. - /// - /// An HTTP client. - /// The feed URI. - /// A task that represents the asynchronous operation. - /// The task result () returns an - /// . - public static async Task> GetPackages(HttpClient client, Uri uri) - { - const string createdDateProperty = "Created"; - const string lastEditedDateProperty = "LastEdited"; - const string publishedDateProperty = "Published"; - const string idProperty = "Id"; - const string normalizedVersionProperty = "NormalizedVersion"; - const string licenseNamesProperty = "LicenseNames"; - const string licenseReportUrlProperty = "LicenseReportUrl"; - - var packages = new List(); - - XElement feed; - try - { - using (var stream = await client.GetStreamAsync(uri)) - { - feed = XElement.Load(stream); - } - } - catch (TaskCanceledException tce) - { - // If the HTTP request timed out, a TaskCanceledException will be thrown. - throw new HttpClientTimeoutException($"HttpClient request timed out in {nameof(FeedHelpers.GetPackages)}.", tce); - } - - XNamespace atom = "http://www.w3.org/2005/Atom"; - XNamespace dataservices = "http://schemas.microsoft.com/ado/2007/08/dataservices"; - XNamespace metadata = "http://schemas.microsoft.com/ado/2007/08/dataservices/metadata"; - - foreach (var entry in feed.Elements(atom + "entry")) - { - var content = new Uri(entry.Element(atom + "content").Attribute("src").Value); - - var propertiesElement = entry.Element(metadata + "properties"); - - var packageIdElement = propertiesElement.Element(dataservices + idProperty); - var packageId = packageIdElement?.Value; - var packageNormalizedVersionElement = propertiesElement.Element(dataservices + normalizedVersionProperty); - var packageNormalizedVersion = packageNormalizedVersionElement?.Value; - - var createdElement = propertiesElement.Element(dataservices + createdDateProperty); - var createdValue = createdElement?.Value; - var createdDate = string.IsNullOrEmpty(createdValue) ? DateTime.MinValue : DateTime.Parse(createdValue); - - var lastEditedValue = propertiesElement.Element(dataservices + lastEditedDateProperty).Value; - var lastEditedDate = string.IsNullOrEmpty(lastEditedValue) ? DateTime.MinValue : DateTime.Parse(lastEditedValue); - - var publishedValue = propertiesElement.Element(dataservices + publishedDateProperty).Value; - var publishedDate = string.IsNullOrEmpty(publishedValue) ? createdDate : DateTime.Parse(publishedValue); - - // License details - var licenseNamesElement = propertiesElement.Element(dataservices + licenseNamesProperty); - var licenseNames = licenseNamesElement?.Value; - - var licenseReportUrlElement = propertiesElement.Element(dataservices + licenseReportUrlProperty); - var licenseReportUrl = licenseReportUrlElement?.Value; - - // NOTE that DateTime returned by the v2 feed does not have Z at the end even though it is in UTC. So, the DateTime kind is unspecified - // So, forcibly convert it to UTC here - createdDate = createdDate.ForceUtc(); - lastEditedDate = lastEditedDate.ForceUtc(); - publishedDate = publishedDate.ForceUtc(); - - packages.Add(new FeedPackageDetails( - content, - createdDate, - lastEditedDate, - publishedDate, - packageId, - packageNormalizedVersion, - licenseNames, - licenseReportUrl, - deprecationInfo: null)); - } - - return packages; - } } } \ No newline at end of file diff --git a/src/Catalog/Helpers/FeedPackageDetails.cs b/src/Catalog/Helpers/FeedPackageDetails.cs index adbecc566..0d2d94d5f 100644 --- a/src/Catalog/Helpers/FeedPackageDetails.cs +++ b/src/Catalog/Helpers/FeedPackageDetails.cs @@ -15,6 +15,7 @@ public sealed class FeedPackageDetails public string PackageVersion { get; } public string LicenseNames { get; } public string LicenseReportUrl { get; } + public bool RequiresLicenseAcceptance { get; } public PackageDeprecationItem DeprecationInfo { get; } public bool HasDeprecationInfo => DeprecationInfo != null; @@ -35,7 +36,8 @@ public FeedPackageDetails( packageVersion, licenseNames: null, licenseReportUrl: null, - deprecationInfo: null) + deprecationInfo: null, + requiresLicenseAcceptance: false) { } @@ -48,7 +50,8 @@ public FeedPackageDetails( string packageVersion, string licenseNames, string licenseReportUrl, - PackageDeprecationItem deprecationInfo) + PackageDeprecationItem deprecationInfo, + bool requiresLicenseAcceptance) { ContentUri = contentUri; CreatedDate = createdDate; @@ -59,6 +62,7 @@ public FeedPackageDetails( LicenseNames = licenseNames; LicenseReportUrl = licenseReportUrl; DeprecationInfo = deprecationInfo; + RequiresLicenseAcceptance = requiresLicenseAcceptance; } } } \ No newline at end of file diff --git a/src/Catalog/Helpers/GalleryDatabaseQueryService.cs b/src/Catalog/Helpers/GalleryDatabaseQueryService.cs index 1950479fc..3518def5c 100644 --- a/src/Catalog/Helpers/GalleryDatabaseQueryService.cs +++ b/src/Catalog/Helpers/GalleryDatabaseQueryService.cs @@ -29,6 +29,7 @@ public class GalleryDatabaseQueryService : IGalleryDatabaseQueryService P.[HideLicenseReport], P.[LicenseNames], P.[LicenseReportUrl], + P.[RequiresLicenseAcceptance], PD.[Status] AS '{Db2CatalogProjectionColumnNames.DeprecationStatus}', APR.[Id] AS '{Db2CatalogProjectionColumnNames.AlternatePackageId}', AP.[NormalizedVersion] AS '{Db2CatalogProjectionColumnNames.AlternatePackageVersion}', diff --git a/src/Catalog/Helpers/JsonSort.cs b/src/Catalog/Helpers/JsonSort.cs index adfd8a26e..0e147bebf 100644 --- a/src/Catalog/Helpers/JsonSort.cs +++ b/src/Catalog/Helpers/JsonSort.cs @@ -4,8 +4,6 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace NuGet.Services.Metadata.Catalog.Helpers { diff --git a/src/Catalog/Helpers/UriUtils.cs b/src/Catalog/Helpers/UriUtils.cs index 95bf0d8cb..f27a368b2 100644 --- a/src/Catalog/Helpers/UriUtils.cs +++ b/src/Catalog/Helpers/UriUtils.cs @@ -4,9 +4,7 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Net.Http; using System.Text.RegularExpressions; -using System.Threading.Tasks; using NuGet.Versioning; namespace NuGet.Services.Metadata.Catalog.Helpers diff --git a/src/Catalog/Helpers/XsltHelper.cs b/src/Catalog/Helpers/XsltHelper.cs index 3e474ee87..819016491 100644 --- a/src/Catalog/Helpers/XsltHelper.cs +++ b/src/Catalog/Helpers/XsltHelper.cs @@ -1,8 +1,6 @@ // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -using System.Collections.Generic; -using System.Linq; using System.Xml; using System.Xml.XPath; using NuGet.Services.Metadata.Catalog.Helpers; diff --git a/src/Catalog/PackageCatalogItem.cs b/src/Catalog/PackageCatalogItem.cs index 101b9cc4e..eebade807 100644 --- a/src/Catalog/PackageCatalogItem.cs +++ b/src/Catalog/PackageCatalogItem.cs @@ -152,13 +152,14 @@ public override IGraph CreateContentGraph(CatalogContext context) return graph; } - private bool GetListed(DateTime published) + public static bool GetListed(DateTime published) { //If the published date is 1900/01/01, then the package is unlisted - if (published.ToUniversalTime() == Convert.ToDateTime("1900-01-01T00:00:00Z").ToUniversalTime()) + if (published.ToUniversalTime() == Constants.UnpublishedDate) { return false; } + return true; } diff --git a/src/Catalog/SingleGraphPersistence.cs b/src/Catalog/SingleGraphPersistence.cs index 7aac5d314..4cb48ae83 100644 --- a/src/Catalog/SingleGraphPersistence.cs +++ b/src/Catalog/SingleGraphPersistence.cs @@ -4,7 +4,6 @@ using System; using System.Threading; using System.Threading.Tasks; -using Newtonsoft.Json.Linq; using NuGet.Services.Metadata.Catalog.Persistence; using VDS.RDF; diff --git a/src/Catalog/VerboseFileSystemEmulatorHandler.cs b/src/Catalog/VerboseFileSystemEmulatorHandler.cs index 882e14a4b..6cc2d72be 100644 --- a/src/Catalog/VerboseFileSystemEmulatorHandler.cs +++ b/src/Catalog/VerboseFileSystemEmulatorHandler.cs @@ -1,6 +1,5 @@ // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -using System; using System.Diagnostics; using System.Net.Http; using System.Threading; diff --git a/src/Ng/Jobs/Catalog2PackageFixupJob.cs b/src/Ng/Jobs/Catalog2PackageFixupJob.cs index 0adbf2934..901d89ccb 100644 --- a/src/Ng/Jobs/Catalog2PackageFixupJob.cs +++ b/src/Ng/Jobs/Catalog2PackageFixupJob.cs @@ -7,7 +7,6 @@ using System.Diagnostics; using System.Linq; using System.Net.Http; -using System.Reflection; using System.Threading; using System.Threading.Tasks; using Microsoft.Extensions.DependencyInjection; diff --git a/src/Ng/Jobs/ClearLuceneJob.cs b/src/Ng/Jobs/ClearLuceneJob.cs index 5fbbb904a..5711169e6 100644 --- a/src/Ng/Jobs/ClearLuceneJob.cs +++ b/src/Ng/Jobs/ClearLuceneJob.cs @@ -1,7 +1,6 @@ // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -using System; using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; diff --git a/src/Ng/Jobs/MonitoringProcessorJob.cs b/src/Ng/Jobs/MonitoringProcessorJob.cs index 01bd67349..c8cc0cded 100644 --- a/src/Ng/Jobs/MonitoringProcessorJob.cs +++ b/src/Ng/Jobs/MonitoringProcessorJob.cs @@ -122,7 +122,7 @@ protected override async Task RunInternalAsync(CancellationToken cancellationTok private async Task ProcessPackagesAsync(CancellationToken token) { - StorageQueueMessage queueMessage = null; + StorageQueueMessage queueMessage; do { Logger.LogInformation("Fetching next queue message."); diff --git a/src/NuGet.ApplicationInsights.Owin/ExceptionTrackingMiddleware.cs b/src/NuGet.ApplicationInsights.Owin/ExceptionTrackingMiddleware.cs index c700270d5..b4c74e51e 100644 --- a/src/NuGet.ApplicationInsights.Owin/ExceptionTrackingMiddleware.cs +++ b/src/NuGet.ApplicationInsights.Owin/ExceptionTrackingMiddleware.cs @@ -2,7 +2,6 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; -using System.ComponentModel; using System.Threading.Tasks; using Microsoft.ApplicationInsights; using Microsoft.ApplicationInsights.Extensibility; diff --git a/src/NuGet.Indexing/ChainedFilter.cs b/src/NuGet.Indexing/ChainedFilter.cs index 1a533297b..bf96dad8f 100644 --- a/src/NuGet.Indexing/ChainedFilter.cs +++ b/src/NuGet.Indexing/ChainedFilter.cs @@ -1,8 +1,6 @@ // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; -using System.Collections.Generic; -using System.Linq; using System.Text; using Lucene.Net.Search; diff --git a/src/NuGet.Indexing/DescriptionAnalyzer.cs b/src/NuGet.Indexing/DescriptionAnalyzer.cs index f6e2ab2da..e23a9461b 100644 --- a/src/NuGet.Indexing/DescriptionAnalyzer.cs +++ b/src/NuGet.Indexing/DescriptionAnalyzer.cs @@ -1,7 +1,6 @@ // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using Lucene.Net.Analysis; -using System.Collections.Generic; using System.IO; namespace NuGet.Indexing diff --git a/src/NuGet.Indexing/DownloadsByVersion.cs b/src/NuGet.Indexing/DownloadsByVersion.cs index 8b26899e9..ce7b957ba 100644 --- a/src/NuGet.Indexing/DownloadsByVersion.cs +++ b/src/NuGet.Indexing/DownloadsByVersion.cs @@ -3,7 +3,6 @@ using System; using System.Collections.Generic; -using System.Linq; namespace NuGet.Indexing { diff --git a/src/NuGet.Indexing/FileLoader.cs b/src/NuGet.Indexing/FileLoader.cs index 5307618d7..10f980fa0 100644 --- a/src/NuGet.Indexing/FileLoader.cs +++ b/src/NuGet.Indexing/FileLoader.cs @@ -4,7 +4,6 @@ using Newtonsoft.Json; using System.IO; using System; -using System.Threading.Tasks; namespace NuGet.Indexing { diff --git a/src/NuGet.Indexing/IndexConsistencyReport.cs b/src/NuGet.Indexing/IndexConsistencyReport.cs index c42002b06..75a2663b8 100644 --- a/src/NuGet.Indexing/IndexConsistencyReport.cs +++ b/src/NuGet.Indexing/IndexConsistencyReport.cs @@ -1,9 +1,5 @@ // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; using Newtonsoft.Json.Linq; namespace NuGet.Indexing diff --git a/src/NuGet.Indexing/IndexDirectoryProvider/IIndexDirectoryProvider.cs b/src/NuGet.Indexing/IndexDirectoryProvider/IIndexDirectoryProvider.cs index cf254e766..a864143d5 100644 --- a/src/NuGet.Indexing/IndexDirectoryProvider/IIndexDirectoryProvider.cs +++ b/src/NuGet.Indexing/IndexDirectoryProvider/IIndexDirectoryProvider.cs @@ -1,5 +1,4 @@ -using System.Threading.Tasks; -using Lucene.Net.Store; +using Lucene.Net.Store; namespace NuGet.Indexing.IndexDirectoryProvider { diff --git a/src/NuGet.Indexing/IndexDirectoryProvider/LocalIndexDirectoryProvider.cs b/src/NuGet.Indexing/IndexDirectoryProvider/LocalIndexDirectoryProvider.cs index 5f331370b..ffe811be4 100644 --- a/src/NuGet.Indexing/IndexDirectoryProvider/LocalIndexDirectoryProvider.cs +++ b/src/NuGet.Indexing/IndexDirectoryProvider/LocalIndexDirectoryProvider.cs @@ -1,5 +1,4 @@ -using System.Threading.Tasks; -using Lucene.Net.Store; +using Lucene.Net.Store; namespace NuGet.Indexing.IndexDirectoryProvider { diff --git a/src/NuGet.Indexing/KeyCollector.cs b/src/NuGet.Indexing/KeyCollector.cs index 3b02a9e95..daa033f91 100644 --- a/src/NuGet.Indexing/KeyCollector.cs +++ b/src/NuGet.Indexing/KeyCollector.cs @@ -1,7 +1,6 @@ // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using Lucene.Net.Search; -using Newtonsoft.Json.Linq; using System.Collections.Generic; namespace NuGet.Indexing diff --git a/src/NuGet.Indexing/OwnerAnalyzer.cs b/src/NuGet.Indexing/OwnerAnalyzer.cs index 01d60a64b..7e105e6f4 100644 --- a/src/NuGet.Indexing/OwnerAnalyzer.cs +++ b/src/NuGet.Indexing/OwnerAnalyzer.cs @@ -1,7 +1,6 @@ // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using Lucene.Net.Analysis; -using System.Collections.Generic; using System.IO; namespace NuGet.Indexing diff --git a/src/NuGet.Indexing/PerfEventTracker.cs b/src/NuGet.Indexing/PerfEventTracker.cs index 94f0a173e..75300e987 100644 --- a/src/NuGet.Indexing/PerfEventTracker.cs +++ b/src/NuGet.Indexing/PerfEventTracker.cs @@ -3,10 +3,7 @@ using System; using System.Collections.Concurrent; using System.Collections.Generic; -using System.Diagnostics; using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace NuGet.Indexing { diff --git a/src/NuGet.Indexing/SearcherManagerT.cs b/src/NuGet.Indexing/SearcherManagerT.cs index 9fcfd2bfe..8b1b1d877 100644 --- a/src/NuGet.Indexing/SearcherManagerT.cs +++ b/src/NuGet.Indexing/SearcherManagerT.cs @@ -6,7 +6,6 @@ using Lucene.Net.Index; using Lucene.Net.Search; using Lucene.Net.Store; -using System.Threading.Tasks; namespace NuGet.Indexing { diff --git a/src/NuGet.Indexing/SegmentInfoEventArgs.cs b/src/NuGet.Indexing/SegmentInfoEventArgs.cs index f82708ead..3db9a7ba6 100644 --- a/src/NuGet.Indexing/SegmentInfoEventArgs.cs +++ b/src/NuGet.Indexing/SegmentInfoEventArgs.cs @@ -3,7 +3,6 @@ using System; using System.Collections.Generic; -using System.Linq; namespace NuGet.Indexing { diff --git a/src/NuGet.Indexing/TenantFilter.cs b/src/NuGet.Indexing/TenantFilter.cs index 47526ca16..56943e9c3 100644 --- a/src/NuGet.Indexing/TenantFilter.cs +++ b/src/NuGet.Indexing/TenantFilter.cs @@ -3,7 +3,6 @@ using Lucene.Net.Index; using Lucene.Net.Search; using Lucene.Net.Util; -using System; namespace NuGet.Indexing { diff --git a/src/NuGet.Indexing/TypeFilter.cs b/src/NuGet.Indexing/TypeFilter.cs index 472818e37..4b0af5582 100644 --- a/src/NuGet.Indexing/TypeFilter.cs +++ b/src/NuGet.Indexing/TypeFilter.cs @@ -2,8 +2,6 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using Lucene.Net.Index; using Lucene.Net.Search; -using Lucene.Net.Util; -using System; namespace NuGet.Indexing { diff --git a/src/NuGet.Services.BasicSearch/Configuration/SecretReaderFactory.cs b/src/NuGet.Services.BasicSearch/Configuration/SecretReaderFactory.cs index 8bef6b696..ae7fd865d 100644 --- a/src/NuGet.Services.BasicSearch/Configuration/SecretReaderFactory.cs +++ b/src/NuGet.Services.BasicSearch/Configuration/SecretReaderFactory.cs @@ -2,7 +2,6 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; -using System.Security.Cryptography.X509Certificates; using System.Threading.Tasks; using NuGet.Services.Configuration; using NuGet.Services.KeyVault; diff --git a/src/NuGet.Services.Metadata.Catalog.Monitoring/Model/PackageRegistrationAlternatePackageMetadata.cs b/src/NuGet.Services.Metadata.Catalog.Monitoring/Model/PackageRegistrationAlternatePackageMetadata.cs new file mode 100644 index 000000000..330b2abab --- /dev/null +++ b/src/NuGet.Services.Metadata.Catalog.Monitoring/Model/PackageRegistrationAlternatePackageMetadata.cs @@ -0,0 +1,27 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +namespace NuGet.Services.Metadata.Catalog.Monitoring.Model +{ + public class PackageRegistrationAlternatePackageMetadata + { + public string Id { get; set; } + public string Range { get; set; } + + /// + /// Default constructor for JSON serialization purposes. + /// + public PackageRegistrationAlternatePackageMetadata() + { + } + + /// + /// Converts a into a format that can be directly compared to a . + /// + public PackageRegistrationAlternatePackageMetadata(PackageDeprecationItem deprecation) + { + Id = deprecation.AlternatePackageId; + Range = deprecation.AlternatePackageRange; + } + } +} diff --git a/src/NuGet.Services.Metadata.Catalog.Monitoring/Model/PackageRegistrationDeprecationMetadata.cs b/src/NuGet.Services.Metadata.Catalog.Monitoring/Model/PackageRegistrationDeprecationMetadata.cs new file mode 100644 index 000000000..1cd6b4ea9 --- /dev/null +++ b/src/NuGet.Services.Metadata.Catalog.Monitoring/Model/PackageRegistrationDeprecationMetadata.cs @@ -0,0 +1,31 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.Collections.Generic; + +namespace NuGet.Services.Metadata.Catalog.Monitoring.Model +{ + public class PackageRegistrationDeprecationMetadata + { + public IEnumerable Reasons { get; set; } + public string Message { get; set; } + public PackageRegistrationAlternatePackageMetadata AlternatePackage { get; set; } + + /// + /// Default constructor for JSON serialization purposes. + /// + public PackageRegistrationDeprecationMetadata() + { + } + + /// + /// Converts a into a format that can be directly compared to a . + /// + public PackageRegistrationDeprecationMetadata(PackageDeprecationItem deprecation) + { + Reasons = deprecation.Reasons; + Message = deprecation.Message; + AlternatePackage = new PackageRegistrationAlternatePackageMetadata(deprecation); + } + } +} diff --git a/src/NuGet.Services.Metadata.Catalog.Monitoring/Model/PackageRegistrationIndexMetadata.cs b/src/NuGet.Services.Metadata.Catalog.Monitoring/Model/PackageRegistrationIndexMetadata.cs index f57bee498..295e417af 100644 --- a/src/NuGet.Services.Metadata.Catalog.Monitoring/Model/PackageRegistrationIndexMetadata.cs +++ b/src/NuGet.Services.Metadata.Catalog.Monitoring/Model/PackageRegistrationIndexMetadata.cs @@ -1,10 +1,10 @@ // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -using System.Collections.Generic; -using System.Linq; using Newtonsoft.Json; using NuGet.Protocol; +using NuGet.Services.Metadata.Catalog.Helpers; +using NuGet.Services.Metadata.Catalog.Monitoring.Model; using NuGet.Versioning; namespace NuGet.Services.Metadata.Catalog.Monitoring @@ -14,31 +14,17 @@ namespace NuGet.Services.Metadata.Catalog.Monitoring /// public class PackageRegistrationIndexMetadata : PackageRegistrationLeafMetadata { - public string Authors { get; set; } - - public string Description { get; set; } - - public string IconUrl { get; set; } - public string Id { get; set; } - public string LicenseUrl { get; set; } - - [JsonConverter(typeof(NullableNuGetVersionConverter))] - public NuGetVersion MinClientVersion { get; set; } - - public string ProjectUrl { get; set; } + [JsonConverter(typeof(NuGetVersionConverter))] + public NuGetVersion Version { get; set; } + /// + /// In the database, this property is called "RequiresLicenseAcceptance" (notice the "s"). + /// public bool RequireLicenseAcceptance { get; set; } - public string Summary { get; set; } - - public IEnumerable Tags { get; set; } - - public string Title { get; set; } - - [JsonConverter(typeof(NuGetVersionConverter))] - public NuGetVersion Version { get; set; } + public PackageRegistrationDeprecationMetadata Deprecation { get; set; } /// /// Default constructor for JSON serialization purposes. @@ -48,22 +34,18 @@ public PackageRegistrationIndexMetadata() } /// - /// Converts a into a format that can be directly compared to a . + /// Converts a into a format that can be directly compared to a . /// - public PackageRegistrationIndexMetadata(V2FeedPackageInfo package) + public PackageRegistrationIndexMetadata(FeedPackageDetails package) : base(package) { - Authors = string.Join(", ", package.Authors); - Description = package.Description; - IconUrl = package.IconUrl; - Id = package.Id; - MinClientVersion = package.MinClientVersion; - ProjectUrl = package.ProjectUrl; - RequireLicenseAcceptance = package.RequireLicenseAcceptance; - Summary = package.Summary; - Tags = package.Tags.Split(' ').Where(s => !string.IsNullOrEmpty(s)).ToArray(); - Title = package.Title; - Version = package.Version; + Id = package.PackageId; + Version = NuGetVersion.Parse(package.PackageVersion); + RequireLicenseAcceptance = package.RequiresLicenseAcceptance; + if (package.HasDeprecationInfo) + { + Deprecation = new PackageRegistrationDeprecationMetadata(package.DeprecationInfo); + } } } } diff --git a/src/NuGet.Services.Metadata.Catalog.Monitoring/Model/PackageRegistrationLeafMetadata.cs b/src/NuGet.Services.Metadata.Catalog.Monitoring/Model/PackageRegistrationLeafMetadata.cs index bef6d24bf..f186529ee 100644 --- a/src/NuGet.Services.Metadata.Catalog.Monitoring/Model/PackageRegistrationLeafMetadata.cs +++ b/src/NuGet.Services.Metadata.Catalog.Monitoring/Model/PackageRegistrationLeafMetadata.cs @@ -2,7 +2,7 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; -using NuGet.Protocol; +using NuGet.Services.Metadata.Catalog.Helpers; namespace NuGet.Services.Metadata.Catalog.Monitoring { @@ -14,8 +14,6 @@ public class PackageRegistrationLeafMetadata { public bool Listed { get; set; } - public string PackageContent { get; set; } - public DateTimeOffset? Published { get; set; } /// @@ -26,13 +24,12 @@ public PackageRegistrationLeafMetadata() } /// - /// Converts a into a format that can be directly compared to a . + /// Converts a into a format that can be directly compared to a . /// - public PackageRegistrationLeafMetadata(V2FeedPackageInfo package) + public PackageRegistrationLeafMetadata(FeedPackageDetails package) { - Listed = package.IsListed; - PackageContent = package.DownloadUrl; - Published = package.Published; + Listed = PackageCatalogItem.GetListed(package.PublishedDate); + Published = package.PublishedDate; } } } diff --git a/src/NuGet.Services.Metadata.Catalog.Monitoring/NuGet.Services.Metadata.Catalog.Monitoring.csproj b/src/NuGet.Services.Metadata.Catalog.Monitoring/NuGet.Services.Metadata.Catalog.Monitoring.csproj index 4b5a6dad3..85aeebd1e 100644 --- a/src/NuGet.Services.Metadata.Catalog.Monitoring/NuGet.Services.Metadata.Catalog.Monitoring.csproj +++ b/src/NuGet.Services.Metadata.Catalog.Monitoring/NuGet.Services.Metadata.Catalog.Monitoring.csproj @@ -54,6 +54,8 @@ + + @@ -63,14 +65,14 @@ - + - + - + - + @@ -90,6 +92,8 @@ + + diff --git a/src/NuGet.Services.Metadata.Catalog.Monitoring/Providers/PackageRegistrationMetadataResourceV2FeedProvider.cs b/src/NuGet.Services.Metadata.Catalog.Monitoring/Providers/PackageRegistrationMetadataResourceDatabaseProvider.cs similarity index 64% rename from src/NuGet.Services.Metadata.Catalog.Monitoring/Providers/PackageRegistrationMetadataResourceV2FeedProvider.cs rename to src/NuGet.Services.Metadata.Catalog.Monitoring/Providers/PackageRegistrationMetadataResourceDatabaseProvider.cs index 1ae3bd732..99b6d9a33 100644 --- a/src/NuGet.Services.Metadata.Catalog.Monitoring/Providers/PackageRegistrationMetadataResourceV2FeedProvider.cs +++ b/src/NuGet.Services.Metadata.Catalog.Monitoring/Providers/PackageRegistrationMetadataResourceDatabaseProvider.cs @@ -6,15 +6,20 @@ using System.Threading.Tasks; using NuGet.Protocol; using NuGet.Protocol.Core.Types; +using NuGet.Services.Metadata.Catalog.Helpers; namespace NuGet.Services.Metadata.Catalog.Monitoring { - public class PackageRegistrationMetadataResourceV2FeedProvider : ResourceProvider + public class PackageRegistrationMetadataResourceDatabaseFeedProvider : ResourceProvider { - public PackageRegistrationMetadataResourceV2FeedProvider() : + private readonly IGalleryDatabaseQueryService _queryService; + + public PackageRegistrationMetadataResourceDatabaseFeedProvider( + IGalleryDatabaseQueryService queryService) : base(typeof(IPackageRegistrationMetadataResource), nameof(IPackageRegistrationMetadataResource)) { + _queryService = queryService ?? throw new ArgumentNullException(nameof(queryService)); } public override async Task> TryCreate(SourceRepository source, CancellationToken token) @@ -23,12 +28,7 @@ public override async Task> TryCreate(SourceReposito if (await source.GetFeedType(token) == FeedType.HttpV2) { - var serviceDocumentResource = await source.GetResourceAsync(token); - - var httpSourceResource = await source.GetResourceAsync(token); - var feedParser = new V2FeedParser(httpSourceResource.HttpSource, serviceDocumentResource.BaseAddress, source.PackageSource.Source); - - resource = new PackageRegistrationMetadataResourceV2Feed(feedParser); + resource = new PackageRegistrationMetadataResourceDatabase(_queryService); } return new Tuple(resource != null, resource); diff --git a/src/NuGet.Services.Metadata.Catalog.Monitoring/Providers/PackageTimestampMetadataResourceV2Provider.cs b/src/NuGet.Services.Metadata.Catalog.Monitoring/Providers/PackageTimestampMetadataResourceDatabaseProvider.cs similarity index 81% rename from src/NuGet.Services.Metadata.Catalog.Monitoring/Providers/PackageTimestampMetadataResourceV2Provider.cs rename to src/NuGet.Services.Metadata.Catalog.Monitoring/Providers/PackageTimestampMetadataResourceDatabaseProvider.cs index 23e53f63c..961d5f08e 100644 --- a/src/NuGet.Services.Metadata.Catalog.Monitoring/Providers/PackageTimestampMetadataResourceV2Provider.cs +++ b/src/NuGet.Services.Metadata.Catalog.Monitoring/Providers/PackageTimestampMetadataResourceDatabaseProvider.cs @@ -11,11 +11,11 @@ namespace NuGet.Services.Metadata.Catalog.Monitoring { - public class PackageTimestampMetadataResourceV2Provider : ResourceProvider + public class PackageTimestampMetadataResourceDatabaseProvider : ResourceProvider { private readonly IGalleryDatabaseQueryService _galleryDatabase; - public PackageTimestampMetadataResourceV2Provider( + public PackageTimestampMetadataResourceDatabaseProvider( IGalleryDatabaseQueryService galleryDatabaseQueryService, ILoggerFactory loggerFactory) : base(typeof(IPackageTimestampMetadataResource)) @@ -28,13 +28,13 @@ public PackageTimestampMetadataResourceV2Provider( public override async Task> TryCreate(SourceRepository source, CancellationToken token) { - PackageTimestampMetadataResourceV2 resource = null; + PackageTimestampMetadataResourceDatabase resource = null; if (await source.GetFeedType(token) == FeedType.HttpV2) { - resource = new PackageTimestampMetadataResourceV2( + resource = new PackageTimestampMetadataResourceDatabase( _galleryDatabase, - _loggerFactory.CreateLogger()); + _loggerFactory.CreateLogger()); } return new Tuple(resource != null, resource); diff --git a/src/NuGet.Services.Metadata.Catalog.Monitoring/Resources/PackageRegistrationMetadataResourceDatabaseFeed.cs b/src/NuGet.Services.Metadata.Catalog.Monitoring/Resources/PackageRegistrationMetadataResourceDatabaseFeed.cs new file mode 100644 index 000000000..98e20733c --- /dev/null +++ b/src/NuGet.Services.Metadata.Catalog.Monitoring/Resources/PackageRegistrationMetadataResourceDatabaseFeed.cs @@ -0,0 +1,60 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Threading; +using System.Threading.Tasks; +using NuGet.Common; +using NuGet.Packaging.Core; +using NuGet.Services.Metadata.Catalog.Helpers; + +namespace NuGet.Services.Metadata.Catalog.Monitoring +{ + public class PackageRegistrationMetadataResourceDatabase : IPackageRegistrationMetadataResource + { + private readonly IGalleryDatabaseQueryService _galleryDatabase; + + public PackageRegistrationMetadataResourceDatabase( + IGalleryDatabaseQueryService galleryDatabase) + { + _galleryDatabase = galleryDatabase ?? throw new ArgumentNullException(nameof(galleryDatabase)); + } + + /// + /// Returns a that represents how a package appears in the database. + /// + public async Task GetIndexAsync(PackageIdentity package, ILogger log, CancellationToken token) + { + try + { + var feedPackage = await GetPackageAsync(package); + return feedPackage != null ? new PackageRegistrationIndexMetadata(feedPackage) : null; + } + catch (Exception e) + { + throw new ValidationException($"Could not fetch {nameof(PackageRegistrationIndexMetadata)} from database!", e); + } + } + + /// + /// Returns a that represents how a package appears in the database. + /// + public async Task GetLeafAsync(PackageIdentity package, ILogger log, CancellationToken token) + { + try + { + var feedPackage = await GetPackageAsync(package); + return feedPackage != null ? new PackageRegistrationLeafMetadata(feedPackage) : null; + } + catch (Exception e) + { + throw new ValidationException($"Could not fetch {nameof(PackageRegistrationLeafMetadata)} from database!", e); + } + } + + private Task GetPackageAsync(PackageIdentity package) + { + return _galleryDatabase.GetPackageOrNull(package.Id, package.Version.ToNormalizedString()); + } + } +} diff --git a/src/NuGet.Services.Metadata.Catalog.Monitoring/Resources/PackageRegistrationMetadataResourceV2Feed.cs b/src/NuGet.Services.Metadata.Catalog.Monitoring/Resources/PackageRegistrationMetadataResourceV2Feed.cs deleted file mode 100644 index e77338c74..000000000 --- a/src/NuGet.Services.Metadata.Catalog.Monitoring/Resources/PackageRegistrationMetadataResourceV2Feed.cs +++ /dev/null @@ -1,70 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; -using NuGet.Common; -using NuGet.Packaging.Core; -using NuGet.Protocol; -using NuGet.Protocol.Core.Types; - -namespace NuGet.Services.Metadata.Catalog.Monitoring -{ - public class PackageRegistrationMetadataResourceV2Feed : IPackageRegistrationMetadataResource - { - private V2FeedParser _feedParser; - - public PackageRegistrationMetadataResourceV2Feed( - V2FeedParser feedParser) - { - _feedParser = feedParser; - } - - /// - /// Returns a that represents how a package appears in V2's FindPackagesById. - /// - public async Task GetIndexAsync(PackageIdentity package, ILogger log, CancellationToken token) - { - try - { - var feedPackage = await GetPackageFromIndexAsync(package, log, token); - return feedPackage != null ? new PackageRegistrationIndexMetadata(feedPackage) : null; - } - catch (Exception e) - { - throw new ValidationException($"Could not fetch {nameof(PackageRegistrationIndexMetadata)} from V2 feed!", e); - } - } - - /// - /// Returns a that represents how a package appears in V2's specific package endpoint (e.g. Packages(Id='...',Version='...')). - /// - public async Task GetLeafAsync(PackageIdentity package, ILogger log, CancellationToken token) - { - try - { - var feedPackage = await GetPackageFromLeafAsync(package, log, token); - return feedPackage != null ? new PackageRegistrationLeafMetadata(feedPackage) : null; - } - catch (Exception e) - { - throw new ValidationException($"Could not fetch {nameof(PackageRegistrationLeafMetadata)} from V2 feed!", e); - } - } - - private async Task GetPackageFromIndexAsync(PackageIdentity package, ILogger log, CancellationToken token) - { - // If the package is missing from FindPackagesById, this will return null. - var feedPackages = await _feedParser.FindPackagesByIdAsync(package.Id, NullSourceCacheContext.Instance, log, token); - return feedPackages.FirstOrDefault(p => p.Version == package.Version); - } - - private Task GetPackageFromLeafAsync(PackageIdentity package, ILogger log, CancellationToken token) - { - // If the package is missing from Packages(Id='...',Version='...'), this will return null. - return _feedParser.GetPackage(package, NullSourceCacheContext.Instance, log, token); - } - } -} diff --git a/src/NuGet.Services.Metadata.Catalog.Monitoring/Resources/PackageTimestampMetadataResourceV2.cs b/src/NuGet.Services.Metadata.Catalog.Monitoring/Resources/PackageTimestampMetadataResourceDatabase.cs similarity index 88% rename from src/NuGet.Services.Metadata.Catalog.Monitoring/Resources/PackageTimestampMetadataResourceV2.cs rename to src/NuGet.Services.Metadata.Catalog.Monitoring/Resources/PackageTimestampMetadataResourceDatabase.cs index 94282dcc0..c90021d24 100644 --- a/src/NuGet.Services.Metadata.Catalog.Monitoring/Resources/PackageTimestampMetadataResourceV2.cs +++ b/src/NuGet.Services.Metadata.Catalog.Monitoring/Resources/PackageTimestampMetadataResourceDatabase.cs @@ -9,14 +9,14 @@ namespace NuGet.Services.Metadata.Catalog.Monitoring { - public class PackageTimestampMetadataResourceV2 : IPackageTimestampMetadataResource + public class PackageTimestampMetadataResourceDatabase : IPackageTimestampMetadataResource { private readonly IGalleryDatabaseQueryService _galleryDatabase; - private readonly ILogger _logger; + private readonly ILogger _logger; - public PackageTimestampMetadataResourceV2( + public PackageTimestampMetadataResourceDatabase( IGalleryDatabaseQueryService galleryDatabase, - ILogger logger) + ILogger logger) { _galleryDatabase = galleryDatabase ?? throw new ArgumentNullException(nameof(galleryDatabase)); _logger = logger ?? throw new ArgumentNullException(nameof(logger)); diff --git a/src/NuGet.Services.Metadata.Catalog.Monitoring/Utility/ContainerBuilderExtensions.cs b/src/NuGet.Services.Metadata.Catalog.Monitoring/Utility/ContainerBuilderExtensions.cs index 2332b7adf..2637c0a09 100644 --- a/src/NuGet.Services.Metadata.Catalog.Monitoring/Utility/ContainerBuilderExtensions.cs +++ b/src/NuGet.Services.Metadata.Catalog.Monitoring/Utility/ContainerBuilderExtensions.cs @@ -5,11 +5,11 @@ using System.Collections.Generic; using System.Net.Http; using Autofac; -using Microsoft.Extensions.DependencyInjection; using NuGet.Configuration; using NuGet.Protocol; using NuGet.Protocol.Core.Types; using NuGet.Services.Metadata.Catalog.Helpers; +using NuGet.Services.Metadata.Catalog.Monitoring.Validation.Test.Registration; namespace NuGet.Services.Metadata.Catalog.Monitoring { @@ -89,6 +89,7 @@ public static void RegisterValidators(this ContainerBuilder builder) builder.RegisterValidator(); builder.RegisterValidator(); builder.RegisterValidator(); + builder.RegisterValidator(); // Flat-container validators builder.RegisterValidator(); @@ -177,8 +178,8 @@ private static void RegisterDefaultResourceProviders(this ContainerBuilder build private static void RegisterV2ResourceProviders(this ContainerBuilder builder) { builder.RegisterResourceProvider(FeedType.HttpV2); - builder.RegisterResourceProvider(FeedType.HttpV2); - builder.RegisterResourceProvider(FeedType.HttpV2); + builder.RegisterResourceProvider(FeedType.HttpV2); + builder.RegisterResourceProvider(FeedType.HttpV2); } private static void RegisterV3ResourceProviders(this ContainerBuilder builder) diff --git a/src/NuGet.Services.Metadata.Catalog.Monitoring/Validation/Test/Exceptions/AggregateMetadataInconsistencyException.cs b/src/NuGet.Services.Metadata.Catalog.Monitoring/Validation/Test/Exceptions/AggregateMetadataInconsistencyException.cs new file mode 100644 index 000000000..90d91e57f --- /dev/null +++ b/src/NuGet.Services.Metadata.Catalog.Monitoring/Validation/Test/Exceptions/AggregateMetadataInconsistencyException.cs @@ -0,0 +1,22 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; + +namespace NuGet.Services.Metadata.Catalog.Monitoring.Validation.Test.Exceptions +{ + public class AggregateMetadataInconsistencyException : MetadataInconsistencyException + { + public AggregateMetadataInconsistencyException(IReadOnlyCollection> innerExceptions) + : base(null) + { + InnerExceptions = innerExceptions ?? throw new ArgumentNullException(nameof(innerExceptions)); + Data.Add("InnerExceptions", JsonConvert.SerializeObject(InnerExceptions)); + } + + public IReadOnlyCollection> InnerExceptions { get; } + } +} diff --git a/src/NuGet.Services.Metadata.Catalog.Monitoring/Validation/Test/Exceptions/MetadataFieldInconsistencyException.cs b/src/NuGet.Services.Metadata.Catalog.Monitoring/Validation/Test/Exceptions/MetadataFieldInconsistencyException.cs index 9de229f23..40745a001 100644 --- a/src/NuGet.Services.Metadata.Catalog.Monitoring/Validation/Test/Exceptions/MetadataFieldInconsistencyException.cs +++ b/src/NuGet.Services.Metadata.Catalog.Monitoring/Validation/Test/Exceptions/MetadataFieldInconsistencyException.cs @@ -2,21 +2,22 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; +using Newtonsoft.Json; namespace NuGet.Services.Metadata.Catalog.Monitoring { public class MetadataFieldInconsistencyException : MetadataInconsistencyException { - public MetadataFieldInconsistencyException(TMetadata v2Metadata, TMetadata v3Metadata, string fieldName, Func getField) - : this(v2Metadata, v3Metadata, fieldName, getField(v2Metadata), getField(v3Metadata)) + public MetadataFieldInconsistencyException(TMetadata databaseMetadata, TMetadata v3Metadata, string fieldName, Func getField) + : this(databaseMetadata, v3Metadata, fieldName, getField(databaseMetadata), getField(v3Metadata)) { } - public MetadataFieldInconsistencyException(TMetadata v2Metadata, TMetadata v3Metadata, string fieldName, object v2Field, object v3Field) - : base(v2Metadata, v3Metadata, $"{fieldName} does not match!") + public MetadataFieldInconsistencyException(TMetadata databaseMetadata, TMetadata v3Metadata, string fieldName, object databaseField, object v3Field) + : base(databaseMetadata, v3Metadata, $"{fieldName} does not match!") { - Data.Add($"{nameof(V2Metadata)}.{fieldName}", v2Field); - Data.Add($"{nameof(V3Metadata)}.{fieldName}", v3Field); + Data.Add($"{nameof(DatabaseMetadata)}.{fieldName}", JsonConvert.SerializeObject(databaseField, JsonSerializerUtility.SerializerSettings)); + Data.Add($"{nameof(V3Metadata)}.{fieldName}", JsonConvert.SerializeObject(v3Field, JsonSerializerUtility.SerializerSettings)); } } } diff --git a/src/NuGet.Services.Metadata.Catalog.Monitoring/Validation/Test/Exceptions/MetadataInconsistencyException.cs b/src/NuGet.Services.Metadata.Catalog.Monitoring/Validation/Test/Exceptions/MetadataInconsistencyException.cs index 9171beb99..7a778416c 100644 --- a/src/NuGet.Services.Metadata.Catalog.Monitoring/Validation/Test/Exceptions/MetadataInconsistencyException.cs +++ b/src/NuGet.Services.Metadata.Catalog.Monitoring/Validation/Test/Exceptions/MetadataInconsistencyException.cs @@ -8,7 +8,7 @@ namespace NuGet.Services.Metadata.Catalog.Monitoring public class MetadataInconsistencyException : ValidationException { public MetadataInconsistencyException(string additionalMessage) - : base("The metadata between V2 and V3 is inconsistent!" + + : base("The metadata between the database and V3 is inconsistent!" + (additionalMessage != null ? $" {additionalMessage}" : "")) { } @@ -16,21 +16,21 @@ public MetadataInconsistencyException(string additionalMessage) public class MetadataInconsistencyException : MetadataInconsistencyException { - public T V2Metadata { get; private set; } + public T DatabaseMetadata { get; private set; } public T V3Metadata { get; private set; } - public MetadataInconsistencyException(T v2Metadata, T v3Metadata) - : this(v2Metadata, v3Metadata, null) + public MetadataInconsistencyException(T databaseMetadata, T v3Metadata) + : this(databaseMetadata, v3Metadata, null) { } - public MetadataInconsistencyException(T v2Metadata, T v3Metadata, string additionalMessage) + public MetadataInconsistencyException(T databaseMetadata, T v3Metadata, string additionalMessage) : base(additionalMessage) { - V2Metadata = v2Metadata; + DatabaseMetadata = databaseMetadata; V3Metadata = v3Metadata; - Data.Add(nameof(V2Metadata), JsonConvert.SerializeObject(V2Metadata)); + Data.Add(nameof(DatabaseMetadata), JsonConvert.SerializeObject(DatabaseMetadata)); Data.Add(nameof(V3Metadata), JsonConvert.SerializeObject(V3Metadata)); } } diff --git a/src/NuGet.Services.Metadata.Catalog.Monitoring/Validation/Test/Exceptions/TimestampComparisonException.cs b/src/NuGet.Services.Metadata.Catalog.Monitoring/Validation/Test/Exceptions/TimestampComparisonException.cs index 2fac129dc..4fc31b0ac 100644 --- a/src/NuGet.Services.Metadata.Catalog.Monitoring/Validation/Test/Exceptions/TimestampComparisonException.cs +++ b/src/NuGet.Services.Metadata.Catalog.Monitoring/Validation/Test/Exceptions/TimestampComparisonException.cs @@ -7,16 +7,16 @@ namespace NuGet.Services.Metadata.Catalog.Monitoring { public class TimestampComparisonException : ValidationException { - public PackageTimestampMetadata TimestampV2 { get; } + public PackageTimestampMetadata TimestampDatabase { get; } public PackageTimestampMetadata TimestampCatalog { get; } - public TimestampComparisonException(PackageTimestampMetadata timestampV2, PackageTimestampMetadata timestampCatalog, string message) + public TimestampComparisonException(PackageTimestampMetadata timestampDatabase, PackageTimestampMetadata timestampCatalog, string message) : base(message) { - TimestampV2 = timestampV2; + TimestampDatabase = timestampDatabase; TimestampCatalog = timestampCatalog; - Data.Add(nameof(TimestampV2), JsonConvert.SerializeObject(TimestampV2)); + Data.Add(nameof(TimestampDatabase), JsonConvert.SerializeObject(TimestampDatabase)); Data.Add(nameof(TimestampCatalog), JsonConvert.SerializeObject(TimestampCatalog)); } } diff --git a/src/NuGet.Services.Metadata.Catalog.Monitoring/Validation/Test/Registration/RegistrationDeprecationValidator.cs b/src/NuGet.Services.Metadata.Catalog.Monitoring/Validation/Test/Registration/RegistrationDeprecationValidator.cs new file mode 100644 index 000000000..2ef93eccd --- /dev/null +++ b/src/NuGet.Services.Metadata.Catalog.Monitoring/Validation/Test/Registration/RegistrationDeprecationValidator.cs @@ -0,0 +1,135 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using Microsoft.Extensions.Logging; +using NuGet.Services.Metadata.Catalog.Monitoring.Model; +using NuGet.Services.Metadata.Catalog.Monitoring.Validation.Test.Exceptions; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace NuGet.Services.Metadata.Catalog.Monitoring.Validation.Test.Registration +{ + public class RegistrationDeprecationValidator : RegistrationIndexValidator + { + public RegistrationDeprecationValidator( + ValidatorConfiguration config, + ILogger logger) + : base(config, logger) + { + } + + public override Task CompareIndexAsync(ValidationContext context, PackageRegistrationIndexMetadata database, PackageRegistrationIndexMetadata v3) + { + var exceptions = new List>(); + + if (database.Deprecation == null && v3.Deprecation == null) + { + return Task.CompletedTask; + } + else if (database.Deprecation == null || v3.Deprecation == null) + { + throw new MetadataFieldInconsistencyException( + database, v3, + nameof(PackageRegistrationIndexMetadata.Deprecation), + i => i.Deprecation); + } + + if (!database.Deprecation.Reasons.SequenceEqual(v3.Deprecation.Reasons)) + { + AddDeprecationInconsistencyException( + exceptions, + database, v3, + nameof(PackageRegistrationDeprecationMetadata.Reasons), + d => d.Reasons); + } + + if (database.Deprecation.Message != v3.Deprecation.Message) + { + AddDeprecationInconsistencyException( + exceptions, + database, v3, + nameof(PackageRegistrationDeprecationMetadata.Message), + d => d.Message); + } + + CompareIndexAlternatePackage(exceptions, database, v3); + + if (exceptions.Any()) + { + throw new AggregateMetadataInconsistencyException(exceptions); + } + + return Task.CompletedTask; + } + + private void CompareIndexAlternatePackage( + List> exceptions, + PackageRegistrationIndexMetadata database, + PackageRegistrationIndexMetadata v3) + { + if (database.Deprecation.AlternatePackage == null && v3.Deprecation.AlternatePackage == null) + { + return; + } + else if (database.Deprecation.AlternatePackage == null || v3.Deprecation.AlternatePackage == null) + { + AddDeprecationInconsistencyException( + exceptions, + database, v3, + nameof(PackageRegistrationDeprecationMetadata.AlternatePackage), + d => d.AlternatePackage); + + return; + } + + if (database.Deprecation.AlternatePackage.Id != v3.Deprecation.AlternatePackage.Id) + { + AddAlternatePackageInconsistencyException( + exceptions, + database, v3, + nameof(PackageRegistrationAlternatePackageMetadata.Id), + a => a.Id); + } + + if (database.Deprecation.AlternatePackage.Range != v3.Deprecation.AlternatePackage.Range) + { + AddAlternatePackageInconsistencyException( + exceptions, + database, v3, + nameof(PackageRegistrationAlternatePackageMetadata.Range), + a => a.Range); + } + } + + private void AddDeprecationInconsistencyException( + List> list, + PackageRegistrationIndexMetadata database, + PackageRegistrationIndexMetadata v3, + string deprecationFieldName, + Func getDeprecationField) + { + var exception = new MetadataFieldInconsistencyException( + database, v3, + nameof(PackageRegistrationIndexMetadata.Deprecation) + "." + deprecationFieldName, + i => getDeprecationField(i.Deprecation)); + + list.Add(exception); + } + + private void AddAlternatePackageInconsistencyException( + List> list, + PackageRegistrationIndexMetadata database, + PackageRegistrationIndexMetadata v3, + string alternatePackageField, + Func getAlternatePackageField) + { + AddDeprecationInconsistencyException( + list, + database, v3, + nameof(PackageRegistrationDeprecationMetadata.AlternatePackage) + "." + alternatePackageField, + d => getAlternatePackageField(d.AlternatePackage)); + } + } +} diff --git a/src/NuGet.Services.Metadata.Catalog.Monitoring/Validation/Test/Registration/RegistrationExistsValidator.cs b/src/NuGet.Services.Metadata.Catalog.Monitoring/Validation/Test/Registration/RegistrationExistsValidator.cs index a0f834472..bbf4c7eb2 100644 --- a/src/NuGet.Services.Metadata.Catalog.Monitoring/Validation/Test/Registration/RegistrationExistsValidator.cs +++ b/src/NuGet.Services.Metadata.Catalog.Monitoring/Validation/Test/Registration/RegistrationExistsValidator.cs @@ -15,7 +15,7 @@ public RegistrationExistsValidator(ValidatorConfiguration config, ILogger ShouldRunLeafAsync( ValidationContext context, - PackageRegistrationLeafMetadata v2, + PackageRegistrationLeafMetadata database, PackageRegistrationLeafMetadata v3) { return Task.FromResult(true); @@ -23,21 +23,21 @@ public override Task ShouldRunLeafAsync( public override Task CompareLeafAsync( ValidationContext context, - PackageRegistrationLeafMetadata v2, + PackageRegistrationLeafMetadata database, PackageRegistrationLeafMetadata v3) { - var v2Exists = v2 != null; + var databaseExists = database != null; var v3Exists = v3 != null; var completedTask = Task.FromResult(0); - if (v2Exists != v3Exists) + if (databaseExists != v3Exists) { // Currently, leaf nodes are not deleted after a package is deleted. // This is a known bug. Do not fail validations because of it. // See https://github.com/NuGet/NuGetGallery/issues/4475 if (v3Exists && !(v3 is PackageRegistrationIndexMetadata)) { - Logger.LogInformation("{PackageId} {PackageVersion} doesn't exist in V2 but has a leaf node in V3!", context.Package.Id, context.Package.Version); + Logger.LogInformation("{PackageId} {PackageVersion} doesn't exist in the database but has a leaf node in V3!", context.Package.Id, context.Package.Version); return completedTask; } @@ -45,9 +45,9 @@ public override Task CompareLeafAsync( const string doesNotExistString = "doesn't exist"; throw new MetadataInconsistencyException( - v2, + database, v3, - $"V2 {(v2Exists ? existsString : doesNotExistString)} but V3 {(v3Exists ? existsString : doesNotExistString)}!"); + $"Database {(databaseExists ? existsString : doesNotExistString)} but V3 {(v3Exists ? existsString : doesNotExistString)}!"); } return completedTask; diff --git a/src/NuGet.Services.Metadata.Catalog.Monitoring/Validation/Test/Registration/RegistrationIdValidator.cs b/src/NuGet.Services.Metadata.Catalog.Monitoring/Validation/Test/Registration/RegistrationIdValidator.cs index cdb6bd95d..cfa9165ca 100644 --- a/src/NuGet.Services.Metadata.Catalog.Monitoring/Validation/Test/Registration/RegistrationIdValidator.cs +++ b/src/NuGet.Services.Metadata.Catalog.Monitoring/Validation/Test/Registration/RegistrationIdValidator.cs @@ -15,13 +15,13 @@ public RegistrationIdValidator(ValidatorConfiguration config, ILogger( - v2, v3, + database, v3, nameof(PackageRegistrationIndexMetadata.Id), m => m.Id); } diff --git a/src/NuGet.Services.Metadata.Catalog.Monitoring/Validation/Test/Registration/RegistrationIndexValidator.cs b/src/NuGet.Services.Metadata.Catalog.Monitoring/Validation/Test/Registration/RegistrationIndexValidator.cs index c38ca0dd0..9b7010094 100644 --- a/src/NuGet.Services.Metadata.Catalog.Monitoring/Validation/Test/Registration/RegistrationIndexValidator.cs +++ b/src/NuGet.Services.Metadata.Catalog.Monitoring/Validation/Test/Registration/RegistrationIndexValidator.cs @@ -16,38 +16,38 @@ public RegistrationIndexValidator(ValidatorConfiguration config, ILogger ShouldRunAsync(ValidationContext context) { - var v2Index = await context.GetIndexV2Async(); + var databaseIndex = await context.GetIndexDatabaseAsync(); var v3Index = await context.GetIndexV3Async(); - return await base.ShouldRunAsync(context) && await ShouldRunIndexAsync(context, v2Index, v3Index); + return await base.ShouldRunAsync(context) && await ShouldRunIndexAsync(context, databaseIndex, v3Index); } protected override async Task RunInternalAsync(ValidationContext context) { - var v2Index = await context.GetIndexV2Async(); + var databaseIndex = await context.GetIndexDatabaseAsync(); var v3Index = await context.GetIndexV3Async(); try { - await CompareIndexAsync(context, v2Index, v3Index); + await CompareIndexAsync(context, databaseIndex, v3Index); } catch (Exception e) { - throw new ValidationException("Registration index metadata does not match the FindPackagesById metadata!", e); + throw new ValidationException("Registration index metadata does not match the database metadata!", e); } } public Task ShouldRunIndexAsync( ValidationContext context, - PackageRegistrationIndexMetadata v2, + PackageRegistrationIndexMetadata database, PackageRegistrationIndexMetadata v3) { - return Task.FromResult(v2 != null && v3 != null); + return Task.FromResult(database != null && v3 != null); } public abstract Task CompareIndexAsync( ValidationContext context, - PackageRegistrationIndexMetadata v2, + PackageRegistrationIndexMetadata database, PackageRegistrationIndexMetadata v3); } } \ No newline at end of file diff --git a/src/NuGet.Services.Metadata.Catalog.Monitoring/Validation/Test/Registration/RegistrationLeafValidator.cs b/src/NuGet.Services.Metadata.Catalog.Monitoring/Validation/Test/Registration/RegistrationLeafValidator.cs index 10e6ff554..a8c7c1eb1 100644 --- a/src/NuGet.Services.Metadata.Catalog.Monitoring/Validation/Test/Registration/RegistrationLeafValidator.cs +++ b/src/NuGet.Services.Metadata.Catalog.Monitoring/Validation/Test/Registration/RegistrationLeafValidator.cs @@ -18,42 +18,42 @@ public RegistrationLeafValidator(ValidatorConfiguration config, ILogger ShouldRunAsync(ValidationContext context) { - var v2Index = await context.GetIndexV2Async(); + var databaseIndex = await context.GetIndexDatabaseAsync(); var v3Index = await context.GetIndexV3Async(); - var v2Leaf = await context.GetLeafV2Async(); + var databaseLeaf = await context.GetLeafDatabaseAsync(); var v3Leaf = await context.GetLeafV3Async(); return await base.ShouldRunAsync(context) - && await ShouldRunLeafAsync(context, v2Index, v3Index) - && await ShouldRunLeafAsync(context, v2Leaf, v3Leaf); + && await ShouldRunLeafAsync(context, databaseIndex, v3Index) + && await ShouldRunLeafAsync(context, databaseLeaf, v3Leaf); } protected override async Task RunInternalAsync(ValidationContext context) { var exceptions = new List(); - var v2Index = await context.GetIndexV2Async(); + var databaseIndex = await context.GetIndexDatabaseAsync(); var v3Index = await context.GetIndexV3Async(); try { - await CompareLeafAsync(context, v2Index, v3Index); + await CompareLeafAsync(context, databaseIndex, v3Index); } catch (Exception e) { - exceptions.Add(new ValidationException("Registration index metadata does not match the FindPackagesById metadata!", e)); + exceptions.Add(new ValidationException("Registration index metadata does not match the database!", e)); } - var v2Leaf = await context.GetLeafV2Async(); + var databaseLeaf = await context.GetLeafDatabaseAsync(); var v3Leaf = await context.GetLeafV3Async(); try { - await CompareLeafAsync(context, v2Leaf, v3Leaf); + await CompareLeafAsync(context, databaseLeaf, v3Leaf); } catch (Exception e) { - exceptions.Add(new ValidationException("Registration leaf metadata does not match the Packages(Id='...',Version='...') metadata!", e)); + exceptions.Add(new ValidationException("Registration leaf metadata does not match the database!", e)); } if (exceptions.Any()) @@ -64,12 +64,12 @@ protected override async Task RunInternalAsync(ValidationContext context) public abstract Task ShouldRunLeafAsync( ValidationContext context, - PackageRegistrationLeafMetadata v2, + PackageRegistrationLeafMetadata database, PackageRegistrationLeafMetadata v3); public abstract Task CompareLeafAsync( ValidationContext context, - PackageRegistrationLeafMetadata v2, + PackageRegistrationLeafMetadata database, PackageRegistrationLeafMetadata v3); } } \ No newline at end of file diff --git a/src/NuGet.Services.Metadata.Catalog.Monitoring/Validation/Test/Registration/RegistrationListedValidator.cs b/src/NuGet.Services.Metadata.Catalog.Monitoring/Validation/Test/Registration/RegistrationListedValidator.cs index d3e1916f7..63522a9ae 100644 --- a/src/NuGet.Services.Metadata.Catalog.Monitoring/Validation/Test/Registration/RegistrationListedValidator.cs +++ b/src/NuGet.Services.Metadata.Catalog.Monitoring/Validation/Test/Registration/RegistrationListedValidator.cs @@ -17,21 +17,21 @@ public RegistrationListedValidator( public override Task ShouldRunLeafAsync( ValidationContext context, - PackageRegistrationLeafMetadata v2, + PackageRegistrationLeafMetadata database, PackageRegistrationLeafMetadata v3) { - return Task.FromResult(v2 != null && v3 != null); + return Task.FromResult(database != null && v3 != null); } public override Task CompareLeafAsync( ValidationContext context, - PackageRegistrationLeafMetadata v2, + PackageRegistrationLeafMetadata database, PackageRegistrationLeafMetadata v3) { - if (v2.Listed != v3.Listed) + if (database.Listed != v3.Listed) { throw new MetadataFieldInconsistencyException( - v2, v3, + database, v3, nameof(PackageRegistrationLeafMetadata.Listed), m => m.Listed); } diff --git a/src/NuGet.Services.Metadata.Catalog.Monitoring/Validation/Test/Registration/RegistrationRequireLicenseAcceptanceValidator.cs b/src/NuGet.Services.Metadata.Catalog.Monitoring/Validation/Test/Registration/RegistrationRequireLicenseAcceptanceValidator.cs index 679eb9dfc..f241ba1ad 100644 --- a/src/NuGet.Services.Metadata.Catalog.Monitoring/Validation/Test/Registration/RegistrationRequireLicenseAcceptanceValidator.cs +++ b/src/NuGet.Services.Metadata.Catalog.Monitoring/Validation/Test/Registration/RegistrationRequireLicenseAcceptanceValidator.cs @@ -15,14 +15,14 @@ public RegistrationRequireLicenseAcceptanceValidator( { } - public override Task CompareIndexAsync(ValidationContext context, PackageRegistrationIndexMetadata v2, PackageRegistrationIndexMetadata v3) + public override Task CompareIndexAsync(ValidationContext context, PackageRegistrationIndexMetadata database, PackageRegistrationIndexMetadata v3) { - var isEqual = v2.RequireLicenseAcceptance == v3.RequireLicenseAcceptance; + var isEqual = database.RequireLicenseAcceptance == v3.RequireLicenseAcceptance; if (!isEqual) { throw new MetadataFieldInconsistencyException( - v2, v3, + database, v3, nameof(PackageRegistrationIndexMetadata.RequireLicenseAcceptance), m => m.RequireLicenseAcceptance); } diff --git a/src/NuGet.Services.Metadata.Catalog.Monitoring/Validation/Test/Registration/RegistrationVersionValidator.cs b/src/NuGet.Services.Metadata.Catalog.Monitoring/Validation/Test/Registration/RegistrationVersionValidator.cs index 3d3389101..32c9927fa 100644 --- a/src/NuGet.Services.Metadata.Catalog.Monitoring/Validation/Test/Registration/RegistrationVersionValidator.cs +++ b/src/NuGet.Services.Metadata.Catalog.Monitoring/Validation/Test/Registration/RegistrationVersionValidator.cs @@ -15,14 +15,14 @@ public RegistrationVersionValidator( { } - public override Task CompareIndexAsync(ValidationContext context, PackageRegistrationIndexMetadata v2, PackageRegistrationIndexMetadata v3) + public override Task CompareIndexAsync(ValidationContext context, PackageRegistrationIndexMetadata database, PackageRegistrationIndexMetadata v3) { - var isEqual = v2.Version == v3.Version; + var isEqual = database.Version == v3.Version; if (!isEqual) { throw new MetadataFieldInconsistencyException( - v2, v3, + database, v3, nameof(PackageRegistrationIndexMetadata.Version), m => m.Version.ToFullString()); } diff --git a/src/NuGet.Services.Metadata.Catalog.Monitoring/Validation/Test/ValidationContext.cs b/src/NuGet.Services.Metadata.Catalog.Monitoring/Validation/Test/ValidationContext.cs index a354d4bdb..0d9eb0994 100644 --- a/src/NuGet.Services.Metadata.Catalog.Monitoring/Validation/Test/ValidationContext.cs +++ b/src/NuGet.Services.Metadata.Catalog.Monitoring/Validation/Test/ValidationContext.cs @@ -17,14 +17,14 @@ namespace NuGet.Services.Metadata.Catalog.Monitoring /// public class ValidationContext { - private readonly IPackageRegistrationMetadataResource _v2PackageRegistrationMetadataResource; + private readonly IPackageRegistrationMetadataResource _databasePackageRegistrationMetadataResource; private readonly IPackageRegistrationMetadataResource _v3PackageRegistrationMetadataResource; - private readonly Lazy> _v2Index; + private readonly Lazy> _databaseIndex; private readonly Lazy> _v3Index; - private readonly Lazy> _v2Leaf; + private readonly Lazy> _databaseLeaf; private readonly Lazy> _v3Leaf; - private readonly IPackageTimestampMetadataResource _v2timestampMetadataResource; - private readonly Lazy> _timestampMetadataV2; + private readonly IPackageTimestampMetadataResource _databasetimestampMetadataResource; + private readonly Lazy> _timestampMetadataDatabase; /// /// The to run the test on. @@ -86,30 +86,30 @@ public ValidationContext( Client = client ?? throw new ArgumentNullException(nameof(client)); CancellationToken = token; - _v2timestampMetadataResource = sourceRepositories.V2.GetResource(); - _v2PackageRegistrationMetadataResource = sourceRepositories.V2.GetResource(); + _databasetimestampMetadataResource = sourceRepositories.V2.GetResource(); + _databasePackageRegistrationMetadataResource = sourceRepositories.V2.GetResource(); _v3PackageRegistrationMetadataResource = sourceRepositories.V3.GetResource(); var commonLogger = logger.AsCommon(); - _v2Index = new Lazy>( - () => _v2PackageRegistrationMetadataResource.GetIndexAsync(Package, commonLogger, CancellationToken)); + _databaseIndex = new Lazy>( + () => _databasePackageRegistrationMetadataResource.GetIndexAsync(Package, commonLogger, CancellationToken)); _v3Index = new Lazy>( () => _v3PackageRegistrationMetadataResource.GetIndexAsync(Package, commonLogger, CancellationToken)); - _v2Leaf = new Lazy>( - () => _v2PackageRegistrationMetadataResource.GetLeafAsync(Package, commonLogger, CancellationToken)); + _databaseLeaf = new Lazy>( + () => _databasePackageRegistrationMetadataResource.GetLeafAsync(Package, commonLogger, CancellationToken)); _v3Leaf = new Lazy>( () => _v3PackageRegistrationMetadataResource.GetLeafAsync(Package, commonLogger, CancellationToken)); - _timestampMetadataV2 = new Lazy>( - () => _v2timestampMetadataResource.GetAsync(this)); + _timestampMetadataDatabase = new Lazy>( + () => _databasetimestampMetadataResource.GetAsync(this)); } - public Task GetIndexV2Async() => _v2Index.Value; + public Task GetIndexDatabaseAsync() => _databaseIndex.Value; public Task GetIndexV3Async() => _v3Index.Value; - public Task GetLeafV2Async() => _v2Leaf.Value; + public Task GetLeafDatabaseAsync() => _databaseLeaf.Value; public Task GetLeafV3Async() => _v3Leaf.Value; - public Task GetTimestampMetadataV2Async() => _timestampMetadataV2.Value; + public Task GetTimestampMetadataDatabaseAsync() => _timestampMetadataDatabase.Value; } } \ No newline at end of file diff --git a/src/NuGet.Services.Metadata.Catalog.Monitoring/Validation/Test/Validator.cs b/src/NuGet.Services.Metadata.Catalog.Monitoring/Validation/Test/Validator.cs index 7ea4a6352..4379e4e0c 100644 --- a/src/NuGet.Services.Metadata.Catalog.Monitoring/Validation/Test/Validator.cs +++ b/src/NuGet.Services.Metadata.Catalog.Monitoring/Validation/Test/Validator.cs @@ -63,34 +63,34 @@ public async Task ValidateAsync(ValidationContext context) } /// - /// Checks that the current batch of catalog entries contains the entry that was created from the current state of the V2 feed. + /// Checks that the current batch of catalog entries contains the entry that was created from the current state of the database. /// protected virtual async Task ShouldRunAsync(ValidationContext context) { - var timestampV2 = await context.GetTimestampMetadataV2Async(); + var timestampDatabase = await context.GetTimestampMetadataDatabaseAsync(); var timestampCatalog = await PackageTimestampMetadata.FromCatalogEntries(context.Client, context.Entries); - if (!timestampV2.Last.HasValue) + if (!timestampDatabase.Last.HasValue) { - throw new TimestampComparisonException(timestampV2, timestampCatalog, - "Cannot get timestamp data for package from the V2 feed!"); + throw new TimestampComparisonException(timestampDatabase, timestampCatalog, + "Cannot get timestamp data for package from the database!"); } if (!timestampCatalog.Last.HasValue) { - throw new TimestampComparisonException(timestampV2, timestampCatalog, + throw new TimestampComparisonException(timestampDatabase, timestampCatalog, "Cannot get timestamp data for package from the catalog!"); } - if (timestampCatalog.Last > timestampV2.Last) + if (timestampCatalog.Last > timestampDatabase.Last) { - throw new TimestampComparisonException(timestampV2, timestampCatalog, - "The timestamp in the catalog is newer than the timestamp in the feed! This should never happen because all data flows from the feed into the catalog!"); + throw new TimestampComparisonException(timestampDatabase, timestampCatalog, + "The timestamp in the catalog is newer than the timestamp in the database! This should never happen because all data flows from the feed into the catalog!"); } - // If the timestamp metadata in the catalog is LESS than that of the feed, we must not be looking at the latest entry that corresponds with this package, so skip the test for now. - // If the timestamp metadata in the catalog is EQUAL to that of the feed, we are looking at the latest catalog entry that corresponds with this package, so run the test. - return timestampCatalog.Last == timestampV2.Last; + // If the timestamp metadata in the catalog is LESS than that of the database, we must not be looking at the latest entry that corresponds with this package, so skip the test for now. + // If the timestamp metadata in the catalog is EQUAL to that of the database, we are looking at the latest catalog entry that corresponds with this package, so run the test. + return timestampCatalog.Last == timestampDatabase.Last; } protected abstract Task RunInternalAsync(ValidationContext context); diff --git a/tests/CatalogMetadataTests/Properties/AssemblyInfo.cs b/tests/CatalogMetadataTests/Properties/AssemblyInfo.cs index ec0bac1c1..c073b87ab 100644 --- a/tests/CatalogMetadataTests/Properties/AssemblyInfo.cs +++ b/tests/CatalogMetadataTests/Properties/AssemblyInfo.cs @@ -1,5 +1,4 @@ using System.Reflection; -using System.Runtime.CompilerServices; using System.Runtime.InteropServices; // General Information about an assembly is controlled through the following diff --git a/tests/CatalogTests/CatalogTests.csproj b/tests/CatalogTests/CatalogTests.csproj index c127b389c..3585a8751 100644 --- a/tests/CatalogTests/CatalogTests.csproj +++ b/tests/CatalogTests/CatalogTests.csproj @@ -96,7 +96,6 @@ - diff --git a/tests/CatalogTests/Helpers/Db2CatalogProjectionTests.cs b/tests/CatalogTests/Helpers/Db2CatalogProjectionTests.cs index 35709492d..9a85610dd 100644 --- a/tests/CatalogTests/Helpers/Db2CatalogProjectionTests.cs +++ b/tests/CatalogTests/Helpers/Db2CatalogProjectionTests.cs @@ -61,6 +61,7 @@ public void PerformsCorrectProjections(bool listed, bool hideLicenseReport) const string normalizedPackageVersion = "1.0.0"; const string licenseNames = "MIT"; const string licenseReportUrl = "https://unittest.org/licenses/MIT"; + const bool requiresLicenseAcceptance = true; var utcNow = DateTime.UtcNow; var createdDate = utcNow.AddDays(-1); @@ -70,6 +71,7 @@ public void PerformsCorrectProjections(bool listed, bool hideLicenseReport) var expectedPublishedDate = listed ? publishedDate : Constants.UnpublishedDate; var expectedLicenseNames = hideLicenseReport ? null : licenseNames; var expectedLicenseReportUrl = hideLicenseReport ? null : licenseReportUrl; + var expectedRequiresLicenseAcceptance = true; var dataRecordMock = MockDataReader( packageId, @@ -80,7 +82,8 @@ public void PerformsCorrectProjections(bool listed, bool hideLicenseReport) listed, hideLicenseReport, licenseNames, - licenseReportUrl); + licenseReportUrl, + requiresLicenseAcceptance); // Act var projection = _db2catalogProjection.ReadFeedPackageDetailsFromDataReader(dataRecordMock.Object); @@ -94,6 +97,7 @@ public void PerformsCorrectProjections(bool listed, bool hideLicenseReport) Assert.Equal(expectedContentUri, projection.ContentUri); Assert.Equal(expectedLicenseNames, projection.LicenseNames); Assert.Equal(expectedLicenseReportUrl, projection.LicenseReportUrl); + Assert.Equal(expectedRequiresLicenseAcceptance, projection.RequiresLicenseAcceptance); Assert.Null(projection.DeprecationInfo); } @@ -106,13 +110,15 @@ private static Mock MockDataReader( bool listed, bool hideLicenseReport, string licenseNames, - string licenseReportUrl) + string licenseReportUrl, + bool requiresLicenseAcceptance) { const int ordinalCreated = 2; const int ordinalLastEdited = 3; const int ordinalPublished = 4; const int ordinalListed = 5; const int ordinalHideLicenseReport = 6; + const int ordinalRequiresLicenseAcceptance = 9; var dataReaderMock = new Mock(MockBehavior.Strict); @@ -140,6 +146,10 @@ private static Mock MockDataReader( dataReaderMock.Setup(m => m.GetOrdinal(Db2CatalogProjectionColumnNames.Published)).Returns(ordinalPublished); dataReaderMock.Setup(m => m.GetDateTime(ordinalPublished)).Returns(publishedDate); + dataReaderMock.SetupGet(m => m[Db2CatalogProjectionColumnNames.RequiresLicenseAcceptance]).Returns(requiresLicenseAcceptance); + dataReaderMock.Setup(m => m.GetOrdinal(Db2CatalogProjectionColumnNames.RequiresLicenseAcceptance)).Returns(ordinalRequiresLicenseAcceptance); + dataReaderMock.Setup(m => m.GetBoolean(ordinalRequiresLicenseAcceptance)).Returns(requiresLicenseAcceptance); + // Simulate that these columns do not exist in the resultset. dataReaderMock.Setup(m => m.GetOrdinal(Db2CatalogProjectionColumnNames.DeprecationStatus)).Throws(); diff --git a/tests/CatalogTests/Properties/AssemblyInfo.cs b/tests/CatalogTests/Properties/AssemblyInfo.cs index 6ddcc5494..4ac107f3d 100644 --- a/tests/CatalogTests/Properties/AssemblyInfo.cs +++ b/tests/CatalogTests/Properties/AssemblyInfo.cs @@ -1,7 +1,6 @@ // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System.Reflection; -using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using Xunit; diff --git a/tests/CatalogTests/Registration/RegistrationMakerCatalogItemTests.cs b/tests/CatalogTests/Registration/RegistrationMakerCatalogItemTests.cs index c53a5acbb..da4814d85 100644 --- a/tests/CatalogTests/Registration/RegistrationMakerCatalogItemTests.cs +++ b/tests/CatalogTests/Registration/RegistrationMakerCatalogItemTests.cs @@ -6,7 +6,6 @@ using System.IO; using System.Linq; using Newtonsoft.Json.Linq; -using NuGet.ContentModel; using NuGet.Services.Metadata.Catalog; using NuGet.Services.Metadata.Catalog.Persistence; using NuGet.Services.Metadata.Catalog.Registration; diff --git a/tests/NgTests/Db2CatalogTests.cs b/tests/NgTests/Db2CatalogTests.cs index e5a095948..fbf9b959a 100644 --- a/tests/NgTests/Db2CatalogTests.cs +++ b/tests/NgTests/Db2CatalogTests.cs @@ -1175,7 +1175,8 @@ private PackageCreationOrEdit CreatePackageCreationOrEdit(DateTime? createdDate packageVersion: normalizedVersion, licenseNames: null, licenseReportUrl: null, - deprecationInfo: null); + deprecationInfo: null, + requiresLicenseAcceptance: false); return new PackageCreationOrEdit(package, feedPackageDetails); } @@ -1209,7 +1210,8 @@ private PackageCreationOrEdit AddEditedPackageToFeed(PackageCreationOrEdit entry packageVersion: entry.FeedPackageDetails.PackageVersion, licenseNames: entry.FeedPackageDetails.LicenseNames, licenseReportUrl: entry.FeedPackageDetails.LicenseReportUrl, - deprecationInfo: entry.FeedPackageDetails.DeprecationInfo); + deprecationInfo: entry.FeedPackageDetails.DeprecationInfo, + requiresLicenseAcceptance: entry.FeedPackageDetails.RequiresLicenseAcceptance); var operation = new PackageCreationOrEdit(editedPackage, feedPackageDetails); diff --git a/tests/NgTests/NgTests.csproj b/tests/NgTests/NgTests.csproj index 57f9d653d..d528f64b4 100644 --- a/tests/NgTests/NgTests.csproj +++ b/tests/NgTests/NgTests.csproj @@ -110,6 +110,7 @@ + diff --git a/tests/NgTests/Validation/RegistrationDeprecationValidatorTestData.cs b/tests/NgTests/Validation/RegistrationDeprecationValidatorTestData.cs new file mode 100644 index 000000000..902a1bd7d --- /dev/null +++ b/tests/NgTests/Validation/RegistrationDeprecationValidatorTestData.cs @@ -0,0 +1,113 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using Microsoft.Extensions.Logging; +using NuGet.Services.Entities; +using NuGet.Services.Metadata.Catalog.Monitoring; +using NuGet.Services.Metadata.Catalog.Monitoring.Model; +using NuGet.Services.Metadata.Catalog.Monitoring.Validation.Test.Registration; +using System; +using System.Collections.Generic; +using System.Linq; + +namespace NgTests.Validation +{ + public class RegistrationDeprecationValidatorTestData : RegistrationIndexValidatorTestData + { + protected override RegistrationDeprecationValidator CreateValidator( + ILogger logger) + { + var config = new ValidatorConfiguration("https://nuget.test/packages", requireRepositorySignature: false); + + return new RegistrationDeprecationValidator(config, logger); + } + + public override IEnumerable> CreateIndexes + { + get + { + yield return () => new PackageRegistrationIndexMetadata { Deprecation = null }; + + foreach (var reasons in GetPossibleDeprecationReasonCombinations()) + { + foreach (var hasMessage in new[] { false, true }) + { + yield return () => new PackageRegistrationIndexMetadata + { + Deprecation = new PackageRegistrationDeprecationMetadata + { + Reasons = reasons, + Message = hasMessage ? "this is the message" : null + } + }; + + yield return () => new PackageRegistrationIndexMetadata + { + Deprecation = new PackageRegistrationDeprecationMetadata + { + Reasons = reasons, + Message = hasMessage ? "this is the message" : null, + AlternatePackage = new PackageRegistrationAlternatePackageMetadata + { + Id = "thePackage", + Range = "*" + } + } + }; + + yield return () => new PackageRegistrationIndexMetadata + { + Deprecation = new PackageRegistrationDeprecationMetadata + { + Reasons = reasons, + Message = hasMessage ? "this is the message" : null, + AlternatePackage = new PackageRegistrationAlternatePackageMetadata + { + Id = "thePackage", + Range = "[1.0.0,1.0.0]" + } + } + }; + } + } + } + } + + public override IEnumerable> CreateSkippedIndexes => new Func[] + { + () => null + }; + + private static IEnumerable> GetPossibleDeprecationReasonCombinations() + { + return GetNextPossibleDeprecationReasonCombinations( + Enum + .GetValues(typeof(PackageDeprecationStatus)) + .Cast() + .Where(s => s != PackageDeprecationStatus.NotDeprecated)); + } + + private static IEnumerable> GetNextPossibleDeprecationReasonCombinations(IEnumerable remainingStatuses) + { + if (!remainingStatuses.Any()) + { + yield break; + } + + var nextStatus = remainingStatuses.First().ToString(); + var nextPossibleStatuses = GetNextPossibleDeprecationReasonCombinations(remainingStatuses.Skip(1)); + if (nextPossibleStatuses.Any()) + { + foreach (var nextPossibleStatus in nextPossibleStatuses) + { + yield return nextPossibleStatus; + yield return nextPossibleStatus.Concat(new[] { nextStatus }); + } + } + else + { + yield return new[] { nextStatus }; + } + } + } +} diff --git a/tests/NgTests/Validation/RegistrationVersionValidatorTestData.cs b/tests/NgTests/Validation/RegistrationVersionValidatorTestData.cs index c01f0140b..531780147 100644 --- a/tests/NgTests/Validation/RegistrationVersionValidatorTestData.cs +++ b/tests/NgTests/Validation/RegistrationVersionValidatorTestData.cs @@ -21,8 +21,10 @@ protected override RegistrationVersionValidator CreateValidator( public override IEnumerable> CreateIndexes => new Func[] { - () => new PackageRegistrationIndexMetadata() { Version = new NuGetVersion(1, 0, 0) }, - () => new PackageRegistrationIndexMetadata() { Version = new NuGetVersion(2, 0, 0) } + () => new PackageRegistrationIndexMetadata() { Version = new NuGetVersion("1.0.0") }, + () => new PackageRegistrationIndexMetadata() { Version = new NuGetVersion("2.0.0-pre") }, + () => new PackageRegistrationIndexMetadata() { Version = new NuGetVersion("3.4.3+build") }, + () => new PackageRegistrationIndexMetadata() { Version = new NuGetVersion("87.23.11-alpha.9") } }; public override IEnumerable> CreateSkippedIndexes => new Func[] diff --git a/tests/NgTests/Validation/ValidationContextTests.cs b/tests/NgTests/Validation/ValidationContextTests.cs index 532d27311..52b187f3a 100644 --- a/tests/NgTests/Validation/ValidationContextTests.cs +++ b/tests/NgTests/Validation/ValidationContextTests.cs @@ -189,8 +189,8 @@ public void GetIndexV2Async_ReturnsMemoizedIndexTask() { var context = CreateContext(); - var task1 = context.GetIndexV2Async(); - var task2 = context.GetIndexV2Async(); + var task1 = context.GetIndexDatabaseAsync(); + var task2 = context.GetIndexDatabaseAsync(); Assert.Same(task1, task2); } @@ -206,7 +206,7 @@ public async Task GetIndexV2Async_ReturnsIndex() var context = CreateContext(v2Resource: v2Resource.Object); - var actualResult = await context.GetIndexV2Async(); + var actualResult = await context.GetIndexDatabaseAsync(); Assert.Same(expectedResult, actualResult); } @@ -243,8 +243,8 @@ public void GetLeafV2Async_ReturnsMemoizedIndexTask() { var context = CreateContext(); - var task1 = context.GetLeafV2Async(); - var task2 = context.GetLeafV2Async(); + var task1 = context.GetLeafDatabaseAsync(); + var task2 = context.GetLeafDatabaseAsync(); Assert.Same(task1, task2); } @@ -260,7 +260,7 @@ public async Task GetLeafV2Async_ReturnsLeaf() var context = CreateContext(v2Resource: v2Resource.Object); - var actualResult = await context.GetLeafV2Async(); + var actualResult = await context.GetLeafDatabaseAsync(); Assert.Same(expectedResult, actualResult); } @@ -303,7 +303,7 @@ public async Task GetTimestampMetadataV2Async_ReturnsCorrectValue() timestampMetadataResourceV2.Setup(x => x.GetAsync(It.Is(vc => vc == context))) .ReturnsAsync(timestampMetadata); - var actualResult = await context.GetTimestampMetadataV2Async(); + var actualResult = await context.GetTimestampMetadataDatabaseAsync(); Assert.Same(timestampMetadata, actualResult); } @@ -319,8 +319,8 @@ public void GetTimestampMetadataV2Async_ReturnsMemoizedTimestampMetadataV2Task() timestampMetadataResourceV2.Setup(x => x.GetAsync(It.Is(vc => vc == context))) .ReturnsAsync(timestampMetadata); - var task1 = context.GetTimestampMetadataV2Async(); - var task2 = context.GetTimestampMetadataV2Async(); + var task1 = context.GetTimestampMetadataDatabaseAsync(); + var task2 = context.GetTimestampMetadataDatabaseAsync(); Assert.Same(task1, task2); } diff --git a/tests/NuGet.IndexingTests/Properties/AssemblyInfo.cs b/tests/NuGet.IndexingTests/Properties/AssemblyInfo.cs index 2006d8260..44999f380 100644 --- a/tests/NuGet.IndexingTests/Properties/AssemblyInfo.cs +++ b/tests/NuGet.IndexingTests/Properties/AssemblyInfo.cs @@ -1,5 +1,4 @@ using System.Reflection; -using System.Runtime.CompilerServices; using System.Runtime.InteropServices; // General Information about an assembly is controlled through the following diff --git a/tests/NuGet.IndexingTests/TestSupport/MockSearcher.cs b/tests/NuGet.IndexingTests/TestSupport/MockSearcher.cs index 31d0436d2..e9376f7f4 100644 --- a/tests/NuGet.IndexingTests/TestSupport/MockSearcher.cs +++ b/tests/NuGet.IndexingTests/TestSupport/MockSearcher.cs @@ -8,7 +8,6 @@ using Microsoft.Extensions.Logging; using Moq; using NuGet.Indexing; -using NuGet.Services.Configuration; namespace NuGet.IndexingTests.TestSupport { diff --git a/tests/NuGet.IndexingTests/VersionResultTests.cs b/tests/NuGet.IndexingTests/VersionResultTests.cs index f4311b37a..cd42de45e 100644 --- a/tests/NuGet.IndexingTests/VersionResultTests.cs +++ b/tests/NuGet.IndexingTests/VersionResultTests.cs @@ -5,7 +5,6 @@ using NuGet.Indexing; using NuGet.Versioning; using System; -using System.Collections; using System.Collections.Generic; using System.Linq; using Xunit; diff --git a/tests/NuGet.Protocol.Catalog.Tests/CatalogClientFacts.cs b/tests/NuGet.Protocol.Catalog.Tests/CatalogClientFacts.cs index 756d31fed..c71e68eba 100644 --- a/tests/NuGet.Protocol.Catalog.Tests/CatalogClientFacts.cs +++ b/tests/NuGet.Protocol.Catalog.Tests/CatalogClientFacts.cs @@ -4,7 +4,6 @@ using System; using System.Net.Http; using System.Threading.Tasks; -using Microsoft.Extensions.Logging.Abstractions; using Xunit; namespace NuGet.Protocol.Catalog diff --git a/tests/NuGet.Services.BasicSearchTests/DictionaryConfigurationProvider.cs b/tests/NuGet.Services.BasicSearchTests/DictionaryConfigurationProvider.cs index 291de3fad..1aca512f7 100644 --- a/tests/NuGet.Services.BasicSearchTests/DictionaryConfigurationProvider.cs +++ b/tests/NuGet.Services.BasicSearchTests/DictionaryConfigurationProvider.cs @@ -1,7 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; +using System.Collections.Generic; using System.Threading.Tasks; using NuGet.Services.Configuration; diff --git a/tests/NuGet.Services.BasicSearchTests/Properties/AssemblyInfo.cs b/tests/NuGet.Services.BasicSearchTests/Properties/AssemblyInfo.cs index 27c010d4e..2bbc8c00f 100644 --- a/tests/NuGet.Services.BasicSearchTests/Properties/AssemblyInfo.cs +++ b/tests/NuGet.Services.BasicSearchTests/Properties/AssemblyInfo.cs @@ -1,5 +1,4 @@ using System.Reflection; -using System.Runtime.CompilerServices; using System.Runtime.InteropServices; // General Information about an assembly is controlled through the following