How do I have a meaningful error message from powershell script running in TeamCity build? - powershell

I have a TeamCity build and one of the steps is an MSBuild invokation of a .proj file:
Runner type: MSBuild
Build file path: TestProject.proj
Targets: Test
inside the .proj I have targets:
<Target Name="DeployTestService">
<Message Text="Deploying test service" />
<Exec Command="powershell -Command "& { myUsefulPsScript.ps }"" />
</Target>
<Target Name="Test">
// other stuff, then
<CallTarget Targets="DeployTestService" />
</Target>
and it works good most of the time. Yet if the powershell script fails (an unhandled exception is thrown and I can see its text in the full log) and exits with non-zero code I see the following in Teamcity build results:
Tests passed: (some number); exit code 1
and the build tree just says:
Build failure condition (1)
Process exited with code 1
[Time]Process exited with code 1
and until I get the full log I don't really know which step failed and how exactly. It's not about fixing the initial problem it's about locating the faulty step faster.
Is there a way to make Teamcity say something like "runner in step N failed with this error message [message which I see in the full log]"?

You need to use the Teamcity output format. For example, every time a new test starts, print:
##teamcity[testStarted name='foo|'s test']
This way Teamcity will know what was the last step or the last test before the app crashed and it will be able to format the output accordingly.

Related

SonarQube cannot parse TEST-report.xml which contains any failures

