Skip to content

Commit 9f1a978

Browse files
authored
[Infrastructure improvements] (#8275)
* Improved selenium start and tear down * Selenium is set up and torn down in an assembly fixture. * Selenium is initialized lazily and in a non-blocking way. * Selenium processes are tracked as part of the build and their pids written to a file on disk for cleanup in the event of unexpected termination of the test process. * Browser fixture retries with linear backoff to create a remote driver. Under heavy load (like when we are doing a simultaneous NPM restore) the selenium server can become unresponsive so we retry three times, with a longer comand timeout allowance each time up to a max of 3 minutes. * Moved test project setup to build time instead of runtime. * Added target PrepareForTest to create the required files for testing * The template creation folder. * The template props file to use our built packages. * The folder for the custom hive. * Added assembly metadata attributes to find all the data we need to run the tests. * Path to the artifacts shipping packages folder. * Path to the artifacts non-shipping packages folder. * Path to the test templates creation folder. * Path to use for the custom templating hive used in tests. * Proper cleanup as part of the build * Remove the test templates creation folder. * Remove the test packages restore path. * Recreate the test templates creation folder. * Recreate the test packages restore path. * Generated Directory.Build.Props and Directory.Build.Targets in the test templates creation folder. * Cleaned up potentially stale templatetestsprops. * Improved test flows * Initialization is done lazily and asynchronously. * Selenium * Browser fixture * Template initialization. * Flattened test flows to avoid assertions inside deep callstacks. * All assertions happen at the test level with improved error messages. * With the exception of the migrations assertions. * Assertions contain information about which step failed, for what project and what failure details. * Broke down tests to perform individual steps instead of mixing build and publish. * Publish project. * Build project. (Debug) * Run built project. * Run published project. * Concentrated build logic into the Project class. * Context between the different steps of a test is maintained in this class. * All operations that require coordination are performed within this class. * There is a lock for dotnet and a lock for nodejs. When building SPAs we acquire the nodejs lock to correctly prevent multiple runs of nodejs in parallel. [ApiAuthorization template cleanups] * Fix preview3 issues with breaking changes on Entity framework by manually configuring the model in ApiAuthorizationDbContext. * Add app.db to the project file when using local db. * Fix linting errors on angular template. * Fix react tests * Add tests to cover new auth options in the SPA templates.
1 parent 0456c9d commit 9f1a978

File tree

76 files changed

+3445
-1546
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

76 files changed

+3445
-1546
lines changed

.azure/pipelines/ci.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -341,6 +341,8 @@ jobs:
341341
beforeBuild:
342342
- bash: "./eng/scripts/install-nginx-linux.sh"
343343
displayName: Installing Nginx
344+
- bash: "echo fs.inotify.max_user_watches=524288 | sudo tee -a /etc/sysctl.conf && sudo sysctl -p"
345+
displayName: Increase inotify limit
344346
afterBuild:
345347
- bash: ./build.sh --no-build --ci --test -p:RunFlakyTests=true
346348
displayName: Run Flaky Tests

.azure/pipelines/jobs/default-build.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,8 @@ jobs:
125125
displayName: Install JDK 11
126126
- powershell: Write-Host "##vso[task.prependpath]$env:JAVA_HOME\bin"
127127
displayName: Prepend JAVA bin folder to the PATH.
128+
- powershell: Write-Host "##vso[task.setvariable variable=SeleniumProcessTrackingFolder]$(BuildDirectory)\obj\selenium\"
129+
displayName: Add Selenium process tracking folder environment variable
128130
- powershell: ./eng/scripts/InstallGoogleChrome.ps1
129131
displayName: Install chrome
130132
- ${{ if and(eq(variables['System.TeamProject'], 'internal'), eq(parameters.agentOs, 'Windows'), eq(parameters.codeSign, 'true')) }}:

eng/scripts/KillProcesses.ps1

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,22 @@ function _killJavaInstances() {
2222
}
2323
}
2424

25+
function _killSeleniumTrackedProcesses() {
26+
$files = Get-ChildItem $env:SeleniumProcessTrackingFolder -ErrorAction SilentlyContinue;
27+
# PID files have a format of <<pid>>.<<guid>>.pid
28+
$pids = $files |
29+
Where-Object { $_.Name -match "([0-9]+)\..*?.pid"; } |
30+
Foreach-Object { $Matches[1] };
31+
32+
foreach ($currentPid in $pids) {
33+
try {
34+
& cmd /c "taskkill /T /F /PID $currentPid 2>&1"
35+
} catch {
36+
Write-Host "Failed to kill process: $currentPid"
37+
}
38+
}
39+
}
40+
2541
_kill dotnet.exe
2642
_kill testhost.exe
2743
_kill iisexpress.exe
@@ -35,6 +51,7 @@ _kill chrome.exe
3551
_kill h2spec.exe
3652
_kill WerFault.exe
3753
_killJavaInstances
54+
_killSeleniumTrackedProcesses
3855

