Skip to content

Commit

Permalink
Add the parameters to VSTestTask to allow dotnet test to work (#2438)
Browse files Browse the repository at this point in the history
* Add the msbuild parameters to VSTestTask to allow dotnet test to work

* Remove trim
  • Loading branch information
nohwnd authored May 15, 2020
1 parent cffe186 commit 59354e1
Show file tree
Hide file tree
Showing 7 changed files with 264 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,12 @@ Copyright (c) .NET Foundation. All rights reserved.
VSTestVerbosity="$(VSTestVerbosity)"
VSTestCollect="$(VSTestCollect)"
VSTestBlame="$(VSTestBlame)"
VSTestBlameCrash="$(VSTestBlameCrash)"
VSTestBlameCrashDumpType="$(VSTestBlameCrashDumpType)"
VSTestBlameCrashCollectAlways="$(VSTestBlameCrashCollectAlways)"
VSTestBlameHang="$(VSTestBlameHang)"
VSTestBlameHangDumpType="$(VSTestBlameHangDumpType)"
VSTestBlameHangTimeout="$(VSTestBlameHangTimeout)"
VSTestTraceDataCollectorDirectoryPath="$(TraceDataCollectorDirectoryPath)"
VSTestNoLogo="$(VSTestNoLogo)"
Condition="'$(IsTestProject)' == 'true'"
Expand Down
88 changes: 83 additions & 5 deletions src/Microsoft.TestPlatform.Build/Tasks/VSTestTask.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ namespace Microsoft.TestPlatform.Build.Tasks
{
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;
using Microsoft.TestPlatform.Build.Resources;
Expand Down Expand Up @@ -108,6 +109,41 @@ public string VSTestBlame
set;
}

public string VSTestBlameCrash
{
get;
set;
}

public string VSTestBlameCrashDumpType
{
get;
set;
}

public string VSTestBlameCrashCollectAlways
{
get;
set;
}

public string VSTestBlameHang
{
get;
set;
}

public string VSTestBlameHangDumpType
{
get;
set;
}
public string VSTestBlameHangTimeout
{
get;
set;
}

public string VSTestTraceDataCollectorDirectoryPath
{
get;
Expand Down Expand Up @@ -242,8 +278,8 @@ private List<string> AddArgs()
// Console logger was not specified by user, but verbosity was, hence add default console logger with verbosity as specified
if (!string.IsNullOrWhiteSpace(this.VSTestVerbosity) && !isConsoleLoggerSpecifiedByUser)
{
var normalTestLogging = new List<string>() {"n", "normal", "d", "detailed", "diag", "diagnostic"};
var quietTestLogging = new List<string>() {"q", "quiet"};
var normalTestLogging = new List<string>() { "n", "normal", "d", "detailed", "diag", "diagnostic" };
var quietTestLogging = new List<string>() { "q", "quiet" };

string vsTestVerbosity = "minimal";
if (normalTestLogging.Contains(this.VSTestVerbosity.ToLowerInvariant()))
Expand All @@ -258,9 +294,51 @@ private List<string> AddArgs()
allArgs.Add("--logger:Console;Verbosity=" + vsTestVerbosity);
}

if (!string.IsNullOrEmpty(this.VSTestBlame))
var blameCrash = !string.IsNullOrEmpty(this.VSTestBlameCrash);
var blameHang = !string.IsNullOrEmpty(this.VSTestBlameHang);
if (!string.IsNullOrEmpty(this.VSTestBlame) || blameCrash || blameHang)
{
allArgs.Add("--Blame");
var blameArgs = "--Blame";

var dumpArgs = new List<string>();
if (blameCrash || blameHang)
{
if (blameCrash)
{
dumpArgs.Add("CollectDump");
if (!string.IsNullOrEmpty(this.VSTestBlameCrashCollectAlways))
{
dumpArgs.Add($"CollectAlways={this.VSTestBlameCrashCollectAlways}");
}

if (!string.IsNullOrEmpty(this.VSTestBlameCrashDumpType))
{
dumpArgs.Add($"DumpType={this.VSTestBlameCrashDumpType}");
}
}

if (blameHang)
{
dumpArgs.Add("CollectHangDump");

if (!string.IsNullOrEmpty(this.VSTestBlameHangDumpType))
{
dumpArgs.Add($"HangDumpType={this.VSTestBlameHangDumpType}");
}

if (!string.IsNullOrEmpty(this.VSTestBlameHangTimeout))
{
dumpArgs.Add($"TestTimeout={this.VSTestBlameHangTimeout}");
}
}

if (dumpArgs.Any())
{
blameArgs += $":\"{string.Join(";", dumpArgs)}\"";
}
}

allArgs.Add(blameArgs);
}

if (this.VSTestCollect != null && this.VSTestCollect.Length > 0)
Expand Down Expand Up @@ -302,7 +380,7 @@ private List<string> AddArgs()
}
}

