| File: DenoFunctionalTests.cs | Web Access |
| Project: src\tests\Aspire.Hosting.JavaScript.Tests\Aspire.Hosting.JavaScript.Tests.csproj (Aspire.Hosting.JavaScript.Tests) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. #pragma warning disable ASPIREDENO001 // Type is for evaluation purposes only using System.Net; using System.Text.Json; using Aspire.TestUtilities; using Aspire.Hosting.Testing; using Microsoft.AspNetCore.InternalTesting; namespace Aspire.Hosting.JavaScript.Tests; [RequiresTools(["deno"])] public class DenoFunctionalTests : IClassFixture<DenoAppFixture> { private readonly DenoAppFixture _denoFixture; public DenoFunctionalTests(DenoAppFixture denoFixture) { _denoFixture = denoFixture; } [Fact] public async Task VerifyDenoAppDirectExecutionWorks() { using var cts = new CancellationTokenSource(TestConstants.LongTimeoutDuration); using var denoClient = _denoFixture.App.CreateHttpClient(_denoFixture.DenoAppBuilder!.Resource.Name, "http"); var response = await denoClient.GetStringAsync("/", cts.Token); Assert.Equal("Hello from deno!", response); } [Fact] public async Task VerifyDenoAppTaskScriptWorks() { using var cts = new CancellationTokenSource(TestConstants.LongTimeoutDuration); using var denoClient = _denoFixture.App.CreateHttpClient(_denoFixture.DenoScriptBuilder!.Resource.Name, "http"); var response = await denoClient.GetStringAsync("/", cts.Token); Assert.Equal("Hello from deno task!", response); } } [RequiresTools(["deno"])] public class DenoTelemetryFunctionalTests(DenoTelemetryFixture denoFixture) : IClassFixture<DenoTelemetryFixture> { [Fact] public async Task VerifyDenoAppExportsNativeTelemetryToDashboard() { using var cts = new CancellationTokenSource(TestConstants.LongTimeoutDuration); var resourceName = denoFixture.DenoAppBuilder!.Resource.Name; using var denoClient = denoFixture.App.CreateHttpClient(resourceName, "http"); var response = await denoClient.GetStringAsync("/", cts.Token); Assert.Equal("Hello from deno!", response); await WaitForDashboardTelemetryAsync(denoFixture.App, resourceName, cts.Token); } private static async Task WaitForDashboardTelemetryAsync(DistributedApplication app, string resourceName, CancellationToken cancellationToken) { using var dashboardClient = app.CreateHttpClient(DenoTelemetryFixture.AspireDashboardResourceName, "http"); dashboardClient.DefaultRequestHeaders.TryAddWithoutValidation("x-api-key", DenoTelemetryFixture.DashboardApiKey); var resourceQuery = Uri.EscapeDataString(resourceName); var tracesRequest = $"/api/telemetry/traces?resource={resourceQuery}&limit=10"; var logsRequest = $"/api/telemetry/logs?resource={resourceQuery}&limit=10"; while (true) { cancellationToken.ThrowIfCancellationRequested(); var traceCount = await GetTelemetryCountAsync(dashboardClient, tracesRequest, cancellationToken); var logCount = await GetTelemetryCountAsync(dashboardClient, logsRequest, cancellationToken); // Deno emits traces and logs over OTLP natively. Requiring both means a regression that silences // one signal fails the test instead of being masked by the other still arriving. if (traceCount > 0 && logCount > 0) { return; } await Task.Delay(TimeSpan.FromMilliseconds(500), cancellationToken); } } private static async Task<int> GetTelemetryCountAsync(HttpClient client, string requestUri, CancellationToken cancellationToken) { using var response = await client.GetAsync(requestUri, cancellationToken); if (response.StatusCode == HttpStatusCode.NotFound) { return 0; } response.EnsureSuccessStatusCode(); using var stream = await response.Content.ReadAsStreamAsync(cancellationToken); using var document = await JsonDocument.ParseAsync(stream, cancellationToken: cancellationToken); return document.RootElement.GetProperty("returnedCount").GetInt32(); } }