How to send the XML report to SonarQube? I mean, while the TEST-report.xml file contains any failures, the import operation fails. I got an error:
Running SonarQube using SonarQube Runner.17:18:18.452 ERROR: Error during SonarScanner execution
java.lang.NullPointerException
at java.text.DecimalFormat.parse(DecimalFormat.java:2030)
at java.text.NumberFormat.parse(NumberFormat.java:383)
...
The TEST-report.xml file (JUnit) contains something like:
<?xml version='1.0' encoding='UTF-8'?>
<testsuites name='X UITests.xctest' tests='12' failures='3'>
<testsuite name='X.MoreViewTests' tests='1' failures='1'>
<testcase classname='X.MoreViewTests' name='testSucceed_allAction'>
<failure message='XCTAssertTrue failed'>X UITests/Cases/Bottom Navigation/MoreViewTests.swift:212</failure>
</testcase>
</testsuite>
<testsuite name='X.OrderViewTests' tests='1' failures='0'>
<testcase classname='X.OrderViewTests' name='testSucceed_allAction' time='68.570'/>
</testsuite>
</testsuites>
But when I removed the failure lines, becomes:
<?xml version='1.0' encoding='UTF-8'?>
<testsuites name='X UITests.xctest' tests='12' failures='3'>
<testsuite name='X.OrderViewTests' tests='1' failures='0'>
<testcase classname='X.OrderViewTests' name='testSucceed_allAction' time='68.570'/>
</testsuite>
</testsuites>
It works. Any idea? Thanks.
Your XML report is invalid (doesn't meet the Surefire XML format requirements).
testsuite required parameters:
name - Full class name of the test for non-aggregated testsuite documents. Class name without the package for aggregated testsuites documents
tests - The total number of tests in the suite
failures - The total number of tests in the suite that failed. A failure is a test which the code has explicitly failed by using the mechanisms for that purpose. e.g., via an assertEquals
errors - The total number of tests in the suite that errored. An errored test is one that had an unanticipated problem. e.g., an unchecked throwable; or a problem with the implementation of the test
skipped - The total number of ignored or skipped tests in the suite
The exception starts with DecimalFormat.parse
java.lang.NullPointerException
at java.text.DecimalFormat.parse(DecimalFormat.java:2030)
at java.text.NumberFormat.parse(NumberFormat.java:383)
which means that the XML report parser couldn't parse a number. You have two missing parameters: errors and skipped. I don't know how you generate these reports (which JUnit version etc.), but probably the used tool is outdated or miss-configured.

.net core 2.1 Test Result not displaying in TFS 2018

I have .net core 2.1 project build pipeline as shown below.
I have 2 simple unit test cases which executed successfully. “.NET Core test” command executes successfully and publishes thereport.
2018-09-06T22:05:41.8494077Z
2018-09-06T22:05:42.0138714Z Passed Login_Test
2018-09-06T22:05:42.0139277Z Passed Logoff_Test
2018-09-06T22:05:42.0495295Z Results File: P:\*******2018-09-06_17_05_41.trx
2018-09-06T22:05:42.0514262Z
2018-09-06T22:05:42.0516990Z Attachments:
2018-09-06T22:05:42.0517972Z P:\*****\TestResults\329a8629-7ec1-454b-97d8-2623d29bbd0e\XXXXX 2018-09-06 17_05_39.coverage
2018-09-06T22:05:42.0518130Z
2018-09-06T22:05:42.0518516Z Total tests: 2. Passed: 2. Failed: 0. Skipped: 0.
2018-09-06T22:05:42.0519312Z Test Run Successful.
2018-09-06T22:05:42.0528123Z Test execution time: 1.9003 Seconds
2018-09-06T22:05:42.1424722Z Publishing test results to test run '90'
2018-09-06T22:05:42.1424881Z Test results remaining: 2. Test run id: 90
2018-09-06T22:05:42.1592889Z ##[section]Async Command Start: Publish test results
2018-09-06T22:05:42.2384075Z Published Test Run : http://******/_TestManagement/Runs#runId=90&_a=runCharts
2018-09-06T22:05:42.2384433Z ##[section]Async Command End: Publish test results
2018-09-06T22:05:42.2385471Z ##[section]Finishing: VsTest - testAssemblies
But I don’t see any “Test Results” under dashboard.
I included "Visual Studio Test" too, but still dont see the result in the dashboard. What am I missing here?

How to write AssemblyVersion to file using MSBuild?

FinalEdit: Despite relative directories not working in the first post, it worked if I simply removed the $(MsBuildThisFileDirectory) from the Exec line.
Edit2: I added the new targets to the DefaultTargets. Which now runs them by default. However, timing was now off with the postbuild command. I added <Exec Command="call $(MsBuildThisFileDirectory)documentation\tools\GenerateDocumentation.bat" IgnoreExitCode="false" /> to the target, but it gives an error that C:\Users\my is not a valid batch file because of the space which is actually C:\Users\my program\documentation\tools\GenerateDocumentation.bat. Putting quotes around the path gives me error MSB4025 that Name cannot begin with $.
Edit: I have tried stijn's code and it works when I explicitly run it from the command line using /t:RetrieveIdentities, but for some reason it doesn't seem to run otherwise.
I have been using Doxygen to generate documentation for my source code, however, I would like to be able to do it automatically. I wrote a simple .bat script to run Doxygen with my desired config file and compile the output into a .chm help file, but I have been unable to change the revision number automatically in Doxygen.
I was attempting to simply update the config file by adding a new line to the config file with the new revision number using MSBuild, but I have been unable to get anything to print or even create a new file when none is present.
The code I have so far I have gotten from other similar questions, but I cannot seem to get it to work.
<ItemGroup>
<MyTextFile Include="\documentation\DoxygenConfigFile.doxyconfig"/>
<MyItems Include="PROJECT_NUMBER = %(MyAssemblyIdentitiesAssemblyInfo.Version)"/>
</ItemGroup>
<Target Name="RetrieveIdentities">
<GetAssemblyIdentity AssemblyFiles="bin\foo.exe">
<Output TaskParameter="Assemblies" ItemName="MyAssemblyIdentities"/>
</GetAssemblyIdentity>
<WriteLinesToFile File="#(MyTextFile)" Lines="#(MyItems)" Overwrite="false" Encoding="UTF8" />
</Target>
Encoding is wrong, it should be UTF-8
When working with items/properties, the % and # and $ must come right before the (, no spacing in between: %(MyAssemblyIdentitiesAssemblyInfo.Version)
MyAssemblyIdentitiesAssemblyInfo does not exist, you probably meant MyAssemblyIdentities
Look up how msbuild evaluates properties and items. Basically what it will do in your script is evaluate MyItems, but at that time MyAssemblyIdentities does not yet exist so is empty, and only afterwards the GetAssemblyIdentity gets executed. Fix this by enforcing correct evaluation order: put your items inside the target and make it depend on another target that creates MyAssemblyIdentities before evaluating your items.
To summarize:
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Target Name="GetAssemblyIdentities">
<GetAssemblyIdentity AssemblyFiles="bin\foo.exe">
<Output TaskParameter="Assemblies" ItemName="MyAssemblyIdentities"/>
</GetAssemblyIdentity>
</Target>
<Target Name="RetrieveIdentities" DependsOnTargets="GetAssemblyIdentities">
<ItemGroup>
<MyTextFile Include="\documentation\DoxygenConfigFile.doxyconfig"/>
<MyItems Include="PROJECT_NUMBER = %(MyAssemblyIdentities.Version)"/>
</ItemGroup>
<WriteLinesToFile File="#(MyTextFile)" Lines="#(MyItems)"
Overwrite="false" Encoding="UTF-8" />
</Target>
</Project>
Note this will only work if you invoke msbuild in the directory where the script is, else the paths (documentation/foo) will be wrong. That could be fixed by using eg $(MsBuildThisFileDirectory)\bin\foo.exe)

