예제 #1
0
        public async Task UpdateStateAsync(IProgress <IItemLoaderState> progress, CancellationToken cancellationToken)
        {
            cancellationToken.ThrowIfCancellationRequested();
            SearchResultContextInfo searchResult = await _searchService.RefreshSearchAsync(cancellationToken);

            cancellationToken.ThrowIfCancellationRequested();
            await UpdateStateAndReportAsync(searchResult, progress, cancellationToken);
        }
        public async Task GetCurrent_WithAnySearchResults_PreservesSearchResultsOrderAsync(string[] inputIds)
        {
            // Arrange
            var psmContextInfos = new List <PackageSearchMetadataContextInfo>();

            foreach (var id in inputIds)
            {
                psmContextInfos.Add(PackageSearchMetadataContextInfo.Create(new PackageSearchMetadataBuilder.ClonedPackageSearchMetadata()
                {
                    Identity = new PackageIdentity(id, new NuGetVersion("1.0")),
                }));
            }
            var searchResult = new SearchResultContextInfo(psmContextInfos, new Dictionary <string, LoadingStatus> {
                { "Search", LoadingStatus.Loading }
            }, hasMoreItems: false);

            var serviceBroker      = Mock.Of <IServiceBroker>();
            var packageFileService = new Mock <INuGetPackageFileService>();
            var searchService      = new Mock <IReconnectingNuGetSearchService>(MockBehavior.Strict);

            searchService.Setup(s => s.SearchAsync(It.IsAny <IReadOnlyCollection <IProjectContextInfo> >(),
                                                   It.IsAny <IReadOnlyCollection <PackageSourceContextInfo> >(),
                                                   It.IsAny <IReadOnlyCollection <string> >(),
                                                   It.IsAny <string>(),
                                                   It.IsAny <SearchFilter>(),
                                                   It.IsAny <NuGet.VisualStudio.Internal.Contracts.ItemFilter>(),
                                                   It.IsAny <bool>(),
                                                   It.IsAny <bool>(),
                                                   It.IsAny <CancellationToken>()))
            .Returns(new ValueTask <SearchResultContextInfo>(searchResult));
            var uiContext = new Mock <INuGetUIContext>();

            uiContext.Setup(ui => ui.ServiceBroker).Returns(serviceBroker);
            var context      = new PackageLoadContext(isSolution: false, uiContext.Object);
            var mockProgress = Mock.Of <IProgress <IItemLoaderState> >();

            using var localFeedDir = TestDirectory.Create(); // local feed
            var localSource = new PackageSource(localFeedDir);
            var loader      = await PackageItemLoader.CreateAsync(
                serviceBroker,
                context,
                new List <PackageSourceContextInfo>() { PackageSourceContextInfo.Create(localSource) },
                NuGet.VisualStudio.Internal.Contracts.ItemFilter.All,
                searchService.Object,
                packageFileService.Object,
                TestSearchTerm);

            // Act
            await loader.LoadNextAsync(progress : mockProgress, CancellationToken.None);

            IEnumerable <PackageItemViewModel> items = loader.GetCurrent();

            // Assert
            string[] result = items.Select(pkg => pkg.Id).ToArray();
            Assert.Equal(inputIds, result);
        }
예제 #3
0
        public async Task UpdateStateAsync(IProgress <IItemLoaderState> progress, CancellationToken cancellationToken)
        {
            cancellationToken.ThrowIfCancellationRequested();

            NuGetEventTrigger.Instance.TriggerEvent(NuGetEvent.PackageLoadBegin);

            progress?.Report(_state);

            SearchResultContextInfo searchResult = await _searchService.RefreshSearchAsync(cancellationToken);

            cancellationToken.ThrowIfCancellationRequested();
            await UpdateStateAndReportAsync(searchResult, progress, cancellationToken);

            NuGetEventTrigger.Instance.TriggerEvent(NuGetEvent.PackageLoadEnd);
        }
        public void SerializeThenDeserialize_WithValidArguments_RoundTrips(SearchResultContextInfo expectedResult)
        {
            var formatters = new IMessagePackFormatter[]
            {
                PackageSearchMetadataContextInfoFormatter.Instance,
                PackageVulnerabilityMetadataContextInfoFormatter.Instance,
            };
            var resolvers = new IFormatterResolver[] { MessagePackSerializerOptions.Standard.Resolver };
            var options   = MessagePackSerializerOptions.Standard.WithSecurity(MessagePackSecurity.UntrustedData).WithResolver(CompositeResolver.Create(formatters, resolvers));

            SearchResultContextInfo actualResult = SerializeThenDeserialize(SearchResultContextInfoFormatter.Instance, expectedResult, options);

            Assert.Equal(expectedResult.OperationId, actualResult.OperationId);
            Assert.Equal(expectedResult.HasMoreItems, actualResult.HasMoreItems);
            Assert.Equal(expectedResult.SourceLoadingStatus, actualResult.SourceLoadingStatus);
            Assert.Equal(expectedResult.PackageSearchItems.Count, actualResult.PackageSearchItems.Count);
        }
