Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/dotnet/aspnetcore.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDamian Edwards <damian@damianedwards.com>2022-05-13 03:36:15 +0300
committerGitHub <noreply@github.com>2022-05-13 03:36:15 +0300
commitcab4c6ec6e900b2c4b5b93f2237c6972efebc02a (patch)
treeb7e6c36c587e60ac4748b987e1b46ef161a16cd1
parent65bb1ec1e3a6c521224703bc28399877c7614baa (diff)
Fix project template test issues
* Update template baseline test to use original file name * Enable more tracing & dump collect in helix test runner * Disable test parallelization for project template tests * Ensure project directory name uniqueness * Fix tests using skip attributes but not using ConditionalFact/ConditionalTheory attributes * Print test timeout message from Helix test runner * Add timestamps to helix runner console logs * Increase helix timeout for project template tests * Skip LocalDb template tests on non-Windows platforms * Update test cmd args in TestRunner.cs to modern, documented versions * Split up long-running theories to avoid test timeouts * Remove template test locks * Skip template tests on Debian11.Arm as they take too long to run there * Updated README with details about test timeouts & conditional tests Co-authored-by: Hao Kung <HaoK@users.noreply.github.com>
-rw-r--r--eng/tools/HelixTestRunner/ProcessUtil.cs8
-rw-r--r--eng/tools/HelixTestRunner/Program.cs17
-rw-r--r--eng/tools/HelixTestRunner/TestRunner.cs117
-rw-r--r--src/ProjectTemplates/BlazorTemplates.Tests/BlazorServerTemplateTest.cs8
-rw-r--r--src/ProjectTemplates/BlazorTemplates.Tests/BlazorTemplateTest.cs4
-rw-r--r--src/ProjectTemplates/BlazorTemplates.Tests/BlazorWasmTemplateTest.cs17
-rw-r--r--src/ProjectTemplates/README.md97
-rw-r--r--src/ProjectTemplates/Shared/Project.cs126
-rw-r--r--src/ProjectTemplates/Shared/ProjectFactoryFixture.cs60
-rw-r--r--src/ProjectTemplates/Shared/TemplatePackageInstaller.cs20
-rw-r--r--src/ProjectTemplates/test/ArgConstants.cs1
-rw-r--r--src/ProjectTemplates/test/AssemblyInfo.AssemblyFixtures.cs2
-rw-r--r--src/ProjectTemplates/test/BaselineTest.cs63
-rw-r--r--src/ProjectTemplates/test/BlazorServerTemplateTest.cs27
-rw-r--r--src/ProjectTemplates/test/BlazorTemplateTest.cs4
-rw-r--r--src/ProjectTemplates/test/BlazorWasmTemplateTest.cs109
-rw-r--r--src/ProjectTemplates/test/EmptyWebTemplateTest.cs2
-rw-r--r--src/ProjectTemplates/test/GrpcTemplateTest.cs2
-rw-r--r--src/ProjectTemplates/test/IdentityUIPackageTest.cs2
-rw-r--r--src/ProjectTemplates/test/ItemTemplateTests/BlazorServerTests.cs2
-rw-r--r--src/ProjectTemplates/test/MvcTemplateTest.cs31
-rw-r--r--src/ProjectTemplates/test/ProjectTemplates.Tests.csproj5
-rw-r--r--src/ProjectTemplates/test/RazorClassLibraryTemplateTest.cs4
-rw-r--r--src/ProjectTemplates/test/RazorPagesTemplateTest.cs33
-rw-r--r--src/ProjectTemplates/test/SpaTemplatesTest.cs12
-rw-r--r--src/ProjectTemplates/test/WebApiTemplateTest.cs32
-rw-r--r--src/ProjectTemplates/test/WorkerTemplateTest.cs4
27 files changed, 432 insertions, 377 deletions
diff --git a/eng/tools/HelixTestRunner/ProcessUtil.cs b/eng/tools/HelixTestRunner/ProcessUtil.cs
index 1dc275987c..067850c446 100644
--- a/eng/tools/HelixTestRunner/ProcessUtil.cs
+++ b/eng/tools/HelixTestRunner/ProcessUtil.cs
@@ -4,6 +4,7 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
+using System.Globalization;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;
@@ -79,7 +80,7 @@ public static class ProcessUtil
Action<int>? onStart = null,
CancellationToken cancellationToken = default)
{
- Console.WriteLine($"Running '{filename} {arguments}'");
+ PrintMessage($"Running '{filename} {arguments}'");
using var process = new Process()
{
StartInfo =
@@ -151,7 +152,7 @@ public static class ProcessUtil
process.Exited += (_, e) =>
{
- Console.WriteLine($"'{process.StartInfo.FileName} {process.StartInfo.Arguments}' completed with exit code '{process.ExitCode}'");
+ PrintMessage($"'{process.StartInfo.FileName} {process.StartInfo.Arguments}' completed with exit code '{process.ExitCode}'");
if (throwOnError && process.ExitCode != 0)
{
processLifetimeTask.TrySetException(new InvalidOperationException($"Command {filename} {arguments} returned exit code {process.ExitCode} output: {outputBuilder.ToString()}"));
@@ -206,4 +207,7 @@ public static class ProcessUtil
return await processLifetimeTask.Task;
}
+
+ public static void PrintMessage(string message) => Console.WriteLine($"{DateTime.UtcNow.ToString("O", CultureInfo.InvariantCulture)} {message}");
+ public static void PrintErrorMessage(string message) => Console.Error.WriteLine($"{DateTime.UtcNow.ToString("O", CultureInfo.InvariantCulture)} {message}");
}
diff --git a/eng/tools/HelixTestRunner/Program.cs b/eng/tools/HelixTestRunner/Program.cs
index f388f76851..e2afbb1395 100644
--- a/eng/tools/HelixTestRunner/Program.cs
+++ b/eng/tools/HelixTestRunner/Program.cs
@@ -2,6 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
using System;
+using System.Globalization;
using System.Threading.Tasks;
namespace HelixTestRunner;
@@ -28,7 +29,7 @@ class Program
}
else
{
- Console.WriteLine("Playwright install skipped.");
+ ProcessUtil.PrintMessage("Playwright install skipped.");
}
}
@@ -38,23 +39,29 @@ class Program
{
if (!await runner.CheckTestDiscoveryAsync())
{
- Console.WriteLine("RunTest stopping due to test discovery failure.");
+ ProcessUtil.PrintMessage("RunTest stopping due to test discovery failure.");
Environment.Exit(1);
return;
}
+ ProcessUtil.PrintMessage("Start running tests");
var exitCode = await runner.RunTestsAsync();
+ ProcessUtil.PrintMessage("Running tests complete");
+
+ ProcessUtil.PrintMessage("Uploading test results");
runner.UploadResults();
- Console.WriteLine($"Completed Helix job with exit code '{exitCode}'");
+ ProcessUtil.PrintMessage("Test results uploaded");
+
+ ProcessUtil.PrintMessage($"Completed Helix job with exit code '{exitCode}'");
Environment.Exit(exitCode);
}
- Console.WriteLine("Tests were not run due to previous failures. Exit code=1");
+ ProcessUtil.PrintMessage("Tests were not run due to previous failures. Exit code=1");
Environment.Exit(1);
}
catch (Exception e)
{
- Console.WriteLine($"HelixTestRunner uncaught exception: {e.ToString()}");
+ ProcessUtil.PrintMessage($"HelixTestRunner uncaught exception: {e.ToString()}");
Environment.Exit(1);
}
}
diff --git a/eng/tools/HelixTestRunner/TestRunner.cs b/eng/tools/HelixTestRunner/TestRunner.cs
index 17cbf5b0eb..30285e90ee 100644
--- a/eng/tools/HelixTestRunner/TestRunner.cs
+++ b/eng/tools/HelixTestRunner/TestRunner.cs
@@ -22,33 +22,34 @@ public class TestRunner
EnvironmentVariables.Add("PATH", Options.Path);
EnvironmentVariables.Add("helix", Options.HelixQueue);
- Console.WriteLine($"Current Directory: {Options.HELIX_WORKITEM_ROOT}");
+ ProcessUtil.PrintMessage($"Current Directory: {Options.HELIX_WORKITEM_ROOT}");
var helixDir = Options.HELIX_WORKITEM_ROOT;
- Console.WriteLine($"Setting HELIX_DIR: {helixDir}");
+ ProcessUtil.PrintMessage($"Setting HELIX_DIR: {helixDir}");
EnvironmentVariables.Add("HELIX_DIR", helixDir);
EnvironmentVariables.Add("NUGET_FALLBACK_PACKAGES", helixDir);
var nugetRestore = Path.Combine(helixDir, "nugetRestore");
EnvironmentVariables.Add("NUGET_RESTORE", nugetRestore);
var dotnetEFFullPath = Path.Combine(nugetRestore, helixDir, "dotnet-ef.exe");
- Console.WriteLine($"Set DotNetEfFullPath: {dotnetEFFullPath}");
+ ProcessUtil.PrintMessage($"Set DotNetEfFullPath: {dotnetEFFullPath}");
EnvironmentVariables.Add("DotNetEfFullPath", dotnetEFFullPath);
var dumpPath = Environment.GetEnvironmentVariable("HELIX_DUMP_FOLDER");
- Console.WriteLine($"Set VSTEST_DUMP_PATH: {dumpPath}");
+ ProcessUtil.PrintMessage($"Set VSTEST_DUMP_PATH: {dumpPath}");
EnvironmentVariables.Add("VSTEST_DUMP_PATH", dumpPath);
+ EnvironmentVariables.Add("DOTNET_CLI_VSTEST_TRACE", "1");
if (Options.InstallPlaywright)
{
// Playwright will download and look for browsers to this directory
var playwrightBrowsers = Environment.GetEnvironmentVariable("PLAYWRIGHT_BROWSERS_PATH");
- Console.WriteLine($"Setting PLAYWRIGHT_BROWSERS_PATH: {playwrightBrowsers}");
+ ProcessUtil.PrintMessage($"Setting PLAYWRIGHT_BROWSERS_PATH: {playwrightBrowsers}");
EnvironmentVariables.Add("PLAYWRIGHT_BROWSERS_PATH", playwrightBrowsers);
}
else
{
- Console.WriteLine($"Skipping setting PLAYWRIGHT_BROWSERS_PATH");
+ ProcessUtil.PrintMessage($"Skipping setting PLAYWRIGHT_BROWSERS_PATH");
}
- Console.WriteLine($"Creating nuget restore directory: {nugetRestore}");
+ ProcessUtil.PrintMessage($"Creating nuget restore directory: {nugetRestore}");
Directory.CreateDirectory(nugetRestore);
// Rename default.runner.json to xunit.runner.json if there is not a custom one from the project
@@ -66,7 +67,7 @@ public class TestRunner
}
catch (Exception e)
{
- Console.WriteLine($"Exception in SetupEnvironment: {e}");
+ ProcessUtil.PrintMessage($"Exception in SetupEnvironment: {e}");
return false;
}
}
@@ -76,20 +77,20 @@ public class TestRunner
try
{
Console.WriteLine();
- Console.WriteLine($"Displaying directory contents for {path}:");
+ ProcessUtil.PrintMessage($"Displaying directory contents for {path}:");
foreach (var file in Directory.EnumerateFiles(path))
{
- Console.WriteLine(Path.GetFileName(file));
+ ProcessUtil.PrintMessage(Path.GetFileName(file));
}
foreach (var file in Directory.EnumerateDirectories(path))
{
- Console.WriteLine(Path.GetFileName(file));
+ ProcessUtil.PrintMessage(Path.GetFileName(file));
}
Console.WriteLine();
}
catch (Exception e)
{
- Console.WriteLine($"Exception in DisplayContents: {e}");
+ ProcessUtil.PrintMessage($"Exception in DisplayContents: {e}");
}
}
@@ -97,7 +98,7 @@ public class TestRunner
{
try
{
- Console.WriteLine($"Installing Playwright Browsers to {Environment.GetEnvironmentVariable("PLAYWRIGHT_BROWSERS_PATH")}");
+ ProcessUtil.PrintMessage($"Installing Playwright Browsers to {Environment.GetEnvironmentVariable("PLAYWRIGHT_BROWSERS_PATH")}");
var exitCode = Microsoft.Playwright.Program.Main(new[] { "install" });
@@ -106,7 +107,7 @@ public class TestRunner
}
catch (Exception e)
{
- Console.WriteLine($"Exception installing playwright: {e}");
+ ProcessUtil.PrintMessage($"Exception installing playwright: {e}");
return false;
}
}
@@ -127,30 +128,30 @@ public class TestRunner
await ProcessUtil.RunAsync($"{Options.DotnetRoot}/dotnet",
$"tool install dotnet-dump --tool-path {Options.HELIX_WORKITEM_ROOT} --add-source {correlationPayload}",
environmentVariables: EnvironmentVariables,
- outputDataReceived: Console.WriteLine,
- errorDataReceived: Console.Error.WriteLine,
+ outputDataReceived: ProcessUtil.PrintMessage,
+ errorDataReceived: ProcessUtil.PrintErrorMessage,
throwOnError: false,
cancellationToken: new CancellationTokenSource(TimeSpan.FromMinutes(2)).Token);
await ProcessUtil.RunAsync($"{Options.DotnetRoot}/dotnet",
$"tool install dotnet-ef --tool-path {Options.HELIX_WORKITEM_ROOT} --add-source {correlationPayload}",
environmentVariables: EnvironmentVariables,
- outputDataReceived: Console.WriteLine,
- errorDataReceived: Console.Error.WriteLine,
+ outputDataReceived: ProcessUtil.PrintMessage,
+ errorDataReceived: ProcessUtil.PrintErrorMessage,
throwOnError: false,
cancellationToken: new CancellationTokenSource(TimeSpan.FromMinutes(2)).Token);
await ProcessUtil.RunAsync($"{Options.DotnetRoot}/dotnet",
$"tool install dotnet-serve --tool-path {Options.HELIX_WORKITEM_ROOT} --add-source {correlationPayload}",
environmentVariables: EnvironmentVariables,
- outputDataReceived: Console.WriteLine,
- errorDataReceived: Console.Error.WriteLine,
+ outputDataReceived: ProcessUtil.PrintMessage,
+ errorDataReceived: ProcessUtil.PrintErrorMessage,
throwOnError: false,
cancellationToken: new CancellationTokenSource(TimeSpan.FromMinutes(2)).Token);
}
catch (Exception e)
{
- Console.WriteLine($"Exception in InstallDotnetTools: {e}");
+ ProcessUtil.PrintMessage($"Exception in InstallDotnetTools: {e}");
return false;
}
finally
@@ -160,13 +161,13 @@ public class TestRunner
try
{
- Console.WriteLine($"Adding current directory to nuget sources: {Options.HELIX_WORKITEM_ROOT}");
+ ProcessUtil.PrintMessage($"Adding current directory to nuget sources: {Options.HELIX_WORKITEM_ROOT}");
await ProcessUtil.RunAsync($"{Options.DotnetRoot}/dotnet",
$"nuget add source {Options.HELIX_WORKITEM_ROOT} --configfile {filename}",
environmentVariables: EnvironmentVariables,
- outputDataReceived: Console.WriteLine,
- errorDataReceived: Console.Error.WriteLine,
+ outputDataReceived: ProcessUtil.PrintMessage,
+ errorDataReceived: ProcessUtil.PrintErrorMessage,
throwOnError: false,
cancellationToken: new CancellationTokenSource(TimeSpan.FromMinutes(2)).Token);
@@ -174,14 +175,14 @@ public class TestRunner
await ProcessUtil.RunAsync($"{Options.DotnetRoot}/dotnet",
"nuget list source",
environmentVariables: EnvironmentVariables,
- outputDataReceived: Console.WriteLine,
- errorDataReceived: Console.Error.WriteLine,
+ outputDataReceived: ProcessUtil.PrintMessage,
+ errorDataReceived: ProcessUtil.PrintErrorMessage,
throwOnError: false,
cancellationToken: new CancellationTokenSource(TimeSpan.FromMinutes(2)).Token);
}
catch (Exception e)
{
- Console.WriteLine($"Exception in InstallDotnetTools: {e}");
+ ProcessUtil.PrintMessage($"Exception in InstallDotnetTools: {e}");
return false;
}
@@ -200,15 +201,15 @@ public class TestRunner
if (discoveryResult.StandardOutput.Contains("Exception thrown"))
{
- Console.WriteLine("Exception thrown during test discovery.");
- Console.WriteLine(discoveryResult.StandardOutput);
+ ProcessUtil.PrintMessage("Exception thrown during test discovery.");
+ ProcessUtil.PrintMessage(discoveryResult.StandardOutput);
return false;
}
return true;
}
catch (Exception e)
{
- Console.WriteLine($"Exception in CheckTestDiscovery: {e}");
+ ProcessUtil.PrintMessage($"Exception in CheckTestDiscovery: {e}");
return false;
}
}
@@ -219,50 +220,60 @@ public class TestRunner
try
{
// Timeout test run 5 minutes before the Helix job would timeout
- var cts = new CancellationTokenSource(Options.Timeout.Subtract(TimeSpan.FromMinutes(5)));
+ var testProcessTimeout = Options.Timeout.Subtract(TimeSpan.FromMinutes(5));
+ var cts = new CancellationTokenSource(testProcessTimeout);
var diagLog = Path.Combine(Environment.GetEnvironmentVariable("HELIX_WORKITEM_UPLOAD_ROOT"), "vstest.log");
- var commonTestArgs = $"test {Options.Target} --diag:{diagLog} --logger:xunit --logger:\"console;verbosity=normal\" --blame \"CollectHangDump;TestTimeout=15m\"";
+ var commonTestArgs = $"test {Options.Target} --diag:{diagLog} --logger xunit --logger \"console;verbosity=normal\" " +
+ "--blame-crash --blame-hang-timeout 15m";
if (Options.Quarantined)
{
- Console.WriteLine("Running quarantined tests.");
+ ProcessUtil.PrintMessage("Running quarantined tests.");
// Filter syntax: https://github.com/Microsoft/vstest-docs/blob/master/docs/filter.md
var result = await ProcessUtil.RunAsync($"{Options.DotnetRoot}/dotnet",
- commonTestArgs + " --TestCaseFilter:\"Quarantined=true\"",
+ commonTestArgs + " --filter \"Quarantined=true\"",
environmentVariables: EnvironmentVariables,
- outputDataReceived: Console.WriteLine,
- errorDataReceived: Console.Error.WriteLine,
+ outputDataReceived: ProcessUtil.PrintMessage,
+ errorDataReceived: ProcessUtil.PrintErrorMessage,
throwOnError: false,
cancellationToken: cts.Token);
+ if (cts.Token.IsCancellationRequested)
+ {
+ ProcessUtil.PrintMessage($"Quarantined tests exceeded configured timeout: {testProcessTimeout.TotalMinutes}m.");
+ }
if (result.ExitCode != 0)
{
- Console.WriteLine($"Failure in quarantined tests. Exit code: {result.ExitCode}.");
+ ProcessUtil.PrintMessage($"Failure in quarantined tests. Exit code: {result.ExitCode}.");
}
}
else
{
- Console.WriteLine("Running non-quarantined tests.");
+ ProcessUtil.PrintMessage("Running non-quarantined tests.");
// Filter syntax: https://github.com/Microsoft/vstest-docs/blob/master/docs/filter.md
var result = await ProcessUtil.RunAsync($"{Options.DotnetRoot}/dotnet",
- commonTestArgs + " --TestCaseFilter:\"Quarantined!=true|Quarantined=false\"",
+ commonTestArgs + " --filter \"Quarantined!=true|Quarantined=false\"",
environmentVariables: EnvironmentVariables,
- outputDataReceived: Console.WriteLine,
- errorDataReceived: Console.Error.WriteLine,
+ outputDataReceived: ProcessUtil.PrintMessage,
+ errorDataReceived: ProcessUtil.PrintErrorMessage,
throwOnError: false,
cancellationToken: cts.Token);
+ if (cts.Token.IsCancellationRequested)
+ {
+ ProcessUtil.PrintMessage($"Non-quarantined tests exceeded configured timeout: {testProcessTimeout.TotalMinutes}m.");
+ }
if (result.ExitCode != 0)
{
- Console.WriteLine($"Failure in non-quarantined tests. Exit code: {result.ExitCode}.");
+ ProcessUtil.PrintMessage($"Failure in non-quarantined tests. Exit code: {result.ExitCode}.");
exitCode = result.ExitCode;
}
}
}
catch (Exception e)
{
- Console.WriteLine($"Exception in HelixTestRunner: {e}");
+ ProcessUtil.PrintMessage($"Exception in HelixTestRunner: {e}");
exitCode = 1;
}
return exitCode;
@@ -271,24 +282,24 @@ public class TestRunner
public void UploadResults()
{
// 'testResults.xml' is the file Helix looks for when processing test results
- Console.WriteLine("Trying to upload results...");
+ ProcessUtil.PrintMessage("Trying to upload results...");
if (File.Exists("TestResults/TestResults.xml"))
{
- Console.WriteLine("Copying TestResults/TestResults.xml to ./testResults.xml");
+ ProcessUtil.PrintMessage("Copying TestResults/TestResults.xml to ./testResults.xml");
File.Copy("TestResults/TestResults.xml", "testResults.xml", overwrite: true);
}
else
{
- Console.WriteLine("No test results found.");
+ ProcessUtil.PrintMessage("No test results found.");
}
var HELIX_WORKITEM_UPLOAD_ROOT = Environment.GetEnvironmentVariable("HELIX_WORKITEM_UPLOAD_ROOT");
if (string.IsNullOrEmpty(HELIX_WORKITEM_UPLOAD_ROOT))
{
- Console.WriteLine("No HELIX_WORKITEM_UPLOAD_ROOT specified, skipping log copy");
+ ProcessUtil.PrintMessage("No HELIX_WORKITEM_UPLOAD_ROOT specified, skipping log copy");
return;
}
- Console.WriteLine($"Copying artifacts/log/ to {HELIX_WORKITEM_UPLOAD_ROOT}/");
+ ProcessUtil.PrintMessage($"Copying artifacts/log/ to {HELIX_WORKITEM_UPLOAD_ROOT}/");
if (Directory.Exists("artifacts/log"))
{
foreach (var file in Directory.EnumerateFiles("artifacts/log", "*.log", SearchOption.AllDirectories))
@@ -296,27 +307,27 @@ public class TestRunner
// Combine the directory name + log name for the copied log file name to avoid overwriting
// duplicate test names in different test projects
var logName = $"{Path.GetFileName(Path.GetDirectoryName(file))}_{Path.GetFileName(file)}";
- Console.WriteLine($"Copying: {file} to {Path.Combine(HELIX_WORKITEM_UPLOAD_ROOT, logName)}");
+ ProcessUtil.PrintMessage($"Copying: {file} to {Path.Combine(HELIX_WORKITEM_UPLOAD_ROOT, logName)}");
File.Copy(file, Path.Combine(HELIX_WORKITEM_UPLOAD_ROOT, logName));
}
}
else
{
- Console.WriteLine("No logs found in artifacts/log");
+ ProcessUtil.PrintMessage("No logs found in artifacts/log");
}
- Console.WriteLine($"Copying TestResults/**/Sequence*.xml to {HELIX_WORKITEM_UPLOAD_ROOT}/");
+ ProcessUtil.PrintMessage($"Copying TestResults/**/Sequence*.xml to {HELIX_WORKITEM_UPLOAD_ROOT}/");
if (Directory.Exists("TestResults"))
{
foreach (var file in Directory.EnumerateFiles("TestResults", "Sequence*.xml", SearchOption.AllDirectories))
{
var fileName = Path.GetFileName(file);
- Console.WriteLine($"Copying: {file} to {Path.Combine(HELIX_WORKITEM_UPLOAD_ROOT, fileName)}");
+ ProcessUtil.PrintMessage($"Copying: {file} to {Path.Combine(HELIX_WORKITEM_UPLOAD_ROOT, fileName)}");
File.Copy(file, Path.Combine(HELIX_WORKITEM_UPLOAD_ROOT, fileName));
}
}
else
{
- Console.WriteLine("No TestResults directory found.");
+ ProcessUtil.PrintMessage("No TestResults directory found.");
}
}
}
diff --git a/src/ProjectTemplates/BlazorTemplates.Tests/BlazorServerTemplateTest.cs b/src/ProjectTemplates/BlazorTemplates.Tests/BlazorServerTemplateTest.cs
index 1a04fd77aa..073eaad776 100644
--- a/src/ProjectTemplates/BlazorTemplates.Tests/BlazorServerTemplateTest.cs
+++ b/src/ProjectTemplates/BlazorTemplates.Tests/BlazorServerTemplateTest.cs
@@ -29,7 +29,7 @@ public class BlazorServerTemplateTest : BlazorTemplateTest
[InlineData(BrowserKind.Chromium)]
public async Task BlazorServerTemplateWorks_NoAuth(BrowserKind browserKind)
{
- var project = await CreateBuildPublishAsync("blazorservernoauth" + browserKind);
+ var project = await CreateBuildPublishAsync();
await using var browser = BrowserManager.IsAvailable(browserKind) ?
await BrowserManager.GetBrowserInstance(browserKind, BrowserContextInfo) :
@@ -83,9 +83,9 @@ public class BlazorServerTemplateTest : BlazorTemplateTest
[Theory(Skip = "https://github.com/dotnet/aspnetcore/issues/30882")]
[MemberData(nameof(BlazorServerTemplateWorks_IndividualAuthData))]
[SkipOnHelix("https://github.com/dotnet/aspnetcore/issues/30825", Queues = "All.OSX")]
- public async Task BlazorServerTemplateWorks_IndividualAuth(BrowserKind browserKind, bool useLocalDB)
+ public async Task BlazorServerTemplateWorks_IndividualAuth(BrowserKind browserKind)
{
- var project = await CreateBuildPublishAsync("blazorserverindividual" + browserKind + (useLocalDB ? "uld" : ""));
+ var project = await CreateBuildPublishAsync();
var browser = !BrowserManager.IsAvailable(browserKind) ?
null :
@@ -187,5 +187,5 @@ public class BlazorServerTemplateTest : BlazorTemplateTest
[InlineData("SingleOrg", new string[] { "--called-api-url \"https://graph.microsoft.com\"", "--called-api-scopes user.readwrite" })]
[InlineData("SingleOrg", new string[] { "--calls-graph" })]
public Task BlazorServerTemplate_IdentityWeb_BuildAndPublish(string auth, string[] args)
- => CreateBuildPublishAsync("blazorserveridweb" + Guid.NewGuid().ToString().Substring(0, 10).ToLowerInvariant(), auth, args);
+ => CreateBuildPublishAsync(auth, args);
}
diff --git a/src/ProjectTemplates/BlazorTemplates.Tests/BlazorTemplateTest.cs b/src/ProjectTemplates/BlazorTemplates.Tests/BlazorTemplateTest.cs
index ef2af1f071..8ea4077007 100644
--- a/src/ProjectTemplates/BlazorTemplates.Tests/BlazorTemplateTest.cs
+++ b/src/ProjectTemplates/BlazorTemplates.Tests/BlazorTemplateTest.cs
@@ -24,12 +24,12 @@ public abstract class BlazorTemplateTest : BrowserTestBase
public abstract string ProjectType { get; }
- protected async Task<Project> CreateBuildPublishAsync(string projectName, string auth = null, string[] args = null, string targetFramework = null, bool serverProject = false, bool onlyCreate = false)
+ protected async Task<Project> CreateBuildPublishAsync(string auth = null, string[] args = null, string targetFramework = null, bool serverProject = false, bool onlyCreate = false)
{
// Additional arguments are needed. See: https://github.com/dotnet/aspnetcore/issues/24278
Environment.SetEnvironmentVariable("EnableDefaultScopedCssItems", "true");
- var project = await ProjectFactory.GetOrCreateProject(projectName, Output);
+ var project = await ProjectFactory.CreateProject(Output);
if (targetFramework != null)
{
project.TargetFramework = targetFramework;
diff --git a/src/ProjectTemplates/BlazorTemplates.Tests/BlazorWasmTemplateTest.cs b/src/ProjectTemplates/BlazorTemplates.Tests/BlazorWasmTemplateTest.cs
index 75107526b6..a19b659670 100644
--- a/src/ProjectTemplates/BlazorTemplates.Tests/BlazorWasmTemplateTest.cs
+++ b/src/ProjectTemplates/BlazorTemplates.Tests/BlazorWasmTemplateTest.cs
@@ -27,7 +27,7 @@ public class BlazorWasmTemplateTest : BlazorTemplateTest
[InlineData(BrowserKind.Chromium)]
public async Task BlazorWasmStandaloneTemplate_Works(BrowserKind browserKind)
{
- var project = await CreateBuildPublishAsync("blazorstandalone" + browserKind);
+ var project = await CreateBuildPublishAsync();
// The service worker assets manifest isn't generated for non-PWA projects
var publishDir = Path.Combine(project.TemplatePublishDir, "wwwroot");
@@ -63,7 +63,7 @@ public class BlazorWasmTemplateTest : BlazorTemplateTest
[InlineData(BrowserKind.Chromium)]
public async Task BlazorWasmHostedTemplate_Works(BrowserKind browserKind)
{
- var project = await CreateBuildPublishAsync("blazorhosted" + BrowserKind.Chromium, args: new[] { "--hosted" }, serverProject: true);
+ var project = await CreateBuildPublishAsync(args: new[] { "--hosted" }, serverProject: true);
var serverProject = GetSubProject(project, "Server", $"{project.ProjectName}.Server");
@@ -111,7 +111,7 @@ public class BlazorWasmTemplateTest : BlazorTemplateTest
[InlineData(BrowserKind.Chromium)]
public async Task BlazorWasmStandalonePwaTemplate_Works(BrowserKind browserKind)
{
- var project = await CreateBuildPublishAsync("blazorstandalonepwa", args: new[] { "--pwa" });
+ var project = await CreateBuildPublishAsync(args: new[] { "--pwa" });
await BuildAndRunTest(project.ProjectName, project, browserKind);
@@ -146,7 +146,7 @@ public class BlazorWasmTemplateTest : BlazorTemplateTest
[InlineData(BrowserKind.Chromium)]
public async Task BlazorWasmHostedPwaTemplate_Works(BrowserKind browserKind)
{
- var project = await CreateBuildPublishAsync("blazorhostedpwa", args: new[] { "--hosted", "--pwa" }, serverProject: true);
+ var project = await CreateBuildPublishAsync(args: new[] { "--hosted", "--pwa" }, serverProject: true);
var serverProject = GetSubProject(project, "Server", $"{project.ProjectName}.Server");
@@ -226,13 +226,12 @@ public class BlazorWasmTemplateTest : BlazorTemplateTest
public Task BlazorWasmHostedTemplate_IndividualAuth_Works_WithOutLocalDB(BrowserKind browserKind)
=> BlazorWasmHostedTemplate_IndividualAuth_Works(browserKind, false);
- private async Task<Project> CreateBuildPublishIndividualAuthProject(BrowserKind browserKind, bool useLocalDb)
+ private async Task<Project> CreateBuildPublishIndividualAuthProject(bool useLocalDb)
{
// Additional arguments are needed. See: https://github.com/dotnet/aspnetcore/issues/24278
Environment.SetEnvironmentVariable("EnableDefaultScopedCssItems", "true");
- var project = await CreateBuildPublishAsync("blazorhostedindividual" + browserKind + (useLocalDb ? "uld" : ""),
- args: new[] { "--hosted", "-au", "Individual", useLocalDb ? "-uld" : "" });
+ var project = await CreateBuildPublishAsync(args: new[] { "--hosted", "-au", "Individual", useLocalDb ? "-uld" : "" });
var serverProject = GetSubProject(project, "Server", $"{project.ProjectName}.Server");
@@ -274,7 +273,7 @@ public class BlazorWasmTemplateTest : BlazorTemplateTest
private async Task BlazorWasmHostedTemplate_IndividualAuth_Works(BrowserKind browserKind, bool useLocalDb)
{
- var project = await CreateBuildPublishIndividualAuthProject(browserKind, useLocalDb: useLocalDb);
+ var project = await CreateBuildPublishIndividualAuthProject(useLocalDb: useLocalDb);
var serverProject = GetSubProject(project, "Server", $"{project.ProjectName}.Server");
@@ -376,7 +375,7 @@ public class BlazorWasmTemplateTest : BlazorTemplateTest
[Theory(Skip = "https://github.com/dotnet/aspnetcore/issues/37782")]
[MemberData(nameof(TemplateData))]
public Task BlazorWasmHostedTemplate_AzureActiveDirectoryTemplate_Works(TemplateInstance instance)
- => CreateBuildPublishAsync(instance.Name, args: instance.Arguments, targetFramework: "netstandard2.1");
+ => CreateBuildPublishAsync(args: instance.Arguments, targetFramework: "netstandard2.1");
protected async Task BuildAndRunTest(string appName, Project project, BrowserKind browserKind, bool usesAuth = false)
{
diff --git a/src/ProjectTemplates/README.md b/src/ProjectTemplates/README.md
index dc1615b5cb..acb3b240a1 100644
--- a/src/ProjectTemplates/README.md
+++ b/src/ProjectTemplates/README.md
@@ -36,7 +36,7 @@ To build the ProjectTemplates, use one of:
### Test
-#### Running ProjectTemplate tests:
+#### Running ProjectTemplate tests
To run ProjectTemplate tests, first ensure the ASP.NET localhost development certificate is installed and trusted.
Otherwise, you'll get a test error "Certificate error: Navigation blocked".
@@ -62,6 +62,101 @@ Then, use one of:
previous step, it is NOT advised that you install templates created on your local machine using just
`dotnet new -i [nupkgPath]`.
+#### Conditional tests & skipping test platforms
+
+Individual test methods can be decorated with attributes to configure them to not run ("skip running") on certain platforms. The `[ConditionalFact]` and `[ConditionalTheory]` attributes must be used on tests using the skip attributes in order for them to actually be skipped:
+
+``` csharp
+[ConditionalFact]
+[OSSkipCondition(OperatingSystems.Linux | OperatingSystems.MacOSX)]
+[SkipOnHelix("cert failure", Queues = "All.OSX;" + HelixConstants.Windows10Arm64)]
+public async Task MvcTemplate_SingleFileExe()
+{
+```
+
+An entire test project can be configured to skip specific platforms using the `<SkipHelixQueues>` property in the project's .csproj file, e.g.:
+
+```xml
+<SkipHelixQueues>
+ $(HelixQueueArmDebian11);
+</SkipHelixQueues>
+```
+
+Tests that are skipped should have details, or better yet link to an issue, explaining why they're being skipped, either as a string argument to the attribute or a code comment.
+
+#### Test timeouts
+
+When tests are run as part of the CI infrastructure, a number of different timeouts can impact whether tests pass or not.
+
+##### Helix job timeout
+
+When queuing test jobs to the Helix infrastructure, a timeout value is passed that the entire Helix job must complete within, i.e. that job running on a single queue. This default value is set in [eng\targets\Helix.props](eng/targets/Helix.props):
+
+```xml
+<HelixTimeout>00:45:00</HelixTimeout>
+```
+
+This value is printed by the Helix runner at the beginning of the console log, formatted in seconds, e.g.:
+
+```log
+Console log: 'ProjectTemplates.Tests--net7.0' from job b2f6fbe0-4dbe-45fa-a123-9a8c876d5923 (ubuntu.1804.armarch.open) using docker image mcr.microsoft.com/dotnet-buildtools/prereqs:debian-11-helix-arm64v8-20211001171229-97d8652 on ddvsotx2l137
+running $HELIX_CORRELATION_PAYLOAD/scripts/71557bd7f20e49fbbaa81cc79bd57fd6/execute.sh in /home/helixbot/work/C08609D9/w/B3D709E1/e max 2700 seconds
+```
+
+Note that some test projects might override this value in their project file and that some Helix queues are slower than others, so the same test job might complete within the timeout on one queue but exceed the timeout on another (the ARM queues are particularly prone to being slower than their AMD/Intel counterparts).
+
+##### Helix runner timeout
+
+The [Helix test runner](eng/tools/HelixTestRunner) launches the actual process that runs tests within a Helix job and when doing so configures its own timeout that is 5 minutes less than the Helix job timeout, e.g. if the Helix job timeout is 45 minutes, the Helix test runner process timeout will be 40 minutes.
+
+If this timeout is exceeded, the Helix test runner will capture a dump of the test process before terminating it and printing a message in the console log, e.g.:
+
+```log
+2022-05-12T00:27:28.8279660Z Non-quarantined tests exceeded configured timeout: 40m.
+```
+
+##### Helix runner `dotnet test` timeout
+
+When running in Helix, a test hang timeout, e.g. `dotnet test --blame-hang-timeout 15m` , is configured in [eng\tools\HelixTestRunner\TestRunner.cs](eng/tools/HelixTestRunner/TestRunner.cs)
+
+```csharp
+public async Task<int> RunTestsAsync()
+{
+ ...
+ var commonTestArgs = $"test {Options.Target} --diag:{diagLog} --logger xunit --logger \"console;verbosity=normal\" " +
+ "--blame-crash --blame-hang-timeout 15m";
+```
+
+This timeout applies to each individual `[Fact]` or `[Theory]`. Note that for `[Theory]` this timeout is **not** reset for each instance of the theory, i.e. the entire `[Theory]` must run within the specified timeout.
+
+If this timeout is triggered, a message will be printed to the `vstest.datacollector.[date-time-stamp].log` file for the test run, e.g.:
+
+```
+19:54:18.888, 4653892436493, datacollector.dll, The specified inactivity time of 15 minutes has elapsed. Collecting hang dumps from testhost and its child processes
+```
+
+**Note:** It's a good idea to spread the number of cases for `[Theory]` tests across different test methods if the test method takes more than a few seconds to complete as this will help to keep the total `[Theory]` runtime less than the configured timeout, e.g.:
+
+``` csharp
+[ConditionalTheory]
+[SkipOnHelix("https://github.com/dotnet/aspnetcore/issues/28090", Queues = HelixConstants.Windows10Arm64 + HelixConstants.DebianArm64)]
+[InlineData("IndividualB2C", null)]
+[InlineData("IndividualB2C", new[] { ArgConstants.UseProgramMain })]
+[InlineData("IndividualB2C", new[] { ArgConstants.CalledApiUrlGraphMicrosoftCom, ArgConstants.CalledApiScopesUserReadWrite })]
+[InlineData("IndividualB2C", new[] { ArgConstants.UseProgramMain, ArgConstants.CalledApiUrlGraphMicrosoftCom, ArgConstants.CalledApiScopesUserReadWrite })]
+public Task MvcTemplate_IdentityWeb_IndividualB2C_BuildsAndPublishes(string auth, string[] args) => MvcTemplateBuildsAndPublishes(auth: auth, args: args);
+
+[ConditionalTheory]
+[SkipOnHelix("https://github.com/dotnet/aspnetcore/issues/28090", Queues = HelixConstants.Windows10Arm64 + HelixConstants.DebianArm64)]
+[InlineData("SingleOrg", null)]
+[InlineData("SingleOrg", new[] { ArgConstants.UseProgramMain })]
+[InlineData("SingleOrg", new[] { ArgConstants.CalledApiUrlGraphMicrosoftCom, ArgConstants.CalledApiScopesUserReadWrite })]
+[InlineData("SingleOrg", new[] { ArgConstants.UseProgramMain, ArgConstants.CalledApiUrlGraphMicrosoftCom, ArgConstants.CalledApiScopesUserReadWrite })]
+[InlineData("SingleOrg", new[] { ArgConstants.CallsGraph })]
+[InlineData("SingleOrg", new[] { ArgConstants.UseProgramMain, ArgConstants.CallsGraph })]
+public Task MvcTemplate_IdentityWeb_SingleOrg_BuildsAndPublishes(string auth, string[] args) => MvcTemplateBuildsAndPublishes(auth: auth, args: args);
+```
+
## More Information
For more information, see the [ASP.NET Core README](../../README.md).
diff --git a/src/ProjectTemplates/Shared/Project.cs b/src/ProjectTemplates/Shared/Project.cs
index 4cf73e7ff9..07f27f07d0 100644
--- a/src/ProjectTemplates/Shared/Project.cs
+++ b/src/ProjectTemplates/Shared/Project.cs
@@ -108,38 +108,24 @@ public class Project : IDisposable
argString += $" -o {TemplateOutputDir}";
- // Only run one instance of 'dotnet new' at once, as a workaround for
- // https://github.com/aspnet/templating/issues/63
-
- await DotNetNewLock.WaitAsync();
- try
+ if (Directory.Exists(TemplateOutputDir))
{
- Output.WriteLine("Acquired DotNetNewLock");
-
- if (Directory.Exists(TemplateOutputDir))
- {
- Output.WriteLine($"Template directory already exists, deleting contents of {TemplateOutputDir}");
- Directory.Delete(TemplateOutputDir, recursive: true);
- }
-
- using var execution = ProcessEx.Run(Output, AppContext.BaseDirectory, DotNetMuxer.MuxerPathOrDefault(), argString, environmentVariables);
- await execution.Exited;
+ Output.WriteLine($"Template directory already exists, deleting contents of {TemplateOutputDir}");
+ Directory.Delete(TemplateOutputDir, recursive: true);
+ }
- var result = new ProcessResult(execution);
+ using var execution = ProcessEx.Run(Output, AppContext.BaseDirectory, DotNetMuxer.MuxerPathOrDefault(), argString, environmentVariables);
+ await execution.Exited;
- // Because dotnet new automatically restores but silently ignores restore errors, need to handle restore errors explicitly
- if (errorOnRestoreError && (execution.Output.Contains("Restore failed.") || execution.Error.Contains("Restore failed.")))
- {
- result.ExitCode = -1;
- }
+ var result = new ProcessResult(execution);
- return result;
- }
- finally
+ // Because dotnet new automatically restores but silently ignores restore errors, need to handle restore errors explicitly
+ if (errorOnRestoreError && (execution.Output.Contains("Restore failed.") || execution.Error.Contains("Restore failed.")))
{
- DotNetNewLock.Release();
- Output.WriteLine("Released DotNetNewLock");
+ result.ExitCode = -1;
}
+
+ return result;
}
internal async Task<ProcessResult> RunDotNetPublishAsync(IDictionary<string, string> packageOptions = null, string additionalArgs = null, bool noRestore = true)
@@ -223,62 +209,38 @@ public class Project : IDisposable
{
var args = $"--verbose --no-build migrations add {migrationName}";
- // Only run one instance of 'dotnet new' at once, as a workaround for
- // https://github.com/aspnet/templating/issues/63
- await DotNetNewLock.WaitAsync();
- try
+ var command = DotNetMuxer.MuxerPathOrDefault();
+ if (string.IsNullOrEmpty(Environment.GetEnvironmentVariable("DotNetEfFullPath")))
{
- Output.WriteLine("Acquired DotNetNewLock");
- var command = DotNetMuxer.MuxerPathOrDefault();
- if (string.IsNullOrEmpty(Environment.GetEnvironmentVariable("DotNetEfFullPath")))
- {
- args = $"\"{DotNetEfFullPath}\" " + args;
- }
- else
- {
- command = "dotnet-ef";
- }
-
- using var result = ProcessEx.Run(Output, TemplateOutputDir, command, args);
- await result.Exited;
- return new ProcessResult(result);
+ args = $"\"{DotNetEfFullPath}\" " + args;
}
- finally
+ else
{
- DotNetNewLock.Release();
- Output.WriteLine("Released DotNetNewLock");
+ command = "dotnet-ef";
}
+
+ using var result = ProcessEx.Run(Output, TemplateOutputDir, command, args);
+ await result.Exited;
+ return new ProcessResult(result);
}
internal async Task<ProcessResult> RunDotNetEfUpdateDatabaseAsync()
{
var args = "--verbose --no-build database update";
- // Only run one instance of 'dotnet new' at once, as a workaround for
- // https://github.com/aspnet/templating/issues/63
- await DotNetNewLock.WaitAsync();
- try
+ var command = DotNetMuxer.MuxerPathOrDefault();
+ if (string.IsNullOrEmpty(Environment.GetEnvironmentVariable("DotNetEfFullPath")))
{
- Output.WriteLine("Acquired DotNetNewLock");
- var command = DotNetMuxer.MuxerPathOrDefault();
- if (string.IsNullOrEmpty(Environment.GetEnvironmentVariable("DotNetEfFullPath")))
- {
- args = $"\"{DotNetEfFullPath}\" " + args;
- }
- else
- {
- command = "dotnet-ef";
- }
-
- using var result = ProcessEx.Run(Output, TemplateOutputDir, command, args);
- await result.Exited;
- return new ProcessResult(result);
+ args = $"\"{DotNetEfFullPath}\" " + args;
}
- finally
+ else
{
- DotNetNewLock.Release();
- Output.WriteLine("Released DotNetNewLock");
+ command = "dotnet-ef";
}
+
+ using var result = ProcessEx.Run(Output, TemplateOutputDir, command, args);
+ await result.Exited;
+ return new ProcessResult(result);
}
// If this fails, you should generate new migrations via migrations/updateMigrations.cmd
@@ -334,25 +296,15 @@ public class Project : IDisposable
internal async Task<ProcessEx> RunDotNetNewRawAsync(string arguments)
{
- await DotNetNewLock.WaitAsync();
- try
- {
- Output.WriteLine("Acquired DotNetNewLock");
- var result = ProcessEx.Run(
- Output,
- AppContext.BaseDirectory,
- DotNetMuxer.MuxerPathOrDefault(),
- arguments +
- $" --debug:disable-sdk-templates --debug:custom-hive \"{TemplatePackageInstaller.CustomHivePath}\"" +
- $" -o {TemplateOutputDir}");
- await result.Exited;
- return result;
- }
- finally
- {
- DotNetNewLock.Release();
- Output.WriteLine("Released DotNetNewLock");
- }
+ var result = ProcessEx.Run(
+ Output,
+ AppContext.BaseDirectory,
+ DotNetMuxer.MuxerPathOrDefault(),
+ arguments +
+ $" --debug:disable-sdk-templates --debug:custom-hive \"{TemplatePackageInstaller.CustomHivePath}\"" +
+ $" -o {TemplateOutputDir}");
+ await result.Exited;
+ return result;
}
public void Dispose()
diff --git a/src/ProjectTemplates/Shared/ProjectFactoryFixture.cs b/src/ProjectTemplates/Shared/ProjectFactoryFixture.cs
index f16ef4dbc6..0de11acd78 100644
--- a/src/ProjectTemplates/Shared/ProjectFactoryFixture.cs
+++ b/src/ProjectTemplates/Shared/ProjectFactoryFixture.cs
@@ -24,42 +24,38 @@ public class ProjectFactoryFixture : IDisposable
DiagnosticsMessageSink = diagnosticsMessageSink;
}
- public async Task<Project> GetOrCreateProject(string projectKey, ITestOutputHelper output)
+ public async Task<Project> CreateProject(ITestOutputHelper output)
{
await TemplatePackageInstaller.EnsureTemplatingEngineInitializedAsync(output);
- // Different tests may have different output helpers, so need to fix up the output to write to the correct log
- if (_projects.TryGetValue(projectKey, out var project))
+
+ var project = CreateProjectImpl(output);
+
+ var projectKey = Guid.NewGuid().ToString().Substring(0, 10).ToLowerInvariant();
+ if (!_projects.TryAdd(projectKey, project))
{
- project.Output = output;
- return project;
+ throw new InvalidOperationException($"Project key collision in {nameof(ProjectFactoryFixture)}.{nameof(CreateProject)}!");
}
- return _projects.GetOrAdd(
- projectKey,
- (key, outputHelper) =>
- {
- var project = new Project
- {
- Output = outputHelper,
- DiagnosticsMessageSink = DiagnosticsMessageSink,
- ProjectGuid = Path.GetRandomFileName().Replace(".", string.Empty)
- };
- // Replace first character with a random letter if it's a digit to avoid random insertions of '_'
- // into template namespace declarations (i.e. make it more stable for testing)
- var projectNameSuffix = !char.IsLetter(project.ProjectGuid[0])
- ? string.Create(project.ProjectGuid.Length, project.ProjectGuid, (suffix, guid) =>
- {
- guid.AsSpan(1).CopyTo(suffix[1..]);
- suffix[0] = GetRandomLetter();
- })
- : project.ProjectGuid;
- project.ProjectName = $"AspNet.{projectNameSuffix}";
-
- var assemblyPath = GetType().Assembly;
- var basePath = GetTemplateFolderBasePath(assemblyPath);
- project.TemplateOutputDir = Path.Combine(basePath, project.ProjectName);
- return project;
- },
- output);
+
+ return project;
+ }
+
+ private Project CreateProjectImpl(ITestOutputHelper output)
+ {
+ var project = new Project
+ {
+ Output = output,
+ DiagnosticsMessageSink = DiagnosticsMessageSink,
+ // Ensure first character is a letter to avoid random insertions of '_' into template namespace
+ // declarations (i.e. make it more stable for testing)
+ ProjectGuid = GetRandomLetter() + Path.GetRandomFileName().Replace(".", string.Empty)
+ };
+ project.ProjectName = $"AspNet.{project.ProjectGuid}";
+
+ var assemblyPath = GetType().Assembly;
+ var basePath = GetTemplateFolderBasePath(assemblyPath);
+ project.TemplateOutputDir = Path.Combine(basePath, project.ProjectName);
+
+ return project;
}
private static char GetRandomLetter() => LetterChars[Random.Shared.Next(LetterChars.Length - 1)];
diff --git a/src/ProjectTemplates/Shared/TemplatePackageInstaller.cs b/src/ProjectTemplates/Shared/TemplatePackageInstaller.cs
index e8d5ef5c84..a23b4f0351 100644
--- a/src/ProjectTemplates/Shared/TemplatePackageInstaller.cs
+++ b/src/ProjectTemplates/Shared/TemplatePackageInstaller.cs
@@ -53,24 +53,14 @@ internal static class TemplatePackageInstaller
public static async Task EnsureTemplatingEngineInitializedAsync(ITestOutputHelper output)
{
- await ProcessLock.DotNetNewLock.WaitAsync();
- try
+ if (!_haveReinstalledTemplatePackages)
{
- output.WriteLine("Acquired DotNetNewLock");
- if (!_haveReinstalledTemplatePackages)
+ if (Directory.Exists(CustomHivePath))
{
- if (Directory.Exists(CustomHivePath))
- {
- Directory.Delete(CustomHivePath, recursive: true);
- }
- await InstallTemplatePackages(output);
- _haveReinstalledTemplatePackages = true;
+ Directory.Delete(CustomHivePath, recursive: true);
}
- }
- finally
- {
- ProcessLock.DotNetNewLock.Release();
- output.WriteLine("Released DotNetNewLock");
+ await InstallTemplatePackages(output);
+ _haveReinstalledTemplatePackages = true;
}
}
diff --git a/src/ProjectTemplates/test/ArgConstants.cs b/src/ProjectTemplates/test/ArgConstants.cs
index 530b9d220a..94a3b2965c 100644
--- a/src/ProjectTemplates/test/ArgConstants.cs
+++ b/src/ProjectTemplates/test/ArgConstants.cs
@@ -23,4 +23,5 @@ internal static class ArgConstants
public const string AppIdClientId = "--api-client-id";
public const string TenantId = "--tenant-id";
public const string AadB2cInstance = "--aad-b2c-instance";
+ public const string UseLocalDb = "-uld";
}
diff --git a/src/ProjectTemplates/test/AssemblyInfo.AssemblyFixtures.cs b/src/ProjectTemplates/test/AssemblyInfo.AssemblyFixtures.cs
index 7e531ec57e..b89b6eee90 100644
--- a/src/ProjectTemplates/test/AssemblyInfo.AssemblyFixtures.cs
+++ b/src/ProjectTemplates/test/AssemblyInfo.AssemblyFixtures.cs
@@ -3,5 +3,7 @@
using Microsoft.AspNetCore.Testing;
using Templates.Test.Helpers;
+using Xunit;
[assembly: AssemblyFixture(typeof(ProjectFactoryFixture))]
+[assembly: CollectionBehavior(DisableTestParallelization = true)]
diff --git a/src/ProjectTemplates/test/BaselineTest.cs b/src/ProjectTemplates/test/BaselineTest.cs
index 73a5867204..57e4c5186b 100644
--- a/src/ProjectTemplates/test/BaselineTest.cs
+++ b/src/ProjectTemplates/test/BaselineTest.cs
@@ -72,7 +72,7 @@ public class BaselineTest : LoggedTest
[MemberData(nameof(TemplateBaselines))]
public async Task Template_Produces_The_Right_Set_Of_FilesAsync(string arguments, string[] expectedFiles)
{
- Project = await ProjectFactory.GetOrCreateProject(CreateProjectKey(arguments), Output);
+ Project = await ProjectFactory.CreateProject(Output);
var createResult = await Project.RunDotNetNewRawAsync(arguments);
Assert.True(createResult.ExitCode == 0, createResult.GetFormattedOutput());
@@ -105,7 +105,7 @@ public class BaselineTest : LoggedTest
if (relativePath.EndsWith(".cs", StringComparison.Ordinal))
{
var namespaceDeclarationPrefix = "namespace ";
- var namespaceDeclaration = File.ReadLines(Path.Combine(Project.TemplateOutputDir, relativePath))
+ var namespaceDeclaration = File.ReadLines(file)
.SingleOrDefault(line => line.StartsWith(namespaceDeclarationPrefix, StringComparison.Ordinal))
?.Substring(namespaceDeclarationPrefix.Length);
@@ -118,65 +118,6 @@ public class BaselineTest : LoggedTest
}
}
- private static ConcurrentDictionary<string, object> _projectKeys = new();
-
- private string CreateProjectKey(string arguments)
- {
- var text = "baseline";
-
- // Turn string like "new templatename -minimal -au SingleOrg --another-option OptionValue"
- // into array like [ "new templatename", "minimal", "au SingleOrg", "another-option OptionValue" ]
- var argumentsArray = arguments
- .Split(new[] { " --", " -" }, StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries)
- .ToArray();
-
- // Add template name, value has form of "new name"
- text += argumentsArray[0].Substring("new ".Length);
-
- // Sort arguments to ensure definitions that differ only by arguments order are caught
- Array.Sort(argumentsArray, StringComparer.Ordinal);
-
- foreach (var argValue in argumentsArray)
- {
- var argSegments = argValue.Split(' ', StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries);
-
- if (argSegments.Length == 0)
- {
- continue;
- }
- else if (argSegments.Length == 1)
- {
- text += argSegments[0] switch
- {
- "ho" => "hosted",
- "p" => "pwa",
- _ => argSegments[0].Replace("-", "")
- };
- }
- else
- {
- text += argSegments[0] switch
- {
- "au" => argSegments[1],
- "uld" => "uld",
- "language" => argSegments[1].Replace("#", "Sharp"),
- "support-pages-and-views" when argSegments[1] == "true" => "supportpagesandviewstrue",
- _ => ""
- };
- }
- }
-
- if (!_projectKeys.TryAdd(text, null))
- {
- throw new InvalidOperationException(
- $"Project key for template with args '{arguments}' already exists. " +
- $"Check that the metadata specified in {BaselineDefinitionFileResourceName} is correct and that " +
- $"the {nameof(CreateProjectKey)} method is considering enough template arguments to ensure uniqueness.");
- }
-
- return text;
- }
-
private void AssertFileExists(string basePath, string path, bool shouldExist)
{
var fullPath = Path.Combine(basePath, path);
diff --git a/src/ProjectTemplates/test/BlazorServerTemplateTest.cs b/src/ProjectTemplates/test/BlazorServerTemplateTest.cs
index 71984addf0..e6dc0bf87a 100644
--- a/src/ProjectTemplates/test/BlazorServerTemplateTest.cs
+++ b/src/ProjectTemplates/test/BlazorServerTemplateTest.cs
@@ -24,31 +24,36 @@ public class BlazorServerTemplateTest : BlazorTemplateTest
public override string ProjectType { get; } = "blazorserver";
[Fact]
- public Task BlazorServerTemplateWorks_NoAuth() => CreateBuildPublishAsync("blazorservernoauth");
+ public Task BlazorServerTemplateWorks_NoAuth() => CreateBuildPublishAsync();
[Fact]
- public Task BlazorServerTemplateWorks_ProgamMainNoAuth() => CreateBuildPublishAsync("blazorservernoauth", args: new[] { ArgConstants.UseProgramMain });
+ public Task BlazorServerTemplateWorks_ProgamMainNoAuth() => CreateBuildPublishAsync(args: new[] { ArgConstants.UseProgramMain });
- [Theory]
- [InlineData(true, null)]
- [InlineData(true, new string[] { ArgConstants.UseProgramMain })]
- [InlineData(false, null)]
- [InlineData(false, new string[] { ArgConstants.UseProgramMain })]
+ [ConditionalTheory]
+ [InlineData("Individual", null)]
+ [InlineData("Individual", new string[] { ArgConstants.UseProgramMain })]
[SkipOnHelix("https://github.com/dotnet/aspnetcore/issues/30825", Queues = "All.OSX")]
- public Task BlazorServerTemplateWorks_IndividualAuth(bool useLocalDB, string[] args) => CreateBuildPublishAsync("blazorserverindividual" + (useLocalDB ? "uld" : "", args: args));
+ public Task BlazorServerTemplateWorks_IndividualAuth(string auth, string[] args) => CreateBuildPublishAsync(auth, args: args);
+
+ [ConditionalTheory]
+ [InlineData("Individual", new string[] { ArgConstants.UseLocalDb })]
+ [InlineData("Individual", new string[] { ArgConstants.UseProgramMain, ArgConstants.UseLocalDb })]
+ [OSSkipCondition(OperatingSystems.Linux | OperatingSystems.MacOSX, SkipReason = "No LocalDb on non-Windows")]
+ public Task BlazorServerTemplateWorks_IndividualAuth_LocalDb(string auth, string[] args) => CreateBuildPublishAsync(auth, args: args);
[Theory]
[InlineData("IndividualB2C", null)]
[InlineData("IndividualB2C", new[] { ArgConstants.UseProgramMain })]
[InlineData("IndividualB2C", new[] { ArgConstants.CalledApiUrlGraphMicrosoftCom, ArgConstants.CalledApiScopesUserReadWrite })]
[InlineData("IndividualB2C", new[] { ArgConstants.UseProgramMain, ArgConstants.CalledApiUrlGraphMicrosoftCom, ArgConstants.CalledApiScopesUserReadWrite })]
+ public Task BlazorServerTemplate_IdentityWeb_BuildAndPublish_IndividualB2C(string auth, string[] args) => CreateBuildPublishAsync(auth, args);
+
+ [Theory]
[InlineData("SingleOrg", null)]
[InlineData("SingleOrg", new[] { ArgConstants.UseProgramMain })]
[InlineData("SingleOrg", new[] { ArgConstants.CalledApiUrlGraphMicrosoftCom, ArgConstants.CalledApiScopesUserReadWrite })]
[InlineData("SingleOrg", new[] { ArgConstants.UseProgramMain, ArgConstants.CalledApiUrlGraphMicrosoftCom, ArgConstants.CalledApiScopesUserReadWrite })]
[InlineData("SingleOrg", new[] { ArgConstants.CallsGraph })]
[InlineData("SingleOrg", new[] { ArgConstants.UseProgramMain, ArgConstants.CallsGraph })]
- public Task BlazorServerTemplate_IdentityWeb_BuildAndPublish(string auth, string[] args)
- => CreateBuildPublishAsync("blazorserveridweb" + Guid.NewGuid().ToString().Substring(0, 10).ToLowerInvariant(), auth, args);
-
+ public Task BlazorServerTemplate_IdentityWeb_BuildAndPublish_SingleOrg(string auth, string[] args) => CreateBuildPublishAsync(auth, args);
}
diff --git a/src/ProjectTemplates/test/BlazorTemplateTest.cs b/src/ProjectTemplates/test/BlazorTemplateTest.cs
index 246a502883..d0cf3717d2 100644
--- a/src/ProjectTemplates/test/BlazorTemplateTest.cs
+++ b/src/ProjectTemplates/test/BlazorTemplateTest.cs
@@ -41,12 +41,12 @@ public abstract class BlazorTemplateTest : LoggedTest
public abstract string ProjectType { get; }
- protected async Task<Project> CreateBuildPublishAsync(string projectName, string auth = null, string[] args = null, string targetFramework = null, bool serverProject = false, bool onlyCreate = false)
+ protected async Task<Project> CreateBuildPublishAsync(string auth = null, string[] args = null, string targetFramework = null, bool serverProject = false, bool onlyCreate = false)
{
// Additional arguments are needed. See: https://github.com/dotnet/aspnetcore/issues/24278
Environment.SetEnvironmentVariable("EnableDefaultScopedCssItems", "true");
- var project = await ProjectFactory.GetOrCreateProject(projectName, Output);
+ var project = await ProjectFactory.CreateProject(Output);
if (targetFramework != null)
{
project.TargetFramework = targetFramework;
diff --git a/src/ProjectTemplates/test/BlazorWasmTemplateTest.cs b/src/ProjectTemplates/test/BlazorWasmTemplateTest.cs
index 2c24bd1e0d..1edca07fd8 100644
--- a/src/ProjectTemplates/test/BlazorWasmTemplateTest.cs
+++ b/src/ProjectTemplates/test/BlazorWasmTemplateTest.cs
@@ -27,7 +27,7 @@ public class BlazorWasmTemplateTest : BlazorTemplateTest
[Fact]
public async Task BlazorWasmStandaloneTemplateCanCreateBuildPublish()
{
- var project = await CreateBuildPublishAsync("blazorstandalone");
+ var project = await CreateBuildPublishAsync();
// The service worker assets manifest isn't generated for non-PWA projects
var publishDir = Path.Combine(project.TemplatePublishDir, "wwwroot");
@@ -35,18 +35,18 @@ public class BlazorWasmTemplateTest : BlazorTemplateTest
}
[Fact]
- public Task BlazorWasmHostedTemplateCanCreateBuildPublish() => CreateBuildPublishAsync("blazorhosted", args: new[] { ArgConstants.Hosted }, serverProject: true);
+ public Task BlazorWasmHostedTemplateCanCreateBuildPublish() => CreateBuildPublishAsync(args: new[] { ArgConstants.Hosted }, serverProject: true);
[Fact]
- public Task BlazorWasmHostedTemplateWithProgamMainCanCreateBuildPublish() => CreateBuildPublishAsync("blazorhosted", args: new[] { ArgConstants.UseProgramMain, ArgConstants.Hosted }, serverProject: true);
+ public Task BlazorWasmHostedTemplateWithProgamMainCanCreateBuildPublish() => CreateBuildPublishAsync(args: new[] { ArgConstants.UseProgramMain, ArgConstants.Hosted }, serverProject: true);
[Fact]
- public Task BlazorWasmStandalonePwaTemplateCanCreateBuildPublish() => CreateBuildPublishAsync("blazorstandalonepwa", args: new[] { ArgConstants.Pwa });
+ public Task BlazorWasmStandalonePwaTemplateCanCreateBuildPublish() => CreateBuildPublishAsync(args: new[] { ArgConstants.Pwa });
[Fact]
public async Task BlazorWasmHostedPwaTemplateCanCreateBuildPublish()
{
- var project = await CreateBuildPublishAsync("blazorhostedpwa", args: new[] { ArgConstants.Hosted, ArgConstants.Pwa }, serverProject: true);
+ var project = await CreateBuildPublishAsync(args: new[] { ArgConstants.Hosted, ArgConstants.Pwa }, serverProject: true);
var serverProject = GetSubProject(project, "Server", $"{project.ProjectName}.Server");
@@ -105,8 +105,7 @@ public class BlazorWasmTemplateTest : BlazorTemplateTest
// Additional arguments are needed. See: https://github.com/dotnet/aspnetcore/issues/24278
Environment.SetEnvironmentVariable("EnableDefaultScopedCssItems", "true");
- var project = await CreateBuildPublishAsync("blazorhostedindividual" + (useLocalDb ? "uld" : ""),
- args: new[] { ArgConstants.Hosted, ArgConstants.Auth, "Individual", useLocalDb ? "-uld" : "", useProgramMain ? ArgConstants.UseProgramMain : "" });
+ var project = await CreateBuildPublishAsync("Individual", args: new[] { ArgConstants.Hosted, useLocalDb ? "-uld" : "", useProgramMain ? ArgConstants.UseProgramMain : "" });
var serverProject = GetSubProject(project, "Server", $"{project.ProjectName}.Server");
@@ -150,9 +149,7 @@ public class BlazorWasmTemplateTest : BlazorTemplateTest
[Fact]
public async Task BlazorWasmStandaloneTemplate_IndividualAuth_CreateBuildPublish()
{
- var project = await CreateBuildPublishAsync("blazorstandaloneindividual", args: new[] {
- ArgConstants.Auth,
- "Individual",
+ var project = await CreateBuildPublishAsync("Individual", args: new[] {
"--authority",
"https://login.microsoftonline.com/common/v2.0/.well-known/openid-configuration",
ArgConstants.ClientId,
@@ -160,7 +157,7 @@ public class BlazorWasmTemplateTest : BlazorTemplateTest
});
}
- public static TheoryData<TemplateInstance> TemplateData => new TheoryData<TemplateInstance>
+ public static TheoryData<TemplateInstance> TemplateDataIndividualB2C => new TheoryData<TemplateInstance>
{
new TemplateInstance(
"blazorwasmhostedaadb2c", "-ho",
@@ -184,6 +181,25 @@ public class BlazorWasmTemplateTest : BlazorTemplateTest
ArgConstants.AppIdClientId, "1234123413241324",
ArgConstants.UseProgramMain),
new TemplateInstance(
+ "blazorwasmstandaloneaadb2c",
+ ArgConstants.Auth, "IndividualB2C",
+ ArgConstants.AadB2cInstance, "example.b2clogin.com",
+ "-ssp", "b2c_1_siupin",
+ ArgConstants.ClientId, "clientId",
+ ArgConstants.Domain, "my-domain"),
+ new TemplateInstance(
+ "blazorwasmstandaloneaadb2c_program_main",
+ ArgConstants.Auth, "IndividualB2C",
+ ArgConstants.AadB2cInstance, "example.b2clogin.com",
+ "-ssp", "b2c_1_siupin",
+ ArgConstants.ClientId, "clientId",
+ ArgConstants.Domain, "my-domain",
+ ArgConstants.UseProgramMain),
+ };
+
+ public static TheoryData<TemplateInstance> TemplateDataSingleOrg => new TheoryData<TemplateInstance>
+ {
+ new TemplateInstance(
"blazorwasmhostedaad", "-ho",
ArgConstants.Auth, "SingleOrg",
ArgConstants.Domain, "my-domain",
@@ -193,19 +209,20 @@ public class BlazorWasmTemplateTest : BlazorTemplateTest
ArgConstants.AppIdUri, "ApiUri",
ArgConstants.AppIdClientId, "1234123413241324"),
new TemplateInstance(
- "blazorwasmhostedaad_program_main", "-ho",
+ "blazorwasmhostedaadgraph", "-ho",
ArgConstants.Auth, "SingleOrg",
+ ArgConstants.CallsGraph,
ArgConstants.Domain, "my-domain",
ArgConstants.TenantId, "tenantId",
ArgConstants.ClientId, "clientId",
ArgConstants.DefaultScope, "full",
ArgConstants.AppIdUri, "ApiUri",
- ArgConstants.AppIdClientId, "1234123413241324",
- ArgConstants.UseProgramMain),
+ ArgConstants.AppIdClientId, "1234123413241324"),
new TemplateInstance(
- "blazorwasmhostedaadgraph", "-ho",
+ "blazorwasmhostedaadapi", "-ho",
ArgConstants.Auth, "SingleOrg",
- ArgConstants.CallsGraph,
+ ArgConstants.CalledApiUrl, "\"https://graph.microsoft.com\"",
+ ArgConstants.CalledApiScopes, "user.readwrite",
ArgConstants.Domain, "my-domain",
ArgConstants.TenantId, "tenantId",
ArgConstants.ClientId, "clientId",
@@ -213,9 +230,18 @@ public class BlazorWasmTemplateTest : BlazorTemplateTest
ArgConstants.AppIdUri, "ApiUri",
ArgConstants.AppIdClientId, "1234123413241324"),
new TemplateInstance(
- "blazorwasmhostedaadgraph_program_main", "-ho",
+ "blazorwasmstandaloneaad",
+ ArgConstants.Auth, "SingleOrg",
+ ArgConstants.Domain, "my-domain",
+ ArgConstants.TenantId, "tenantId",
+ ArgConstants.ClientId, "clientId"),
+ };
+
+ public static TheoryData<TemplateInstance> TemplateDataSingleOrgProgramMain => new TheoryData<TemplateInstance>
+ {
+ new TemplateInstance(
+ "blazorwasmhostedaad_program_main", "-ho",
ArgConstants.Auth, "SingleOrg",
- ArgConstants.CallsGraph,
ArgConstants.Domain, "my-domain",
ArgConstants.TenantId, "tenantId",
ArgConstants.ClientId, "clientId",
@@ -224,16 +250,16 @@ public class BlazorWasmTemplateTest : BlazorTemplateTest
ArgConstants.AppIdClientId, "1234123413241324",
ArgConstants.UseProgramMain),
new TemplateInstance(
- "blazorwasmhostedaadapi", "-ho",
+ "blazorwasmhostedaadgraph_program_main", "-ho",
ArgConstants.Auth, "SingleOrg",
- ArgConstants.CalledApiUrl, "\"https://graph.microsoft.com\"",
- ArgConstants.CalledApiScopes, "user.readwrite",
+ ArgConstants.CallsGraph,
ArgConstants.Domain, "my-domain",
ArgConstants.TenantId, "tenantId",
ArgConstants.ClientId, "clientId",
ArgConstants.DefaultScope, "full",
ArgConstants.AppIdUri, "ApiUri",
- ArgConstants.AppIdClientId, "1234123413241324"),
+ ArgConstants.AppIdClientId, "1234123413241324",
+ ArgConstants.UseProgramMain),
new TemplateInstance(
"blazorwasmhostedaadapi_program_main", "-ho",
ArgConstants.Auth, "SingleOrg",
@@ -247,27 +273,6 @@ public class BlazorWasmTemplateTest : BlazorTemplateTest
ArgConstants.AppIdClientId, "1234123413241324",
ArgConstants.UseProgramMain),
new TemplateInstance(
- "blazorwasmstandaloneaadb2c",
- ArgConstants.Auth, "IndividualB2C",
- ArgConstants.AadB2cInstance, "example.b2clogin.com",
- "-ssp", "b2c_1_siupin",
- ArgConstants.ClientId, "clientId",
- ArgConstants.Domain, "my-domain"),
- new TemplateInstance(
- "blazorwasmstandaloneaadb2c_program_main",
- ArgConstants.Auth, "IndividualB2C",
- ArgConstants.AadB2cInstance, "example.b2clogin.com",
- "-ssp", "b2c_1_siupin",
- ArgConstants.ClientId, "clientId",
- ArgConstants.Domain, "my-domain",
- ArgConstants.UseProgramMain),
- new TemplateInstance(
- "blazorwasmstandaloneaad",
- ArgConstants.Auth, "SingleOrg",
- ArgConstants.Domain, "my-domain",
- ArgConstants.TenantId, "tenantId",
- ArgConstants.ClientId, "clientId"),
- new TemplateInstance(
"blazorwasmstandaloneaad_program_main",
ArgConstants.Auth, "SingleOrg",
ArgConstants.Domain, "my-domain",
@@ -288,10 +293,20 @@ public class BlazorWasmTemplateTest : BlazorTemplateTest
public string[] Arguments { get; }
}
- [Theory]
- [MemberData(nameof(TemplateData))]
- public Task BlazorWasmHostedTemplate_AzureActiveDirectoryTemplate_Works(TemplateInstance instance)
- => CreateBuildPublishAsync(instance.Name, args: instance.Arguments, targetFramework: "netstandard2.1");
+ [ConditionalTheory]
+ [MemberData(nameof(TemplateDataIndividualB2C))]
+ public Task BlazorWasmHostedTemplate_AzureActiveDirectoryTemplate_IndividualB2C_Works(TemplateInstance instance)
+ => CreateBuildPublishAsync(args: instance.Arguments, targetFramework: "netstandard2.1");
+
+ [ConditionalTheory]
+ [MemberData(nameof(TemplateDataSingleOrg))]
+ public Task BlazorWasmHostedTemplate_AzureActiveDirectoryTemplate_SingleOrg_Works(TemplateInstance instance)
+ => CreateBuildPublishAsync(args: instance.Arguments, targetFramework: "netstandard2.1");
+
+ [ConditionalTheory]
+ [MemberData(nameof(TemplateDataSingleOrgProgramMain))]
+ public Task BlazorWasmHostedTemplate_AzureActiveDirectoryTemplate_SingleOrg_ProgramMain_Works(TemplateInstance instance)
+ => CreateBuildPublishAsync(args: instance.Arguments, targetFramework: "netstandard2.1");
private string ReadFile(string basePath, string path)
{
diff --git a/src/ProjectTemplates/test/EmptyWebTemplateTest.cs b/src/ProjectTemplates/test/EmptyWebTemplateTest.cs
index 60cf26af50..7be864efcd 100644
--- a/src/ProjectTemplates/test/EmptyWebTemplateTest.cs
+++ b/src/ProjectTemplates/test/EmptyWebTemplateTest.cs
@@ -53,7 +53,7 @@ public class EmptyWebTemplateTest : LoggedTest
private async Task EmtpyTemplateCore(string languageOverride, string[] args = null)
{
- var project = await ProjectFactory.GetOrCreateProject("empty" + (languageOverride == "F#" ? "fsharp" : "csharp"), Output);
+ var project = await ProjectFactory.CreateProject(Output);
var createResult = await project.RunDotNetNewAsync("web", args: args, language: languageOverride);
Assert.True(0 == createResult.ExitCode, ErrorMessages.GetFailedProcessMessage("create/restore", project, createResult));
diff --git a/src/ProjectTemplates/test/GrpcTemplateTest.cs b/src/ProjectTemplates/test/GrpcTemplateTest.cs
index edb8aa9338..5f86925cc5 100644
--- a/src/ProjectTemplates/test/GrpcTemplateTest.cs
+++ b/src/ProjectTemplates/test/GrpcTemplateTest.cs
@@ -41,7 +41,7 @@ public class GrpcTemplateTest : LoggedTest
[InlineData(false)]
public async Task GrpcTemplate(bool useProgramMain)
{
- var project = await ProjectFactory.GetOrCreateProject("grpc", Output);
+ var project = await ProjectFactory.CreateProject(Output);
var args = useProgramMain ? new[] { ArgConstants.UseProgramMain } : null;
var createResult = await project.RunDotNetNewAsync("grpc", args: args);
diff --git a/src/ProjectTemplates/test/IdentityUIPackageTest.cs b/src/ProjectTemplates/test/IdentityUIPackageTest.cs
index ed081c459a..ee4f7fac45 100644
--- a/src/ProjectTemplates/test/IdentityUIPackageTest.cs
+++ b/src/ProjectTemplates/test/IdentityUIPackageTest.cs
@@ -102,7 +102,7 @@ public class IdentityUIPackageTest : LoggedTest
public async Task IdentityUIPackage_WorksWithDifferentOptions()
{
var packageOptions = new Dictionary<string, string>();
- var project = await ProjectFactory.GetOrCreateProject("identityuipackage" + string.Concat(packageOptions.Values), Output);
+ var project = await ProjectFactory.CreateProject(Output);
var useLocalDB = false;
var createResult = await project.RunDotNetNewAsync("razor", auth: "Individual", useLocalDB: useLocalDB, environmentVariables: packageOptions);
diff --git a/src/ProjectTemplates/test/ItemTemplateTests/BlazorServerTests.cs b/src/ProjectTemplates/test/ItemTemplateTests/BlazorServerTests.cs
index b2728d7f96..29c3a3e2cd 100644
--- a/src/ProjectTemplates/test/ItemTemplateTests/BlazorServerTests.cs
+++ b/src/ProjectTemplates/test/ItemTemplateTests/BlazorServerTests.cs
@@ -25,7 +25,7 @@ public class BlazorServerTest
[Fact]
public async Task BlazorServerItemTemplate()
{
- Project = await ProjectFactory.GetOrCreateProject("razorcomponentitem", Output);
+ Project = await ProjectFactory.CreateProject(Output);
var createResult = await Project.RunDotNetNewAsync("razorcomponent --name Different");
Assert.True(0 == createResult.ExitCode, ErrorMessages.GetFailedProcessMessage("create", Project, createResult));
diff --git a/src/ProjectTemplates/test/MvcTemplateTest.cs b/src/ProjectTemplates/test/MvcTemplateTest.cs
index 1d3d2876aa..6eb289af34 100644
--- a/src/ProjectTemplates/test/MvcTemplateTest.cs
+++ b/src/ProjectTemplates/test/MvcTemplateTest.cs
@@ -42,7 +42,7 @@ public class MvcTemplateTest : LoggedTest
private async Task MvcTemplateCore(string languageOverride, string[] args = null)
{
- var project = await ProjectFactory.GetOrCreateProject("mvcnoauth" + (languageOverride == "F#" ? "fsharp" : "csharp"), Output);
+ var project = await ProjectFactory.CreateProject(Output);
var createResult = await project.RunDotNetNewAsync("mvc", language: languageOverride, args: args);
Assert.True(0 == createResult.ExitCode, ErrorMessages.GetFailedProcessMessage("create/restore", project, createResult));
@@ -113,14 +113,21 @@ public class MvcTemplateTest : LoggedTest
}
[ConditionalTheory]
- [InlineData(true, false)]
- [InlineData(true, true)]
- [InlineData(false, false)]
- [InlineData(false, true)]
+ [InlineData(false)]
+ [InlineData(true)]
[SkipOnHelix("Cert failure, https://github.com/dotnet/aspnetcore/issues/28090", Queues = "All.OSX;" + HelixConstants.Windows10Arm64 + HelixConstants.DebianArm64 + HelixConstants.DebianAmd64)]
- public async Task MvcTemplate_IndividualAuth(bool useLocalDB, bool useProgramMain)
+ [OSSkipCondition(OperatingSystems.Linux | OperatingSystems.MacOSX, SkipReason = "No LocalDb on non-Windows")]
+ public Task MvcTemplate_IndividualAuth_LocalDb(bool useProgramMain) => MvcTemplate_IndividualAuth_Core(useLocalDB: true, useProgramMain);
+
+ [ConditionalTheory]
+ [InlineData(false)]
+ [InlineData(true)]
+ [SkipOnHelix("Cert failure, https://github.com/dotnet/aspnetcore/issues/28090", Queues = "All.OSX;" + HelixConstants.Windows10Arm64 + HelixConstants.DebianArm64 + HelixConstants.DebianAmd64)]
+ public Task MvcTemplate_IndividualAuth(bool useProgramMain) => MvcTemplate_IndividualAuth_Core(useLocalDB: false, useProgramMain);
+
+ private async Task MvcTemplate_IndividualAuth_Core(bool useLocalDB, bool useProgramMain)
{
- var project = await ProjectFactory.GetOrCreateProject("mvcindividual" + (useLocalDB ? "uld" : ""), Output);
+ var project = await ProjectFactory.CreateProject(Output);
var args = useProgramMain ? new[] { ArgConstants.UseProgramMain } : null;
var createResult = await project.RunDotNetNewAsync("mvc", auth: "Individual", useLocalDB: useLocalDB, args: args);
@@ -242,7 +249,7 @@ public class MvcTemplateTest : LoggedTest
// This test verifies publishing an MVC app as a single file exe works. We'll limit testing
// this to a few operating systems to make our lives easier.
var runtimeIdentifer = "win-x64";
- var project = await ProjectFactory.GetOrCreateProject("mvcsinglefileexe", Output);
+ var project = await ProjectFactory.CreateProject(Output);
project.RuntimeIdentifier = runtimeIdentifer;
var createResult = await project.RunDotNetNewAsync("mvc");
@@ -288,17 +295,21 @@ public class MvcTemplateTest : LoggedTest
[InlineData("IndividualB2C", new[] { ArgConstants.UseProgramMain })]
[InlineData("IndividualB2C", new[] { ArgConstants.CalledApiUrlGraphMicrosoftCom, ArgConstants.CalledApiScopesUserReadWrite })]
[InlineData("IndividualB2C", new[] { ArgConstants.UseProgramMain, ArgConstants.CalledApiUrlGraphMicrosoftCom, ArgConstants.CalledApiScopesUserReadWrite })]
+ public Task MvcTemplate_IdentityWeb_IndividualB2C_BuildsAndPublishes(string auth, string[] args) => MvcTemplateBuildsAndPublishes(auth: auth, args: args);
+
+ [ConditionalTheory]
+ [SkipOnHelix("https://github.com/dotnet/aspnetcore/issues/28090", Queues = HelixConstants.Windows10Arm64 + HelixConstants.DebianArm64)]
[InlineData("SingleOrg", null)]
[InlineData("SingleOrg", new[] { ArgConstants.UseProgramMain })]
[InlineData("SingleOrg", new[] { ArgConstants.CalledApiUrlGraphMicrosoftCom, ArgConstants.CalledApiScopesUserReadWrite })]
[InlineData("SingleOrg", new[] { ArgConstants.UseProgramMain, ArgConstants.CalledApiUrlGraphMicrosoftCom, ArgConstants.CalledApiScopesUserReadWrite })]
[InlineData("SingleOrg", new[] { ArgConstants.CallsGraph })]
[InlineData("SingleOrg", new[] { ArgConstants.UseProgramMain, ArgConstants.CallsGraph })]
- public Task MvcTemplate_IdentityWeb_BuildsAndPublishes(string auth, string[] args) => MvcTemplateBuildsAndPublishes(auth: auth, args: args);
+ public Task MvcTemplate_IdentityWeb_SingleOrg_BuildsAndPublishes(string auth, string[] args) => MvcTemplateBuildsAndPublishes(auth: auth, args: args);
private async Task<Project> MvcTemplateBuildsAndPublishes(string auth, string[] args)
{
- var project = await ProjectFactory.GetOrCreateProject("mvc" + Guid.NewGuid().ToString().Substring(0, 10).ToLowerInvariant(), Output);
+ var project = await ProjectFactory.CreateProject(Output);
var createResult = await project.RunDotNetNewAsync("mvc", auth: auth, args: args);
Assert.True(0 == createResult.ExitCode, ErrorMessages.GetFailedProcessMessage("create/restore", project, createResult));
diff --git a/src/ProjectTemplates/test/ProjectTemplates.Tests.csproj b/src/ProjectTemplates/test/ProjectTemplates.Tests.csproj
index e2a0fad606..9a477c21a3 100644
--- a/src/ProjectTemplates/test/ProjectTemplates.Tests.csproj
+++ b/src/ProjectTemplates/test/ProjectTemplates.Tests.csproj
@@ -7,7 +7,7 @@
<TestGroupName>ProjectTemplates.E2ETests</TestGroupName>
<DefineConstants>$(DefineConstants);XPLAT</DefineConstants>
- <RunTemplateTests Condition="'$(RunTemplateTests)' == ''" >true</RunTemplateTests>
+ <RunTemplateTests Condition="'$(RunTemplateTests)' == ''">true</RunTemplateTests>
<SkipTests Condition="'$(RunTemplateTests)' != 'true'">true</SkipTests>
<BaseOutputPath />
@@ -18,6 +18,9 @@
<TestTemplateCreationFolder>TestTemplates\</TestTemplateCreationFolder>
<TestPackageRestorePath>$([MSBuild]::EnsureTrailingSlash('$(RepoRoot)'))obj\template-restore\</TestPackageRestorePath>
<TestDependsOnAspNetPackages>true</TestDependsOnAspNetPackages>
+ <SkipHelixQueues>
+ $(HelixQueueArmDebian11);
+ </SkipHelixQueues>
</PropertyGroup>
<ItemGroup>
diff --git a/src/ProjectTemplates/test/RazorClassLibraryTemplateTest.cs b/src/ProjectTemplates/test/RazorClassLibraryTemplateTest.cs
index f3360f62e2..7675499fd0 100644
--- a/src/ProjectTemplates/test/RazorClassLibraryTemplateTest.cs
+++ b/src/ProjectTemplates/test/RazorClassLibraryTemplateTest.cs
@@ -33,7 +33,7 @@ public class RazorClassLibraryTemplateTest : LoggedTest
[Fact]
public async Task RazorClassLibraryTemplate_WithViews_Async()
{
- var project = await ProjectFactory.GetOrCreateProject("razorclasslibwithviews", Output);
+ var project = await ProjectFactory.CreateProject(Output);
var createResult = await project.RunDotNetNewAsync("razorclasslib", args: new[] { "--support-pages-and-views", "true" });
Assert.True(0 == createResult.ExitCode, ErrorMessages.GetFailedProcessMessage("create/restore", project, createResult));
@@ -53,7 +53,7 @@ public class RazorClassLibraryTemplateTest : LoggedTest
[SkipOnHelix("https://github.com/dotnet/aspnetcore/issues/28090", Queues = HelixConstants.Windows10Arm64 + HelixConstants.DebianArm64)]
public async Task RazorClassLibraryTemplateAsync()
{
- var project = await ProjectFactory.GetOrCreateProject("razorclasslib", Output);
+ var project = await ProjectFactory.CreateProject(Output);
var createResult = await project.RunDotNetNewAsync("razorclasslib");
Assert.True(0 == createResult.ExitCode, ErrorMessages.GetFailedProcessMessage("create/restore", project, createResult));
diff --git a/src/ProjectTemplates/test/RazorPagesTemplateTest.cs b/src/ProjectTemplates/test/RazorPagesTemplateTest.cs
index f6e2c61779..8d1d258bc4 100644
--- a/src/ProjectTemplates/test/RazorPagesTemplateTest.cs
+++ b/src/ProjectTemplates/test/RazorPagesTemplateTest.cs
@@ -40,7 +40,7 @@ public class RazorPagesTemplateTest : LoggedTest
[InlineData(false)]
public async Task RazorPagesTemplate_NoAuth(bool useProgramMain)
{
- var project = await ProjectFactory.GetOrCreateProject("razorpagesnoauth", Output);
+ var project = await ProjectFactory.CreateProject(Output);
var args = useProgramMain ? new[] { ArgConstants.UseProgramMain } : null;
var createResult = await project.RunDotNetNewAsync("razor", args: args);
@@ -107,14 +107,21 @@ public class RazorPagesTemplateTest : LoggedTest
}
[ConditionalTheory]
- [InlineData(false, false)]
- [InlineData(false, true)]
- [InlineData(true, false)]
- [InlineData(true, true)]
- [SkipOnHelix("Cert failure, https://github.com/dotnet/aspnetcore/issues/28090", Queues = "All.OSX;" + HelixConstants.Windows10Arm64 + HelixConstants.DebianArm64)]
- public async Task RazorPagesTemplate_IndividualAuth(bool useLocalDB, bool useProgramMain)
+ [InlineData(false)]
+ [InlineData(true)]
+ [SkipOnHelix("Cert failure, https://github.com/dotnet/aspnetcore/issues/28090", Queues = "All.OSX;" + HelixConstants.Windows10Arm64 + HelixConstants.DebianArm64 + HelixConstants.DebianAmd64)]
+ [OSSkipCondition(OperatingSystems.Linux | OperatingSystems.MacOSX, SkipReason = "No LocalDb on non-Windows")]
+ public Task RazorPagesTemplate_IndividualAuth_LocalDb(bool useProgramMain) => RazorPagesTemplate_IndividualAuth_Core(useLocalDB: true, useProgramMain);
+
+ [ConditionalTheory]
+ [InlineData(false)]
+ [InlineData(true)]
+ [SkipOnHelix("Cert failure, https://github.com/dotnet/aspnetcore/issues/28090", Queues = "All.OSX;" + HelixConstants.Windows10Arm64 + HelixConstants.DebianArm64 + HelixConstants.DebianAmd64)]
+ public Task RazorPagesTemplate_IndividualAuth(bool useProgramMain) => RazorPagesTemplate_IndividualAuth_Core(useLocalDB: false, useProgramMain);
+
+ private async Task RazorPagesTemplate_IndividualAuth_Core(bool useLocalDB, bool useProgramMain)
{
- var project = await ProjectFactory.GetOrCreateProject("razorpagesindividual" + (useLocalDB ? "uld" : ""), Output);
+ var project = await ProjectFactory.CreateProject(Output);
var args = useProgramMain ? new[] { ArgConstants.UseProgramMain } : null;
var createResult = await project.RunDotNetNewAsync("razor", auth: "Individual", useLocalDB: useLocalDB, args: args);
@@ -234,20 +241,24 @@ public class RazorPagesTemplateTest : LoggedTest
[InlineData("IndividualB2C", new[] { ArgConstants.UseProgramMain })]
[InlineData("IndividualB2C", new[] { ArgConstants.CalledApiUrlGraphMicrosoftCom, ArgConstants.CalledApiScopesUserReadWrite })]
[InlineData("IndividualB2C", new[] { ArgConstants.UseProgramMain, ArgConstants.CalledApiUrlGraphMicrosoftCom, ArgConstants.CalledApiScopesUserReadWrite })]
+ public Task RazorPagesTemplate_IdentityWeb_IndividualB2C_BuildsAndPublishes(string auth, string[] args) => BuildAndPublishRazorPagesTemplate(auth: auth, args: args);
+
+ [ConditionalTheory]
+ [SkipOnHelix("https://github.com/dotnet/aspnetcore/issues/28090", Queues = HelixConstants.Windows10Arm64 + HelixConstants.DebianArm64)]
[InlineData("SingleOrg", null)]
[InlineData("SingleOrg", new[] { ArgConstants.UseProgramMain })]
[InlineData("SingleOrg", new[] { ArgConstants.CalledApiUrlGraphMicrosoftCom, ArgConstants.CalledApiScopesUserReadWrite })]
[InlineData("SingleOrg", new[] { ArgConstants.UseProgramMain, ArgConstants.CalledApiUrlGraphMicrosoftCom, ArgConstants.CalledApiScopesUserReadWrite })]
- public Task RazorPagesTemplate_IdentityWeb_BuildsAndPublishes(string auth, string[] args) => BuildAndPublishRazorPagesTemplate(auth: auth, args: args);
+ public Task RazorPagesTemplate_IdentityWeb_SingleOrg_BuildsAndPublishes(string auth, string[] args) => BuildAndPublishRazorPagesTemplate(auth: auth, args: args);
[ConditionalTheory]
[InlineData("SingleOrg", new[] { ArgConstants.CallsGraph })]
[InlineData("SingleOrg", new[] { ArgConstants.UseProgramMain, ArgConstants.CallsGraph })]
- public Task RazorPagesTemplate_IdentityWeb_BuildsAndPublishes_WithSingleOrg(string auth, string[] args) => BuildAndPublishRazorPagesTemplate(auth: auth, args: args);
+ public Task RazorPagesTemplate_IdentityWeb_SingleOrg_CallsGraph_BuildsAndPublishes(string auth, string[] args) => BuildAndPublishRazorPagesTemplate(auth: auth, args: args);
private async Task<Project> BuildAndPublishRazorPagesTemplate(string auth, string[] args)
{
- var project = await ProjectFactory.GetOrCreateProject("razorpages" + Guid.NewGuid().ToString().Substring(0, 10).ToLowerInvariant(), Output);
+ var project = await ProjectFactory.CreateProject(Output);
var createResult = await project.RunDotNetNewAsync("razor", auth: auth, args: args);
Assert.True(0 == createResult.ExitCode, ErrorMessages.GetFailedProcessMessage("create/restore", project, createResult));
diff --git a/src/ProjectTemplates/test/SpaTemplatesTest.cs b/src/ProjectTemplates/test/SpaTemplatesTest.cs
index 76c77ad07f..f067923b03 100644
--- a/src/ProjectTemplates/test/SpaTemplatesTest.cs
+++ b/src/ProjectTemplates/test/SpaTemplatesTest.cs
@@ -35,13 +35,13 @@ public class SpaTemplatesTest : LoggedTest
}
[Theory]
- [InlineData("angularind", "angular", "Individual")]
- [InlineData("reactind", "react", "Individual")]
- [InlineData("angularnoauth", "angular", null)]
- [InlineData("reactnoauth", "react", null)]
- public async Task SpaTemplates_BuildAndPublish(string projectKey, string template, string auth)
+ [InlineData("angular", "Individual")]
+ [InlineData("react", "Individual")]
+ [InlineData("angular", null)]
+ [InlineData("react", null)]
+ public async Task SpaTemplates_BuildAndPublish(string template, string auth)
{
- var project = await ProjectFactory.GetOrCreateProject(projectKey, Output);
+ var project = await ProjectFactory.CreateProject(Output);
var args = new[] { "--NoSpaFrontEnd", "true" };
var createResult = await project.RunDotNetNewAsync(template, auth: auth, args: args);
Assert.True(0 == createResult.ExitCode, ErrorMessages.GetFailedProcessMessage(template, project, createResult));
diff --git a/src/ProjectTemplates/test/WebApiTemplateTest.cs b/src/ProjectTemplates/test/WebApiTemplateTest.cs
index 4840e8cee0..778e11d99f 100644
--- a/src/ProjectTemplates/test/WebApiTemplateTest.cs
+++ b/src/ProjectTemplates/test/WebApiTemplateTest.cs
@@ -35,26 +35,40 @@ public class WebApiTemplateTest : LoggedTest
[ConditionalTheory]
[SkipOnHelix("https://github.com/dotnet/aspnetcore/issues/28090", Queues = HelixConstants.Windows10Arm64 + HelixConstants.DebianArm64)]
[InlineData("IndividualB2C", null)]
- [InlineData("IndividualB2C", new string[] { ArgConstants.UseProgramMain })]
[InlineData("IndividualB2C", new string[] { ArgConstants.UseMinimalApis })]
- [InlineData("IndividualB2C", new string[] { ArgConstants.UseProgramMain, ArgConstants.UseMinimalApis })]
[InlineData("IndividualB2C", new string[] { ArgConstants.CalledApiUrlGraphMicrosoftCom, ArgConstants.CalledApiScopesUserReadWrite })]
[InlineData("IndividualB2C", new string[] { ArgConstants.UseMinimalApis, ArgConstants.CalledApiUrlGraphMicrosoftCom, ArgConstants.CalledApiScopesUserReadWrite })]
+ public Task WebApiTemplateCSharp_IdentityWeb_IndividualB2C_BuildsAndPublishes(string auth, string[] args) => PublishAndBuildWebApiTemplate(languageOverride: null, auth: auth, args: args);
+
+ [ConditionalTheory]
+ [SkipOnHelix("https://github.com/dotnet/aspnetcore/issues/28090", Queues = HelixConstants.Windows10Arm64 + HelixConstants.DebianArm64)]
+ [InlineData("IndividualB2C", null)]
+ [InlineData("IndividualB2C", new string[] { ArgConstants.UseProgramMain })]
+ [InlineData("IndividualB2C", new string[] { ArgConstants.UseProgramMain, ArgConstants.UseMinimalApis })]
[InlineData("IndividualB2C", new string[] { ArgConstants.UseProgramMain, ArgConstants.CalledApiUrlGraphMicrosoftCom, ArgConstants.CalledApiScopesUserReadWrite })]
[InlineData("IndividualB2C", new string[] { ArgConstants.UseProgramMain, ArgConstants.UseMinimalApis, ArgConstants.CalledApiUrlGraphMicrosoftCom, ArgConstants.CalledApiScopesUserReadWrite })]
+ public Task WebApiTemplateCSharp_IdentityWeb_IndividualB2C_ProgramMain_BuildsAndPublishes(string auth, string[] args) => PublishAndBuildWebApiTemplate(languageOverride: null, auth: auth, args: args);
+
+ [ConditionalTheory]
+ [SkipOnHelix("https://github.com/dotnet/aspnetcore/issues/28090", Queues = HelixConstants.Windows10Arm64 + HelixConstants.DebianArm64)]
[InlineData("SingleOrg", null)]
- [InlineData("SingleOrg", new string[] { ArgConstants.UseProgramMain })]
[InlineData("SingleOrg", new string[] { ArgConstants.UseMinimalApis })]
- [InlineData("SingleOrg", new string[] { ArgConstants.UseProgramMain, ArgConstants.UseMinimalApis })]
[InlineData("SingleOrg", new string[] { ArgConstants.CalledApiUrlGraphMicrosoftCom, ArgConstants.CalledApiScopesUserReadWrite })]
[InlineData("SingleOrg", new string[] { ArgConstants.UseMinimalApis, ArgConstants.CalledApiUrlGraphMicrosoftCom, ArgConstants.CalledApiScopesUserReadWrite })]
+ [InlineData("SingleOrg", new string[] { ArgConstants.CallsGraph })]
+ [InlineData("SingleOrg", new string[] { ArgConstants.UseMinimalApis, ArgConstants.CallsGraph })]
+ public Task WebApiTemplateCSharp_IdentityWeb_SingleOrg_BuildsAndPublishes(string auth, string[] args) => PublishAndBuildWebApiTemplate(languageOverride: null, auth: auth, args: args);
+
+ [ConditionalTheory]
+ [SkipOnHelix("https://github.com/dotnet/aspnetcore/issues/28090", Queues = HelixConstants.Windows10Arm64 + HelixConstants.DebianArm64)]
+ [InlineData("SingleOrg", null)]
+ [InlineData("SingleOrg", new string[] { ArgConstants.UseProgramMain })]
+ [InlineData("SingleOrg", new string[] { ArgConstants.UseProgramMain, ArgConstants.UseMinimalApis })]
[InlineData("SingleOrg", new string[] { ArgConstants.UseProgramMain, ArgConstants.CalledApiUrlGraphMicrosoftCom, ArgConstants.CalledApiScopesUserReadWrite })]
[InlineData("SingleOrg", new string[] { ArgConstants.UseProgramMain, ArgConstants.UseMinimalApis, ArgConstants.CalledApiUrlGraphMicrosoftCom, ArgConstants.CalledApiScopesUserReadWrite })]
- [InlineData("SingleOrg", new string[] { ArgConstants.CallsGraph })]
[InlineData("SingleOrg", new string[] { ArgConstants.UseProgramMain, ArgConstants.CallsGraph })]
- [InlineData("SingleOrg", new string[] { ArgConstants.UseMinimalApis, ArgConstants.CallsGraph })]
[InlineData("SingleOrg", new string[] { ArgConstants.UseProgramMain, ArgConstants.UseMinimalApis, ArgConstants.CallsGraph })]
- public Task WebApiTemplateCSharp_IdentityWeb_BuildsAndPublishes(string auth, string[] args) => PublishAndBuildWebApiTemplate(languageOverride: null, auth: auth, args: args);
+ public Task WebApiTemplateCSharp_IdentityWeb_SingleOrg_ProgramMain_BuildsAndPublishes(string auth, string[] args) => PublishAndBuildWebApiTemplate(languageOverride: null, auth: auth, args: args);
[Fact]
public Task WebApiTemplateFSharp() => WebApiTemplateCore(languageOverride: "F#");
@@ -83,7 +97,7 @@ public class WebApiTemplateTest : LoggedTest
[SkipOnHelix("Cert failure, https://github.com/dotnet/aspnetcore/issues/28090", Queues = "All.OSX;" + HelixConstants.Windows10Arm64 + HelixConstants.DebianArm64)]
public async Task WebApiTemplateCSharp_WithoutOpenAPI(bool useProgramMain, bool useMinimalApis)
{
- var project = await FactoryFixture.GetOrCreateProject("webapinoopenapi", Output);
+ var project = await FactoryFixture.CreateProject(Output);
var args = useProgramMain
? useMinimalApis
@@ -108,7 +122,7 @@ public class WebApiTemplateTest : LoggedTest
private async Task<Project> PublishAndBuildWebApiTemplate(string languageOverride, string auth, string[] args = null)
{
- var project = await FactoryFixture.GetOrCreateProject("webapi" + (languageOverride == "F#" ? "fsharp" : "csharp") + Guid.NewGuid().ToString().Substring(0, 10).ToLowerInvariant(), Output);
+ var project = await FactoryFixture.CreateProject(Output);
var createResult = await project.RunDotNetNewAsync("webapi", language: languageOverride, auth: auth, args: args);
Assert.True(0 == createResult.ExitCode, ErrorMessages.GetFailedProcessMessage("create/restore", project, createResult));
diff --git a/src/ProjectTemplates/test/WorkerTemplateTest.cs b/src/ProjectTemplates/test/WorkerTemplateTest.cs
index 07b2b0476a..5faa726172 100644
--- a/src/ProjectTemplates/test/WorkerTemplateTest.cs
+++ b/src/ProjectTemplates/test/WorkerTemplateTest.cs
@@ -38,9 +38,7 @@ public class WorkerTemplateTest : LoggedTest
[QuarantinedTest("https://github.com/dotnet/aspnetcore/issues/25404")]
public async Task WorkerTemplateAsync(string language, string[] args)
{
- var project = await ProjectFactory.GetOrCreateProject(
- $"worker-{language.ToLowerInvariant()[0]}sharp",
- Output);
+ var project = await ProjectFactory.CreateProject(Output);
var createResult = await project.RunDotNetNewAsync("worker", language: language, args: args);
Assert.True(0 == createResult.ExitCode, ErrorMessages.GetFailedProcessMessage("create/restore", project, createResult));