Skip to content

Commit a98c363

Browse files
authored
Add DefaultTimeout to dashboard tests (#6540)
1 parent 51e9a0d commit a98c363

19 files changed

+217
-197
lines changed

Aspire.sln

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -643,6 +643,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HealthChecksSandbox.AppHost
643643
EndProject
644644
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DaprServiceC", "playground\dapr\ServiceC\DaprServiceC.csproj", "{B26653B9-439E-4850-A7F8-43C6E5121952}"
645645
EndProject
646+
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Dashboard", "Dashboard", "{830F7CA9-8E51-4D62-832F-91F53F85B7AE}"
647+
EndProject
646648
Global
647649
GlobalSection(SolutionConfigurationPlatforms) = preSolution
648650
Debug|Any CPU = Debug|Any CPU
@@ -1738,7 +1740,7 @@ Global
17381740
{31F5E4F3-AC4E-4538-BC7D-85BCF9CA686A} = {975F6F41-B455-451D-A312-098DE4A167B6}
17391741
{A37AAFDB-545B-4599-806A-EFCB8B310446} = {975F6F41-B455-451D-A312-098DE4A167B6}
17401742
{8CB12764-E469-4BB5-8554-5F9CA0F6DE18} = {975F6F41-B455-451D-A312-098DE4A167B6}
1741-
{1ABCD945-5CAA-4F30-A741-7A9DA919254A} = {4981B3A5-4AFD-4191-BF7D-8692D9783D60}
1743+
{1ABCD945-5CAA-4F30-A741-7A9DA919254A} = {830F7CA9-8E51-4D62-832F-91F53F85B7AE}
17421744
{E20280B8-8BE0-4967-AFC2-65FFCD6EC5E4} = {F534D4F8-5E3A-42FC-BCD7-4C2D6060F9C8}
17431745
{6EAA089D-7ADD-4C74-B040-FD3D75DB5C75} = {C424395C-1235-41A4-BF55-07880A04368C}
17441746
{9D9C360B-9DF1-4076-8416-66964427C8F3} = {C424395C-1235-41A4-BF55-07880A04368C}
@@ -1820,7 +1822,7 @@ Global
18201822
{157A434E-E3CA-4080-96CF-903CC3DF66E9} = {8AA07A14-A4A7-45EC-B0F6-4690B516B16D}
18211823
{921CB408-5E37-4354-B4CF-EAE517F633DC} = {8AA07A14-A4A7-45EC-B0F6-4690B516B16D}
18221824
{C774BE00-EE93-4148-B866-8F0F2BA1E473} = {C424395C-1235-41A4-BF55-07880A04368C}
1823-
{0870A667-FB0C-4758-AEAF-9E5F092AD7C1} = {4981B3A5-4AFD-4191-BF7D-8692D9783D60}
1825+
{0870A667-FB0C-4758-AEAF-9E5F092AD7C1} = {830F7CA9-8E51-4D62-832F-91F53F85B7AE}
18241826
{C4833DEC-0A4F-4504-B8D0-06C60B84119C} = {91F22EEA-EB23-425A-9B32-9438A0809F4B}
18251827
{9CA94707-E801-444F-A582-D5BD0104CF9B} = {91F22EEA-EB23-425A-9B32-9438A0809F4B}
18261828
{3216CF59-84B0-46FF-8572-D0AFB0155423} = {A7C6452C-FEDB-4883-9AE7-29892D260AA3}
@@ -1998,6 +2000,7 @@ Global
19982000
{B7345F72-712F-436C-AE18-CAF7CDD4A990} = {D173887B-AF42-4576-B9C1-96B9E9B3D9C0}
19992001
{042DD8C6-A26C-4B06-80A1-FE7F8659C5BC} = {B7345F72-712F-436C-AE18-CAF7CDD4A990}
20002002
{B26653B9-439E-4850-A7F8-43C6E5121952} = {57A42144-739E-49A7-BADB-BB8F5F20FA17}
2003+
{830F7CA9-8E51-4D62-832F-91F53F85B7AE} = {4981B3A5-4AFD-4191-BF7D-8692D9783D60}
20012004
EndGlobalSection
20022005
GlobalSection(ExtensibilityGlobals) = postSolution
20032006
SolutionGuid = {6DCEDFEC-988E-4CB3-B45B-191EB5086E0C}

tests/Aspire.Dashboard.Tests/BrowserSecurityHeadersMiddlewareTests.cs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using Aspire.Dashboard.Authentication.Connection;
55
using Aspire.Dashboard.Model;
66
using Microsoft.AspNetCore.Http;
7+
using Microsoft.AspNetCore.InternalTesting;
78
using Microsoft.Extensions.FileProviders;
89
using Microsoft.Extensions.Hosting;
910
using Microsoft.Extensions.Primitives;
@@ -21,7 +22,7 @@ public async Task InvokeAsync_Development_AllowExternalFetch()
2122
var httpContext = new DefaultHttpContext();
2223

2324
// Act
24-
await middleware.InvokeAsync(httpContext);
25+
await middleware.InvokeAsync(httpContext).DefaultTimeout();
2526

2627
// Assert
2728
Assert.NotEqual(StringValues.Empty, httpContext.Response.Headers.ContentSecurityPolicy);
@@ -36,7 +37,7 @@ public async Task InvokeAsync_Production_DenyExternalFetch()
3637
var httpContext = new DefaultHttpContext();
3738

3839
// Act
39-
await middleware.InvokeAsync(httpContext);
40+
await middleware.InvokeAsync(httpContext).DefaultTimeout();
4041

4142
// Assert
4243
Assert.NotEqual(StringValues.Empty, httpContext.Response.Headers.ContentSecurityPolicy);
@@ -54,7 +55,7 @@ public async Task InvokeAsync_Scheme_ImageSourceChangesOnScheme(string scheme, s
5455
httpContext.Request.Scheme = scheme;
5556

5657
// Act
57-
await middleware.InvokeAsync(httpContext);
58+
await middleware.InvokeAsync(httpContext).DefaultTimeout();
5859

5960
// Assert
6061
Assert.NotEqual(StringValues.Empty, httpContext.Response.Headers.ContentSecurityPolicy);
@@ -70,7 +71,7 @@ public async Task InvokeAsync_Otlp_NotAdded()
7071
httpContext.Features.Set<IConnectionTypeFeature>(new TestConnectionTypeFeature { ConnectionTypes = [ConnectionType.Otlp] });
7172

7273
// Act
73-
await middleware.InvokeAsync(httpContext);
74+
await middleware.InvokeAsync(httpContext).DefaultTimeout();
7475

7576
// Assert
7677
Assert.Equal(StringValues.Empty, httpContext.Response.Headers.ContentSecurityPolicy);

tests/Aspire.Dashboard.Tests/ChannelExtensionsTests.cs

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using System.Diagnostics;
55
using System.Threading.Channels;
66
using Aspire.Dashboard.Utils;
7+
using Microsoft.AspNetCore.InternalTesting;
78
using Xunit;
89

910
namespace Aspire.Dashboard.Tests;
@@ -31,7 +32,7 @@ public async Task GetBatchesAsync_CancellationToken_Exits()
3132
});
3233

