Skip to content

Commit

Permalink
Support wildcard in filenames (#2096)
Browse files Browse the repository at this point in the history
* Support wildcard in filenames
  • Loading branch information
vagisha-nidhi committed Aug 8, 2019
1 parent 7db63ce commit 2d36ed9
Show file tree
Hide file tree
Showing 33 changed files with 645 additions and 244 deletions.
1 change: 1 addition & 0 deletions scripts/build/TestPlatform.Dependencies.props
Expand Up @@ -19,6 +19,7 @@
<NUnitConsoleRunnerVersion>3.8.0</NUnitConsoleRunnerVersion>

<ChutzpahAdapterVersion>4.3.7</ChutzpahAdapterVersion>
<FileSystemGlobbingVersion>1.1.1</FileSystemGlobbingVersion>

<JsonNetVersion>9.0.1</JsonNetVersion>
<MoqVersion>4.7.63</MoqVersion>
Expand Down
6 changes: 3 additions & 3 deletions scripts/verify-nupkgs.ps1
Expand Up @@ -14,12 +14,12 @@ function Verify-Nuget-Packages($packageDirectory)
Write-Log "Starting Verify-Nuget-Packages."
$expectedNumOfFiles = @{"Microsoft.CodeCoverage" = 29;
"Microsoft.NET.Test.Sdk" = 13;
"Microsoft.TestPlatform" = 421;
"Microsoft.TestPlatform" = 422;
"Microsoft.TestPlatform.Build" = 19;
"Microsoft.TestPlatform.CLI" = 300;
"Microsoft.TestPlatform.CLI" = 301;
"Microsoft.TestPlatform.Extensions.TrxLogger" = 33;
"Microsoft.TestPlatform.ObjectModel" = 62;
"Microsoft.TestPlatform.Portable" = 469;
"Microsoft.TestPlatform.Portable" = 471;
"Microsoft.TestPlatform.TestHost" = 140;
"Microsoft.TestPlatform.TranslationLayer" = 121}

Expand Down
2 changes: 2 additions & 0 deletions src/package/nuspec/Microsoft.TestPlatform.Portable.nuspec
Expand Up @@ -22,6 +22,7 @@
<file src="net451\$Runtime$\datacollector.exe" target="tools\net451\datacollector.exe" />
<file src="net451\$Runtime$\datacollector.exe.config" target="tools\net451\datacollector.exe.config" />
<file src="net451\$Runtime$\Microsoft.Extensions.DependencyModel.dll" target="tools\net451\Microsoft.Extensions.DependencyModel.dll" />
<file src="net451\$Runtime$\Microsoft.Extensions.FileSystemGlobbing.dll" target="tools\net451\Microsoft.Extensions.FileSystemGlobbing.dll" />
<file src="net451\$Runtime$\Microsoft.TestPlatform.CommunicationUtilities.dll" target="tools\net451\Microsoft.TestPlatform.CommunicationUtilities.dll" />
<file src="net451\$Runtime$\Microsoft.TestPlatform.CoreUtilities.dll" target="tools\net451\Microsoft.TestPlatform.CoreUtilities.dll" />
<file src="net451\$Runtime$\Microsoft.TestPlatform.CrossPlatEngine.dll" target="tools\net451\Microsoft.TestPlatform.CrossPlatEngine.dll" />
Expand Down Expand Up @@ -224,6 +225,7 @@
<file src="netcoreapp2.1\datacollector.runtimeconfig.json" target="tools\netcoreapp2.1\datacollector.runtimeconfig.json" />
<file src="netcoreapp2.1\Microsoft.Extensions.DependencyModel.dll" target="tools\netcoreapp2.1\Microsoft.Extensions.DependencyModel.dll" />
<file src="netcoreapp2.1\System.Runtime.CompilerServices.Unsafe.dll" target="tools\netcoreapp2.1\System.Runtime.CompilerServices.Unsafe.dll" />
<file src="netcoreapp2.1\Microsoft.Extensions.FileSystemGlobbing.dll" target="tools\netcoreapp2.1\Microsoft.Extensions.FileSystemGlobbing.dll" />
<file src="netcoreapp2.1\Microsoft.TestPlatform.CommunicationUtilities.dll" target="tools\netcoreapp2.1\Microsoft.TestPlatform.CommunicationUtilities.dll" />
<file src="netcoreapp2.1\Microsoft.TestPlatform.CoreUtilities.dll" target="tools\netcoreapp2.1\Microsoft.TestPlatform.CoreUtilities.dll" />
<file src="netcoreapp2.1\Microsoft.TestPlatform.CrossPlatEngine.dll" target="tools\netcoreapp2.1\Microsoft.TestPlatform.CrossPlatEngine.dll" />
Expand Down
1 change: 1 addition & 0 deletions src/package/nuspec/Microsoft.TestPlatform.nuspec
Expand Up @@ -97,6 +97,7 @@
<file src="net451\$Runtime$\ManualTests.testtype" target="tools\net451\Common7\IDE\Extensions\TestPlatform\ManualTests.testtype" />
<file src="net451\$Runtime$\Microsoft.DiaSymReader.dll" target="tools\net451\Common7\IDE\Extensions\TestPlatform\Microsoft.DiaSymReader.dll" />
<file src="net451\$Runtime$\Microsoft.Extensions.DependencyModel.dll" target="tools\net451\Common7\IDE\Extensions\TestPlatform\Microsoft.Extensions.DependencyModel.dll" />
<file src="net451\$Runtime$\Microsoft.Extensions.FileSystemGlobbing.dll" target="tools\net451\Common7\IDE\Extensions\TestPlatform\Microsoft.Extensions.FileSystemGlobbing.dll" />
<file src="net451\$Runtime$\Microsoft.IntelliTrace.Core.dll" target="tools\net451\Common7\IDE\Extensions\TestPlatform\Microsoft.IntelliTrace.Core.dll" />
<file src="net451\$Runtime$\Microsoft.TestPlatform.CommunicationUtilities.dll" target="tools\net451\Common7\IDE\Extensions\TestPlatform\Microsoft.TestPlatform.CommunicationUtilities.dll" />
<file src="net451\$Runtime$\Microsoft.TestPlatform.CoreUtilities.dll" target="tools\net451\Common7\IDE\Extensions\TestPlatform\Microsoft.TestPlatform.CoreUtilities.dll" />
Expand Down
27 changes: 11 additions & 16 deletions src/vstest.console/CommandLine/CommandLineOptions.cs
Expand Up @@ -5,7 +5,6 @@ namespace Microsoft.VisualStudio.TestPlatform.CommandLine
{
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;

using Microsoft.VisualStudio.TestPlatform.ObjectModel;
Expand All @@ -15,6 +14,7 @@ namespace Microsoft.VisualStudio.TestPlatform.CommandLine

using CommandLineResources = Microsoft.VisualStudio.TestPlatform.CommandLine.Resources.Resources;
using System.IO;
using vstest.console.Internal;

/// <summary>
/// Provides access to the command-line options.
Expand Down Expand Up @@ -83,6 +83,7 @@ protected CommandLineOptions()
this.BatchSize = DefaultBatchSize;
this.TestStatsEventTimeout = this.DefaultRetrievalTimeout;
this.FileHelper = new FileHelper();
this.FilePatternParser = new FilePatternParser();
#if TODO
UseVsixExtensions = Utilities.GetAppSettingValue(UseVsixExtensionsKey, false);
#endif
Expand Down Expand Up @@ -238,6 +239,8 @@ public bool ShouldCollectSourceInformation

internal IFileHelper FileHelper { get; set; }

internal FilePatternParser FilePatternParser { get; set; }

/// <summary>
/// Gets or sets the target Framework version for test run.
/// </summary>
Expand Down Expand Up @@ -283,28 +286,20 @@ public void AddSource(string source)
{
throw new CommandLineException(CommandLineResources.CannotBeNullOrEmpty);
}

source = source.Trim();

// Convert the relative path to absolute path
if(!Path.IsPathRooted(source))
if (!Path.IsPathRooted(source))
{
source = Path.Combine(FileHelper.GetCurrentDirectory(), source);
}

if (!FileHelper.Exists(source))
{
throw new CommandLineException(
string.Format(CultureInfo.CurrentUICulture, CommandLineResources.TestSourceFileNotFound, source));
}

if (this.sources.Contains(source, StringComparer.OrdinalIgnoreCase))
{
throw new CommandLineException(
string.Format(CultureInfo.CurrentCulture, CommandLineResources.DuplicateSource, source));
}
// Get matching files from file pattern parser
var matchingFiles = FilePatternParser.GetMatchingFiles(source);

this.sources.Add(source);
// Add the matching files to source list
this.sources = this.sources.Union(matchingFiles).ToList();
}

#endregion
Expand Down
21 changes: 21 additions & 0 deletions src/vstest.console/Internal/ConsoleLogger.cs
Expand Up @@ -176,6 +176,7 @@ public void Initialize(TestLoggerEvents events, string testRunDirectory)
events.TestRunMessage += this.TestMessageHandler;
events.TestResult += this.TestResultHandler;
events.TestRunComplete += this.TestRunCompleteHandler;
events.TestRunStart += this.TestRunStartHandler;

// Register for the discovery events.
events.DiscoveryMessage += this.TestMessageHandler;
Expand Down Expand Up @@ -358,6 +359,26 @@ private static void DisplayFullInformation(TestResult result)

#region Event Handlers

/// <summary>
/// Called when a test run start is received
/// </summary>
private void TestRunStartHandler(object sender, TestRunStartEventArgs e)
{
ValidateArg.NotNull<object>(sender, "sender");
ValidateArg.NotNull<TestRunStartEventArgs>(e, "e");

// Print all test containers.
Output.WriteLine(string.Empty, OutputLevel.Information);
Output.WriteLine(string.Format(CultureInfo.CurrentCulture, CommandLineResources.TestSourcesDiscovered, CommandLineOptions.Instance.Sources.Count()), OutputLevel.Information);
if (verbosityLevel == Verbosity.Detailed)
{
foreach (var source in CommandLineOptions.Instance.Sources)
{
Output.WriteLine(source, OutputLevel.Information);
}
}
}

/// <summary>
/// Called when a test message is received.
/// </summary>
Expand Down
99 changes: 99 additions & 0 deletions src/vstest.console/Internal/FilePatternParser.cs
@@ -0,0 +1,99 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

namespace vstest.console.Internal
{
using Microsoft.Extensions.FileSystemGlobbing;
using Microsoft.Extensions.FileSystemGlobbing.Abstractions;
using Microsoft.VisualStudio.TestPlatform.CommandLine;
using Microsoft.VisualStudio.TestPlatform.ObjectModel;
using Microsoft.VisualStudio.TestPlatform.Utilities.Helpers;
using Microsoft.VisualStudio.TestPlatform.Utilities.Helpers.Interfaces;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;

using CommandLineResources = Microsoft.VisualStudio.TestPlatform.CommandLine.Resources.Resources;

/// <summary>
/// Class for getting matching files from wild card pattern file name
/// Microsoft.Extensions.FileSystemGlobbing methods used to get matching file names
/// </summary>
public class FilePatternParser
{
private Matcher matcher;
private IFileHelper fileHelper;
private char[] wildCardCharacters = { '*' };

public FilePatternParser()
: this(new Matcher(), new FileHelper())
{
}

internal FilePatternParser(Matcher matcher, IFileHelper fileHelper)
{
this.matcher = matcher;
this.fileHelper = fileHelper;
}

/// <summary>
/// Used to get matching files with pattern
/// </summary>
/// <returns>Returns the list of matching files</returns>
public List<string> GetMatchingFiles(string filePattern)
{
var matchingFiles = new List<string>();

// If there is no wildcard simply add the file to the list of matching files.
if(filePattern.IndexOfAny(wildCardCharacters) == -1)
{
EqtTrace.Info($"FilePatternParser: The given file {filePattern} is a full path.");

// Check if the file exists.
if (!this.fileHelper.Exists(filePattern))
{
throw new CommandLineException(
string.Format(CultureInfo.CurrentUICulture, CommandLineResources.TestSourceFileNotFound, filePattern));
}

matchingFiles.Add(filePattern);

return matchingFiles;
}

// Split the given wildcard into search directory and pattern to be searched.
var splitPattern = SplitFilePatternOnWildCard(filePattern);
EqtTrace.Info($"FilePatternParser: Matching file pattern '{splitPattern.Item2}' within directory '{splitPattern.Item1}'");

this.matcher.AddInclude(splitPattern.Item2);

// Execute the given pattern in the search directory.
var matches = this.matcher.Execute(new DirectoryInfoWrapper(new DirectoryInfo(splitPattern.Item1)));

// Add all the files to the list of matching files.
foreach (var match in matches.Files)
{
matchingFiles.Add(Path.Combine(splitPattern.Item1, match.Path));
}

return matchingFiles;
}

/// <summary>
/// Splits full pattern into search directory and pattern.
/// </summary>
private Tuple<string, string> SplitFilePatternOnWildCard(string filePattern)
{
// Split the pattern based on first wildcard character found.
var splitOnWildCardIndex = filePattern.IndexOfAny(wildCardCharacters);
var directorySeparatorIndex = filePattern.Substring(0, splitOnWildCardIndex).LastIndexOf(Path.DirectorySeparatorChar);

string searchDir = filePattern.Substring(0, directorySeparatorIndex);
string pattern = filePattern.Substring(directorySeparatorIndex + 1);

Tuple<string, string> splitPattern = new Tuple<string, string>(searchDir, pattern);
return splitPattern;
}
}
}
23 changes: 13 additions & 10 deletions src/vstest.console/Resources/Resources.Designer.cs

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

13 changes: 7 additions & 6 deletions src/vstest.console/Resources/Resources.resx
Expand Up @@ -221,9 +221,6 @@
<data name="DuplicateArgumentError" xml:space="preserve">
<value>The parameter "{0}" should be provided only once.</value>
</data>
<data name="DuplicateSource" xml:space="preserve">
<value>Duplicate source {0} specified.</value>
</data>
<data name="EnableCodeCoverageArgumentProcessorHelp" xml:space="preserve">
<value>/EnableCodeCoverage
Enables data collector 'CodeCoverage' for the test run.</value>
Expand Down Expand Up @@ -486,10 +483,11 @@
</data>
<data name="RunTestsArgumentHelp" xml:space="preserve">
<value>[TestFileNames]
Run tests from the specified files. Separate multiple test file names
by spaces.
Run tests from the specified files or wild card pattern. Separate multiple test file names or pattern
by spaces. Set console logger verbosity to detailed to view matched test files.
Examples: mytestproject.dll
mytestproject.dll myothertestproject.exe</value>
mytestproject.dll myothertestproject.exe
testproject*.dll my*project.dll</value>
</data>
<data name="SearchStringDelimiter" xml:space="preserve">
<value>,</value>
Expand Down Expand Up @@ -730,4 +728,7 @@
<data name="ProgressIndicatorString" xml:space="preserve">
<value>Test run in progress</value>
</data>
<data name="TestSourcesDiscovered" xml:space="preserve">
<value>A total of {0} test files matched the specified pattern.</value>
</data>
</root>
25 changes: 11 additions & 14 deletions src/vstest.console/Resources/xlf/Resources.cs.xlf
Expand Up @@ -20,15 +20,6 @@
</count-group>
</header>
<body>
<trans-unit id="DuplicateSource">
<source>Duplicate source {0} specified.</source>
<target state="translated">Zadal se duplicitní zdroj {0}.</target>
<note />
<alt-trans match-quality="100%" tool="BlackBox/MSR MT">
<target state-qualifier="mt-suggestion">Doppelte Quelle {0} angegeben.</target>
</alt-trans>
<note from="bb-metadata">fuzzyMatch="15" wordcount="4" adjWordcount="3.4" curWordcount="3.4"</note>
</trans-unit>
<trans-unit id="FileNotFound">
<source>'{0}' not found.</source>
<target state="translated">{0} se nenašel.</target>
Expand Down Expand Up @@ -299,16 +290,17 @@
</trans-unit>
<trans-unit id="RunTestsArgumentHelp">
<source>[TestFileNames]
Run tests from the specified files. Separate multiple test file names
by spaces.
Run tests from the specified files or wild card pattern. Separate multiple test file names or pattern
by spaces. Set console logger verbosity to detailed to view matched test files.
Examples: mytestproject.dll
mytestproject.dll myothertestproject.exe</source>
<target state="translated">[TestFileNames]
mytestproject.dll myothertestproject.exe
testproject*.dll my*project.dll</source>
<target state="new">[TestFileNames]
Spustí testy ze zadaných souborů. Pokud máte názvů souborů více, oddělte je
mezerami.
Příklad: mytestproject.dll
mytestproject.dll myothertestproject.exe</target>
<note />
<note></note>
<alt-trans match-quality="100%" tool="BlackBox/MSR MT">
<target state-qualifier="mt-suggestion">[TestFileNames]
Führen Sie Tests aus den angegebenen Dateien. Trennen Sie mehrere Test-Dateinamen
Expand Down Expand Up @@ -1653,6 +1645,11 @@
<target state="translated"> Přeskočené: {0}</target>
<note></note>
</trans-unit>
<trans-unit id="TestSourcesDiscovered">
<source>A total of {0} test files matched the specified pattern.</source>
<target state="new">A total of {0} test source files are discovered.</target>
<note></note>
</trans-unit>
</body>
</file>
</xliff>

0 comments on commit 2d36ed9

Please sign in to comment.