diff --git a/.gitignore b/.gitignore index be16796fd..e871f125d 100644 --- a/.gitignore +++ b/.gitignore @@ -20,3 +20,4 @@ ILSpy.Installer/wix/ /VERSION /ICSharpCode.Decompiler/Properties/DecompilerVersionInfo.cs */.vscode/ +DecompilerTests.config.json \ No newline at end of file diff --git a/Directory.Packages.props b/Directory.Packages.props index 15f165921..324ee40f2 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -21,6 +21,8 @@ + + diff --git a/ICSharpCode.Decompiler.Tests/CorrectnessTestRunner.cs b/ICSharpCode.Decompiler.Tests/CorrectnessTestRunner.cs index 53cb566c0..2b877d110 100644 --- a/ICSharpCode.Decompiler.Tests/CorrectnessTestRunner.cs +++ b/ICSharpCode.Decompiler.Tests/CorrectnessTestRunner.cs @@ -408,13 +408,13 @@ namespace ICSharpCode.Decompiler.Tests if ((options & CompilerOptions.UseRoslynMask) != 0 && (options & CompilerOptions.TargetNet40) == 0) options |= CompilerOptions.UseTestRunner; string testFileName = testName + ".cs"; - string testOutputFileName = testName + Tester.GetSuffix(options) + ".exe"; + string testOutputFileName = TestsAssemblyOutput.GetFilePath(TestCasePath, testName, Tester.GetSuffix(options) + ".exe"); CompilerResults outputFile = null, decompiledOutputFile = null; try { outputFile = await Tester.CompileCSharp(Path.Combine(TestCasePath, testFileName), options, - outputFileName: Path.Combine(TestCasePath, testOutputFileName)).ConfigureAwait(false); + outputFileName: testOutputFileName).ConfigureAwait(false); string decompiledCodeFile = await Tester.DecompileCSharp(outputFile.PathToAssembly, Tester.GetSettings(options)).ConfigureAwait(false); if ((options & CompilerOptions.UseMcsMask) != 0) { @@ -452,13 +452,13 @@ namespace ICSharpCode.Decompiler.Tests if ((options & CompilerOptions.UseRoslynMask) != 0) options |= CompilerOptions.UseTestRunner; string testFileName = testName + ".vb"; - string testOutputFileName = testName + Tester.GetSuffix(options) + ".exe"; + string testOutputFileName = TestsAssemblyOutput.GetFilePath(TestCasePath, testName, Tester.GetSuffix(options) + ".exe"); CompilerResults outputFile = null, decompiledOutputFile = null; try { outputFile = await Tester.CompileVB(Path.Combine(TestCasePath, testFileName), options, - outputFileName: Path.Combine(TestCasePath, testOutputFileName)).ConfigureAwait(false); + outputFileName: testOutputFileName).ConfigureAwait(false); string decompiledCodeFile = await Tester.DecompileCSharp(outputFile.PathToAssembly, Tester.GetSettings(options)).ConfigureAwait(false); decompiledOutputFile = await Tester.CompileCSharp(decompiledCodeFile, options).ConfigureAwait(false); diff --git a/ICSharpCode.Decompiler.Tests/Helpers/Tester.cs b/ICSharpCode.Decompiler.Tests/Helpers/Tester.cs index ecbcf5c1b..92eb339f6 100644 --- a/ICSharpCode.Decompiler.Tests/Helpers/Tester.cs +++ b/ICSharpCode.Decompiler.Tests/Helpers/Tester.cs @@ -886,7 +886,7 @@ namespace ICSharpCode.Decompiler.Tests.Helpers get { if (pathToAssembly == null) { - pathToAssembly = Path.GetTempFileName(); + pathToAssembly = TestsAssemblyOutput.GetTempFileName(); tempFiles.Add(pathToAssembly); } return pathToAssembly; diff --git a/ICSharpCode.Decompiler.Tests/Helpers/TestsAssemblyOutput.cs b/ICSharpCode.Decompiler.Tests/Helpers/TestsAssemblyOutput.cs new file mode 100644 index 000000000..492ccf7fb --- /dev/null +++ b/ICSharpCode.Decompiler.Tests/Helpers/TestsAssemblyOutput.cs @@ -0,0 +1,75 @@ +// Copyright (c) 2024 Christoph Wille +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of this +// software and associated documentation files (the "Software"), to deal in the Software +// without restriction, including without limitation the rights to use, copy, modify, merge, +// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons +// to whom the Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all copies or +// substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE +// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. + + +using System; +using System.IO; + +using Microsoft.Extensions.Configuration; + +namespace ICSharpCode.Decompiler.Tests.Helpers +{ + /// + /// Centralizes all file-path generation for compilation output (assemblies) + /// + /// DecompilerTests.config.json file format: + /// { + /// "TestsAssemblyTempPath": "d:\\test\\" + /// } + /// + internal static class TestsAssemblyOutput + { + static string? TestsAssemblyTempPath = null; + + private static bool UseCustomPath => !string.IsNullOrWhiteSpace(TestsAssemblyTempPath); + + static TestsAssemblyOutput() + { + if (!File.Exists("DecompilerTests.config.json")) + return; + + var builder = new ConfigurationBuilder() + .AddJsonFile("DecompilerTests.config.json", optional: true, reloadOnChange: false); + + IConfigurationRoot configuration = builder.Build(); + var pathRedirectIfAny = configuration["TestsAssemblyTempPath"]; + + if (!string.IsNullOrWhiteSpace(pathRedirectIfAny)) + { + TestsAssemblyTempPath = pathRedirectIfAny; + } + } + + public static string GetFilePath(string testCasePath, string testName, string computedExtension) + { + if (!UseCustomPath) + return Path.Combine(testCasePath, testName) + computedExtension; + + // As we are using the TestsAssemblyTempPath flat, we need to make sure that duplicated test names don't create file name clashes + return Path.Combine(TestsAssemblyTempPath, testName) + Guid.NewGuid().ToString() + computedExtension; + } + + public static string GetTempFileName() + { + if (!UseCustomPath) + return Path.GetTempFileName(); + + return Path.Combine(TestsAssemblyTempPath, Path.GetRandomFileName()); + } + } +} diff --git a/ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj b/ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj index c35d60c3e..7970f6265 100644 --- a/ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj +++ b/ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj @@ -1,9 +1,16 @@ + + true + true + + net8.0-windows - win-x64 + win-x64 + win-arm64 + false AutoGeneratedProgram @@ -43,14 +50,16 @@ + + - - + + all @@ -114,6 +123,7 @@ + diff --git a/ICSharpCode.Decompiler.Tests/PrettyTestRunner.cs b/ICSharpCode.Decompiler.Tests/PrettyTestRunner.cs index 4fe48369d..e5c09c9c1 100644 --- a/ICSharpCode.Decompiler.Tests/PrettyTestRunner.cs +++ b/ICSharpCode.Decompiler.Tests/PrettyTestRunner.cs @@ -714,7 +714,7 @@ namespace ICSharpCode.Decompiler.Tests async Task Run([CallerMemberName] string testName = null, AssemblerOptions asmOptions = AssemblerOptions.None, CompilerOptions cscOptions = CompilerOptions.None, DecompilerSettings decompilerSettings = null) { var csFile = Path.Combine(TestCasePath, testName + ".cs"); - var exeFile = Path.Combine(TestCasePath, testName) + Tester.GetSuffix(cscOptions) + ".exe"; + var exeFile = TestsAssemblyOutput.GetFilePath(TestCasePath, testName, Tester.GetSuffix(cscOptions) + ".exe"); if (cscOptions.HasFlag(CompilerOptions.Library)) { exeFile = Path.ChangeExtension(exeFile, ".dll"); diff --git a/ICSharpCode.Decompiler.Tests/VBPrettyTestRunner.cs b/ICSharpCode.Decompiler.Tests/VBPrettyTestRunner.cs index c21dc0775..9fcc77b7d 100644 --- a/ICSharpCode.Decompiler.Tests/VBPrettyTestRunner.cs +++ b/ICSharpCode.Decompiler.Tests/VBPrettyTestRunner.cs @@ -147,7 +147,7 @@ namespace ICSharpCode.Decompiler.Tests { var vbFile = Path.Combine(TestCasePath, testName + ".vb"); var csFile = Path.Combine(TestCasePath, testName + ".cs"); - var exeFile = Path.Combine(TestCasePath, testName) + Tester.GetSuffix(options) + ".exe"; + var exeFile = TestsAssemblyOutput.GetFilePath(TestCasePath, testName, Tester.GetSuffix(options) + ".exe"); if (options.HasFlag(CompilerOptions.Library)) { exeFile = Path.ChangeExtension(exeFile, ".dll"); diff --git a/ILSpy.BamlDecompiler.Tests/ILSpy.BamlDecompiler.Tests.csproj b/ILSpy.BamlDecompiler.Tests/ILSpy.BamlDecompiler.Tests.csproj index 0c00fb98c..05807b302 100644 --- a/ILSpy.BamlDecompiler.Tests/ILSpy.BamlDecompiler.Tests.csproj +++ b/ILSpy.BamlDecompiler.Tests/ILSpy.BamlDecompiler.Tests.csproj @@ -1,9 +1,16 @@  + + true + true + + net8.0-windows - win-x64 + win-x64 + win-arm64 + false AutoGeneratedProgram