MSBuild hangs after NUnit is finished - msbuild

I'm trying to set up a MSBuild with NUnit as unit test driver but the script keeps hanging after NUnit is done. It doesn't seem to finalize its work and let MSBuild get on with its job.
I'm working in .NET 4.0 and using NUnit 2.5.8.
If I run the test manually or using the gui (either VS2010 or NUnit) it works fine but not when called by MSBuild.
I'd appreciate any help with error finding or just a heads up on where to looks for answers.
The manual command looks like this:
C:\....>nunit\nunit-console.exe buildbinaries\YYYY.XXXX.Extractor.Test.IntegrationTest.dll /xml=nunit.xml
and the abbreviated MSBuild:
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<!-- define folders for build output and reports -->
<PropertyGroup>
<BuildPath>buildbinaries\</BuildPath>
<ReportPath>buildreports\</ReportPath>
<ReleaseFolder>release_artefacts\</ReleaseFolder>
<PublishFolder>c:\ZZZ Applications\published builds\</PublishFolder>
<DeploymentFolder>\\seldclq99\ZZZ_Costanza_Dev$\</DeploymentFolder>
</PropertyGroup>
<PropertyGroup>
<!-- specify assemblies that should be included in coverage report -->
<NCoverAssemblyList>YYYY.XXXX.Extractor.Business.dll; YYYY.XXXX.Extractor.Common.dll YYYY.XXXX.Extractor.Configuration.dll YYYY.XXXX.Extractor.DAL.Access.dll YYYY.XXXX.Extractor.DAL.Facade.dll YYYY.XXXX.Extractor.Service.Contracts.dll YYYY.XXXX.Extractor.Service.dll YYYY.XXXX.Extractor.Service.Host.WebHost.dll YYYY.XXXX.Extractor.ServiceGateway.dll</NCoverAssemblyList>
</PropertyGroup>
<!-- define item group for deliverables -->
<ItemGroup>
<Binaries Include="$(BuildPath)/**/*.*" Exclude="$(BuildPath)nunit*" />
</ItemGroup>
<!--
This is the default target that will be executed if MSBuild is not started
with a specific target (this is decided by the DefaultTargets attribute in
the root element of this XML document)
-->
<Target Name="BuildAndTest">
<CallTarget Targets="SetupDirs" />
<CallTarget Targets="Build" />
<CallTarget Targets="UnitAndIntegrationTest" />
<CallTarget Targets="FxCop" />
<CallTarget Targets="CopyToReleaseFolder" />
</Target>
<!-- Setup folders used during the build -->
<Target Name="SetupDirs">
<RemoveDir Directories="$(ReportPath);$(BuildPath);$(ReleaseFolder)" ContinueOnError="true"/>
<MakeDir Directories="$(ReportPath);$(BuildPath);$(ReleaseFolder);$(AssemblyVersionFolder)" ContinueOnError="true"/>
</Target>
<Target Name="Build">
<!-- build the software using msbuild -->
<!-- Build error in the Install build-->
<MSBuild ContinueOnError="true" RebaseOutputs="false" Targets="Clean;Rebuild" Projects="YYYYXXXXExtractor.sln" Properties="Configuration=Release;OutDir=..\$(BuildPath)" />
</Target>
<!--Run the coverage stats-->
<Target Name="UnitAndIntegrationTest">
<Exec Command="nunit\nunit-console.exe buildbinaries\YYYY.XXXX.Extractor.Test.IntegrationTest.dll /xml=$(ReportPath)nunit.xml "/>
<CallTarget Targets="UnitTest" />
</Target>
<Target Name="UnitTest">
<Exec Command="nunit\nunit-console.exe buildbinaries\YYYY.XXXX.Extractor.Test.UnitTest.dll /xml=$(ReportPath)nunit.xml"/>
</Target>
<!-- Run FxCop -->
<!-- The ForceError.bat fires if the xml file is not found... aka an error was found -->
<!-- The quiet command forces an Xml file ONLY if warnings or Errors are found -->
<Target Name="FxCop">
<Exec Command="..\tools\fxcop\FxCopCmd.exe /p:..\FxCopSettings.FxCop /o:$(ReportPath)fxcop.xml" />
<Exec Condition="Exists('$(ReportPath)fxcop.xml')" Command="..\tools\fxcop\FX_Cop_Failed_Rule_Checks.bat" />
<!--STATS: Run again but don't fail and this time run for all rules.-->
<Exec Command="..\tools\fxcop\FxCopCmd.exe /p:..\FxCopSettingsALLRULES.FxCop /o:$(ReportPath)fxCopAllRules.xml" />
</Target >

