Example #1
0
        public void AddAggregateData_DifferentSources()
        {
            // Arrange
            var pde1 = CreateSampleProtocolDiagnosticsEvent(source: "source1");
            var pde2 = CreateSampleProtocolDiagnosticsEvent(source: "source2");
            var data = new ConcurrentDictionary <string, PackageSourceTelemetry.Data>();

            // Act
            PackageSourceTelemetry.AddAggregateData(pde1, data);
            PackageSourceTelemetry.AddAggregateData(pde2, data);

            // Assert
            Assert.Equal(2, data.Count);
        }
Example #2
0
        public void AddResourceData_SameSourceDifferentResource_StoredSeparately()
        {
            // Arrange
            var re1         = CreateSampleResourceEvent(method: nameof(FindPackageByIdResource.GetDependencyInfoAsync));
            var re2         = CreateSampleResourceEvent(method: nameof(FindPackageByIdResource.CopyNupkgToStreamAsync));
            var data        = CreateDataDictionary(SampleSource);
            var stringTable = new ConcurrentDictionary <string, ConcurrentDictionary <string, string> >();

            // Act
            PackageSourceTelemetry.AddResourceData(re1, data, stringTable);
            PackageSourceTelemetry.AddResourceData(re2, data, stringTable);

            // Assert
            var sourceData = data[SampleSource];

            Assert.Equal(2, sourceData.Resources.Count);
        }
Example #3
0
        public void Ctor_DuplicateSourceUrls_DoesNotThrow()
        {
            // Arrange
            const string feedUrl = "https://source.test/v3/index.json";

            SourceRepository[] sources = new[]
            {
                new SourceRepository(new PackageSource(source: feedUrl, name: "Source1"), Repository.Provider.GetCoreV3()),
                new SourceRepository(new PackageSource(source: feedUrl, name: "Source2"), Repository.Provider.GetCoreV3())
            };

            // Act
            _ = new PackageSourceTelemetry(sources, Guid.Empty, PackageSourceTelemetry.TelemetryAction.Restore);

            // Assert
            // no assert, just making sure ctor didn't throw.
        }
Example #4
0
        public void AddAggregateData_HeaderTimingCountedCorrectly()
        {
            // Arrange
            var pde1 = CreateSampleProtocolDiagnosticsEvent(headerDuration: null);
            var pde2 = CreateSampleProtocolDiagnosticsEvent(headerDuration: TimeSpan.FromMilliseconds(100));
            var data = new ConcurrentDictionary <string, PackageSourceTelemetry.Data>();

            // Act
            PackageSourceTelemetry.AddAggregateData(pde1, data);
            PackageSourceTelemetry.AddAggregateData(pde2, data);

            // Assert
            KeyValuePair <string, PackageSourceTelemetry.Data> pair = Assert.Single(data);

            Assert.Equal(1, pair.Value.Nupkg.HeaderTiming.Requests);
            Assert.Equal(2, pair.Value.Nupkg.EventTiming.Requests);
        }
Example #5
0
        public void Ctor_DuplicateSourceUrls_DoesNotThrow()
        {
            // Arrange
            const string feedUrl = "https://source.test/v3/index.json";

            PackageSource[] sources = new[]
            {
                new PackageSource(source: feedUrl, name: "Source1"),
                new PackageSource(source: feedUrl, name: "Source2")
            };

            // Act
            _ = new PackageSourceTelemetry(sources, Guid.Empty);

            // Assert
            // no assert, just making sure ctor didn't throw.
        }
Example #6
0
        public void AddHttpData_NullHeaderDuration_SetsResultToNull()
        {
            // Arrange
            var pde1 = CreateSampleHttpEvent(headerDuration: TimeSpan.FromMilliseconds(150));
            var pde2 = CreateSampleHttpEvent(headerDuration: null);
            var pde3 = CreateSampleHttpEvent(headerDuration: TimeSpan.FromMilliseconds(100));
            var data = CreateDataDictionary(SampleSource);

            // Act
            PackageSourceTelemetry.AddHttpData(pde1, data);
            PackageSourceTelemetry.AddHttpData(pde2, data);
            PackageSourceTelemetry.AddHttpData(pde3, data);

            // Assert
            KeyValuePair <string, PackageSourceTelemetry.Data> pair = Assert.Single(data);

            Assert.Null(pair.Value.Http.HeaderDuration);
        }