3334
// Assert
34-
await TaskHelpers.WaitIgnoreCancelAsync(readTask);
35+
await TaskHelpers.WaitIgnoreCancelAsync(readTask).DefaultTimeout();
3536
}
3637

3738
[Fact]
@@ -55,7 +56,7 @@ public async Task GetBatchesAsync_WithCancellation_Exits()
5556
});
5657

5758
// Assert
58-
await TaskHelpers.WaitIgnoreCancelAsync(readTask);
59+
await TaskHelpers.WaitIgnoreCancelAsync(readTask).DefaultTimeout();
5960
}
6061

6162
[Fact]
@@ -87,19 +88,19 @@ public async Task GetBatchesAsync_MinReadInterval_WaitForNextRead()
8788

8889
// Assert
8990
var stopwatch = Stopwatch.StartNew();
90-
var read1 = await resultChannel.Reader.ReadAsync();
91+
var read1 = await resultChannel.Reader.ReadAsync().DefaultTimeout();
9192
Assert.Equal(["a", "b", "c"], read1.Single());
9293

9394
channel.Writer.TryWrite(["d", "e", "f"]);
9495

95-
var read2 = await resultChannel.Reader.ReadAsync();
96+
var read2 = await resultChannel.Reader.ReadAsync().DefaultTimeout();
9697
Assert.Equal(["d", "e", "f"], read2.Single());
9798

