Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve System Test performance with stubbing dotnet new #294

Merged
merged 9 commits into from
Nov 6, 2024
Prev Previous commit
Next Next commit
Ensure dotnet command is executed with the corresponding sdk version
obligaron committed Oct 31, 2024
commit 5e4682e9982bce78220d618656bd93aaf733de59
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using Reqnroll.TestProjectGenerator.FilesystemWriter;
using System;
using System.Collections.Concurrent;
using System.IO;

@@ -7,14 +8,16 @@ namespace Reqnroll.TestProjectGenerator.Dotnet;
public class CacheAndCopyCommandBuilder : CommandBuilder
{
private const string TemplateName = "TName";
private readonly NetCoreSdkInfo _sdk;
private readonly CommandBuilder _baseCommandBuilder;
private readonly string _targetPath;
private readonly string _nameToReplace;
private static readonly ConcurrentDictionary<string, object> LockObjects = new();

public CacheAndCopyCommandBuilder(IOutputWriter outputWriter, CommandBuilder baseCommandBuilder, string targetPath, string nameToReplace = null)
public CacheAndCopyCommandBuilder(IOutputWriter outputWriter, NetCoreSdkInfo sdk, CommandBuilder baseCommandBuilder, string targetPath, string nameToReplace = null)
: base(outputWriter, baseCommandBuilder.ExecutablePath, baseCommandBuilder.ArgumentsFormat, baseCommandBuilder.WorkingDirectory)
{
_sdk = sdk;
_baseCommandBuilder = baseCommandBuilder;
_targetPath = targetPath;
_nameToReplace = nameToReplace;
@@ -30,7 +33,7 @@ private string CalculateCacheTargetPath(string suffix = "")
argsCleaned = argsCleaned.Replace(_nameToReplace, TemplateName);
directoryName = directoryName.Replace(_nameToReplace, TemplateName);
}
return Path.Combine(Path.GetTempPath(), "RRC", $"RRC_{argsCleaned}{suffix}", directoryName);
return Path.Combine(Path.GetTempPath(), "RRC", $"RRC_{_sdk.Version}_{argsCleaned}{suffix}", directoryName);
}

public override CommandResult Execute(Func<Exception, Exception> exceptionFunction)
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
using Reqnroll.TestProjectGenerator.FilesystemWriter;

