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); }
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); }
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. }
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); }
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. }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); } } }