9899
var elapsed = stopwatch.Elapsed;
99100
CustomAssert.AssertExceedsMinInterval(elapsed, minReadInterval);
100101

101102
channel.Writer.Complete();
102-
await TaskHelpers.WaitIgnoreCancelAsync(readTask);
103+
await TaskHelpers.WaitIgnoreCancelAsync(readTask).DefaultTimeout();
103104
}
104105

105106
[Fact]
@@ -131,18 +132,18 @@ public async Task GetBatchesAsync_MinReadInterval_WithCancellation_Exit()
131132

132133
// Assert
133134
var stopwatch = Stopwatch.StartNew();
134-
var read1 = await resultChannel.Reader.ReadAsync();
135+
var read1 = await resultChannel.Reader.ReadAsync().DefaultTimeout();
135136
Assert.Equal(["a", "b", "c"], read1.Single());
136137

137138
channel.Writer.TryWrite(["d", "e", "f"]);
138139

139-
var read2Task = resultChannel.Reader.ReadAsync();
140+
var read2Task = resultChannel.Reader.ReadAsync().DefaultTimeout();
140141
cts.Cancel();
141142

142-
await TaskHelpers.WaitIgnoreCancelAsync(readTask);
143+
await TaskHelpers.WaitIgnoreCancelAsync(readTask).DefaultTimeout();
143144
try
144145
{
145-
await read2Task;
146+
await read2Task.DefaultTimeout();
146147
}
147148
catch (ChannelClosedException)
148149
{

tests/Aspire.Dashboard.Tests/Integration/DashboardClientAuthTests.cs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
using Grpc.Core;
1212
using Microsoft.AspNetCore.Builder;
1313
using Microsoft.AspNetCore.Hosting;
14+
using Microsoft.AspNetCore.InternalTesting;
1415
using Microsoft.AspNetCore.Server.Kestrel.Core;
1516
using Microsoft.Extensions.Configuration;
1617
using Microsoft.Extensions.DependencyInjection;
@@ -40,10 +41,10 @@ public DashboardClientAuthTests(ITestOutputHelper testOutputHelper)
4041
public async Task ConnectsToResourceService_Unsecured(bool useHttps)
4142
{
4243
var loggerFactory = IntegrationTestHelpers.CreateLoggerFactory(_testOutputHelper);
43-
await using var server = await CreateResourceServiceServerAsync(loggerFactory, useHttps);
44-
await using var client = await CreateDashboardClientAsync(loggerFactory, server.Url, authMode: ResourceClientAuthMode.Unsecured);
44+
await using var server = await CreateResourceServiceServerAsync(loggerFactory, useHttps).DefaultTimeout();
45+
await using var client = await CreateDashboardClientAsync(loggerFactory, server.Url, authMode: ResourceClientAuthMode.Unsecured).DefaultTimeout();
4546

46-
var call = await server.Calls.ApplicationInformationCallsChannel.Reader.ReadAsync();
47+
var call = await server.Calls.ApplicationInformationCallsChannel.Reader.ReadAsync().DefaultTimeout();
4748

4849
Assert.NotNull(call.Request);
4950
Assert.NotNull(call.RequestHeaders);
@@ -56,10 +57,10 @@ public async Task ConnectsToResourceService_Unsecured(bool useHttps)
5657
public async Task ConnectsToResourceService_ApiKey(bool useHttps)
5758
{
5859
var loggerFactory = IntegrationTestHelpers.CreateLoggerFactory(_testOutputHelper);
59-
await using var server = await CreateResourceServiceServerAsync(loggerFactory, useHttps);
60-
await using var client = await CreateDashboardClientAsync(loggerFactory, server.Url, authMode: ResourceClientAuthMode.ApiKey, configureOptions: options => options.ResourceServiceClient.ApiKey = "TestApiKey!");
60+
await using var server = await CreateResourceServiceServerAsync(loggerFactory, useHttps).DefaultTimeout();
61+
await using var client = await CreateDashboardClientAsync(loggerFactory, server.Url, authMode: ResourceClientAuthMode.ApiKey, configureOptions: options => options.ResourceServiceClient.ApiKey = "TestApiKey!").DefaultTimeout();
6162

62-
var call = await server.Calls.ApplicationInformationCallsChannel.Reader.ReadAsync();
63+
var call = await server.Calls.ApplicationInformationCallsChannel.Reader.ReadAsync().DefaultTimeout();
6364

6465
Assert.NotNull(call.Request);
6566
Assert.NotNull(call.RequestHeaders);

tests/Aspire.Dashboard.Tests/Integration/FrontendBrowserTokenAuthTests.cs

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
using Aspire.Dashboard.Configuration;
99
using Aspire.Dashboard.Utils;
1010
using Aspire.Hosting;
11+
using Microsoft.AspNetCore.InternalTesting;
1112
using Microsoft.Extensions.Logging;
1213
using Microsoft.Extensions.Logging.Testing;
1314
using Xunit;
@@ -34,12 +35,12 @@ public async Task Get_Unauthenticated_RedirectToLogin()
3435
config[DashboardConfigNames.DashboardFrontendAuthModeName.ConfigKey] = FrontendAuthMode.BrowserToken.ToString();
3536
config[DashboardConfigNames.DashboardFrontendBrowserTokenName.ConfigKey] = apiKey;
3637
});
37-
await app.StartAsync();
38+
await app.StartAsync().DefaultTimeout();
3839

3940
using var client = new HttpClient { BaseAddress = new Uri($"http://{app.FrontendSingleEndPointAccessor().EndPoint}") };
4041

4142
// Act
42-
var response = await client.GetAsync("/");
43+
var response = await client.GetAsync("/").DefaultTimeout();
4344

4445
// Assert
4546
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
@@ -56,19 +57,19 @@ public async Task Get_LoginPage_ValidToken_RedirectToApp()
5657
config[DashboardConfigNames.DashboardFrontendAuthModeName.ConfigKey] = FrontendAuthMode.BrowserToken.ToString();
5758
config[DashboardConfigNames.DashboardFrontendBrowserTokenName.ConfigKey] = apiKey;
5859
});
59-
await app.StartAsync();
60+
await app.StartAsync().DefaultTimeout();
6061