3956
if (Get-Command iisreset -ErrorAction ignore) {
4057
iisreset /restart
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// Copyright (c) .NET Foundation. All rights reserved.
2+
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3+
4+
using Microsoft.AspNetCore.E2ETesting;
5+
using Xunit;
6+
7+
[assembly: TestFramework("Microsoft.AspNetCore.E2ETesting.XunitTestFrameworkWithAssemblyFixture", "Microsoft.AspNetCore.Components.E2ETests")]
8+
[assembly: AssemblyFixture(typeof(SeleniumStandaloneServer))]

src/Components/test/E2ETest/ServerExecutionTests/ServerComponentRenderingTest.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ public void ThrowsIfRenderIsRequestedOutsideSyncContext()
3232

3333
appElement.FindElement(By.Id("run-without-dispatch")).Click();
3434

35-
WaitAssert.Contains(
35+
Browser.Contains(
3636
$"{typeof(InvalidOperationException).FullName}: The current thread is not associated with the renderer's synchronization context",
3737
() => result.Text);
3838
}

src/Components/test/E2ETest/ServerExecutionTests/ServerSideAppTest.cs

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
using OpenQA.Selenium.Support.UI;
99
using System;
1010
using System.Linq;
11+
using System.Threading.Tasks;
1112
using Xunit;
1213
using Xunit.Abstractions;
1314

@@ -23,12 +24,14 @@ public ServerSideAppTest(
2324
{
2425
_serverFixture.Environment = AspNetEnvironment.Development;
2526
_serverFixture.BuildWebHostMethod = ComponentsApp.Server.Program.BuildWebHost;
27+
}
2628

29+
protected override void InitializeAsyncCore()
30+
{
2731
Navigate("/", noReload: false);
2832
WaitUntilLoaded();
2933
}
3034

31-
3235
[Fact]
3336
public void HasTitle()
3437
{
@@ -56,13 +59,13 @@ public void NavMenuHighlightsCurrentLocation()
5659
Browser.FindElement(By.LinkText("Counter")).Click();
5760

5861
// Verify we're now on the counter page, with that nav link (only) highlighted
59-
WaitAssert.Equal("Counter", () => Browser.FindElement(mainHeaderSelector).Text);
62+
Browser.Equal("Counter", () => Browser.FindElement(mainHeaderSelector).Text);
6063
Assert.Collection(Browser.FindElements(activeNavLinksSelector),
6164
item => Assert.Equal("Counter", item.Text));
6265

6366
// Verify we can navigate back to home too
6467
Browser.FindElement(By.LinkText("Home")).Click();
65-
WaitAssert.Equal("Hello, world!", () => Browser.FindElement(mainHeaderSelector).Text);
68+
Browser.Equal("Hello, world!", () => Browser.FindElement(mainHeaderSelector).Text);
6669
Assert.Collection(Browser.FindElements(activeNavLinksSelector),
6770
item => Assert.Equal("Home", item.Text));
6871
}
@@ -72,7 +75,7 @@ public void HasCounterPage()
7275
{
7376
// Navigate to "Counter"
7477
Browser.FindElement(By.LinkText("Counter")).Click();
75-
WaitAssert.Equal("Counter", () => Browser.FindElement(By.TagName("h1")).Text);
78+
Browser.Equal("Counter", () => Browser.FindElement(By.TagName("h1")).Text);
7679

7780
// Observe the initial value is zero
7881
var countDisplayElement = Browser.FindElement(By.CssSelector("h1 + p"));
@@ -81,19 +84,19 @@ public void HasCounterPage()
8184
// Click the button; see it counts
8285
var button = Browser.FindElement(By.CssSelector(".main button"));
8386
button.Click();
84-
WaitAssert.Equal("Current count: 1", () => countDisplayElement.Text);
87+
Browser.Equal("Current count: 1", () => countDisplayElement.Text);
8588
button.Click();
86-
WaitAssert.Equal("Current count: 2", () => countDisplayElement.Text);
89+
Browser.Equal("Current count: 2", () => countDisplayElement.Text);
8790
button.Click();
88-
WaitAssert.Equal("Current count: 3", () => countDisplayElement.Text);
91+
Browser.Equal("Current count: 3", () => countDisplayElement.Text);
8992
}
9093

9194
[Fact]
9295
public void HasFetchDataPage()
9396
{
9497
// Navigate to "Fetch Data"
9598
Browser.FindElement(By.LinkText("Fetch data")).Click();
96-
WaitAssert.Equal("Weather forecast", () => Browser.FindElement(By.TagName("h1")).Text);
99+
Browser.Equal("Weather forecast", () => Browser.FindElement(By.TagName("h1")).Text);
97100

98101
// Wait until loaded
99102
var tableSelector = By.CssSelector("table.table");

src/Components/test/E2ETest/Tests/BinaryHttpClientTest.cs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
using OpenQA.Selenium;
99
using OpenQA.Selenium.Support.UI;
1010
using System;
11+
using System.Threading.Tasks;
1112
using Xunit;
1213
using Xunit.Abstractions;
1314

@@ -16,7 +17,7 @@ namespace Microsoft.AspNetCore.Components.E2ETest.Tests
1617
public class BinaryHttpClientTest : BasicTestAppTestBase, IClassFixture<AspNetSiteServerFixture>
1718
{
1819
readonly ServerFixture _apiServerFixture;
19-
readonly IWebElement _appElement;
20+
IWebElement _appElement;
2021
IWebElement _responseStatus;
2122
IWebElement _responseStatusText;
2223
IWebElement _testOutcome;
@@ -30,11 +31,14 @@ public BinaryHttpClientTest(
3031
{
3132
apiServerFixture.BuildWebHostMethod = TestServer.Program.BuildWebHost;
3233
_apiServerFixture = apiServerFixture;
34+
}
3335

36+
protected override void InitializeAsyncCore()
37+
{
3438
Navigate(ServerPathBase, noReload: true);
3539
_appElement = MountTestComponent<BinaryHttpRequestsComponent>();
3640
}
37-
41+
3842
[Fact]
3943
public void CanSendAndReceiveBytes()
4044
{

0 commit comments

Comments
 (0)