Example #7
0
        public void AddAggregateData_IsThreadSafe()
        {
            // Arrange
            var data          = new ConcurrentDictionary <string, PackageSourceTelemetry.Data>();
            var eventsToRaise = 10000;

            // Act
            Parallel.For(0, eventsToRaise, _ =>
            {
                var pde = CreateSampleProtocolDiagnosticsEvent();
                PackageSourceTelemetry.AddAggregateData(pde, data);
            });

            // Assert
            KeyValuePair <string, PackageSourceTelemetry.Data> pair = Assert.Single(data);

            Assert.Equal(eventsToRaise, pair.Value.Nupkg.EventTiming.Requests);
        }
Example #8
0
        public async Task <SearchResult <IPackageSearchMetadata> > SearchAsync(string searchText, SearchFilter filter, CancellationToken cancellationToken)
        {
            var searchOperationId = Guid.NewGuid();

            if (_telemetryService != null)
            {
                _telemetryService.EmitTelemetryEvent(new SearchTelemetryEvent(
                                                         searchOperationId,
                                                         searchText,
                                                         filter.IncludePrerelease));
            }

            SearchResult <IPackageSearchMetadata> result;

            using (var packageSourceTelemetry = new PackageSourceTelemetry(_sourceRepositories, searchOperationId, PackageSourceTelemetry.TelemetryAction.Search))
            {
                var searchTasks = TaskCombinators.ObserveErrorsAsync(
                    _sourceRepositories,
                    r => r.PackageSource.Name,
                    (r, t) => r.SearchAsync(searchText, filter, PageSize, t),
                    LogError,
                    cancellationToken);

                result = await WaitForCompletionOrBailOutAsync(
                    searchText,
                    searchTasks,
                    new TelemetryState(searchOperationId, pageIndex : 0),
                    cancellationToken);

                if (_telemetryService != null)
                {
                    await packageSourceTelemetry.SendTelemetryAsync();

                    var protocolDiagnosticTotals = packageSourceTelemetry.GetTotals();
                    _telemetryService.EmitTelemetryEvent(SourceTelemetry.GetSearchSourceSummaryEvent(
                                                             searchOperationId,
                                                             _sourceRepositories.Select(x => x.PackageSource),
                                                             protocolDiagnosticTotals));
                }
            }

            return(result);
        }
Example #9
0
        public void AddResourceData_SameSourceSameResource_AccumulatesCorrectly()
        {
            // Arrange
            var re1         = CreateSampleResourceEvent(duration: TimeSpan.FromMilliseconds(100));
            var re2         = CreateSampleResourceEvent(duration: TimeSpan.FromMilliseconds(200));
            var data        = CreateDataDictionary(SampleSource);
            var stringTable = new ConcurrentDictionary <string, ConcurrentDictionary <string, string> >();

            // Act
            PackageSourceTelemetry.AddResourceData(re1, data, stringTable);
            PackageSourceTelemetry.AddResourceData(re2, data, stringTable);

            // Assert
            var result       = Assert.Single(data).Value;
            var resourceData = Assert.Single(result.Resources).Value;

            Assert.Equal(2, resourceData.count);
            Assert.Equal(TimeSpan.FromMilliseconds(300), resourceData.duration);
        }
Example #10
0
        public void AddNupkgCopiedData_MultipleEvents_AccumulatesCorrectly()
        {
            // Arrange
            var sizes = new[] { 1, 22, 333, 4444, 55555, 666666 };
            var data  = CreateDataDictionary(SampleSource);

            // Act
            for (int i = 0; i < sizes.Length; i++)
            {
                var nce = new ProtocolDiagnosticNupkgCopiedEvent(SampleSource, sizes[i]);
                PackageSourceTelemetry.AddNupkgCopiedData(nce, data);
            }

            // Assert
            var result = Assert.Single(data).Value;

            Assert.Equal(sizes.Length, result.NupkgCount);
            Assert.Equal(sizes.Sum(), result.NupkgSize);
        }