6162
using var client = new HttpClient { BaseAddress = new Uri($"http://{app.FrontendSingleEndPointAccessor().EndPoint}") };
6263

6364
// Act 1
64-
var response1 = await client.GetAsync(DashboardUrls.LoginUrl(returnUrl: DashboardUrls.TracesUrl(), token: apiKey));
65+
var response1 = await client.GetAsync(DashboardUrls.LoginUrl(returnUrl: DashboardUrls.TracesUrl(), token: apiKey)).DefaultTimeout();
6566

6667
// Assert 1
6768
Assert.Equal(HttpStatusCode.OK, response1.StatusCode);
6869
Assert.Equal(DashboardUrls.TracesUrl(), response1.RequestMessage!.RequestUri!.PathAndQuery);
6970

7071
// Act 2
71-
var response2 = await client.GetAsync(DashboardUrls.StructuredLogsUrl());
72+
var response2 = await client.GetAsync(DashboardUrls.StructuredLogsUrl()).DefaultTimeout();
7273

7374
// Assert 2
7475
Assert.Equal(HttpStatusCode.OK, response2.StatusCode);
@@ -87,12 +88,12 @@ public async Task Get_LoginPage_ValidToken_OtlpHttpConnection_Denied()
8788
config[DashboardConfigNames.DashboardFrontendAuthModeName.ConfigKey] = FrontendAuthMode.BrowserToken.ToString();
8889
config[DashboardConfigNames.DashboardFrontendBrowserTokenName.ConfigKey] = apiKey;
8990
}, testSink: testSink);
90-
await app.StartAsync();
91+
await app.StartAsync().DefaultTimeout();
9192