예제 #5
0
        public async Task LoadNextAsync(IProgress <IItemLoaderState> progress, CancellationToken cancellationToken)
        {
            ActivityCorrelationId.StartNew();

            cancellationToken.ThrowIfCancellationRequested();

            await UpdateStateAndReportAsync(
                new SearchResultContextInfo(Array.Empty <PackageSearchMetadataContextInfo>(),
                                            ImmutableDictionary <string, LoadingStatus> .Empty,
                                            hasMoreItems : _state.Results?.HasMoreItems ?? false),
                progress,
                cancellationToken);

            SearchResultContextInfo searchResult = await SearchAsync(cancellationToken);

            cancellationToken.ThrowIfCancellationRequested();

            await UpdateStateAndReportAsync(searchResult, progress, cancellationToken);
        }
예제 #6
0
        public async ValueTask <IReadOnlyCollection <PackageSearchMetadataContextInfo> > GetAllPackagesAsync(SearchFilter searchFilter, CancellationToken cancellationToken)
        {
            var packages = new List <PackageSearchMetadataContextInfo>();

            do
            {
                SearchResultContextInfo searchResult = _lastMainFeedSearchResult?.NextToken != null
                    ? await ContinueSearchAsync(cancellationToken)
                    : await SearchAsync(string.Empty, searchFilter, useRecommender : false, cancellationToken);

                if (_lastMainFeedSearchResult?.RefreshToken != null)
                {
                    searchResult = await RefreshSearchAsync(cancellationToken);
                }

                packages.AddRange(searchResult.PackageSearchItems);
            } while (_lastMainFeedSearchResult?.NextToken != null);

            return(packages);
        }
예제 #7
0
        public async Task UpdateStateAndReportAsync(SearchResultContextInfo searchResult, IProgress <IItemLoaderState> progress, CancellationToken cancellationToken)
        {
            // cache installed packages here for future use
            _installedPackages = await _context.GetInstalledPackagesAsync();

            // fetch package references from all the projects and cache locally
            // for solution view, we'll always show the highest available version
            // but for project view, get the allowed version range and pass it to package item view model to choose the latest version based on that
            if (_packageReferences == null && !_context.IsSolution)
            {
                IEnumerable <Task <IReadOnlyCollection <IPackageReferenceContextInfo> > > tasks = _context.Projects
                                                                                                  .Select(project => project.GetInstalledPackagesAsync(
                                                                                                              _context.ServiceBroker,
                                                                                                              cancellationToken).AsTask());
                _packageReferences = (await Task.WhenAll(tasks)).SelectMany(p => p).Where(p => p != null);
            }

            var state = new PackageFeedSearchState(searchResult);

            _state = state;
            progress?.Report(state);
        }