I had the same problem with NUnit 2.5.8. There is some discussion of this at the nunit site about the test process hanging. I switched to NUnit 2.5.7 and the problem went away.
It looks like this was fixed a couple of weeks ago in 2.5.9.

I have noticed similar behaviour on out build server since upgrading to .NET 4. MsBuild seems to intermittently hang on either NUnit, FxCop or Dotcover EXEC commands. If you check task manager the process for externally executed command (e.g. Nunit.exe) is still hanging around. If you manually kill the process MsBuild continues on it's merry way - which is far from ideal!
Could this be a bug in the latest version of MsBuild? Our build server was running quite happily until the .NET 4 upgrade.

If you run ProcessExplorer on your server you will notice that an out of band process called nunit-agent is spawned which ends up blocking the nunit runner.
I have not validated that this is fixed in 2.5.9, but it might be some info that could be helpful.

Related

Standalone project shows empty after initialization

Well, this is not a question and I don't know if this is against the rules. But I found no topic on this point and I figured out one potential method.
Yesterday, I try to create a standalone vue project with .net6. I read the official guideline and installed node.js,npm,vue,vue#cli and so on. I was pretty sure all the prerequisites were met.
But the project turned out to be empty after initialization by vs2022 with a command window that runs successfully. I tried to reinstall node.js because the project file shows information below:
sampleproject
<Project Sdk="Microsoft.VisualStudio.JavaScript.Sdk/0.4.0-alpha">
<PropertyGroup Label="Globals">
<ProjectGuid>...</ProjectGuid>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<StartupCommand>npm run serve</StartupCommand>
<JavaScriptTestRoot>.\</JavaScriptTestRoot>
<JavaScriptTestFramework>Jest</JavaScriptTestFramework>
</PropertyGroup>
<ItemGroup>
<Script Include="**" Exclude="*.esproj;**\node_modules\**" />
</ItemGroup>
<!-- This target is copied from the ASP.NET SPA template in order to ensure node_modules are in place. -->
<Target Name="DebugEnsureNodeEnv" BeforeTargets="Build" Condition=" '$(Configuration)' == 'Debug' And !Exists('$(SpaRoot)node_modules') ">
<!-- Ensure Node.js is installed -->
<Exec Command="node --version" ContinueOnError="true">
<Output TaskParameter="ExitCode" PropertyName="ErrorCode" />
</Exec>
<Error Condition="'$(ErrorCode)' != '0'" Text="Node.js is required to build and run this project. To continue, please install Node.js from https://nodejs.org/, and then restart your command prompt or IDE." />
<Message Importance="high" Text="Restoring dependencies using 'npm'. This may take several minutes..." />
<Exec WorkingDirectory="$(SpaRoot)" Command="npm install" />
</Target>
</Project>
Then I found that all needed files were ready in the target filesfiles
Anyway, the point is vs2022 language. I changed back my vs2022 language to English by uninstall other languages pack in vs installer. And all files comes out in the project.
before
after
Everything works well now.

MSBuild /m:4 fails because it builds the same project twice