9293
using var client = new HttpClient { BaseAddress = new Uri($"http://{app.OtlpServiceHttpEndPointAccessor().EndPoint}") };
9394

9495
// Act
95-
var response = await client.GetAsync(DashboardUrls.LoginUrl(returnUrl: DashboardUrls.TracesUrl(), token: apiKey));
96+
var response = await client.GetAsync(DashboardUrls.LoginUrl(returnUrl: DashboardUrls.TracesUrl(), token: apiKey)).DefaultTimeout();
9697

9798
// Assert
9899
Assert.Equal(HttpStatusCode.NotFound, response.StatusCode);
@@ -111,12 +112,12 @@ public async Task Get_LoginPage_InvalidToken_RedirectToLoginWithoutToken()
111112
config[DashboardConfigNames.DashboardFrontendAuthModeName.ConfigKey] = FrontendAuthMode.BrowserToken.ToString();
112113
config[DashboardConfigNames.DashboardFrontendBrowserTokenName.ConfigKey] = apiKey;
113114
});
114-
await app.StartAsync();
115+
await app.StartAsync().DefaultTimeout();
115116

116117
using var client = new HttpClient { BaseAddress = new Uri($"http://{app.FrontendSingleEndPointAccessor().EndPoint}") };
117118

118119
// Act
119-
var response = await client.GetAsync(DashboardUrls.LoginUrl(returnUrl: DashboardUrls.TracesUrl(), token: "Wrong!"));
120+
var response = await client.GetAsync(DashboardUrls.LoginUrl(returnUrl: DashboardUrls.TracesUrl(), token: "Wrong!")).DefaultTimeout();
120121

121122
// Assert
122123
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
@@ -136,12 +137,12 @@ public async Task Post_ValidateTokenApi_AvailableBasedOnOptions(FrontendAuthMode
136137
config[DashboardConfigNames.DashboardFrontendAuthModeName.ConfigKey] = authMode.ToString();
137138
config[DashboardConfigNames.DashboardFrontendBrowserTokenName.ConfigKey] = apiKey;
138139
});
139-
await app.StartAsync();
140+
await app.StartAsync().DefaultTimeout();
140141

141142
using var client = new HttpClient { BaseAddress = new Uri($"http://{app.FrontendSingleEndPointAccessor().EndPoint}") };
142143

143144
// Act
144-
var response = await client.PostAsync("/api/validatetoken?token=" + requestToken, content: null);
145+
var response = await client.PostAsync("/api/validatetoken?token=" + requestToken, content: null).DefaultTimeout();
145146

146147
// Assert
147148
Assert.Equal(statusCode, response.StatusCode);
@@ -164,7 +165,7 @@ public async Task LogOutput_NoToken_GeneratedTokenLogged()
164165
}, testSink: testSink);
165166

166167
// Act
167-
await app.StartAsync();
168+
await app.StartAsync().DefaultTimeout();
168169

169170
// Assert
170171
var l = testSink.Writes.Where(w => w.LoggerName == typeof(DashboardWebApplication).FullName).ToList();
@@ -225,7 +226,7 @@ public async Task LogOutput_AnyIP_LoginLinkLocalhost(string frontendUrl, string
225226
}, testSink: testSink);
226227

227228
// Act
228-
await app.StartAsync();
229+
await app.StartAsync().DefaultTimeout();
229230

230231
// Assert
231232
var l = testSink.Writes.Where(w => w.LoggerName == typeof(DashboardWebApplication).FullName).ToList();
@@ -252,7 +253,7 @@ public async Task LogOutput_InContainer_LoginLinkContainerMessage()
252253
}, testSink: testSink);
253254

254255
// Act
255-
await app.StartAsync();
256+
await app.StartAsync().DefaultTimeout();
256257

257258
// Assert
258259
var l = testSink.Writes.Where(w => w.LoggerName == typeof(DashboardWebApplication).FullName).ToList();