예제 #8
0
        public async Task MultipleSourcesPrefixReserved_Works()
        {
            var solutionManager = Mock.Of <INuGetSolutionManagerService>();
            var uiContext       = new Mock <INuGetUIContext>();
            var searchService   = new Mock <INuGetSearchService>(MockBehavior.Strict);

            var packageSearchMetadata = new PackageSearchMetadataBuilder.ClonedPackageSearchMetadata()
            {
                Identity       = new PackageIdentity("NuGet.org", new NuGetVersion("1.0")),
                PrefixReserved = true
            };

            var packageSearchMetadataContextInfo = new List <PackageSearchMetadataContextInfo>()
            {
                PackageSearchMetadataContextInfo.Create(packageSearchMetadata)
            };

            var searchResult = new SearchResultContextInfo(packageSearchMetadataContextInfo, new Dictionary <string, LoadingStatus> {
                { "Completed", LoadingStatus.Ready }
            }, false);

            searchService.Setup(x =>
                                x.SearchAsync(
                                    It.IsAny <IReadOnlyCollection <IProjectContextInfo> >(),
                                    It.IsAny <IReadOnlyCollection <PackageSourceContextInfo> >(),
                                    It.IsAny <IReadOnlyCollection <string> >(),
                                    It.IsAny <string>(),
                                    It.IsAny <SearchFilter>(),
                                    It.IsAny <NuGet.VisualStudio.Internal.Contracts.ItemFilter>(),
                                    It.IsAny <bool>(),
                                    It.IsAny <CancellationToken>()))
            .Returns(new ValueTask <SearchResultContextInfo>(searchResult));

            searchService.Setup(x =>
                                x.RefreshSearchAsync(It.IsAny <CancellationToken>()))
            .Returns(new ValueTask <SearchResultContextInfo>(searchResult));

            uiContext.Setup(x => x.SolutionManagerService)
            .Returns(solutionManager);

            uiContext.Setup(x => x.ServiceBroker)
            .Returns(Mock.Of <IServiceBroker>());

            var source1 = new PackageSourceContextInfo("https://pkgs.dev.azure.com/dnceng/public/_packaging/nuget-build/nuget/v3/index.json", "NuGetBuild");
            var source2 = new PackageSourceContextInfo("https://api.nuget.org/v3/index.json", "NuGet.org");

            var context = new PackageLoadContext(false, uiContext.Object);
            var loader  = await PackageItemLoader.CreateAsync(
                Mock.Of <IServiceBroker>(),
                context,
                new List <PackageSourceContextInfo> {
                source1, source2
            },
                NuGet.VisualStudio.Internal.Contracts.ItemFilter.All,
                searchService.Object,
                TestSearchTerm);

            await loader.LoadNextAsync(null, CancellationToken.None);

            var items = loader.GetCurrent();

            Assert.NotEmpty(items);

            // All items should not have a prefix reserved because the feed is multisource
            foreach (var item in items)
            {
                Assert.False(item.PrefixReserved);
            }
        }
예제 #9
0
        public async Task PackageReader_NotNull()
        {
            // Prepare
            var solutionManager = Mock.Of <INuGetSolutionManagerService>();
            var uiContext       = new Mock <INuGetUIContext>();

            uiContext.Setup(x => x.SolutionManagerService)
            .Returns(solutionManager);
            var searchService = new Mock <INuGetSearchService>(MockBehavior.Strict);

            var packageSearchMetadata = new PackageSearchMetadataBuilder.ClonedPackageSearchMetadata()
            {
                Identity       = new PackageIdentity("NuGet.org", new NuGetVersion("1.0")),
                PrefixReserved = true
            };

            var packageSearchMetadataContextInfo = new List <PackageSearchMetadataContextInfo>()
            {
                PackageSearchMetadataContextInfo.Create(packageSearchMetadata)
            };

            var searchResult = new SearchResultContextInfo(packageSearchMetadataContextInfo, new Dictionary <string, LoadingStatus> {
                { "Search", LoadingStatus.Loading }
            }, false);

            searchService.Setup(x =>
                                x.SearchAsync(
                                    It.IsAny <IReadOnlyCollection <IProjectContextInfo> >(),
                                    It.IsAny <IReadOnlyCollection <PackageSourceContextInfo> >(),
                                    It.IsAny <IReadOnlyCollection <string> >(),
                                    It.IsAny <string>(),
                                    It.IsAny <SearchFilter>(),
                                    It.IsAny <NuGet.VisualStudio.Internal.Contracts.ItemFilter>(),
                                    It.IsAny <bool>(),
                                    It.IsAny <CancellationToken>()))
            .Returns(new ValueTask <SearchResultContextInfo>(searchResult));

            uiContext.Setup(x => x.ServiceBroker)
            .Returns(Mock.Of <IServiceBroker>());

            using (var localFeedDir = TestDirectory.Create()) // local feed
            {
                // create test package
                var pkgId = new PackageIdentity("nuget.lpsm.test", new NuGetVersion(0, 0, 1));
                var pkg   = new SimpleTestPackageContext(pkgId.Id, pkgId.Version.ToNormalizedString());
                await SimpleTestPackageUtility.CreatePackagesAsync(localFeedDir.Path, pkg);

                // local test source
                var localUri    = new Uri(localFeedDir.Path, UriKind.Absolute);
                var localSource = new PackageSource(localUri.ToString(), "LocalSource");

                var sourceRepositoryProvider = TestSourceRepositoryUtility.CreateSourceRepositoryProvider(new[] { localSource });
                var repositories             = sourceRepositoryProvider.GetRepositories();

                var context = new PackageLoadContext(isSolution: false, uiContext.Object);

                var packageFeed = new MultiSourcePackageFeed(repositories, logger: null, telemetryService: null);
                var loader      = await PackageItemLoader.CreateAsync(
                    Mock.Of <IServiceBroker>(),
                    context,
                    new List <PackageSourceContextInfo> {
                    PackageSourceContextInfo.Create(localSource)
                },
                    NuGet.VisualStudio.Internal.Contracts.ItemFilter.All,
                    searchService.Object,
                    TestSearchTerm);

                // Act
                await loader.LoadNextAsync(progress : null, CancellationToken.None);

                var results = loader.GetCurrent();

                // Assert
                Assert.Single(results);
                Assert.NotNull(results.First().PackageReader);
            }
        }