if(!string.IsNullOrWhiteSpace(this.VSTestNoLogo))
if (!string.IsNullOrWhiteSpace(this.VSTestNoLogo))
{
allArgs.Add("--nologo");
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

using System;
using System.Text.RegularExpressions;

namespace Microsoft.VisualStudio.TestPlatform.Utilities
{
public static class TimeSpanParser
{
static readonly Regex pattern = new Regex(@"(?<value>^\d+(?:\.\d+)?)\s*(?<suffix>ms|mil|m|h|d|s?[a-z]*)$", RegexOptions.IgnoreCase);

public static TimeSpan Parse(string time)
{
return TryParse(time, out var result) ? result : throw GetFormatException(time);
}

public static bool TryParse(string time, out TimeSpan result)
{
if (string.IsNullOrWhiteSpace(time))
{
result = TimeSpan.Zero;
return true;
}

var match = pattern.Match(time);
if (!match.Success)
{
result = TimeSpan.Zero;
return false;
}

var value = match.Groups["value"].Value;
if (!double.TryParse(value, out var number))
{
throw GetFormatException(value);
}

var suffix = match.Groups["suffix"].Value;
var c = StringComparison.OrdinalIgnoreCase;

// mil to distinguish milliseconds from minutes
// "" when there is just the raw milliseconds value
if (suffix.StartsWith("ms", c) || suffix.StartsWith("mil", c) || suffix == string.Empty)
{
result = TimeSpan.FromMilliseconds(number);
return true;
}

if (suffix.StartsWith("s", c))
{
result = TimeSpan.FromSeconds(number);
return true;
}

if (suffix.StartsWith("m", c))
{
result = TimeSpan.FromMinutes(number);
return true;
}

if (suffix.StartsWith("h", c))
{
result = TimeSpan.FromHours(number);
return true;
}

if (suffix.StartsWith("d", c))
{
result = TimeSpan.FromDays(number);
return true;
}

result = TimeSpan.Zero;
return false;
}

static FormatException GetFormatException(string value)
{
return new FormatException($"The value '{value}' is not a valid time string. Use a time string in this format 5400000 / 5400000ms / 5400s / 90m / 1.5h / 0.625d.");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -285,9 +285,9 @@ private void ValidateAndAddHangBasedProcessDumpParameters(XmlElement collectDump
{
case XmlAttribute attribute when string.Equals(attribute.Name, Constants.TestTimeout, StringComparison.OrdinalIgnoreCase):

if (!string.IsNullOrWhiteSpace(attribute.Value) && int.TryParse(attribute.Value, out int inactivityTimespanInMilliseconds))
if (!string.IsNullOrWhiteSpace(attribute.Value) && TimeSpanParser.TryParse(attribute.Value, out var timeout))
{
this.inactivityTimespan = TimeSpan.FromMilliseconds(inactivityTimespanInMilliseconds);
this.inactivityTimespan = timeout;
}
else
{
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,6 @@
<value>CollectDump was enabled but dump file was not generated.</value>
</data>
<data name="UnexpectedValueForInactivityTimespanValue" xml:space="preserve">
<value>Unexpected value {0} provided for ExpectedExecutionTimeOfLongestRunningTestInMinutes. Please provide a positive integer as input.</value>
<value>Unexpected value '{0}' provided as timeout. Please provide a value in this format: 1.5h / 90m / 5400s / 5400000ms / 5400000</value>
</data>
</root>
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

namespace TestPlatform.CoreUtilities.UnitTests
{
using Microsoft.VisualStudio.TestPlatform.Utilities;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;

[TestClass]
public class TimeSpanParserTests
{
[TestMethod]
// core use cases
[DataRow("5400000")]
[DataRow("5400000ms")]
[DataRow("5400s")]
[DataRow("90m")]
[DataRow("1.5h")]
[DataRow("0.0625d")]

// with space for parsing from xml
[DataRow("5400000 ms")]
[DataRow("5400 s")]
[DataRow("90 m")]
[DataRow("1.5 h")]
[DataRow("0.0625 d")]

// nice to haves
[DataRow("5400000MS")]
[DataRow("5400000millisecond")]
[DataRow("5400000milliseconds")]
[DataRow("5400000mil")]
[DataRow("5400000milisecond")]
[DataRow("5400000miliseconds")]
[DataRow("5400000mils")]
[DataRow("5400000millis")]
[DataRow("5400000millisecs")]
[DataRow("5400000milisecs")]
[DataRow("5400S")]
[DataRow("5400second")]
[DataRow("5400seconds")]
[DataRow("5400sec")]
[DataRow("5400secs")]
[DataRow("90M")]
[DataRow("90minute")]
[DataRow("90minutes")]
[DataRow("90min")]
[DataRow("90mins")]
[DataRow("1.5H")]
[DataRow("1.5hour")]
[DataRow("1.5hours")]
[DataRow("1.5hrs")]
[DataRow("1.5hr")]
[DataRow("0.0625D")]
[DataRow("0.0625day")]
[DataRow("0.0625days")]
public void Parses90Minutes(string time)
{
Assert.IsTrue(TimeSpanParser.TryParse(time, out var t));
Assert.AreEqual(TimeSpan.FromMinutes(90), t);
}

[TestMethod]
[DataRow(null)]
[DataRow("")]
[DataRow(" ")]
[DataRow("\n")]
[DataRow("\t")]
public void ReturnsEmptyTimeSpanOnNullOrWhiteSpace(string time)
{
Assert.IsTrue(TimeSpanParser.TryParse(time, out var t));
Assert.AreEqual(TimeSpan.Zero, t);
}

[TestMethod]
[DataRow("09808asf")]
[DataRow("asfsadf")]
[DataRow("min")]
[DataRow("ms")]
[DataRow("1.1.1")]
public void ReturnsFalseForInvalidInput(string time)
{
Assert.IsFalse(TimeSpanParser.TryParse(time, out var _));
}
}
}

0 comments on commit 59354e1

Please sign in to comment.