namespace Reqnroll.TestProjectGenerator.Dotnet
{
public class DotNet
{
public static NewCommandBuilder New(IOutputWriter outputWriter) => NewCommandBuilder.Create(outputWriter);
public static NewCommandBuilder New(IOutputWriter outputWriter, NetCoreSdkInfo sdk) => NewCommandBuilder.Create(outputWriter, sdk);
public static BuildCommandBuilder Build(IOutputWriter outputWriter) => BuildCommandBuilder.Create(outputWriter);
public static SolutionCommandBuilder Sln(IOutputWriter outputWriter) => SolutionCommandBuilder.Create(outputWriter);
public static VersionCommandBuilder Version(IOutputWriter outputWriter) => VersionCommandBuilder.Create(outputWriter);
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using Reqnroll.TestProjectGenerator.FilesystemWriter;
using System.IO;

namespace Reqnroll.TestProjectGenerator.Dotnet
@@ -6,13 +7,16 @@ public partial class NewCommandBuilder
{
public class StubNewProjectCommandBuilder : NewProjectCommandBuilder
{
public StubNewProjectCommandBuilder(IOutputWriter outputWriter) : base(outputWriter)
private readonly NetCoreSdkInfo _sdk;

public StubNewProjectCommandBuilder(IOutputWriter outputWriter, NetCoreSdkInfo sdk) : base(outputWriter)
{
_sdk = sdk;
}

public override CommandBuilder Build()
{
return new CacheAndCopyCommandBuilder(_outputWriter, base.Build(), _folder);
return new CacheAndCopyCommandBuilder(_outputWriter, _sdk, base.Build(), _folder);

//return new CopyFolderCommandBuilder(_outputWriter, @"C:\Temp\DotNetNewIssue\DotNetNewTest\DefaultTestProject", _folder);
//return base.Build();
Original file line number Diff line number Diff line change
@@ -1,16 +1,21 @@
using Reqnroll.TestProjectGenerator.FilesystemWriter;

namespace Reqnroll.TestProjectGenerator.Dotnet;

public partial class NewCommandBuilder
{
public class StubNewSolutionCommandBuilder : NewSolutionCommandBuilder
{
public StubNewSolutionCommandBuilder(IOutputWriter outputWriter) : base(outputWriter)
private readonly NetCoreSdkInfo _sdk;

public StubNewSolutionCommandBuilder(IOutputWriter outputWriter, NetCoreSdkInfo sdk) : base(outputWriter)
{
_sdk = sdk;
}

public override CommandBuilder Build()
{
return new CacheAndCopyCommandBuilder(_outputWriter, base.Build(), _rootPath, _name);
return new CacheAndCopyCommandBuilder(_outputWriter, _sdk, base.Build(), _rootPath, _name);

//return new CopyFolderCommandBuilder(_outputWriter, @"C:\Temp\DotNetNewIssue\DotNetNewTest\DefaultTestProject", _folder);
//return base.Build();
Original file line number Diff line number Diff line change
@@ -1,18 +1,22 @@
using Reqnroll.TestProjectGenerator.FilesystemWriter;

namespace Reqnroll.TestProjectGenerator.Dotnet
{
public partial class NewCommandBuilder
{
private readonly IOutputWriter _outputWriter;
private readonly NetCoreSdkInfo _sdk;

public NewCommandBuilder(IOutputWriter outputWriter)
public NewCommandBuilder(IOutputWriter outputWriter, NetCoreSdkInfo sdk)
{
_outputWriter = outputWriter;
_sdk = sdk;
}

internal static NewCommandBuilder Create(IOutputWriter outputWriter) => new NewCommandBuilder(outputWriter);
internal static NewCommandBuilder Create(IOutputWriter outputWriter, NetCoreSdkInfo sdk) => new NewCommandBuilder(outputWriter, sdk);

public NewSolutionCommandBuilder Solution() => new StubNewSolutionCommandBuilder(_outputWriter);
public NewSolutionCommandBuilder Solution() => new StubNewSolutionCommandBuilder(_outputWriter, _sdk);

public NewProjectCommandBuilder Project() => new StubNewProjectCommandBuilder(_outputWriter);
public NewProjectCommandBuilder Project() => new StubNewProjectCommandBuilder(_outputWriter, _sdk);
}
}
Original file line number Diff line number Diff line change
@@ -4,7 +4,7 @@ namespace Reqnroll.TestProjectGenerator.FilesystemWriter
{
public interface IProjectWriter
{
string WriteProject(Project project, string path);
string WriteProject(NetCoreSdkInfo sdk, Project project, string path);

void WriteReferences(Project project, string projectFilePath);
}
Original file line number Diff line number Diff line change
@@ -21,15 +21,15 @@ public NewFormatProjectWriter(IOutputWriter outputWriter, TargetFrameworkMoniker
_targetFrameworkMonikerStringBuilder = targetFrameworkMonikerStringBuilder;
}

public virtual string WriteProject(Project project, string projRootPath)
public virtual string WriteProject(NetCoreSdkInfo sdk, Project project, string projRootPath)
{
if (project is null)
{
throw new ArgumentNullException(nameof(project));
}


CreateProjectFile(project, projRootPath);
CreateProjectFile(sdk, project, projRootPath);

string projFileName = $"{project.Name}.{project.ProgrammingLanguage.ToProjectFileExtension()}";

@@ -232,7 +232,7 @@ private void WriteAssemblyReference(XmlWriter xw, Reference reference)
xw.WriteEndElement();
}

private void CreateProjectFile(Project project, string projRootPath)
private void CreateProjectFile(NetCoreSdkInfo sdk, Project project, string projRootPath)
{
string template;

@@ -253,7 +253,7 @@ private void CreateProjectFile(Project project, string projRootPath)



var newProjCommand = DotNet.New(_outputWriter)
var newProjCommand = DotNet.New(_outputWriter, sdk)
.Project()
.InFolder(projRootPath)
.WithName(project.Name)
Original file line number Diff line number Diff line change
@@ -20,7 +20,7 @@ public OldFormatProjectWriter(IOutputWriter outputWriter, TargetFrameworkMoniker
_targetFrameworkVersionStringBuilder = targetFrameworkVersionStringBuilder;
}

public virtual string WriteProject(Project project, string path)
public virtual string WriteProject(NetCoreSdkInfo sdk, Project project, string path)
{
if (project is null)
{
Original file line number Diff line number Diff line change
@@ -43,9 +43,17 @@ public string WriteToFileSystem(Solution solution, string outputPath)
? new NetCoreSdkInfo(solution.SdkVersion)
: _netCoreSdkInfoProvider.GetSdkFromTargetFramework(targetFramework);

if (targetFramework != 0 && sdk != null)
{
var globalJsonBuilder = new GlobalJsonBuilder().WithSdk(sdk);

var globalJsonFile = globalJsonBuilder.ToProjectFile();
_fileWriter.Write(globalJsonFile, outputPath);
}

DisableUsingSdkFromEnvironmentVariable();

var createSolutionCommand = DotNet.New(_outputWriter).Solution().InFolder(outputPath).WithName(solution.Name).Build();
var createSolutionCommand = DotNet.New(_outputWriter, sdk).Solution().InFolder(outputPath).WithName(solution.Name).Build();
createSolutionCommand.ExecuteWithRetry(1, TimeSpan.FromSeconds(1), (innerException) =>
{
if (innerException is AggregateException aggregateException && aggregateException.InnerExceptions.Any(x => x.InnerException.Message.Contains("Install the [" + sdk.Version)))
@@ -54,7 +62,7 @@ public string WriteToFileSystem(Solution solution, string outputPath)
});
string solutionFilePath = Path.Combine(outputPath, $"{solution.Name}.sln");

WriteProjects(solution, outputPath, solutionFilePath);
WriteProjects(sdk, solution, outputPath, solutionFilePath);

if (solution.NugetConfig != null)
{
@@ -66,14 +74,6 @@ public string WriteToFileSystem(Solution solution, string outputPath)
_fileWriter.Write(file, outputPath);
}

if (targetFramework != 0 && sdk != null)
{
var globalJsonBuilder = new GlobalJsonBuilder().WithSdk(sdk);

var globalJsonFile = globalJsonBuilder.ToProjectFile();
_fileWriter.Write(globalJsonFile, outputPath);
}

return solutionFilePath;
}

@@ -90,13 +90,13 @@ private static void DisableUsingSdkFromEnvironmentVariable()
Environment.SetEnvironmentVariable("MSBuildSDKsPath", null);
}

private void WriteProjects(Solution solution, string outputPath, string solutionFilePath)
private void WriteProjects(NetCoreSdkInfo sdk, Solution solution, string outputPath, string solutionFilePath)
{
var projectPathMappings = new Dictionary<Project, string>();
foreach (var project in solution.Projects)
{
var formatProjectWriter = _projectWriterFactory.FromProjectFormat(project.ProjectFormat);
string pathToProjectFile = WriteProject(project, outputPath, formatProjectWriter, solutionFilePath);
string pathToProjectFile = WriteProject(sdk, project, outputPath, formatProjectWriter, solutionFilePath);
projectPathMappings.Add(project, pathToProjectFile);
}

@@ -107,9 +107,9 @@ private void WriteProjects(Solution solution, string outputPath, string solution
}
}

private string WriteProject(Project project, string outputPath, IProjectWriter formatProjectWriter, string solutionFilePath)
private string WriteProject(NetCoreSdkInfo sdk, Project project, string outputPath, IProjectWriter formatProjectWriter, string solutionFilePath)
{
string projPath = formatProjectWriter.WriteProject(project, Path.Combine(outputPath, project.Name));
string projPath = formatProjectWriter.WriteProject(sdk, project, Path.Combine(outputPath, project.Name));

var addProjCommand = DotNet.Sln(_outputWriter).AddProject().Project(projPath).ToSolution(solutionFilePath).Build().Execute();
if (addProjCommand.ExitCode != 0)