Example #11
0
        public void AddHttpData_MultipleEvents_DurationsAccumulate()
        {
            // Arrange
            var timings = new[] { TimeSpan.FromMilliseconds(100), TimeSpan.FromMilliseconds(150), TimeSpan.FromMilliseconds(200) };
            var data    = CreateDataDictionary(SampleSource);

            // Act
            for (int i = 0; i < timings.Length; i++)
            {
                var pde = CreateSampleHttpEvent(eventDuration: timings[i]);
                PackageSourceTelemetry.AddHttpData(pde, data);
            }

            // Assert
            var pair = Assert.Single(data);
            var http = pair.Value.Http;

            Assert.Equal(timings.Length, http.Requests);
            Assert.Equal(timings.Aggregate(TimeSpan.Zero, (a, b) => a + b), http.TotalDuration);
        }
Example #12
0
        public void AddAggregateData_TimingAggregation()
        {
            // Arrange
            var timings = new[] { TimeSpan.FromMilliseconds(100), TimeSpan.FromMilliseconds(150), TimeSpan.FromMilliseconds(200) };
            var data    = new ConcurrentDictionary <string, PackageSourceTelemetry.Data>();

            // Act
            for (int i = 0; i < timings.Length; i++)
            {
                var pde = CreateSampleProtocolDiagnosticsEvent(eventDuration: timings[i]);
                PackageSourceTelemetry.AddAggregateData(pde, data);
            }

            // Assert
            var pair  = Assert.Single(data);
            var times = pair.Value.Nupkg.EventTiming;

            Assert.Equal(timings.Length, times.Requests);
            Assert.Equal(timings.Sum(t => t.TotalMilliseconds), times.TotalDuration.TotalMilliseconds, precision: 3);
        }
Example #13
0
        public async Task AddData_IsThreadSafe()
        {
            // Arrange
            var data          = CreateDataDictionary(SampleSource);
            var stringTable   = new ConcurrentDictionary <string, ConcurrentDictionary <string, string> >();
            var eventsToRaise = 10000;
            var sources       = new HashSet <string>
            {
                SampleSource
            };

            Task SendEvents(Action action)
            {
                var tasks = new List <Task>();

                for (int i = 0; i < eventsToRaise; i++)
                {
                    tasks.Add(Task.Run(() => action()));
                }

                return(Task.WhenAll(tasks));
            }

            var resourceEvent    = CreateSampleResourceEvent();
            var httpEvent        = CreateSampleHttpEvent();
            var nupkgCopiedEvent = new ProtocolDiagnosticNupkgCopiedEvent(SampleSource, fileSize: 123456);

            // Act
            var resourceEvents    = Task.Run(() => SendEvents(() => PackageSourceTelemetry.AddResourceData(resourceEvent, data, stringTable)));
            var httpEvents        = Task.Run(() => SendEvents(() => PackageSourceTelemetry.AddHttpData(httpEvent, data)));
            var nupkgCopiedEvents = Task.Run(() => SendEvents(() => PackageSourceTelemetry.AddNupkgCopiedData(nupkgCopiedEvent, data)));
            await Task.WhenAll(resourceEvents, httpEvents, nupkgCopiedEvents);

            // Assert
            KeyValuePair <string, PackageSourceTelemetry.Data> pair = Assert.Single(data);

            Assert.Equal(eventsToRaise, pair.Value.Resources.Sum(r => r.Value.count));
            Assert.Equal(eventsToRaise, pair.Value.Http.Requests);
            Assert.Equal(eventsToRaise, pair.Value.NupkgCount);
        }