예제 #10
0
 public PackageFeedSearchState(SearchResultContextInfo results)
 {
     _results = results ?? throw new ArgumentNullException(nameof(results));
 }
예제 #11
0
        public async Task PackagePrefixReservation_FromMultiSource()
        {
            var solutionManager    = Mock.Of <INuGetSolutionManagerService>();
            var uiContext          = new Mock <INuGetUIContext>();
            var searchService      = Mock.Of <INuGetSearchService>();
            var packageFileService = Mock.Of <INuGetPackageFileService>();

            uiContext.Setup(x => x.SolutionManagerService)
            .Returns(solutionManager);

            uiContext.Setup(x => x.ServiceBroker)
            .Returns(Mock.Of <IServiceBroker>());

            // Arrange
            var responses = new Dictionary <string, string>
            {
                {
                    "https://api-v3search-0.nuget.org/query?q=EntityFramework&skip=0&take=26&prerelease=false&semVerLevel=2.0.0",
                    ProtocolUtility.GetResource("NuGet.PackageManagement.UI.Test.compiler.resources.EntityFrameworkSearch.json", GetType())
                },
                { "http://testsource.com/v3/index.json", JsonData.IndexWithoutFlatContainer },
                { "http://othersource.com/v3/index.json", JsonData.IndexWithoutFlatContainer }
            };

            var repo  = StaticHttpHandler.CreateSource("http://testsource.com/v3/index.json", Repository.Provider.GetCoreV3(), responses);
            var repo1 = StaticHttpHandler.CreateSource("http://othersource.com/v3/index.json", Repository.Provider.GetCoreV3(), responses);

            var context = new PackageLoadContext(isSolution: false, uiContext.Object);

            var loader = await PackageItemLoader.CreateAsync(
                Mock.Of <IServiceBroker>(),
                context,
                new List <PackageSourceContextInfo>
            {
                PackageSourceContextInfo.Create(repo.PackageSource),
                PackageSourceContextInfo.Create(repo1.PackageSource)
            },
                NuGet.VisualStudio.Internal.Contracts.ItemFilter.All,
                searchService,
                packageFileService,
                "EntityFramework",
                includePrerelease : false);

            var packageSearchMetadata = new PackageSearchMetadataBuilder.ClonedPackageSearchMetadata()
            {
                Identity       = new PackageIdentity("NuGet.org", new NuGetVersion("1.0")),
                PrefixReserved = true
            };

            var packageSearchMetadataContextInfo = new List <PackageSearchMetadataContextInfo>()
            {
                PackageSearchMetadataContextInfo.Create(packageSearchMetadata)
            };

            var searchResult = new SearchResultContextInfo(
                packageSearchMetadataContextInfo,
                new Dictionary <string, LoadingStatus> {
                { "Completed", LoadingStatus.Ready }
            },
                hasMoreItems: false);

            await loader.UpdateStateAndReportAsync(searchResult, progress : null, CancellationToken.None);

            var items = loader.GetCurrent();

            // Resource only has one item
            var item = items.First();

            // Assert that a multisource always has prefixreserved set to false
            Assert.False(item.PrefixReserved);
        }
        public async Task ContinueSearchAsync_WhenSearchIsContinuable_Continues()
        {
            var telemetryService = new Mock <INuGetTelemetryService>();
            var eventsQueue      = new ConcurrentQueue <TelemetryEvent>();

            telemetryService
            .Setup(x => x.EmitTelemetryEvent(It.IsAny <TelemetryEvent>()))
            .Callback <TelemetryEvent>(e => eventsQueue.Enqueue(e));

            TelemetryActivity.NuGetTelemetryService = telemetryService.Object;

            using (NuGetPackageSearchService searchService = SetupSearchService())
            {
                SearchResultContextInfo searchResult = await searchService.SearchAsync(
                    _projects,
                    new List <PackageSourceContextInfo> {
                    PackageSourceContextInfo.Create(_sourceRepository.PackageSource)
                },
                    targetFrameworks : new List <string>()
                {
                    "net45", "net5.0"
                },
                    searchText : "nuget",
                    new SearchFilter(includePrerelease : true),
                    NuGet.VisualStudio.Internal.Contracts.ItemFilter.All,
                    useRecommender : true,
                    CancellationToken.None);

                SearchResultContextInfo continueSearchResult = await searchService.ContinueSearchAsync(CancellationToken.None);

                Assert.True(searchResult.PackageSearchItems.First().Title.Equals("NuGet.Core1", StringComparison.OrdinalIgnoreCase));
                Assert.True(continueSearchResult.PackageSearchItems.First().Title.Equals("NuGet.Core27", StringComparison.OrdinalIgnoreCase));

                TelemetryEvent[] events = eventsQueue.ToArray();
                Assert.True(4 == events.Length, string.Join(Environment.NewLine, events.Select(e => e.Name)));

                TelemetryEvent search = Assert.Single(events, e => e.Name == "Search");
                Assert.Equal(true, search["IncludePrerelease"]);
                Assert.Equal("nuget", search.GetPiiData().First(p => p.Key == "Query").Value);
                string operationId       = Assert.IsType <string>(search["OperationId"]);
                Guid   parsedOperationId = Guid.ParseExact(operationId, "D");

                TelemetryEvent sources = Assert.Single(events, e => e.Name == "SearchPackageSourceSummary");
                Assert.Equal(1, sources["NumHTTPv3Feeds"]);
                Assert.Equal("NotPresent", sources["NuGetOrg"]);
                Assert.Equal(operationId, sources["ParentId"]);

                TelemetryEvent page0 = Assert.Single(events, e => e.Name == "SearchPage" && e["PageIndex"] is int && (int)e["PageIndex"] == 0);
                Assert.Equal("Ready", page0["LoadingStatus"]);
                Assert.Equal(operationId, page0["ParentId"]);
                Assert.IsType <int>(page0["ResultCount"]);
                Assert.IsType <double>(page0["Duration"]);
                Assert.IsType <double>(page0["ResultsAggregationDuration"]);
                Assert.IsType <string>(page0["IndividualSourceDurations"]);
                Assert.Equal(1, ((JArray)JsonConvert.DeserializeObject((string)page0["IndividualSourceDurations"])).Values <double>().Count());

                TelemetryEvent page1 = Assert.Single(events, e => e.Name == "SearchPage" && e["PageIndex"] is int && (int)e["PageIndex"] == 1);
                Assert.Equal("Ready", page1["LoadingStatus"]);
                Assert.Equal(operationId, page1["ParentId"]);
                Assert.IsType <int>(page1["ResultCount"]);
                Assert.IsType <double>(page1["Duration"]);
                Assert.IsType <double>(page1["ResultsAggregationDuration"]);
                Assert.IsType <string>(page1["IndividualSourceDurations"]);
                Assert.Equal(1, ((JArray)JsonConvert.DeserializeObject((string)page1["IndividualSourceDurations"])).Values <double>().Count());
            }
        }