File: Latency\AcceptanceTests.cs
Web Access
Project: src\test\Libraries\Microsoft.AspNetCore.Diagnostics.Middleware.Tests\Microsoft.AspNetCore.Diagnostics.Middleware.Tests.csproj (Microsoft.AspNetCore.Diagnostics.Middleware.Tests)
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
 
using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.TestHost;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Diagnostics.Latency;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Hosting.Testing;
using Xunit;
 
namespace Microsoft.AspNetCore.Diagnostics.Latency.Test;
 
public class AcceptanceTests
{
    [Fact]
    public async Task RequestLatency_LatencyContextIsStarted()
    {
        bool isInLambda = false;
        string checkpointName = "testc";
        string tagName = "testt";
        string measureName = "testm";
 
        using var host = await FakeHost.CreateBuilder()
            .ConfigureWebHost(webBuilder => webBuilder
                .UseTestServer()
                .ConfigureServices(services =>
                {
                    services
                        .AddRouting()
                        .AddLatencyContext()
                        .AddRequestLatencyTelemetry()
                        .RegisterCheckpointNames(new[] { checkpointName })
                        .RegisterTagNames(new[] { tagName })
                        .RegisterMeasureNames(new[] { measureName });
                })
                .Configure(app =>
                {
                    app.UseRouting();
                    app.UseRequestLatencyTelemetry();
                    app.Use(async (context, next) =>
                    {
                        string tagValue = "testVal";
                        int measureValue = 17;
                        int taskTimeMs = 20;
 
                        isInLambda = true;
                        var latencyContext = context.RequestServices.GetRequiredService<ILatencyContext>();
                        var tokenIssuer = context.RequestServices.GetRequiredService<ILatencyContextTokenIssuer>();
                        Assert.NotNull(latencyContext);
                        latencyContext.AddCheckpoint(tokenIssuer.GetCheckpointToken(checkpointName));
                        latencyContext.SetTag(tokenIssuer.GetTagToken(tagName), tagValue);
                        latencyContext.RecordMeasure(tokenIssuer.GetMeasureToken(measureName), measureValue);
                        await Task.Delay(taskTimeMs + 10); // Adding 10 ms buffer
                        await next.Invoke().ConfigureAwait(false);
 
                        var ld = latencyContext!.LatencyData;
                        Assert.True(IsMatchByName(ld.Checkpoints, (c) => c.Name == checkpointName));
                        Assert.True(IsMatchByName(ld.Measures, (m) => m.Name == measureName));
                        Assert.True(IsMatchByName(ld.Tags, (t) => t.Name == tagName));
                        Assert.True(((double)ld.DurationTimestamp / ld.DurationTimestampFrequency) * 1000 >= taskTimeMs);
                    });
 
                    app.UseEndpoints(endpoints =>
                    {
                        endpoints.MapGet("/", async context =>
                        {
                            await context.Response.WriteAsync("Hello World!");
                        });
                    });
                }))
            .StartAsync();
 
        _ = await host.GetTestClient().GetAsync("/");
        await host.StopAsync();
 
        Assert.True(isInLambda);
    }
 
    private static bool IsMatchByName<TX>(in ReadOnlySpan<TX> span, Func<TX, bool> isMatch)
    {
        for (int i = 0; i < span.Length; i++)
        {
            if (isMatch(span[i]))
            {
                return true;
            }
        }
 
        return false;
    }
}