Example #14
0
        public void AddAggregateData_SplitsMetadataAndNupkgCorrectly(string url, bool isNupkg)
        {
            // Arrange
            var pde  = CreateSampleProtocolDiagnosticsEvent(url: new Uri(url));
            var data = new ConcurrentDictionary <string, PackageSourceTelemetry.Data>();

            // Act
            PackageSourceTelemetry.AddAggregateData(pde, data);

            // Assert
            KeyValuePair <string, PackageSourceTelemetry.Data> pair = Assert.Single(data);

            if (isNupkg)
            {
                Assert.Equal(0, pair.Value.Metadata.EventTiming.Requests);
                Assert.Equal(1, pair.Value.Nupkg.EventTiming.Requests);
            }
            else
            {
                Assert.Equal(1, pair.Value.Metadata.EventTiming.Requests);
                Assert.Equal(0, pair.Value.Nupkg.EventTiming.Requests);
            }
        }
        private async Task RestoreAsync(bool forceRestore, RestoreOperationSource restoreSource, CancellationToken token)
        {
            var startTime = DateTimeOffset.Now;

            _status = NuGetOperationStatus.NoOp;

            // start timer for telemetry event
            var stopWatch       = Stopwatch.StartNew();
            var intervalTracker = new IntervalTracker(RestoreTelemetryEvent.RestoreActionEventName);
            var projects        = Enumerable.Empty <NuGetProject>();

            _packageRestoreManager.PackageRestoredEvent      += PackageRestoreManager_PackageRestored;
            _packageRestoreManager.PackageRestoreFailedEvent += PackageRestoreManager_PackageRestoreFailedEvent;

            var sources = _sourceRepositoryProvider.GetRepositories();

            using (var packageSourceTelemetry = new PackageSourceTelemetry(sources, _nuGetProjectContext.OperationId, PackageSourceTelemetry.TelemetryAction.Restore))
            {
                try
                {
                    token.ThrowIfCancellationRequested();

                    string solutionDirectory;
                    bool   isSolutionAvailable;

                    using (intervalTracker.Start(RestoreTelemetryEvent.RestoreOperationChecks))
                    {
                        solutionDirectory   = _solutionManager.SolutionDirectory;
                        isSolutionAvailable = await _solutionManager.IsSolutionAvailableAsync();

                        // Get the projects from the SolutionManager
                        // Note that projects that are not supported by NuGet, will not show up in this list
                        projects = (await _solutionManager.GetNuGetProjectsAsync()).ToList();

                        if (projects.Any() && solutionDirectory == null)
                        {
                            _status = NuGetOperationStatus.Failed;
                            await _logger.ShowErrorAsync(Resources.SolutionIsNotSaved);

                            await _logger.WriteLineAsync(VerbosityLevel.Minimal, Resources.SolutionIsNotSaved);

                            return;
                        }
                    }

                    using (intervalTracker.Start(RestoreTelemetryEvent.PackagesConfigRestore))
                    {
                        // Check if there are any projects that are not INuGetIntegratedProject, that is,
                        // projects with packages.config. OR
                        // any of the deferred project is type of packages.config, If so, perform package restore on them
                        if (projects.Any(project => !(project is INuGetIntegratedProject)))
                        {
                            await RestorePackagesOrCheckForMissingPackagesAsync(
                                projects,
                                solutionDirectory,
                                isSolutionAvailable,
                                restoreSource,
                                token);
                        }
                    }

                    var dependencyGraphProjects = projects
                                                  .OfType <IDependencyGraphProject>()
                                                  .ToList();

                    await RestorePackageSpecProjectsAsync(
                        dependencyGraphProjects,
                        forceRestore,
                        isSolutionAvailable,
                        restoreSource,
                        intervalTracker,
                        token);

                    // TODO: To limit risk, we only publish the event when there is a cross-platform PackageReference
                    // project in the solution. Extending this behavior to all solutions is tracked here:
                    // NuGet/Home#4478
                    if (projects.OfType <CpsPackageReferenceProject>().Any())
                    {
                        _restoreEventsPublisher.OnSolutionRestoreCompleted(
                            new SolutionRestoredEventArgs(_status, solutionDirectory));
                    }
                }
                catch (OperationCanceledException)
                {
                    _status = NuGetOperationStatus.Cancelled;
                    throw;
                }
                catch
                {
                    _status = NuGetOperationStatus.Failed;
                    throw;
                }
                finally
                {
                    _packageRestoreManager.PackageRestoredEvent      -= PackageRestoreManager_PackageRestored;
                    _packageRestoreManager.PackageRestoreFailedEvent -= PackageRestoreManager_PackageRestoreFailedEvent;

                    await packageSourceTelemetry.SendTelemetryAsync();

                    stopWatch.Stop();
                    var duration = stopWatch.Elapsed;

                    // Do not log any restore message if user disabled restore.
                    if (_packageRestoreConsent.IsGranted)
                    {
                        await _logger.WriteSummaryAsync(_status, duration);
                    }
                    else
                    {
                        _logger.LogDebug(Resources.PackageRefNotRestoredBecauseOfNoConsent);
                    }

                    var protocolDiagnosticsTotals = packageSourceTelemetry.GetTotals();
                    // Emit telemetry event for restore operation
                    EmitRestoreTelemetryEvent(
                        projects,
                        forceRestore,
                        restoreSource,
                        startTime,
                        duration.TotalSeconds,
                        protocolDiagnosticsTotals,
                        intervalTracker);
                }
            }
        }