Skip to content

Commit 7489481

Browse files
authored
Add E2E test for aspire otel logs structured logs (#16111)
* Add E2E test for aspire otel logs structured logs * Address review: using on workspace, aspire wait, positive assertion * Add --timeout and WaitUntilTextAsync to aspire wait call
1 parent fd86903 commit 7489481

1 file changed

Lines changed: 89 additions & 0 deletions

File tree

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
using Aspire.Cli.EndToEnd.Tests.Helpers;
5+
using Aspire.Cli.Tests.Utils;
6+
using Hex1b.Automation;
7+
using Xunit;
8+
9+
namespace Aspire.Cli.EndToEnd.Tests;
10+
11+
/// <summary>
12+
/// End-to-end tests for the aspire otel logs command with structured logs.
13+
/// Each test class runs as a separate CI job for parallelization.
14+
/// </summary>
15+
public sealed class OtelLogsTests(ITestOutputHelper output)
16+
{
17+
[Fact]
18+
[CaptureWorkspaceOnFailure]
19+
public async Task OtelLogsReturnsStructuredLogsFromStarterApp()
20+
{
21+
var repoRoot = CliE2ETestHelpers.GetRepoRoot();
22+
var installMode = CliE2ETestHelpers.DetectDockerInstallMode(repoRoot);
23+
24+
using var workspace = TemporaryWorkspace.Create(output);
25+
26+
using var terminal = CliE2ETestHelpers.CreateDockerTestTerminal(repoRoot, installMode, output, mountDockerSocket: true, workspace: workspace);
27+
28+
var pendingRun = terminal.RunAsync(TestContext.Current.CancellationToken);
29+
30+
var counter = new SequenceCounter();
31+
var auto = new Hex1bTerminalAutomator(terminal, defaultTimeout: TimeSpan.FromSeconds(500));
32+
33+
await auto.PrepareDockerEnvironmentAsync(counter, workspace);
34+
await auto.InstallAspireCliInDockerAsync(installMode, counter);
35+
36+
// Create a new Starter project (includes an ASP.NET Core apiservice)
37+
await auto.AspireNewAsync("AspireOtelLogsApp", counter);
38+
39+
// Navigate to the AppHost directory
40+
await auto.TypeAsync("cd AspireOtelLogsApp/AspireOtelLogsApp.AppHost");
41+
await auto.EnterAsync();
42+
await auto.WaitForSuccessPromptAsync(counter);
43+
44+
// Start the AppHost in the background
45+
await auto.AspireStartAsync(counter);
46+
47+
// Wait for the apiservice resource to be running before querying logs
48+
await auto.TypeAsync("aspire wait apiservice --status up --timeout 300");
49+
await auto.EnterAsync();
50+
await auto.WaitUntilTextAsync("is up (running).", timeout: TimeSpan.FromMinutes(6));
51+
await auto.WaitForSuccessPromptAsync(counter);
52+
53+
// Run aspire otel logs and capture output to a file
54+
await auto.TypeAsync("aspire otel logs > otel_logs.txt 2>&1");
55+
await auto.EnterAsync();
56+
await auto.WaitForSuccessPromptAsync(counter);
57+
58+
// Verify the output contains structured log entries with apiservice content
59+
await auto.TypeAsync("cat otel_logs.txt | head -20");
60+
await auto.EnterAsync();
61+
await auto.WaitForSuccessPromptAsync(counter);
62+
63+
// Assert structured logs are present and contain apiservice entries
64+
await auto.TypeAsync("if [ ! -r otel_logs.txt ]; then echo 'OTEL_LOGS_FILE_UNREADABLE'; elif grep -q 'apiservice' otel_logs.txt; then echo 'STRUCTURED_LOGS_PRESENT'; else echo 'STRUCTURED_LOGS_MISSING'; fi");
65+
await auto.EnterAsync();
66+
await auto.WaitUntilTextAsync("STRUCTURED_LOGS_PRESENT", timeout: TimeSpan.FromSeconds(10));
67+
await auto.WaitForAnyPromptAsync(counter);
68+
69+
// Also verify JSON format works and contains structured data
70+
await auto.TypeAsync("aspire otel logs --format json > otel_logs_json.txt 2>&1");
71+
await auto.EnterAsync();
72+
await auto.WaitForSuccessPromptAsync(counter);
73+
74+
// Verify JSON output contains resourceLogs key
75+
await auto.TypeAsync("grep -q 'resourceLogs' otel_logs_json.txt && echo 'JSON_STRUCTURED_LOGS_PRESENT' || echo 'JSON_STRUCTURED_LOGS_MISSING'");
76+
await auto.EnterAsync();
77+
await auto.WaitUntilTextAsync("JSON_STRUCTURED_LOGS_PRESENT", timeout: TimeSpan.FromSeconds(10));
78+
await auto.WaitForAnyPromptAsync(counter);
79+
80+
// Stop the AppHost
81+
await auto.AspireStopAsync(counter);
82+
83+
// Exit the shell
84+
await auto.TypeAsync("exit");
85+
await auto.EnterAsync();
86+
87+
await pendingRun;
88+
}
89+
}

0 commit comments

Comments
 (0)