My team has a large solution (~500 csproj's). We use VS2012, and build using TFS Build, which uses MSBuild 4. Currently we build serially, but we want to build in parallel (using msbuild /maxcpucount:4). However, when I try it on my 4-proc machine, I get a weird failure:
11:2>CSC : fatal error CS0042: Unexpected error creating debug information file 'C:\Common\obj\Debug\Common.PDB' -- 'C:\Common\obj\Debug\Common.pdb: The process cannot access the file because it is being used by another process. [C:\Common\Common.csproj]
Looking at the log, 2 msbuild nodes were trying to build that same csproj, and thus colliding on writing some output:
10>Project "C:\Utils\Utils.csproj" (10) is building "C:\Common\Common.csproj" (11) on node 4 (default targets).
46:2>Project "C:\Objects\Objects.csproj" (46:2) is building "C:\Common\Common.csproj" (11:2) on node 1 (default targets).
Why would MSBuild try to build the same project twice?
Cause: Someone was calling <MSBuild Projects="Common.csproj" Properties="..." />. Then, MSBuild thinks that it should build Common.csproj again with those different properties, and it happened to occur at the same time with the regular compilation of Common.csproj.
Fix: Call <MSBuild ... /> without those unneeded properties.
Test:
Common.targets
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Target Name="Build">
<Message Importance="high" Text="Build in $(MSBuildThisFile)" />
</Target>
<Target Name="After" DependsOnTargets="Build">
<Message Importance="high" Text="After in $(MSBuildThisFile)" />
</Target>
</Project>
Other.targets
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Target Name="Build">
<Message Importance="high" Text="Build in $(MSBuildThisFile)" />
<MSBuild Projects="common.targets" Targets="Build" /> <!-- regular builds -->
<MSBuild Projects="common.targets" <!-- custom invocation with properties -->
Targets="After"
Properties="myprop=myvalue"
/>
</Target>
</Project>
Run:
> msbuild other.targets /clp:verbosity=minimal
Build in other.targets
Build in common.targets
Build in common.targets <<<< Common.targets Build is invoked again
After in common.targets
And indeed, removing Properties="myprop=myvalue" solves the issue.
I found someone had added two project references (from the same project) and that apparently caused msbuild to build twice also.. something to watch out for

Msbuild: transforming one itemgroup into another itemgroup with a different structure

I may be asking the wrong question here, and I'm open to that, so I'll give a bit of background of what I'm trying to do. I invoke mstest via an msbuild project, after dynamically finding all test assemblies. I invoke mstest separately for every test assembly, so that the results can be imported into teamcity (my CI server) as soon as they're available, rather than waiting for all of them to be complete before showing any progress in TC.
The problem is that this runs a single test at a time, and combined with the slow overhead (even on an i7 quad, mstest takes 3-5 seconds overhead to open for each project) and many tests, the tests take a few minutes to run.
Using the msbuild task with BuildInParallel=true (and invoking with the /m parameter), it's possible to build several projects at once.
So what I'm trying to do is
get a list of all *.Tests.dll
Invoke the ExecMsTest target in the same project, in parallel, for each .dll
<PropertyGroup>
<MsTestExePath Condition="'$(MsTestExePath)'==''">C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\MSTest.exe</MsTestExePath>
<MsTestSettingsPath Condition="'$(MsTestSettingsPath)'==''">Project.testsettings</MsTestSettingsPath>
</PropertyGroup>
<ItemGroup>
<TestAssemblies Include="**\bin\**\*.Tests.dll" />
</ItemGroup>
<Target Name="RunTests">
<Message Text="Found test assemblies: #(TestAssemblies)" />
<MakeDir Directories="TestResults" />
<MsBuild Projects="#(ProjectsToBuild)" Targets="ExecMsTest" BuildInParallel="True" />
</Target>
<Target Name="ExecMsTest">
<Message Text="Running tests in $(TestAssembly)" />
<!-- show TC progress -->
<Message Text="##teamcity[progressMessage 'Running tests in $(TestAssembly).dll']" Importance="High" />
<PropertyGroup>
<MsTestCommand>"$(MsTestExePath)" /testcontainer:"$(TestAssembly)" /resultsfile:"TestResults\$(TestAssembly).trx" /testsettings:"$(MsTestSettingsPath)"</MsTestCommand>
</PropertyGroup>
<!-- Message Text="Exec: $(MsTestCommand)" / -->
<Exec Command="$(MsTestCommand)" ContinueOnError="true" />
<!-- import data to teamcity test results -->
<Message Text="##teamcity[importData type='mstest' path='TestResults\$(TestAssembly).trx']" />
<Message Text="Tests complete from $(TestAssembly)" />
However, this isn't quite right. You can see my itemgroup is called TestAssemblies, but I'm passing #(ProjectsToBuild) to mstest. This is because the msbuild task requires a differently-formatted item group, something like:
<ItemGroup>
<ProjectsToBuild Include="Project.mstest.proj">
<Properties>TestAssembly=Project.UI.Tests</Properties>
</ProjectsToBuild>
<ProjectsToBuild Include="Project.mstest.proj">
<Properties>TestAssembly=Project.Model.Tests</Properties>
</ProjectsToBuild>
</ItemGroup>
So this is the crux of my question, assuming I'm even asking the right thing: how do I transform the TestAssemblies itemgroup into something resembling the ProjectsToBuild itemgroup?
In case it's not obvious, the name of the items in TestAssemblies are the *.tests.Dll filenames, while I need that name to be a inside the item, and the name of the ProjectsToBuild item to all be the Project.mstest.proj file (since they're all invoking the same file).
Thanks to #Spider M9, this works:
<ItemGroup>
<TestAssemblies Include="**\bin\**\*.Tests.dll" />
</ItemGroup>
<Target Name="RunTests">
<Message Text="Found test assemblies: #(TestAssemblies)" />
<ItemGroup>
<TestAssembliesToBuild Include="Project.mstest.proj">
<Properties>TestAssembly=%(TestAssemblies.FileName);FullPath=%(TestAssemblies.FullPath)</Properties>
</TestAssembliesToBuild>
</ItemGroup>
<MakeDir Directories="TestResults" />
<MsBuild Projects="#(TestAssembliesToBuild)" Targets="ExecMsTest" BuildInParallel="True" />
</Target>
Running msbuild single-threaded, my entire build (which includes compiling, building application and database snapshots, deploying schema for a couple databases that get used in some of the unit tests, and then finally running mstest) took about 9m30s. After this change, it was taking ~7m.
However, prior to getting an answer to this question, I just tried running a single mstest instance, to see how much it would improve, and that takes about 4m50s (of which mstest takes slightly over 1 minute to run). The downside is I have to wait until all tests are complete before getting results, but considering the staggering improvement from 6m to 1m that's a perfectly acceptable trade-off.
To be clear, the only difference is that mstest is starting once, vs starting a dozen times, and presumably there is also some benefit from multitasking. I'm running this on a Core i7-860 (4 physical cores, 8 logical cores) and I suspect number of cores will highly influence the level of improvement this change makes.
Here is my new RunTests:
<Target Name="RunTests">
<Message Text="Found test assemblies: #(TestAssemblies)" />
<MakeDir Directories="TestResults" />
<!-- this executes mstest once, and runs all assemblies at the same time. Faster, but no output to TC until they're all completed -->
<PropertyGroup>
<MsTestCommand>"$(MsTestExePath)" #(TestAssemblies->'/testcontainer:"%(FullPath)"', ' ') /resultsfile:"TestResults\Results.trx" /testsettings:"$(MsTestSettingsPath)"</MsTestCommand>
</PropertyGroup>
<Message Text="##teamcity[progressMessage 'Running tests']" Importance="High" />
<Message Text="Exec: $(MsTestCommand)" />
<Exec Command="$(MsTestCommand)" ContinueOnError="true" />
<Message Text="##teamcity[importData type='mstest' path='TestResults\Results.trx']" />
</Target>
also, you need a testsettings file with: <Execution parallelTestCount="0"> (0 means autodetect, default is 1) and need to invoke msbuild using the /m parameter and/or <Msbuild BulidInParallel="true">
Try this:
<ItemGroup>
<TestAssemblies Include="**\bin\**\*.Tests.dll" />
<TestAssembliesToBuild Include="Project.mstest.proj">
<Properties>TestAssembly=%(TestAssemblies.FileName)</Properties>
</TestAssembliesToBuild>
</ItemGroup>
<Message Text="'%(TestAssembliesToBuild.Properties)'" />