Why Msbuild task failed to deploy database, but Exec work fine

I'm trying to deploy database project ( dbproj format, not new SSDT sqlproj ) inside automated build server processing. I found the following:
When I'm calling deploy with Exec task in my Msbuild script - everything working fine:
<Exec Command="$(MSBuildPath)\MSBuild.exe $(SourceFilesPath)\$(DeployDatabaseProjectName)\$(DeployDatabaseProjectName).dbproj
/t:Deploy
/p:OutputPath=$(BaseOutput)\$(DeployDatabaseProjectName)\
/p:TargetDatabase=$(DeployDatabaseName)
/p:TargetConnectionString=$(DeployDatabaseConnectionString)" />
But when I try to repeat this with Msbuild task - it behaves differently:
<MSBuild Projects="$(SourceFilesPath)\$(DeployDatabaseProjectName)\$(DeployDatabaseProjectName).dbproj"
Targets="Deploy"
Properties="Configuration=$(BuildConfiguration);
TargetDatabase=$(DeployDatabaseName);
TargetConnectionString="$(DeployDatabaseConnectionString)";
OutputPath=$(BaseOutput)\$(DeployDatabaseProjectName)\;
" />
Msbuild task broke on semicolons in DeployDatabaseConnectionString:
<DeployDatabaseConnectionString>Data Source=$(DeployDatabaseServer);Integrated Security=True;Pooling=False</DeployDatabaseConnectionString>
It will report something like this:
The name "Integrated Security" contains an invalid character " ".
But if I replace semicolons with percent encoding value - %3B - it will broke inside SqlDeployTask:
error MSB4018: The "SqlDeployTask" task failed unexpectedly.
What is the proper way to pass TargetConnectionString to Deploy target of SqlProject ?
PS: I Could live with exec task fine, but make a call to msbuild.exe inside msbuild script just hurts my inner perfectionist man.
I found the proper way - new Msbuild allow to define AdditionalProperties metadata on item. So with this feature everything work fine and have no problems with escaping\encoding
<ItemGroup>
<DbProjectToBuild Include="$(SourceFilesPath)\$(DeployDatabaseProjectName)\$(DeployDatabaseProjectName).dbproj">
<AdditionalProperties>Configuration=$(BuildConfiguration)</AdditionalProperties>
<AdditionalProperties>OutputPath=$(BaseOutput)\$(DeployDatabaseProjectName)\</AdditionalProperties>
<AdditionalProperties>TargetDatabase=$(DeployDatabaseName)</AdditionalProperties>
<AdditionalProperties>TargetConnectionString="Data Source=$(DeployDatabaseServer);Integrated Security=True;Pooling=False"</AdditionalProperties>
</DbProjectToBuild>
</ItemGroup>
<MSBuild Projects="%(DbProjectToBuild.Identity)" Targets="Build;Deploy" />

Running NUnit via NCover with NANT

