diff options
author | Miguel Costa <miguel.costa@qt.io> | 2023-12-20 15:56:15 +0100 |
---|---|---|
committer | Miguel Costa <miguel.costa@qt.io> | 2024-01-09 15:19:00 +0000 |
commit | 6bd5ec96cd32144853fd2cd505c474ea59436b43 (patch) | |
tree | e3f85ef36f3ea586baf89f209a3e4b857004483a | |
parent | b6e902017fbdce55836fcf5ff16c1ef01f399824 (diff) |
Make adjustments to auto-tests
== Test_QtMsBuild.Build
* BigSolution test case available in auto-tests.
* Call MSBuild out-of-proc:
- New method 'Run' starts MSBuild.exe in a separate process.
- In-proc calls to MSBuild API are still possible.
* Print build messages to Debug output and test logs.
== Test_QtMsBuild.Tasks
* Renamed 'TestTaskLoggingHelper' to 'MockTaskLogger'.
* Added 'MockBuildEngine'
* Implemented mock build engine services:
- RegisterTaskObject, UnregisterTaskObject, GetRegisteredTaskObject
Change-Id: I5f1f0eff31aa1976ca451ae894115150c5907f82
Reviewed-by: Karsten Heimrich <karsten.heimrich@qt.io>
-rw-r--r-- | Tests/BigSolution/generator/App.config | 6 | ||||
-rw-r--r-- | Tests/BigSolution/generator/Properties/AssemblyInfo.cs | 36 | ||||
-rw-r--r-- | Tests/BigSolution/generator/generator.csproj | 59 | ||||
-rw-r--r-- | Tests/BigSolution/generator/generator.sln | 25 | ||||
-rw-r--r-- | Tests/Test_QtMsBuild.Build/BigSolution.cs (renamed from Tests/BigSolution/generator/Program.cs) | 32 | ||||
-rw-r--r-- | Tests/Test_QtMsBuild.Build/Logger.cs | 3 | ||||
-rw-r--r-- | Tests/Test_QtMsBuild.Build/MsBuild.cs | 35 | ||||
-rw-r--r-- | Tests/Test_QtMsBuild.Build/TempProject.cs | 8 | ||||
-rw-r--r-- | Tests/Test_QtMsBuild.Build/Test_QtMsBuild.Build.csproj | 1 | ||||
-rw-r--r-- | Tests/Test_QtMsBuild.Tasks/MockBuildEngine.cs | 106 | ||||
-rw-r--r-- | Tests/Test_QtMsBuild.Tasks/MockTaskLogger.cs (renamed from Tests/Test_QtMsBuild.Tasks/TestTaskLoggingHelper.cs) | 2 | ||||
-rw-r--r-- | Tests/Test_QtMsBuild.Tasks/Test_QtMsBuild.Tasks.csproj | 3 |
12 files changed, 166 insertions, 150 deletions
diff --git a/Tests/BigSolution/generator/App.config b/Tests/BigSolution/generator/App.config deleted file mode 100644 index 359541cf..00000000 --- a/Tests/BigSolution/generator/App.config +++ /dev/null @@ -1,6 +0,0 @@ -<?xml version="1.0" encoding="utf-8" ?> -<configuration> - <startup> - <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" /> - </startup> -</configuration> diff --git a/Tests/BigSolution/generator/Properties/AssemblyInfo.cs b/Tests/BigSolution/generator/Properties/AssemblyInfo.cs deleted file mode 100644 index eeb047ca..00000000 --- a/Tests/BigSolution/generator/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("generator")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("generator")] -[assembly: AssemblyCopyright("Copyright © 2021")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("8c16da39-8049-465a-b242-82dfb91e252a")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/Tests/BigSolution/generator/generator.csproj b/Tests/BigSolution/generator/generator.csproj deleted file mode 100644 index 24530493..00000000 --- a/Tests/BigSolution/generator/generator.csproj +++ /dev/null @@ -1,59 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -*************************************************************************************************** - Copyright (C) 2023 The Qt Company Ltd. - SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only -*************************************************************************************************** ---> -<Project ToolsVersion="$(VisualStudioVersion)" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" /> - <PropertyGroup> - <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> - <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> - <ProjectGuid>{8C16DA39-8049-465A-B242-82DFB91E252A}</ProjectGuid> - <OutputType>Exe</OutputType> - <RootNamespace>generator</RootNamespace> - <AssemblyName>generator</AssemblyName> - <TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion> - <FileAlignment>512</FileAlignment> - <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects> - <Deterministic>true</Deterministic> - </PropertyGroup> - <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> - <PlatformTarget>AnyCPU</PlatformTarget> - <DebugSymbols>true</DebugSymbols> - <DebugType>full</DebugType> - <Optimize>false</Optimize> - <OutputPath>bin\Debug\</OutputPath> - <DefineConstants>DEBUG;TRACE</DefineConstants> - <ErrorReport>prompt</ErrorReport> - <WarningLevel>4</WarningLevel> - </PropertyGroup> - <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> - <PlatformTarget>AnyCPU</PlatformTarget> - <DebugType>pdbonly</DebugType> - <Optimize>true</Optimize> - <OutputPath>bin\Release\</OutputPath> - <DefineConstants>TRACE</DefineConstants> - <ErrorReport>prompt</ErrorReport> - <WarningLevel>4</WarningLevel> - </PropertyGroup> - <ItemGroup> - <Reference Include="System" /> - <Reference Include="System.Core" /> - <Reference Include="System.Xml.Linq" /> - <Reference Include="System.Data.DataSetExtensions" /> - <Reference Include="Microsoft.CSharp" /> - <Reference Include="System.Data" /> - <Reference Include="System.Net.Http" /> - <Reference Include="System.Xml" /> - </ItemGroup> - <ItemGroup> - <Compile Include="Program.cs" /> - <Compile Include="Properties\AssemblyInfo.cs" /> - </ItemGroup> - <ItemGroup> - <None Include="App.config" /> - </ItemGroup> - <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> -</Project> diff --git a/Tests/BigSolution/generator/generator.sln b/Tests/BigSolution/generator/generator.sln deleted file mode 100644 index 48200edc..00000000 --- a/Tests/BigSolution/generator/generator.sln +++ /dev/null @@ -1,25 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 17 -VisualStudioVersion = 17.0.31717.71 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "generator", "generator.csproj", "{8C16DA39-8049-465A-B242-82DFB91E252A}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {8C16DA39-8049-465A-B242-82DFB91E252A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {8C16DA39-8049-465A-B242-82DFB91E252A}.Debug|Any CPU.Build.0 = Debug|Any CPU - {8C16DA39-8049-465A-B242-82DFB91E252A}.Release|Any CPU.ActiveCfg = Release|Any CPU - {8C16DA39-8049-465A-B242-82DFB91E252A}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {C23785F8-8749-42B1-B19E-4A6703DD83BB} - EndGlobalSection -EndGlobal diff --git a/Tests/BigSolution/generator/Program.cs b/Tests/Test_QtMsBuild.Build/BigSolution.cs index 6d8b8275..7719c479 100644 --- a/Tests/BigSolution/generator/Program.cs +++ b/Tests/Test_QtMsBuild.Build/BigSolution.cs @@ -3,17 +3,18 @@ SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only ***************************************************************************************************/ -using System; using System.Collections.Generic; +using System.Diagnostics; using System.IO; using System.Linq; using System.Text; using System.Text.RegularExpressions; using System.Threading.Tasks; +using QtVsTools.Core.MsBuild; -namespace generator +namespace QtVsTools.Test.QtMsBuild.Build { - internal class Program + public static class BigSolution { static void GenerateProject( StringBuilder genSolutionProjectRef, @@ -65,21 +66,10 @@ namespace generator } } - static void Main(string[] args) + public static void Generate(string outputPath, string templatePath, int projectCount) { - int projectCount; - if (args.Length == 0 || !int.TryParse(args[0], out projectCount)) { - string userProjectCount; - do { - Console.Write("Project count: "); - userProjectCount = Console.ReadLine(); - } while (!int.TryParse(userProjectCount, out projectCount)); - } - var pathToTemplateDir = Path.GetFullPath(@"..\..\..\template"); - var pathToGeneratedDir = Path.GetFullPath( - $@"..\..\..\generated_{DateTime.Now.ToString("yyyyMMddhhmmssfff")}"); var templateFiles = Directory.GetFiles( - pathToTemplateDir, "*", SearchOption.AllDirectories); + templatePath, "*", SearchOption.AllDirectories); var solutionFilePath = templateFiles .Where(x => Path.GetExtension(x) == ".sln") .First(); @@ -88,8 +78,8 @@ namespace generator var projectFilePaths = templateFiles .Where(x => Path.GetExtension(x) == ".vcxproj"); var genSolutionText = solutionText; - if (Directory.Exists(pathToGeneratedDir)) - Directory.Delete(pathToGeneratedDir, true); + if (Directory.Exists(outputPath)) + Directory.Delete(outputPath, true); foreach (var projectFilePath in projectFilePaths) { var genSolutionProjectRef = new StringBuilder(); var genSolutionProjectConfigs = new StringBuilder(); @@ -112,8 +102,8 @@ namespace generator GenerateProject( genSolutionProjectRef, genSolutionProjectConfigs, - pathToTemplateDir, - pathToGeneratedDir, + templatePath, + outputPath, projectCount, projectGuid, projectName, @@ -123,7 +113,7 @@ namespace generator .Replace(projectRef, genSolutionProjectRef.ToString()) .Replace(projectConfigs, genSolutionProjectConfigs.ToString()); } - var genSolutionFilePath = Path.Combine(pathToGeneratedDir, solutionName); + var genSolutionFilePath = Path.Combine(outputPath, solutionName); File.WriteAllText(genSolutionFilePath, genSolutionText); } } diff --git a/Tests/Test_QtMsBuild.Build/Logger.cs b/Tests/Test_QtMsBuild.Build/Logger.cs index 25c2620d..997de181 100644 --- a/Tests/Test_QtMsBuild.Build/Logger.cs +++ b/Tests/Test_QtMsBuild.Build/Logger.cs @@ -9,6 +9,7 @@ using System.Linq; using Microsoft.Build.Execution; using Microsoft.Build.Framework; using Microsoft.Build.Evaluation; +using System.Diagnostics; namespace QtVsTools.Test.QtMsBuild.Build { @@ -130,6 +131,8 @@ namespace QtVsTools.Test.QtMsBuild.Build EventArgs.Enqueue(e); } } + if (e.GetType().GetProperty("Message")?.GetValue(e)?.ToString() is { Length: > 0 } msg) + Debug.WriteLine(msg); } private void GlobalProjectCollection_ProjectXmlChanged(object sender, ProjectXmlChangedEventArgs e) diff --git a/Tests/Test_QtMsBuild.Build/MsBuild.cs b/Tests/Test_QtMsBuild.Build/MsBuild.cs index 2c012646..4362a0d6 100644 --- a/Tests/Test_QtMsBuild.Build/MsBuild.cs +++ b/Tests/Test_QtMsBuild.Build/MsBuild.cs @@ -4,6 +4,8 @@ ***************************************************************************************************/ using System.Collections.Generic; +using System.Diagnostics; +using System.IO; using System.Linq; using System.Xml; using Microsoft.Build.Evaluation; @@ -33,7 +35,7 @@ namespace QtVsTools.Test.QtMsBuild.Build public static Project Evaluate(string path, params (string name, string value)[] globals) { return ProjectCollection.LoadProject( - path, globals.ToDictionary(x => x.name, x => x.value), null); + path, globals.ToDictionary(x => x.name, x => x.value), "Current"); } public static Project Evaluate(XmlReader xml, params (string name, string value)[] globals) @@ -41,5 +43,36 @@ namespace QtVsTools.Test.QtMsBuild.Build return ProjectCollection.LoadProject( xml, globals.ToDictionary(x => x.name, x => x.value), null); } + + public static bool Run(string workDir, params string[] args) + { + var msbuildStartInfo = new ProcessStartInfo + { + CreateNoWindow = true, + UseShellExecute = false, + RedirectStandardError = true, + RedirectStandardOutput = true, + FileName = Path.Combine(Properties.MSBuildToolsPath, "MSBuild.exe"), + Arguments = string.Join(" ", args + .Where(arg => arg is { Length: > 0}) + .Select(arg => arg.Contains(" ") ? $"\"{arg}\"" : arg)), + WorkingDirectory = workDir + }; + msbuildStartInfo.EnvironmentVariables["VsInstallRoot"] = Properties.VsInstallRoot; + msbuildStartInfo.EnvironmentVariables["VCTargetsPath"] = Properties.VCTargetsPath; + + var msbuildProc = new Process + { + StartInfo = msbuildStartInfo + }; + msbuildProc.OutputDataReceived += (sender, ev) => Debug.WriteLine(ev.Data); + msbuildProc.ErrorDataReceived += (sender, ev) => Debug.WriteLine(ev.Data); + if (!msbuildProc.Start()) + return false; + msbuildProc.BeginOutputReadLine(); + msbuildProc.BeginErrorReadLine(); + msbuildProc.WaitForExit(); + return msbuildProc.ExitCode == 0; + } } } diff --git a/Tests/Test_QtMsBuild.Build/TempProject.cs b/Tests/Test_QtMsBuild.Build/TempProject.cs index a9216018..692afce6 100644 --- a/Tests/Test_QtMsBuild.Build/TempProject.cs +++ b/Tests/Test_QtMsBuild.Build/TempProject.cs @@ -46,6 +46,14 @@ namespace QtVsTools.Test.QtMsBuild.Build WriteAllText(ProjectPath, xml); } + public void GenerateBigSolution(string templatePath, int projectCount) + { + Reset(); + CreateDirectory(ProjectDir); + BigSolution.Generate(ProjectDir, templatePath, projectCount); + ProjectFileName = GetFileName(EnumerateFiles(ProjectDir, "*.sln").FirstOrDefault()); + } + protected override void DisposeUnmanaged() { Reset(); diff --git a/Tests/Test_QtMsBuild.Build/Test_QtMsBuild.Build.csproj b/Tests/Test_QtMsBuild.Build/Test_QtMsBuild.Build.csproj index 5d2cf5a2..e2d1c05d 100644 --- a/Tests/Test_QtMsBuild.Build/Test_QtMsBuild.Build.csproj +++ b/Tests/Test_QtMsBuild.Build/Test_QtMsBuild.Build.csproj @@ -105,6 +105,7 @@ // --> <ItemGroup> <None Include="app.config" /> + <Compile Include="BigSolution.cs" /> <Compile Include="TempProject.cs" /> <Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Logger.cs" /> diff --git a/Tests/Test_QtMsBuild.Tasks/MockBuildEngine.cs b/Tests/Test_QtMsBuild.Tasks/MockBuildEngine.cs new file mode 100644 index 00000000..755c46a8 --- /dev/null +++ b/Tests/Test_QtMsBuild.Tasks/MockBuildEngine.cs @@ -0,0 +1,106 @@ +/*************************************************************************************************** + Copyright (C) 2023 The Qt Company Ltd. + SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +***************************************************************************************************/ + +using System; +using System.Collections; +using System.Collections.Concurrent; +using System.Collections.Generic; +using Microsoft.Build.Framework; + +namespace QtVsTools.Test.QtMsBuild.Tasks +{ + internal class MockBuildEngine : IBuildEngine4 + { + private ConcurrentDictionary<object, object> TaskObject = new(); + + public void ResetTaskObjects() + { + TaskObject.Clear(); + } + + public void RegisterTaskObject(object key, object obj, RegisteredTaskObjectLifetime lifetime, bool allowEarlyCollection) + { + TaskObject[key] = obj; + } + + public object UnregisterTaskObject(object key, RegisteredTaskObjectLifetime lifetime) + { + return TaskObject.TryRemove(key, out var obj) switch + { + true => obj, + false => null + }; + } + + public object GetRegisteredTaskObject(object key, RegisteredTaskObjectLifetime lifetime) + { + return TaskObject.TryGetValue(key, out var obj) switch + { + true => obj, + false => null + }; + } + + public bool IsRunningMultipleNodes => throw new NotImplementedException(); + + public bool ContinueOnError => throw new NotImplementedException(); + + public int LineNumberOfTaskNode => throw new NotImplementedException(); + + public int ColumnNumberOfTaskNode => throw new NotImplementedException(); + + public string ProjectFileOfTaskNode => throw new NotImplementedException(); + + public bool BuildProjectFile(string projectFileName, string[] targetNames, IDictionary globalProperties, IDictionary targetOutputs, string toolsVersion) + { + throw new NotImplementedException(); + } + + public bool BuildProjectFile(string projectFileName, string[] targetNames, IDictionary globalProperties, IDictionary targetOutputs) + { + throw new NotImplementedException(); + } + + public BuildEngineResult BuildProjectFilesInParallel(string[] projectFileNames, string[] targetNames, IDictionary[] globalProperties, IList<string>[] removeGlobalProperties, string[] toolsVersion, bool returnTargetOutputs) + { + throw new NotImplementedException(); + } + + public bool BuildProjectFilesInParallel(string[] projectFileNames, string[] targetNames, IDictionary[] globalProperties, IDictionary[] targetOutputsPerProject, string[] toolsVersion, bool useResultsCache, bool unloadProjectsOnCompletion) + { + throw new NotImplementedException(); + } + + public void LogCustomEvent(CustomBuildEventArgs e) + { + throw new NotImplementedException(); + } + + public void LogErrorEvent(BuildErrorEventArgs e) + { + throw new NotImplementedException(); + } + + public void LogMessageEvent(BuildMessageEventArgs e) + { + throw new NotImplementedException(); + } + + public void LogWarningEvent(BuildWarningEventArgs e) + { + throw new NotImplementedException(); + } + + public void Reacquire() + { + throw new NotImplementedException(); + } + + public void Yield() + { + throw new NotImplementedException(); + } + } +} diff --git a/Tests/Test_QtMsBuild.Tasks/TestTaskLoggingHelper.cs b/Tests/Test_QtMsBuild.Tasks/MockTaskLogger.cs index c4f1f20a..d05c44f1 100644 --- a/Tests/Test_QtMsBuild.Tasks/TestTaskLoggingHelper.cs +++ b/Tests/Test_QtMsBuild.Tasks/MockTaskLogger.cs @@ -11,7 +11,7 @@ using Microsoft.Build.Framework; namespace QtVsTools.Test.QtMsBuild.Tasks { - internal class TestTaskLoggingHelper : QtMSBuild.ITaskLoggingHelper + internal class MockTaskLogger : QtMSBuild.ITaskLoggingHelper { public bool HasLoggedErrors { get; set; } = false; diff --git a/Tests/Test_QtMsBuild.Tasks/Test_QtMsBuild.Tasks.csproj b/Tests/Test_QtMsBuild.Tasks/Test_QtMsBuild.Tasks.csproj index d0c11720..8a8a88f3 100644 --- a/Tests/Test_QtMsBuild.Tasks/Test_QtMsBuild.Tasks.csproj +++ b/Tests/Test_QtMsBuild.Tasks/Test_QtMsBuild.Tasks.csproj @@ -95,7 +95,8 @@ // --> <ItemGroup> <Compile Include="Properties\AssemblyInfo.cs" /> - <Compile Include="TestTaskLoggingHelper.cs" /> + <Compile Include="MockBuildEngine.cs" /> + <Compile Include="MockTaskLogger.cs" /> <Compile Include="Test_GetVarsFromMSBuild.cs" /> <Compile Include="Test_Join.cs" /> <Compile Include="Test_QtRunTask.cs" /> |