Cannot integrate Gallio MBUnit with Team City

I have been trying to get my MBUnit tests suite to work on Team City for many days now without any success.
My solution builds no problem. The program is with my tests. After googling for Gallio integration with Team City I tried many ways to make this thing work and I think I am close but need help.
I have included the gallio bin directory to my repository and also on my TC Server.
Here is my build runner set up in Team City :
Build runner : MSBuild
Build file path : Myproject.msbuild
Targets : RebuildSolution RunTests
Here is Myproject.msbuild file I created and included in the Source control trunk directory :
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<!-- This is needed by MSBuild to locate the Gallio task -->
<UsingTask AssemblyFile="C:\Gallio\bin\Gallio.MSBuildTasks.dll" TaskName="Gallio" />
<!-- Specify the tests assemblies -->
<ItemGroup>
<TestAssemblies Include="C:\_CBL\CBL\CoderForTraders\Source\trunk\UnitTest\DomainModel.Tests\bin\Debug\CBL.CoderForTraders.DomainModel.Tests.dll" />
</ItemGroup>
<Target Name="RunTests">
<Gallio IgnoreFailures="false" Assemblies="#(TestAssemblies)" RunnerExtensions="TeamCityExtension,Gallio.TeamCityIntegration">
<!-- This tells MSBuild to store the output value of the task's ExitCode property into the project's ExitCode property -->
<Output TaskParameter="ExitCode" PropertyName="ExitCode"/>
</Gallio>
<Error Text="Tests execution failed" Condition="'$(ExitCode)' != 0" />
</Target>
<Target Name="RebuildSolution">
<Message Text="Starting to Build"/>
<MSBuild Projects="CoderForTraders.sln"
Properties="Configuration=Debug"
Targets="Rebuild" />
</Target>
</Project>
Here are the errors displayed by Team City :
error MSB4064: The "Assemblies" parameter is not supported by the "Gallio" task. Verify the parameter exists on the task, and it is a settable public instance property
error MSB4063: The "Gallio" task could not be initialized with its input parameters.
Thanks for your help
The Assemblies attribute has been renamed to Files.
Documentation here: http://www.gallio.org/api/html/T_Gallio_MSBuildTasks_Gallio.htm