My unit tests are being executed and reports written, however the coverage reports are empty. This is the Nant task I'm using:
<target name="unitTests">
<foreach item="File" property="filename">
<in>
<items>
<include name="**\UnitTestBinaries\*.UnitTests.*.dll"></include>
</items>
</in>
<do>
<exec program="${ncover-console}"
workingdir="${path::get-directory-name(filename)}"
commandline=""${nunit-console}" ${filename} /xml:${project::get-base-directory()}\_nunit_${path::get-file-name-without-extension(filename)}.xml /nologo //x ${project::get-base-directory()}\_ncover_${path::get-file-name-without-extension(filename)}.xml"
failonerror="true"
verbose="true"/>
</do>
</foreach>
</target>
Any ideas why I'm not getting coverage data? Is there any easier way to achieve this step?
Thanks for any help.
Edit:
This is an example output file:
<!-- saved from NCover 3.0 Export url='http://www.ncover.com/' -->
<coverage profilerVersion="3.3.0.6070" driverVersion="3.3.0" exportversion="3" viewdisplayname="" startTime="2011-10-31T23:27:33.3688015Z" measureTime="2011-10-31T23:27:36.1420615Z" projectName="" buildid="d3a76074-bb16-4677-8273-91c7b6552066" coveragenodeid="0" failed="false" satisfactorybranchthreshold="95" satisfactorycoveragethreshold="95" satisfactorycyclomaticcomplexitythreshold="20" satisfactoryfunctionthreshold="80" satisfactoryunvisitedsequencepoints="10" uiviewtype="TreeView" viewguid="C:\_documents\CI\_ncover_XTFL.UnitTests.Core.xml" viewfilterstyle="None" viewreportstyle="SequencePointCoveragePercentage" viewsortstyle="Name">
<rebasedpaths />
<filters />
<documents>
<doc id="0" excluded="false" url="None" cs="" csa="00000000-0000-0000-0000-000000000000" om="0" nid="0" />
</documents>
</coverage>
Edit II:
This is a sample of the buildlog output (edited for security):
<task name="ncover">
<message level="Info"><![CDATA[Command: C:\Program Files\NUnit 2.5.10\bin\net-2.0\nunit-console.exe]]></message>
<message level="Info"><![CDATA[Command Args: C:\_documents\CI\Working\UnitTestBinaries\XTFL.UnitTests.Workflow.dll /xml:C:\_documents\CI\_nunit_XTFL.UnitTests.Workflow.xml /nologo /noshadow]]></message>
<message level="Info"><![CDATA[Working Directory:]]></message>
<message level="Info"><![CDATA[Assemblies: (All Loaded Assemblies)]]></message>
<message level="Info"><![CDATA[******************* Program Output *******************]]></message>
<message level="Info"><![CDATA[ProcessModel: Default DomainUsage: Single]]></message>
<message level="Info"><![CDATA[Execution Runtime: Default]]></message>
<message level="Info"><![CDATA[..........]]></message>
<message level="Info"><![CDATA[Tests run: 10, Errors: 0, Failures: 0, Inconclusive: 0, Time: 0.9677115 seconds]]></message>
<message level="Info"><![CDATA[Not run: 0, Invalid: 0, Ignored: 0, Skipped: 0]]></message>
<message level="Info"><![CDATA[***************** End Program Output *****************]]></message>
<message level="Info"><![CDATA[Execution Time: 2.8983 s]]></message>
<message level="Info"><![CDATA[Coverage Xml: C:\_documents\CI\_ncover_XTFL.UnitTests.Workflow.xml]]></message>
<duration>3278.1105000000002</duration>
</task>
If your NCover license allows, recommend upgrading to 3.4.18.
Based on the messages alone, it looks like profiling never begins on your NUnit process.
I can't see the exact command line syntax from the NAnt task, but NCover has to start NUnit in order to profile the unit test DLL.
If NCover is starting NUnit successfully, you should see a message after the "Program Output" that says, "Process 'nunit-agent' [PID 3116] has begun profiling" before the NUnit test results, and another message after the results that "Process 'nunit-agent' [PID 3116] has finished profiling".
I remember having a similar problem. Are you placing the related .pdb files besides the assembly files? That solved it for me.
That's a good tip re: the PDB files, but even without them, you should get Branch coverage, though you won't get any Symbols.