Results conversion produces invalid TimeSpan values

Dec 12, 2008 at 10:19 AM

Executing "C:\Program Files\nxslt\nxslt3.exe" "c:\TeamBuild\ICTeam1\Cubes-MAIN\BuildType\..\Sources\..\Binaries\nunit_results.xml" "C:\Program Files\MSBuild\IC\nunit.xslt" -o "c:\TeamBuild\ICTeam1\Cubes-MAIN\BuildType\..\Sources\..\Binaries\nunit_results.trx" > nxslt3.log

Executing "C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE\PrivateAssemblies\..\mstest.exe" /publish:http://ictfs:8080/ /publishbuild:"Cubes-MAIN_2.0.812.051" /publishresultsfile:"c:\TeamBuild\ICTeam1\Cubes-MAIN\BuildType\..\Sources\..\Binaries\nunit_results.trx" /teamproject:"ICTeam1" /platform:"Any CPU" /flavor:"Release"

Microsoft (R) Test Execution Command Line Tool Version 9.0.30729.1

Copyright (c) Microsoft Corporation. All rights reserved.

 

Waiting to publish...

The TimeSpan could not be parsed because at least one of the hours, minutes, or seconds components is outside its valid range.

The command ""C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE\PrivateAssemblies\..\mstest.exe" /publish:http://ictfs:8080/ /publishbuild:"Cubes-MAIN_2.0.812.051" /publishresultsfile:"c:\TeamBuild\ICTeam1\Cubes-MAIN\BuildType\..\Sources\..\Binaries\nunit_results.trx" /teamproject:"ICTeam1" /platform:"Any CPU" /flavor:"Release"" exited with code 1.

Dec 12, 2008 at 10:35 AM
I found the line which caused the problem:

nunit_results.xml contains:
<test-case name="Intercom.Collections.IndexableCollectionFixture.TestJoin" executed="True" success="True" time="66.156" asserts="1" />

and nunit_results.trx contains:
    <UnitTestResult startTime="2008-01-01T00:00:01.0000000+10:00" endTime="2008-01-01T00:00:02.0000000+10:00" testType="13cdc9d9-ddb5-4fa4-a97d-d965ccfc6d4b" testListId="8c84fa94-04c1-424b-9868-57a2d4851a1d" testName="TestJoin" computerName="ICTB32" duration="00:00:066.1560000" testId="07D80C0C-0C0F-1100-91c4-000000000375" executionId="07D80C0C-0C0F-1100-91c4-000000000375" outcome="Passed">
Jan 13, 2009 at 3:18 PM
anyone still alive?
Jan 19, 2009 at 11:19 AM
Edited Jan 19, 2009 at 11:19 AM
I'm having the same problem. Have you found a solution?

Thanks, Keith
Jan 30, 2009 at 2:48 PM
We're seeing the same thing, but only on test failures. Any successful test run publishes fine.
Feb 6, 2009 at 3:28 PM
Edited Feb 6, 2009 at 3:45 PM
The problem is that times > 59 seconds cause the parse error.

if you change the template line that generates the duration attribute to the following, it will compute the minutes and round the seconds.

      <xsl:attribute name="duration">
       <xsl:value-of select="concat('00:',floor(@time div 60),':',round(@time mod 60))"/>
      </xsl:attribute>

[If you just do an @time mod 60 for the seconds, you might get excessive decimal places in the milliseconds so I just dropped them.]

Now trying to figure out what to do when you have executed="False" in the results.xml and there is no time attribute so you end up with NaN in the duration value....
Feb 6, 2009 at 3:35 PM
Try this.

      <xsl:attribute name="duration">
       <xsl:choose>
        <xsl:when test="@executed='True'">
         <xsl:value-of select="concat('00:',floor(@time div 60),':',round(@time mod 60))"/>
        </xsl:when>
        <xsl:otherwise>
         <xsl:value-of select="'00:00:00'"/>
        </xsl:otherwise>
       </xsl:choose>
      </xsl:attribute>
Mar 25, 2009 at 9:34 AM
thanks! I have included the changes in my file. It would be nice someone could release a new version with these fixes, though!
Aug 20, 2009 at 11:40 AM

I have also tried the above code and ran into an issue when trying to publish the resulting file. That's why I changed it. I'll post it here in case someone else has use for it.
The above code is dangerous because it rounds after calculating mod. This can lead to durations of "00:00:60" instead of "00:01:00"! In addition to that is does not care about tests that run for more than an hour.

Basically the template calculates the hours, minutes and seconds based on the parameter and returns a string with elements of length 2 that are separated with a ":", e.g. "01:12:45" for 4365.123 seconds:

  <xsl:template name="seconds_to_hours_minutes_seconds">
    <xsl:param name="secs"/>
    <xsl:variable name="roundedSeconds">
      <xsl:value-of select="round($secs)"/>
    </xsl:variable>
    <xsl:variable name="hours">
      <xsl:value-of select="floor($roundedSeconds div 3600)"/>
    </xsl:variable>
    <xsl:variable name="minutes">
      <xsl:value-of select="floor(floor($roundedSeconds mod 3600) div 60)"/>
    </xsl:variable>
    <xsl:variable name="seconds">
      <xsl:value-of select="round($roundedSeconds mod 60)"/>
    </xsl:variable>
    <xsl:variable name="padHours">
      <xsl:value-of select="substring(concat('00', $hours),string-length($hours) + 1, 2)"/>
    </xsl:variable>
    <xsl:variable name="padMinutes">
      <xsl:value-of select="substring(concat('00', $minutes),string-length($minutes) + 1, 2)"/>
    </xsl:variable>
    <xsl:variable name="padSeconds">
      <xsl:value-of select="substring(concat('00', $seconds),string-length($seconds) + 1, 2)"/>
    </xsl:variable>
    <xsl:value-of select="concat($padHours, ':', $padMinutes, ':', $padSeconds)"/>
  </xsl:template>

The template is then called as follows:

  <xsl:attribute name="duration">
    <xsl:choose>
      <xsl:when test="@executed='True'">
        <xsl:call-template name="seconds_to_hours_minutes_seconds">
          <xsl:with-param name="secs" select="@time"/>
        </xsl:call-template>
      </xsl:when>
      <xsl:otherwise>
        <xsl:value-of select="'00:00:00'"/>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:attribute>