I'm using vstest.console.exe (VS2012) to run tests with /EnableCodeCoverage, and with a .runsettings that defines a "Code Coverage" DataCollector (see CodeCoverage.runsettings in code block below).
I'm running from a powershell build script, that invokes:
vstest.console.exe /inIsolation /Logger:trx /EnableCodeCoverage /Settings:CodeCoverage.runsettings /TestCaseFilter:"TestCategory=Customers" bin\Release\Sdm.Test.IntegTest.dll
Previously this command was working, however a recent new project that integrated some old legacy code has brought in a lot of new dependencies/DLLs.
What I see is that the command just "hangs", and never seems to run any of the tests. When I use the SysInternals Process Explorer I do see some activity in vstest.executionengine.exe ... my best guess is that it is attempting to instrument a whole bunch of DLLs that my .runsettings file say should be excluded. But that's only a guess.
Any help in figuring out how to diagnose the issue would be appreciated.
CodeCoverage.runsettings below:
<?xml version="1.0" encoding="utf-8"?>
<RunSettings>
<!-- Configurations that affect the Test Framework -->
<RunConfiguration>
<!-- Path relative to solution directory -->
<ResultsDirectory>.\TestResults</ResultsDirectory>
<!-- [x86] | x64
- You can also change it from menu Test, Test Settings, Default Processor Architecture -->
<TargetPlatform>x64</TargetPlatform>
<!-- Framework35 | [Framework40] | Framework45 -->
<TargetFrameworkVersion>Framework45</TargetFrameworkVersion>
</RunConfiguration>
<!-- Configurations for data collectors -->
<DataCollectionRunSettings>
<DataCollectors>
<DataCollector friendlyName="Code Coverage" uri="datacollector://Microsoft/CodeCoverage/2.0" assemblyQualifiedName="Microsoft.VisualStudio.Coverage.DynamicCoverageDataCollector, Microsoft.VisualStudio.TraceCollector, Version=11.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<Configuration>
<CodeCoverage>
<!--
Additional paths to search for .pdb (symbol) files. Symbols must be found for modules to be instrumented.
If .pdb files are in the same folder as the .dll or .exe files, they are automatically found. Otherwise, specify them here.
Note that searching for symbols increases code coverage runtime. So keep this small and local.
-->
<!--
<SymbolSearchPaths>
<Path>C:\Users\User\Documents\Visual Studio 2012\Projects\ProjectX\bin\Debug</Path>
<Path>\\mybuildshare\builds\ProjectX</Path>
</SymbolSearchPaths>
-->
<!--
About include/exclude lists:
Empty "Include" clauses imply all; empty "Exclude" clauses imply none.
Each element in the list is a regular expression (ECMAScript syntax). See http://msdn.microsoft.com/library/2k3te2cs.aspx.
An item must first match at least one entry in the include list to be included.
Included items must then not match any entries in the exclude list to remain included.
-->
<!-- Match assembly file paths: -->
<ModulePaths>
<Include>
<ModulePath>.*\.dll$</ModulePath>
<ModulePath>.*\.exe$</ModulePath>
</Include>
<Exclude>
<ModulePath>.*CPPUnitTestFramework.*</ModulePath>
<ModulePath>.*[uU]nit[tT]est\.dll</ModulePath>
<ModulePath>.*[iI]nteg[tT]est\.dll</ModulePath>
<ModulePath>.*bomicustomautopoco\.dll</ModulePath>
<ModulePath>.*Common\.Logging\.dll</ModulePath>
<ModulePath>.*Common\.Logging\.Log4Net129.dll</ModulePath>
<ModulePath>.*fluentassertions\.dll</ModulePath>
<ModulePath>.*x509publickeyparser\.dll</ModulePath>
<ModulePath>.*EFCachingProvider\.dll</ModulePath>
<ModulePath>.*EFProviderWrapperToolkit\.dll</ModulePath>
<ModulePath>.*log4net\.dll</ModulePath>
<ModulePath>.*DatahelperDTCBridge\.dll</ModulePath>
<ModulePath>.*\.ni\.dll</ModulePath>
<ModulePath>.*mscorlib\.dll</ModulePath>
<ModulePath>.*vjslib\.dll</ModulePath>
<ModulePath>.*Microsoft\..*dll</ModulePath>
<ModulePath>.*System\.EnterpriseServices\..*dll</ModulePath>
<ModulePath>.*System\.ComponentModel\..*dll</ModulePath>
<ModulePath>.*System\.Configuration\..*dll</ModulePath>
<ModulePath>.*System\.Core\..*dll</ModulePath>
<ModulePath>.*System\.Data\..*dll</ModulePath>
<ModulePath>.*System\.Entity\..*dll</ModulePath>
<ModulePath>.*System\.IdentityModel\..*dll</ModulePath>
<ModulePath>.*System\.Numerics\..*dll</ModulePath>
<ModulePath>.*System\.Runtime\..*dll</ModulePath>
<ModulePath>.*System\.ServiceModel\..*dll</ModulePath>
<ModulePath>.*System\.Transactions\..*dll</ModulePath>
<ModulePath>.*System\.Web\..*dll</ModulePath>
<ModulePath>.*System\.Xml\..*dll</ModulePath>
<ModulePath>.*msdia110typelib_clr0200\.dll</ModulePath>
<ModulePath>.*vstest.executionengine.exe</ModulePath>
<ModulePath>.*BOMi2Service\.dll</ModulePath>
<ModulePath>.*NakedObjects\..*dll</ModulePath>
<ModulePath>.*nakedobjects\..*dll</ModulePath>
<ModulePath>.*sdm\.corejava\.dll</ModulePath>
<ModulePath>.*sdm\.datahelper\.dll</ModulePath>
<ModulePath>.*sdm\.events\.dll</ModulePath>
<ModulePath>.*Sdm\.Infrastructure\.dll</ModulePath>
<ModulePath>.*Sdm\.Infrastructure\.Attributes\.dll</ModulePath>
<ModulePath>.*sdm\.systems\.application\.dll</ModulePath>
<ModulePath>.*sdm\.systems\.distribution\.library\.dll</ModulePath>
<ModulePath>.*sdm\.systems\.distribution\.server\.dll</ModulePath>
<ModulePath>.*sdm\.objectstore\.dll</ModulePath>
<ModulePath>.*sdm\.profiler\.dll</ModulePath>
<ModulePath>.*sdm\.resultsprocessor\.dll</ModulePath>
<ModulePath>.*sdm\.systems\.reflector\.dll</ModulePath>
<ModulePath>.*Sdm\.Test\.Fixtures\.dll</ModulePath>
<ModulePath>.*sdm\.utilities\.dll</ModulePath>
<ModulePath>.*Spring\.Core\.dll</ModulePath>
<ModulePath>.*TechTalk\.SpecFlow\.dll</ModulePath>
</Exclude>
</ModulePaths>
<!-- Match fully qualified names of functions: -->
<!-- (Use "\." to delimit namespaces in C# or Visual Basic, "::" in C++.) -->
<Functions>
<Exclude>
<Function>^Fabrikam\.UnitTest\..*</Function>
<Function>^std::.*</Function>
<Function>^ATL::.*</Function>
<Function>.*::__GetTestMethodInfo.*</Function>
<Function>^Microsoft::VisualStudio::CppCodeCoverageFramework::.*</Function>
<Function>^Microsoft::VisualStudio::CppUnitTestFramework::.*</Function>
</Exclude>
</Functions>
<!-- Match attributes on any code element: -->
<Attributes>
<Exclude>
<!-- Don’t forget "Attribute" at the end of the name -->
<Attribute>^System.Diagnostics.DebuggerHiddenAttribute$</Attribute>
<Attribute>^System.Diagnostics.DebuggerNonUserCodeAttribute$</Attribute>
<Attribute>^System.Runtime.CompilerServices.CompilerGeneratedAttribute$</Attribute>
<Attribute>^System.CodeDom.Compiler.GeneratedCodeAttribute$</Attribute>
<Attribute>^System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverageAttribute$</Attribute>
</Exclude>
</Attributes>
<!-- Match the path of the source files in which each method is defined: -->
<Sources>
<Exclude>
<Source>.*\\atlmfc\\.*</Source>
<Source>.*\\vctools\\.*</Source>
<Source>.*\\public\\sdk\\.*</Source>
<Source>.*\\microsoft sdks\\.*</Source>
<Source>.*\\vc\\include\\.*</Source>
</Exclude>
</Sources>
<!-- Match the company name property in the assembly: -->
<CompanyNames>
<Exclude>
<CompanyName>.*microsoft.*</CompanyName>
</Exclude>
</CompanyNames>
<!-- Match the public key token of a signed assembly: -->
<PublicKeyTokens>
<!-- Exclude Visual Studio extensions: -->
<Exclude>
<PublicKeyToken>^B77A5C561934E089$</PublicKeyToken>
<PublicKeyToken>^B03F5F7F11D50A3A$</PublicKeyToken>
<PublicKeyToken>^31BF3856AD364E35$</PublicKeyToken>
<PublicKeyToken>^89845DCD8080CC91$</PublicKeyToken>
<PublicKeyToken>^71E9BCE111E9429C$</PublicKeyToken>
<PublicKeyToken>^8F50407C4E9E73B6$</PublicKeyToken>
<PublicKeyToken>^E361AF139669C375$</PublicKeyToken>
</Exclude>
</PublicKeyTokens>
<!-- We recommend you do not change the following values: -->
<UseVerifiableInstrumentation>True</UseVerifiableInstrumentation>
<AllowLowIntegrityProcesses>True</AllowLowIntegrityProcesses>
<CollectFromChildProcesses>True</CollectFromChildProcesses>
<CollectAspDotNet>False</CollectAspDotNet>
</CodeCoverage>
</Configuration>
</DataCollector>
</DataCollectors>
</DataCollectionRunSettings>
<!-- Adapter Specific sections -->
<!-- MSTest adapter -->
<MSTest>
<MapInconclusiveToFailed>True</MapInconclusiveToFailed>
<CaptureTraceOutput>false</CaptureTraceOutput>
<DeleteDeploymentDirectoryAfterTestRunIsComplete>False</DeleteDeploymentDirectoryAfterTestRunIsComplete>
<DeploymentEnabled>False</DeploymentEnabled>
</MSTest>
</RunSettings>
To run automated tests on an ARM architecture-based machine, you must use VSTest. Console.exe. Open Developer Command Prompt to use the command-line tool, or you can find the tool in %Program Files(x86)%\Microsoft Visual Studio\<version>\<edition>\common7\ide\CommonExtensions\<Platform | Microsoft>.
The only clue I could find that eventually led to a solution was in the Event Viewer, specifically:
.NET Runtime version 2.0.50727.5477 - Failed to CoCreate profiler.
This did ultimately led me to a fix, which is to add:
<startup useLegacyV2RuntimeActivationPolicy="true">
<supportedRuntime version="v4.0.30319" />
</startup>
to vstest.executionengine.exe.config (if running 64bit) or vstest.executionengine.x86.exe.config (if running 32bit).
This works under both VS (when spawned by devenv.exe) and from the command line (when spawned by vstest.console.exe)
Here's some notes that got me to this solution:
The new DLLs that are referenced include some pretty old code built against .NET 2.0. After a lot of searching, I've pieced together that:
It isn't possible to add this stuff to the app.config of the project containing the tests; it must go into the vstest.executionengine's config (because this is the exe actually running).
Other things I tried (none of which, ultimately, helped):
Diagnostics in the registry
Computer\HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\11.0\EnterpriseTools\QualityTools\Diagnostics
Diagnostics in the *.config files
for vstest.console.exe, vstest.discoveryengine.*.exe, vstest.executionengine.*.exe
C:\Program Files (x86)\Microsoft Visual Studio 11.0\Common7\IDE\CommonExtensions\Microsoft\TestWindow
added:
<system.diagnostics>
<switches>
<add name="TpTraceLevel" value="4" />
</switches>
</system.diagnostics>
... this causes log files to be written to %TEMP%
Red herring: Tried setting environment variables to disable
- COR_ENABLE_PROFILING=0
- COMPLUS_ProfAPI_ProfilerCompatibilitySetting=DisableV2Profiler
... in an attempt to disable the .NET 2 profiler, but did nothing.
Further investigation (using procexp.exe) showed that vstest.executionengine.exe always sets COR_ENABLE_PROFILING=1 irrespective of env var.
Moreover, COR_PROFILER's set to guid
Looking at the event viewer I saw info messages that the .NET 4 profiler was successfully started:
.NET Runtime version 4.0.30319.18063 - The profiler was loaded successfully. Profiler CLSID: '{b19f184a-cc62-4137-9a6f-af0f91730165}'. Process ID (decimal): 7700. Message ID: [0x2507].
The log files in %TEMP% also suggested no issues.
Red herring: Tried to go the other way, and enable via env vars:
COMPLUS_ProfAPI_ProfilerCompatibilitySetting=EnableV2Profiler
and also explicitly set
COR_PROFILER={B19F184A-CC62-4137-9A6F-AF0F91730165}
made no difference either.
Other red herrings
occasional messages in Event Viewer of form:
engine::notify_process_attach failed with exception: Session "MTM_7d145e0c-1c26-44b0-89e5-acc448aaae6d" does not exist.
vstest.discoveryengine.TpTrace.log... the error "AddProcess : Failed to AddProcess 5" also seems to be irrelevant.
'System.EventHandler`1[Microsoft.VisualStudio.TestTools.Execution.SessionStartEventArgs]' to 'Microsoft.VisualStudio.Coverage.DynamicCoverageDataCollector' I, 2800, 11, 2014/07/01, 10:59:11.875, PCKMA0419\vstest.discoveryengine.exe, Started Vangaurd process with command line unregister /wildcard /session:MTM_* I, 2800, 11, 2014/07/01, 10:59:11.880, PCKMA0419\vstest.discoveryengine.exe, Add Vangaurd process to the project object W, 2800, 11, 2014/07/01, 10:59:11.882, PCKMA0419\vstest.discoveryengine.exe, AddProcess : Failed to AddProcess 5 I, 2800, 11, 2014/07/01, 10:59:11.882, PCKMA0419\vstest.discoveryengine.exe, Started Vangaurd process with command line collect /session:MTM_64f33307-c936-469e-b068-482ec0ea45cf /output:"C:\Users\danhaywood\AppData\Local\Temp\MTM_64f33307-c936-469e-b068-482ec0ea45cf\c44e78af-2475-4747-99f3-e0fc3ca41d51\DanHaywood_PCKMA0419 2014-07-01 10_59_11.coverage" /config:
"C:\Users\danhaywood\AppData\Local\Temp\MTM_64f33307-c936-469e-b068-482ec0ea45cf\CodeCoverage.config" ~~~
Blogs consulted along the way:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With