tests/Aspire.Dashboard.Tests/Integration/FrontendOpenIdConnectAuthTests.cs

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using System.Web;
66
using Aspire.Dashboard.Authentication;
77
using Aspire.Hosting;
8+
using Microsoft.AspNetCore.InternalTesting;
89
using Microsoft.Extensions.Logging.Testing;
910
using Xunit;
1011
using Xunit.Abstractions;
@@ -16,7 +17,7 @@ public class FrontendOpenIdConnectAuthTests(ITestOutputHelper testOutputHelper)
1617
[Fact]
1718
public async Task Get_Unauthenticated_RedirectsToAuthority()
1819
{
19-
await using var authority = await MockOpenIdAuthority.CreateAsync();
20+
await using var authority = await MockOpenIdAuthority.CreateAsync().DefaultTimeout();
2021

2122
await using var app = IntegrationTestHelpers.CreateDashboardWebApplication(
2223
testOutputHelper,
@@ -25,7 +26,7 @@ public async Task Get_Unauthenticated_RedirectsToAuthority()
2526
ConfigureOpenIdConnect(config, authority);
2627
});
2728

28-
await app.StartAsync();
29+
await app.StartAsync().DefaultTimeout();
2930

3031
var handler = new HttpClientHandler()
3132
{
@@ -36,7 +37,7 @@ public async Task Get_Unauthenticated_RedirectsToAuthority()
3637
using var client = new HttpClient(handler) { BaseAddress = new Uri($"http://{app.FrontendSingleEndPointAccessor().EndPoint}") };
3738

3839
// Act
39-
var response = await client.GetAsync("/");
40+
var response = await client.GetAsync("/").DefaultTimeout();
4041

4142
// Assert
4243
Assert.Equal(HttpStatusCode.Redirect, response.StatusCode);
@@ -53,13 +54,13 @@ public async Task Get_Unauthenticated_RedirectsToAuthority()
5354
Assert.Equal("code", query.Get("response_type"));
5455
Assert.Equal("openid profile", query.Get("scope"));
5556

56-
await app.StopAsync();
57+
await app.StopAsync().DefaultTimeout();
5758
}
5859

5960
[Fact]
6061
public async Task Get_Unauthenticated_OtlpHttpConnection_Denied()
6162
{
62-
await using var authority = await MockOpenIdAuthority.CreateAsync();
63+
await using var authority = await MockOpenIdAuthority.CreateAsync().DefaultTimeout();
6364

6465
var testSink = new TestSink();
6566
await using var app = IntegrationTestHelpers.CreateDashboardWebApplication(
@@ -70,7 +71,7 @@ public async Task Get_Unauthenticated_OtlpHttpConnection_Denied()
7071
},
7172
testSink: testSink);
7273

73-
await app.StartAsync();
74+
await app.StartAsync().DefaultTimeout();
7475

7576
var handler = new HttpClientHandler()
7677
{
@@ -81,15 +82,15 @@ public async Task Get_Unauthenticated_OtlpHttpConnection_Denied()
8182
using var client = new HttpClient(handler) { BaseAddress = new Uri($"http://{app.OtlpServiceHttpEndPointAccessor().EndPoint}") };
8283

8384
// Act
84-
var response = await client.GetAsync("/");
85+
var response = await client.GetAsync("/").DefaultTimeout();
8586

8687
// Assert
8788
Assert.Equal(HttpStatusCode.NotFound, response.StatusCode);
8889

8990
var log = testSink.Writes.Single(s => s.LoggerName == typeof(FrontendCompositeAuthenticationHandler).FullName && s.EventId.Name == "AuthenticationSchemeNotAuthenticatedWithFailure");
9091
Assert.Equal("FrontendComposite was not authenticated. Failure message: Connection type Frontend is not enabled on this connection.", log.Message);
9192

92-
await app.StopAsync();
93+
await app.StopAsync().DefaultTimeout();
9394
}
9495

9596
private static void ConfigureOpenIdConnect(Dictionary<string, string?> config, MockOpenIdAuthority.Authority authority)

0 commit comments

Comments
 (0)