/
githubmirror
/
roslyn
Обзор
Документация
Войти
/
githubmirror
/
roslyn
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
src/VisualStudio/IntegrationTest/New.IntegrationTests/InProcess/TelemetryInProcess.cs
117 строк
4 KB
Cyrus Najmabadi
Make sealed
26 мар 2025, 22:21
26 мар 2025, 22:21
d99b771
Код
Авторство
О чём код?
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. using System; using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; using Microsoft.VisualStudio.Extensibility.Testing; using Microsoft.VisualStudio.Telemetry; using Microsoft.VisualStudio.Threading; using Xunit; using IAsyncDisposable = System.IAsyncDisposable; namespace Roslyn.VisualStudio.IntegrationTests.InProcess; [TestService] internal sealed partial class TelemetryInProcess { internal async Task<TelemetryVerifier> EnableTestTelemetryChannelAsync(CancellationToken cancellationToken) { await JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken); TelemetryService.DetachTestChannel(LoggerTestChannel.Instance); LoggerTestChannel.Instance.Clear(); TelemetryService.AttachTestChannel(LoggerTestChannel.Instance); return new TelemetryVerifier(TestServices); } internal async Task DisableTestTelemetryChannelAsync(CancellationToken cancellationToken) { await JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken); TelemetryService.DetachTestChannel(LoggerTestChannel.Instance); LoggerTestChannel.Instance.Clear(); } public async Task<bool> TryWaitForTelemetryEventsAsync(string[] names, CancellationToken cancellationToken) => await LoggerTestChannel.Instance.TryWaitForEventsAsync(names, cancellationToken); public sealed class TelemetryVerifier : IAsyncDisposable { internal TestServices _testServices; public TelemetryVerifier(TestServices testServices) { _testServices = testServices; } public async ValueTask DisposeAsync() => await _testServices.Telemetry.DisableTestTelemetryChannelAsync(CancellationToken.None); /// <summary> /// Asserts that a telemetry event of the given name was fired. Does not /// do any additional validation (of performance numbers, etc). /// </summary> /// <param name="expectedEventNames"></param> public async Task VerifyFiredAsync(string[] expectedEventNames, CancellationToken cancellationToken) { var telemetryEnabled = await _testServices.Telemetry.TryWaitForTelemetryEventsAsync(expectedEventNames, cancellationToken); if (string.Equals(Environment.GetEnvironmentVariable("ROSLYN_TEST_CI"), "true", StringComparison.OrdinalIgnoreCase)) { // Telemetry verification is optional for developer machines, but required for CI. Assert.True(telemetryEnabled); } } } private sealed class LoggerTestChannel : ITelemetryTestChannel { public static readonly LoggerTestChannel Instance = new(); private AsyncQueue<TelemetryEvent> _eventsQueue = new(); /// <summary> /// Waits for one or more events with the specified names /// </summary> /// <param name="events"></param> public async Task<bool> TryWaitForEventsAsync(string[] events, CancellationToken cancellationToken) { if (!TelemetryService.DefaultSession.IsOptedIn) return false; var set = new HashSet<string>(events); while (set.Count > 0) { var result = await _eventsQueue.DequeueAsync(cancellationToken); set.Remove(result.Name); } return true; } /// <summary> /// Clear current queue. /// </summary> public void Clear() { _eventsQueue.Complete(); _eventsQueue = new AsyncQueue<TelemetryEvent>(); } /// <summary> /// Process incoming events. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> void ITelemetryTestChannel.OnPostEvent(object sender, TelemetryTestChannelEventArgs e) { _eventsQueue.Enqueue(e.Event); } } }