Teamcity build loops on successful build

I have set up a build with Teamcity. See my build file below.
When the build is succesful and the tests pass, the build process just runs again and again indefinitely in a loop.
When the build fails, this does not happen.
I have tried to first set 60 second pause on buildtriggering, and finally disabled build triggering altogether. No difference.
What else could be the cause of this?
My MSBuild file looks like this:
<Project DefaultTargets="Build;Test" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
<PropertyGroup>
<DeployDirectory>$(MSBuildProjectDirectory)\..\bin</DeployDirectory>
<DependencyDirectory>$(MSBuildProjectDirectory)\Dependencies</DependencyDirectory>
<LinqToSqlMapFolder>$(DeployDirectory)\LinqToSql</LinqToSqlMapFolder>
<NCoverVersionForMSI>$(BUILD_NUMBER)</NCoverVersionForMSI>
<NCoverVersionPeriod>$(BUILD_NUMBER)</NCoverVersionPeriod>
</PropertyGroup>
<ItemGroup>
<ProjectFiles Include="**\*.vbproj"/>
<ConfigFiles Include="**\*.config"/>
<MapFiles Include="**\*.linqtosql.config"/>
<TestAssemblies Include="$(DeployDirectory)\*.Test.dll"/>
<Dependencies Include="$(DependencyDirectory)\**\*" />
</ItemGroup>
<Target Name="Clean">
<MSBuild Projects="#(ProjectFiles)" Targets="Clean"/>
</Target>
<Target Name="Build">
<MSBuild Projects="#(ProjectFiles)" Targets="Rebuild">
<Output TaskParameter="TargetOutputs" ItemName="BuildOutput"/>
</MSBuild>
<Copy SourceFiles="#(BuildOutput)" DestinationFolder="$(DeployDirectory)" />
<Copy SourceFiles="#(Dependencies)" DestinationFolder="$(DeployDirectory)" SkipUnchangedFiles="true" />
<Copy SourceFiles="#(ConfigFiles)" DestinationFolder="$(DeployDirectory)" SkipUnchangedFiles="true" />
<Copy SourceFiles="#(MapFiles)" DestinationFolder="$(LinqToSqlMapFolder)" SkipUnchangedFiles="true" />
</Target>
<UsingTask AssemblyFile="$(DependencyDirectory)\Gallio\Gallio.MsBuildTasks.dll" TaskName="Gallio" />
<Target Name="Test">
<Gallio IgnoreFailures="true" Files="#(TestAssemblies)">
<Output TaskParameter="ExitCode" PropertyName="ExitCode"/>
</Gallio>
</Target>
</Project>
While it appears that this wasn't your issue, I ran into a similar looping problem of my own. I had enabled labeling in the project configuration. I was also using a check for modifications every 60 seconds rule to trigger the build. As a result, upon successful build, TeamCity would tag the build in the VCS and then 60 seconds later, it would see (it's own) modification and trigger another build.
To fix our problem, we just disabled labeling because we didn't want it anyways, but you can also configure a rule to ignore particular authors such that it won't trigger on modifications it made.
It appears there were some problems with the install of teamcity, and a backup of configuration following a reinstall solved the problem with exactly same configuration and buildscript.