diff --git a/.gitignore b/.gitignore index 9c93fa2e7..6574e1a95 100644 --- a/.gitignore +++ b/.gitignore @@ -6,9 +6,9 @@ /main/**/Debug /main/**/Release /main/**/*.user -/main/OpenCover.opensdf -/main/OpenCover.sdf -/main/OpenCover.suo +/main/**/*.opensdf +/main/**/*.sdf +/main/**/*.suo /main/Docs /main/OpenCover.Profiler/OpenCoverProfiler_i.h /main/OpenCover.Profiler/OpenCoverProfiler_i.c @@ -58,3 +58,18 @@ ReleaseNotes.txt /fakes/**/FakesAssemblies/**/* /fakes/packages !fakes/packages/repositories.config + +#Coverity +cov-int* +coverity.zip + +#SharpDevelop +/**/OpenCover/coverage.xml + +#sonarqube +/.sonarqube +!tools/sonarqube/**/* +!tools/CxxSonarQubeMsbuidRunner.exe +/main/.sonarqube +/main/.cxxresults +/tools/sonarqube/cxx-runner diff --git a/Build.bat b/Build.bat index e1cf94e3b..22395e025 100644 --- a/Build.bat +++ b/Build.bat @@ -1,2 +1,6 @@ @echo off -build\nant-0.91-alpha2\bin\nant.exe -f:"%cd%"\default.build %1 \ No newline at end of file +build\nant-0.91-alpha2\bin\nant.exe -f:"%cd%"\default.build %1 +@echo. +@echo %date% +@echo %time% +@echo. \ No newline at end of file diff --git a/README.md b/README.md index e8b2e06de..30384005b 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,14 @@ +OpenCover is a code coverage tool for .NET 2 and above (Windows OSs only - no MONO), with support for 32 and 64 processes and covers both branch and sequence points. OpenCover was started after attempts to make PartCover support 64-bit processes got just a [little too complicated](http://blog.many-monkeys.com/open_cover_first_beta_release/). + The latest releases can be downloaded from [releases](https://github.com/opencover/opencover/releases) or from the OpenCover mirror site on [bitbucket](https://bitbucket.org/shaunwilde/opencover/downloads). **Alternatively** why not try the [nuget](http://nuget.org/packages/opencover) package (this is the most popular). -[![Build status](https://img.shields.io/appveyor/ci/sawilde/opencover.svg)](https://ci.appveyor.com/project/sawilde/opencover) -[![Coverage](https://img.shields.io/coveralls/OpenCover/opencover/master.svg)](https://coveralls.io/r/OpenCover/opencover) -[![Nuget](https://img.shields.io/nuget/dt/opencover.svg)](http://nuget.org/packages/opencover) -[![Nuget](https://img.shields.io/nuget/v/opencover.svg)](http://nuget.org/packages/opencover) -[![Nuget](https://img.shields.io/nuget/vpre/opencover.svg)](http://nuget.org/packages/opencover) +| Build | [![Build status](https://img.shields.io/appveyor/ci/sawilde/opencover.svg)](https://ci.appveyor.com/project/sawilde/opencover) | +| --- | --- | +| **Coverage** | [![Coverage](https://img.shields.io/coveralls/OpenCover/opencover/master.svg)](https://coveralls.io/r/OpenCover/opencover) [![Coverity](https://scan.coverity.com/projects/3921/badge.svg)](https://scan.coverity.com/projects/opencover-opencover) | +| **Nuget** | [![Nuget](https://img.shields.io/nuget/dt/opencover.svg)](http://nuget.org/packages/opencover) [![Nuget](https://img.shields.io/nuget/v/opencover.svg)](http://nuget.org/packages/opencover) [![Nuget](https://img.shields.io/nuget/vpre/opencover.svg)](http://nuget.org/packages/opencover) | +| **Lead Times** | [![Issue Stats](http://issuestats.com/github/opencover/opencover/badge/pr)](http://issuestats.com/github/opencover/opencover) [![Issue Stats](http://issuestats.com/github/opencover/opencover/badge/issue)](http://issuestats.com/github/opencover/opencover) | + +[![Build History](https://ci-buildstats.azurewebsites.net/appveyor/chart/sawilde/opencover?branch=master&includeBuildsFromPullRequest=false)](https://ci.appveyor.com/project/sawilde/opencover) ### Master The primary repo for the project is [on GitHub](https://github.com/opencover/opencover/) and is also where the [wiki](https://github.com/OpenCover/opencover/wiki) and [issues](https://github.com/OpenCover/opencover/wiki) are managed from. @@ -12,42 +16,47 @@ The primary repo for the project is [on GitHub](https://github.com/opencover/ope ### Team communication [![Join the chat at https://gitter.im/OpenCover/opencover](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/OpenCover/opencover?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) -Team communications can also be done via [slack](http://slack.com), raise an issue to request access (include your email - obfuscated if you wish) and we will send you an invite then just visit the [team page](https://opencover.slack.com/) to sign up and join the conversation. +### WIKI +Please review the [wiki pages](https://github.com/opencover/opencover/wiki/_pages) on how to use OpenCover and take particular interest in the [Usage guide](https://github.com/opencover/opencover/wiki/Usage). + +### Issues +Please raise issues on GitHub, if you can repeat the issue then please provide a sample to make it easier for us to also repeat it and then implement a fix. Please do not hijack unrelated issues, I would rather you create a new issue than add noise to an unrelated issue. + +[Dropbox](http://db.tt/VanqFDn) is very useful for sharing files alternatively you could create a [gist](https://gist.github.com/). ### Licence All Original Software is licensed under the [MIT Licence](https://github.com/opencover/opencover/blob/master/License.md) and does not apply to any other 3rd party tools, utilities or code which may be used to develop this application. If anyone is aware of any licence violations that this code may be making please inform the developers so that the issue can be investigated and rectified. -### WIKI -Please review the [wiki pages](https://github.com/opencover/opencover/wiki/_pages) on how to use OpenCover and take particular interest in the [Usage guide](https://github.com/opencover/opencover/wiki/Usage). +### Integration Test support +OpenCover was initially created to support unit testing techniques such as TDD and tools like NUnit and MSTest. Over time others have found ways to use OpenCover for integration testing especially in tricky scenarios such as IIS and Windows Services. I'll put links here as to how people have achieved this however as they say YMMV (You Mileage May Vary). -### Service support -Note that .zip and .nuget packages (at least) will not ACL files so that a low-privilege service can execute them -- manually add the service principal with read/execute privilege to the OpenCover.Profiler.dll ACLs, either through explorer properties or by a `Get-Acl`/`Set-Acl` PowerShell script. +#### Mono support +It isn't, sorry - this tool uses the profiler API that is currently only available to .NET Frameworks running on the Windows platform. -Launching the profiling operation must be done with Administrator privilege -- this is required to even start the service, and is also needed to create the global objects and set the per-service environment that registers the COM object. Assuming that the COM objects have been pre-registered, the command line to use is like +#### IIS support +Please refer to the wiki - [IIS Support](https://github.com/OpenCover/opencover/wiki/IIS-Support) - OpenCover.console.exe -service:byname -target: -output:coverage.xml - -As this is a blocking operation, launching the coverage gathering a separate process as +#### DNX support +Please refer to the wiki - [DNX Support](https://github.com/OpenCover/opencover/wiki/DNX-Support) - start-process OpenCover.console.exe @("-target:", "-service:byName", "-output:coverage.xml") - -or equivalent in your test scripts. +#### Win8/Win10 Application Support +Not yet [implemented](https://github.com/OpenCover/opencover/issues/144). Sorry no call for it I assume the WPF way of separating model and UI has led to people getting all they need from unit-tests; I know how that is how it works for me. -The `byname` qualifier is used to prevent races if multiple services are being started concurrently by injecting the OpenCover profiling information to the service specific environment. - -### Issues -Please raise issues on GitHub, if you can repeat the issue then please provide a sample to make it easier for us to also repeat it and then implement a fix. Please do not hijack unrelated issues, I would rather you create a new issue than add noise to an unrelated issue. +#### Service support +Please refer to the wiki - [Service Support](https://github.com/OpenCover/opencover/wiki/Service-Support) -[Dropbox](http://db.tt/VanqFDn) is very useful for sharing files alternatively you could create a [gist](https://gist.github.com/). +#### Silverlight support +Please refer to the wiki - [Silverlight support](https://github.com/OpenCover/opencover/wiki/Silverlight-Support) ### Building You will need: 1. Visual Studio VS2013 (Community Edition) or later with C# and C++ 2. WiX 3.9 or later (http://wix.codeplex.com/releases/view/136891) -3. Specflow (http://visualstudiogallery.msdn.microsoft.com/9915524d-7fb0-43c3-bb3c-a8a14fbd40ee) +3. SpecFlow (http://visualstudiogallery.msdn.microsoft.com/9915524d-7fb0-43c3-bb3c-a8a14fbd40ee) +4. Windows SDK 8 and .NET Framework Tools (https://msdn.microsoft.com/en-us/windows/desktop/bg162891.aspx) All other software should be included with this repository. @@ -83,10 +92,13 @@ No Git? Don't worry you can download the latest code as a [zip file](http://gith I would like to thank * JetBrains for my Open Source [ReSharper licence](http://www.jetbrains.com/resharper/), + + * [AppVeyor](https://ci.appveyor.com/project/sawilde/opencover) for allowing free build CI services for Open Source projects, * [Coveralls](https://coveralls.io/r/OpenCover/opencover) for allowing free services for Open Source projects, -* NDepend for my [NDepend licence](http://www.ndepend.com/). +* NDepend for my [NDepend licence](http://www.ndepend.com/), * the guys at [CodeBetter](http://codebetter.com/), [Devlicious](http://devlicio.us/) and [Los Techies](http://lostechies.com/) who orignally arranged my MSDN licence all those years ago without which I doubt I'd have been able to start OpenCover (now no longer needed as we can build OpenCover using the VS2013 Community Edition), * the [NextGenUG](http://www.nxtgenug.net/) and their free swag from where I got lots of useful tools, + I'd also like to thank my family, employers, colleagues and friends for all their support. diff --git a/ReleaseNotes.tmp b/ReleaseNotes.tmp index f1750c803..d31e7541e 100644 --- a/ReleaseNotes.tmp +++ b/ReleaseNotes.tmp @@ -1,4 +1,19 @@ Version [[version]] +#528 -safemode:on to address incomplete coverage due to thread based buffers (feature) +#521 add exclude paths (feature) +#376 protect buffer allocation in multithreaded environment (fix) +#335 allow short wait timeout to be configured (feature) +#310 improved reporting - hide branches due to iterators (feature) +#352 improved reporting - hide branches due to async (feature) +#363 calculate npath comlexity (feature) +#282 exclude by process (feature) +#246 auto crash reports (feature) +#329 address ArgumentOutOfRangeException (potentially related to #274) (fix for VS2015) +#335 error on unrecognized arguments/prefixes (fix) +#328 exclude types when declaredtype is excluded (fix-feature) +#302 ignore branches in known autogenerated sequences (feature) + +Version 4.6.166 #323 push releases and candidates to github via appveyor (prj-mgmt) #315 update nuget package (fix for VS2015) #320 update packages (fix for VS2015) diff --git a/appveyor.yml b/appveyor.yml index 8b8063600..81534853f 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,16 +1,31 @@ version: 4.6.{build} -os: Unstable +skip_tags: true +os: Visual Studio 2015 shallow_clone: true environment: COVERALLS_REPO_TOKEN: - secure: BBBH4QgZXCnE6nFrux34cLWWO5GXrnMU9OZJGJdNePovxJZFzBcm3FsaESNA6zWj + secure: A5Y5pKzc8Xf2qOCrFqYP2BWQYKif/BtlesWT/uojWfOFJj5jcSOaHP+DfwVYid09 + COVERITY_TOKEN: + secure: q4yqC+X51LwoyuBcg0qvks1117rt1HwqsDErKsbLpsQ= + COVERITY_EMAIL: + secure: lgy4M/uQ9jMlxmPzTIYWVE2GggvPntq6kfpO6Z0pjAs= + SONARQUBE_USER: + secure: +9YfPnwJzGsvdyto85pHwg== + SONARQUBE_PASSWORD: + secure: Ptvd9aDNKfVhXvPpq6o1Fw== cache: - build/Version/opencover.snk - build/Version/opencover.public.snk nuget: disable_publish_on_pr: true build_script: -- build create-release +- ps: >- + if ($env:APPVEYOR_SCHEDULED_BUILD -eq "True" -or $env:APPVEYOR_REPO_BRANCH -eq "coverity") { + & .\build.bat create-coverity-release + } else { + & .\build.bat create-release + } + test: off artifacts: - path: main/bin/installer/*.msi @@ -60,4 +75,9 @@ notifications: on_build_failure: true on_build_status_changed: true on_success: -- build dogfood-release \ No newline at end of file +- ps: >- + if (-Not $env:APPVEYOR_PULL_REQUEST_NUMBER -and $env:APPVEYOR_SCHEDULED_BUILD -ne "True" -and $env:APPVEYOR_REPO_BRANCH -ne "coverity") { + & .\build.bat sonarqube-build + } else { + & .\build.bat dogfood-release + } diff --git a/build/Version/opencover.gendarme.snk b/build/Version/opencover.3rdparty.snk similarity index 100% rename from build/Version/opencover.gendarme.snk rename to build/Version/opencover.3rdparty.snk diff --git a/build/coverity/coverity_model.c b/build/coverity/coverity_model.c new file mode 100644 index 000000000..227892242 --- /dev/null +++ b/build/coverity/coverity_model.c @@ -0,0 +1,19 @@ +/* Coverity Scan model +* +* This is a modeling file for Coverity Scan. Modeling helps to avoid false +* positives. +* +* - A model file can't import any header files. +* - Therefore only some built-in primitives like int, char and void are +* available but not wchar_t, NULL etc. +* - Modeling doesn't need full structs and typedefs. Rudimentary structs +* and similar types are sufficient. +* - An uninitialized local pointer is not an error. It signifies that the +* variable could be either NULL or have some data. +* +* Coverity Scan doesn't pick up modifications automatically. The model file +* must be uploaded by an admin in the analysis settings of +* http://scan.coverity.com/projects/3921 +*/ + +/* empty modeling file for now */ \ No newline at end of file diff --git a/build/installer.build b/build/installer.build index b67a6a7f1..9ed75bcc2 100644 --- a/build/installer.build +++ b/build/installer.build @@ -21,6 +21,7 @@ + diff --git a/build/opencover.build b/build/opencover.build index f9725f7af..e3a916f43 100644 --- a/build/opencover.build +++ b/build/opencover.build @@ -1,20 +1,22 @@ + + + + + + + + + + + + + - - - - - - - - - - - - + @@ -26,40 +28,40 @@ - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + - - - - - - - - + + + + + + + + - - - - - - - - + + + + + + + + + + + + + + @@ -92,105 +100,99 @@ - - - + + + - - Output file doesn't exist in ${expected.output} - + + Output file doesn't exist in ${expected.output} - - - - - - - - - - - + + + + - - - - - - + + + + + + - + - + - - - - - - - - + + + + + + - + - + - - - + + + - - - - - - - - - - + + + + + + + + + + - - - - - - - - - + + + + + + + + + - + + + - + - - - - + + + + - + - + - + - + + + - - - - + + + + - + \ No newline at end of file diff --git a/build/version.build b/build/version.build index 7a0a9a40e..3202eb215 100644 --- a/build/version.build +++ b/build/version.build @@ -2,7 +2,7 @@ - + @@ -10,8 +10,8 @@ - + @@ -37,4 +37,4 @@ - \ No newline at end of file + diff --git a/default.build b/default.build index f4b14db91..431360c25 100644 --- a/default.build +++ b/default.build @@ -16,7 +16,18 @@ + + + + + + + + + + + @@ -50,7 +61,7 @@ tofile="${solution.folder}/bin/zip/opencover.${buildnumber.major}.${buildnumber.minor}.${buildnumber.build}.zip" /> - + @@ -58,15 +69,82 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - + @@ -95,6 +173,6 @@ - + \ No newline at end of file diff --git a/main/.nuget/NuGet.targets b/main/.nuget/NuGet.targets index 4f2439166..b483fdb96 100644 --- a/main/.nuget/NuGet.targets +++ b/main/.nuget/NuGet.targets @@ -1,5 +1,5 @@ - + $(MSBuildProjectDirectory)\..\ diff --git a/main/.nuget/packages.config b/main/.nuget/packages.config index 6a2daf408..e3ccae2b1 100644 --- a/main/.nuget/packages.config +++ b/main/.nuget/packages.config @@ -1,10 +1,12 @@  + + \ No newline at end of file diff --git a/main/OpenCover.Gendarme.Signer/App.config b/main/OpenCover.3rdParty.Signer/App.config similarity index 69% rename from main/OpenCover.Gendarme.Signer/App.config rename to main/OpenCover.3rdParty.Signer/App.config index 58262a1fd..9fc5031ad 100644 --- a/main/OpenCover.Gendarme.Signer/App.config +++ b/main/OpenCover.3rdParty.Signer/App.config @@ -1,6 +1,6 @@ - + - + diff --git a/main/OpenCover.3rdParty.Signer/CrashReporterSigner.cs b/main/OpenCover.3rdParty.Signer/CrashReporterSigner.cs new file mode 100644 index 000000000..b64bb6dd4 --- /dev/null +++ b/main/OpenCover.3rdParty.Signer/CrashReporterSigner.cs @@ -0,0 +1,51 @@ +using System.IO; +using Mono.Cecil; + +namespace OpenCover.ThirdParty.Signer +{ + internal static class CrashReporterSigner + { + + private const string Version = "1.5"; + + private static readonly string GendarmeAssemblyName = string.Format("CrashReporterdotNet.{0}", Version); + + public static readonly string TargetFolder = Path.Combine("..", "tools", "CrashReporterSigned"); + private static readonly string SourceFolder = Path.Combine("packages", GendarmeAssemblyName, "lib", "net20"); + private static readonly string StrongNameKey = Path.Combine("..", "build", "Version", "opencover.3rdparty.snk"); + + + public static bool AlreadySigned(string baseFolder) + { + var frameworkAssembly = Path.Combine(baseFolder, TargetFolder, "CrashReporter.NET.dll"); + if (File.Exists(frameworkAssembly)) + { + try + { + var frameworkDefinition = AssemblyDefinition.ReadAssembly(frameworkAssembly); + return frameworkDefinition.Name.HasPublicKey; + } + catch + { + return false; + } + } + return false; + } + + public static void SignAssembly(string baseFolder) + { + var key = Path.Combine(baseFolder, StrongNameKey); + var assembly = Path.Combine(baseFolder, SourceFolder, "CrashReporter.NET.dll"); + var newAssembly = Path.Combine(baseFolder, TargetFolder, "CrashReporter.NET.dll"); + + assembly = Path.GetFullPath(assembly); + newAssembly = Path.GetFullPath(newAssembly); + + File.Copy(assembly, newAssembly, true); + var definition = AssemblyDefinition.ReadAssembly(newAssembly); + + definition.SignFile(newAssembly, key); + } + } +} \ No newline at end of file diff --git a/main/OpenCover.Gendarme.Signer/Program.cs b/main/OpenCover.3rdParty.Signer/GendarmeSigner.cs similarity index 59% rename from main/OpenCover.Gendarme.Signer/Program.cs rename to main/OpenCover.3rdParty.Signer/GendarmeSigner.cs index 8ae24e077..cbfcaea7d 100644 --- a/main/OpenCover.Gendarme.Signer/Program.cs +++ b/main/OpenCover.3rdParty.Signer/GendarmeSigner.cs @@ -1,48 +1,22 @@ -using System; -using System.Collections.Generic; -using System.IO; +using System.IO; using System.Linq; -using System.Reflection; -using System.Text; -using System.Threading.Tasks; using Mono.Cecil; -namespace OpenCover.Gendarme.Signer +namespace OpenCover.ThirdParty.Signer { - class Program + internal static class GendarmeSigner { - private const string GendarmeVersion = "2.11.0.20121120"; - private static readonly string GendarmeAssemblyName = string.Format("Mono.Gendarme.{0}", GendarmeVersion); + private const string GendarmeVersion = "2.11.0.20121120"; - private static readonly string TargetFolder = Path.Combine("..", "tools", "GendarmeSigned"); - private static readonly string SourceFolder = Path.Combine("packages", GendarmeAssemblyName, "tools"); - private static readonly string StrongNameKey = Path.Combine("..", "build", "Version", "opencover.gendarme.snk"); - - static void Main(string[] args) - { - var assemblyLocation = Assembly.GetAssembly (typeof(Program)).Location; - var assemblyFolder = Path.GetDirectoryName(assemblyLocation); - var baseFolder = Path.Combine(assemblyFolder, "..", "..", ".."); + private static readonly string GendarmeAssemblyName = string.Format("Mono.Gendarme.{0}", GendarmeVersion); - var targetDirectory = Path.Combine (baseFolder, TargetFolder); - if (!Directory.Exists(targetDirectory)) - Directory.CreateDirectory (targetDirectory); - - if (AlreadySigned(baseFolder)) - { - Console.WriteLine("Gendarme Framework is already Signed"); - return; - } - - Console.WriteLine("Signing Gendarme Framework"); - SignGendarmeFramework(baseFolder); + public static readonly string TargetFolder = Path.Combine("..", "tools", "GendarmeSigned"); + private static readonly string SourceFolder = Path.Combine("packages", GendarmeAssemblyName, "tools"); + private static readonly string StrongNameKey = Path.Combine("..", "build", "Version", "opencover.3rdparty.snk"); - Console.WriteLine("Signing Gendarme Rules Maintainability"); - SignGendarmeRulesMaintainability(baseFolder); - } - private static bool AlreadySigned(string baseFolder) + public static bool AlreadySigned(string baseFolder) { var frameworkAssembly = Path.Combine(baseFolder, TargetFolder, "Gendarme.Framework.dll"); if (File.Exists(frameworkAssembly)) @@ -54,12 +28,13 @@ private static bool AlreadySigned(string baseFolder) } catch { + return false; } } return false; } - private static void SignGendarmeRulesMaintainability(string baseFolder) + public static void SignGendarmeRulesMaintainability(string baseFolder) { var frameworkAssembly = Path.Combine(baseFolder, TargetFolder, "Gendarme.Framework.dll"); var frameworkDefinition = AssemblyDefinition.ReadAssembly(frameworkAssembly); @@ -92,12 +67,10 @@ private static void SignGendarmeRulesMaintainability(string baseFolder) definition.MainModule.AssemblyReferences.Add(frameworkAssemblyRef); } - var keyPair = new StrongNameKeyPair(new FileStream(key, FileMode.Open, FileAccess.Read)); - definition.Write(newAssembly, new WriterParameters() { StrongNameKeyPair = keyPair }); - + definition.SignFile(newAssembly, key); } - private static void SignGendarmeFramework(string baseFolder) + public static void SignGendarmeFramework(string baseFolder) { var key = Path.Combine(baseFolder, StrongNameKey); var assembly = Path.Combine(baseFolder, SourceFolder, "Gendarme.Framework.dll"); @@ -108,8 +81,8 @@ private static void SignGendarmeFramework(string baseFolder) File.Copy(assembly, newAssembly, true); var definition = AssemblyDefinition.ReadAssembly(newAssembly); - var keyPair = new StrongNameKeyPair(new FileStream(key, FileMode.Open, FileAccess.Read)); - definition.Write(newAssembly, new WriterParameters() { StrongNameKeyPair = keyPair }); + + definition.SignFile(newAssembly, key); } } -} +} \ No newline at end of file diff --git a/main/OpenCover.Gendarme.Signer/OpenCover.Gendarme.Signer.csproj b/main/OpenCover.3rdParty.Signer/OpenCover.3rdParty.Signer.csproj similarity index 86% rename from main/OpenCover.Gendarme.Signer/OpenCover.Gendarme.Signer.csproj rename to main/OpenCover.3rdParty.Signer/OpenCover.3rdParty.Signer.csproj index 7582c303e..c1ce79b74 100644 --- a/main/OpenCover.Gendarme.Signer/OpenCover.Gendarme.Signer.csproj +++ b/main/OpenCover.3rdParty.Signer/OpenCover.3rdParty.Signer.csproj @@ -1,5 +1,5 @@  - + Debug @@ -7,9 +7,9 @@ {0B94C4BF-762B-4722-BF5A-30E7F6D2CB7E} Exe Properties - OpenCover.Gendarme.Signer - OpenCover.Gendarme.Signer - v4.0 + OpenCover.ThirdParty.Signer + OpenCover.3rdParty.Signer + v4.5.2 512 ..\ true @@ -65,8 +65,11 @@ + + + @@ -79,6 +82,10 @@ $(SolutionDir)OpenCover.Gendarme.Signer\bin\$(ConfigurationName)\OpenCover.Gendarme.Signer.exe mono OpenCover.Gendarme.Signer.exe + + cd $(SolutionDir)OpenCover.3rdParty.Signer\bin\$(ConfigurationName) +$(SolutionDir)OpenCover.3rdParty.Signer\bin\$(ConfigurationName)\OpenCover.3rdParty.Signer.exe + - - - + @@ -102,9 +101,7 @@ --> - - - + diff --git a/main/OpenCover.Installer/OpenCover.Installer.wixproj b/main/OpenCover.Installer/OpenCover.Installer.wixproj index 6961f3405..4b6f73c97 100644 --- a/main/OpenCover.Installer/OpenCover.Installer.wixproj +++ b/main/OpenCover.Installer/OpenCover.Installer.wixproj @@ -1,5 +1,5 @@  - + Debug x86 @@ -10,6 +10,8 @@ Package $(MSBuildExtensionsPath32)\Microsoft\WiX\v3.x\Wix.targets $(MSBuildExtensionsPath)\Microsoft\WiX\v3.x\Wix.targets + v4.5.2 + bin\$(Configuration)\ @@ -32,6 +34,9 @@ Version.wxi + + + diff --git a/main/OpenCover.Specs/OpenCover.Specs.csproj b/main/OpenCover.Specs/OpenCover.Specs.csproj index 6514c589d..cd887b9f6 100644 --- a/main/OpenCover.Specs/OpenCover.Specs.csproj +++ b/main/OpenCover.Specs/OpenCover.Specs.csproj @@ -1,5 +1,5 @@  - + Debug @@ -9,10 +9,11 @@ Properties OpenCover.Specs OpenCover.Specs - v4.5 + v4.5.2 512 ..\ true + true diff --git a/main/OpenCover.Specs/Steps/PackagingSteps.cs b/main/OpenCover.Specs/Steps/PackagingSteps.cs index e4358ef93..c28d65c4e 100644 --- a/main/OpenCover.Specs/Steps/PackagingSteps.cs +++ b/main/OpenCover.Specs/Steps/PackagingSteps.cs @@ -17,14 +17,16 @@ public class PackagingSteps public void DeleteZipFolder() { var folder = (string)ScenarioContext.Current["targetFolder"]; - if (Directory.Exists(folder)) Directory.Delete(folder, true); + if (Directory.Exists(folder)) + Directory.Delete(folder, true); } [AfterScenario("msitag")] public void DeleteMsiFolder() { var folder = Path.GetFullPath(Path.Combine((string)ScenarioContext.Current["targetFolder"], "..")); - if (Directory.Exists(folder)) Directory.Delete(folder, true); + if (Directory.Exists(folder)) + Directory.Delete(folder, true); } private static dynamic GetTargetPackage(string folder, string ext) @@ -43,42 +45,47 @@ private static dynamic GetTargetPackage(string folder, string ext) [Given(@"I have a valid zip package in the output folder")] public void GivenIHaveAValidZipPackageInTheOutputFolder() { - var target = GetTargetPackage("zip", "zip"); - - Assert.NotNull(target, "Could not find a valid ZIP file."); - - var targetFile = Path.GetFullPath(target.File); - var targetFolder = Path.GetFullPath(Path.Combine(Environment.CurrentDirectory, "zipFolder")); - var targetOutput = Path.GetFullPath(Path.Combine(Environment.CurrentDirectory, "zipoutput.xml")); - - if (File.Exists(targetOutput)) File.Delete(targetOutput); + string targetFolder; + string targetOutput; + var targetFile = BuildTargets("zip", "zip", "zipFolder", "zipoutput.xml", out targetFolder, out targetOutput); ScenarioContext.Current["targetZip"] = targetFile; ScenarioContext.Current["targetFolder"] = targetFolder; ScenarioContext.Current["targetOutput"] = targetOutput; } + private static dynamic BuildTargets(string folder, string ext, string dir, string xml, out string targetFolder, out string targetOutput) + { + var target = GetTargetPackage(folder, ext); + + Assert.NotNull(target, "Could not find a valid file."); + + var targetFile = Path.GetFullPath(target.File); + targetFolder = Path.GetFullPath(Path.Combine(Environment.CurrentDirectory, dir)); + targetOutput = Path.GetFullPath(Path.Combine(Environment.CurrentDirectory, xml)); + + if (File.Exists(targetOutput)) + File.Delete(targetOutput); + return targetFile; + } + [Given(@"I (?:unzip|unpack) that package into a deployment folder")] public void GivenIUnzipThatPackageIntoADeploymentFolder() { var folder = (string)ScenarioContext.Current["targetFolder"]; - if (Directory.Exists(folder)) Directory.Delete(folder, true); + if (Directory.Exists(folder)) + Directory.Delete(folder, true); var zip = new ZipFile((string)ScenarioContext.Current["targetZip"]); zip.ExtractAll(folder); + zip.Dispose(); } [Given(@"I have a valid nugetpackage in the output folder")] public void GivenIHaveAValidNugetpackageInTheOutputFolder() { - var target = GetTargetPackage("nugetpackage", "nupkg"); - - Assert.NotNull(target, "Could not find a valid NUGET file."); - - var targetFile = Path.GetFullPath(target.File); - var targetFolder = Path.GetFullPath(Path.Combine(Environment.CurrentDirectory, "nuFolder")); - var targetOutput = Path.GetFullPath(Path.Combine(Environment.CurrentDirectory, "nuoutput.xml")); - - if (File.Exists(targetOutput)) File.Delete(targetOutput); + string targetFolder; + string targetOutput; + var targetFile = BuildTargets("nugetpackage", "nupkg", "nuFolder", "nuoutput.xml", out targetFolder, out targetOutput); ScenarioContext.Current["targetZip"] = targetFile; ScenarioContext.Current["targetFolder"] = targetFolder; @@ -88,15 +95,9 @@ public void GivenIHaveAValidNugetpackageInTheOutputFolder() [Given(@"I have a valid installer in the output folder")] public void GivenIHaveAValidInstallerInTheOutputFolder() { - var target = GetTargetPackage("installer", "msi"); - - Assert.NotNull(target, "Could not find a valid MSI file."); - - var targetFile = Path.GetFullPath(target.File); - var targetFolder = Path.GetFullPath(Path.Combine(Environment.CurrentDirectory, "msiFolder")); - var targetOutput = Path.GetFullPath(Path.Combine(Environment.CurrentDirectory, "msioutput.xml")); - - if (File.Exists(targetOutput)) File.Delete(targetOutput); + string targetFolder; + string targetOutput; + var targetFile = BuildTargets("installer", "msi", "msiFolder", "msioutput.xml", out targetFolder, out targetOutput); ScenarioContext.Current["targetMsi"] = targetFile; ScenarioContext.Current["targetFolder"] = targetFolder; @@ -107,14 +108,18 @@ public void GivenIHaveAValidInstallerInTheOutputFolder() public void GivenIInstallThatPackageIntoADeploymentFolder() { var folder = (string)ScenarioContext.Current["targetFolder"]; - if (Directory.Exists(folder)) Directory.Delete(folder, true); + if (Directory.Exists(folder)) + Directory.Delete(folder, true); var installer = (string)ScenarioContext.Current["targetMsi"]; var msiExec = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.System), "msiexec.exe"); - var startInfo = new ProcessStartInfo(msiExec); - startInfo.Arguments = string.Format("/qn /a {0} TARGETDIR={1}", installer, folder); - startInfo.UseShellExecute = false; + var startInfo = new ProcessStartInfo(msiExec) + { + Arguments = string.Format("/qn /a {0} TARGETDIR={1}", installer, folder), + UseShellExecute = false + }; var process = Process.Start(startInfo); + Assert.NotNull(process); process.WaitForExit(); ScenarioContext.Current["targetFolder"] = Path.Combine(folder, "[ApplicationFolderName]"); @@ -123,7 +128,7 @@ public void GivenIInstallThatPackageIntoADeploymentFolder() [When(@"I execute the deployed OpenCover against the (x\d\d) target application")] public void WhenIExecuteTheDeployedOpenCoverAgainstTheXTargetApplication(string binFolder) { - this.WhenIExecuteTheDeployedOpenCoverAgainstTheXTargetApplicationInSubfolder(binFolder, string.Empty); + WhenIExecuteTheDeployedOpenCoverAgainstTheXTargetApplicationInSubfolder(binFolder, string.Empty); } [When(@"I execute the deployed OpenCover against the (x\d\d) target application in subfolder (.*)")] @@ -132,17 +137,21 @@ public void WhenIExecuteTheDeployedOpenCoverAgainstTheXTargetApplicationInSubfol var folder = (string)ScenarioContext.Current["targetFolder"]; var output = (string)ScenarioContext.Current["targetOutput"]; - var outputXml = string.Format(@"{0}\{1}_{2}.{3}", + var outputXml = string.Format(@"{0}\{1}_{2}{3}", Path.GetDirectoryName(output), Path.GetFileNameWithoutExtension(output), binFolder, Path.GetExtension(output)); - if (File.Exists(outputXml)) File.Delete(outputXml); + if (File.Exists(outputXml)) + File.Delete(outputXml); var openCover = Path.Combine(folder, subfolder, "OpenCover.Console.exe"); var target = Path.Combine(folder, string.Format(@"Samples\{0}\OpenCover.Simple.Target.exe", binFolder)); - var startInfo = new ProcessStartInfo(openCover); - startInfo.Arguments = string.Format(@"-register:user ""-target:{0}"" ""-output:{1}""", target, outputXml); - startInfo.UseShellExecute = false; + var startInfo = new ProcessStartInfo(openCover) + { + Arguments = string.Format(@"-register:user ""-target:{0}"" ""-output:{1}""", target, outputXml), + UseShellExecute = false + }; var process = Process.Start(startInfo); + Assert.NotNull(process); process.WaitForExit(); } @@ -156,11 +165,11 @@ public void ThenTheCoverageResultsShouldBeTheSame() var output = (string)ScenarioContext.Current["targetOutput"]; - var outputXml86 = string.Format(@"{0}\{1}_{2}.{3}", + var outputXml86 = string.Format(@"{0}\{1}_{2}{3}", Path.GetDirectoryName(output), Path.GetFileNameWithoutExtension(output), "x86", Path.GetExtension(output)); - var outputXml64 = string.Format(@"{0}\{1}_{2}.{3}", - Path.GetDirectoryName(output), Path.GetFileNameWithoutExtension(output), "x86", Path.GetExtension(output)); + var outputXml64 = string.Format(@"{0}\{1}_{2}{3}", + Path.GetDirectoryName(output), Path.GetFileNameWithoutExtension(output), "x64", Path.GetExtension(output)); Assert.IsTrue(File.Exists(outputXml86)); Assert.IsTrue(File.Exists(outputXml64)); diff --git a/main/OpenCover.Support/Fakes/FakesHelper.cs b/main/OpenCover.Support/Fakes/FakesHelper.cs index bc8506f8b..bbe70067c 100644 --- a/main/OpenCover.Support/Fakes/FakesHelper.cs +++ b/main/OpenCover.Support/Fakes/FakesHelper.cs @@ -4,7 +4,7 @@ namespace OpenCover.Support.Fakes { - public class FakesHelper + public static class FakesHelper { private const string CorEnableProfiling = "COR_ENABLE_PROFILING"; private const string CorProfiler = "COR_PROFILER"; @@ -15,13 +15,7 @@ public class FakesHelper public static void LoadOpenCoverProfilerInstead(object data) { var dict = data as IDictionary; - if (dict == null) - return; - - if (!dict.ContainsKey(CorEnableProfiling) || dict[CorEnableProfiling] != "1") - return; - - if (!dict.ContainsKey(CorProfiler) || dict[CorProfiler] == OpenCoverProfilerGuid) + if (dict == null || IsAnotherProfilerAttached(dict)) return; var currentProfiler = dict[CorProfiler]; @@ -36,6 +30,17 @@ public static void LoadOpenCoverProfilerInstead(object data) dict[CorProfiler] = OpenCoverProfilerGuid; } + private static bool IsAnotherProfilerAttached(IDictionary dict) + { + if (!dict.ContainsKey(CorEnableProfiling) || dict[CorEnableProfiling] != "1") + return true; + + if (!dict.ContainsKey(CorProfiler) || dict[CorProfiler] == OpenCoverProfilerGuid) + return true; + + return false; + } + public static void PretendWeLoadedFakesProfiler(object data) { var enabled = Environment.GetEnvironmentVariable(CorEnableProfiling); diff --git a/main/OpenCover.Support/OpenCover.Support.csproj b/main/OpenCover.Support/OpenCover.Support.csproj index 985a6cc11..4acee5f3f 100644 --- a/main/OpenCover.Support/OpenCover.Support.csproj +++ b/main/OpenCover.Support/OpenCover.Support.csproj @@ -1,5 +1,5 @@  - + Debug @@ -9,7 +9,7 @@ Properties OpenCover.Support OpenCover.Support - v4.0 + v4.5.2 512 diff --git a/main/OpenCover.Support/UITesting/UITestingHelper.cs b/main/OpenCover.Support/UITesting/UITestingHelper.cs index 19fe3f99d..8968291f5 100644 --- a/main/OpenCover.Support/UITesting/UITestingHelper.cs +++ b/main/OpenCover.Support/UITesting/UITestingHelper.cs @@ -8,12 +8,13 @@ namespace OpenCover.Support.UITesting { // ReSharper disable once InconsistentNaming - public class UITestingHelper + public static class UITestingHelper { public static void PropagateRequiredEnvironmentVariables(object data) { var pi = data as ProcessStartInfo; - if (pi == null) return; + if (pi == null) + return; foreach (var ev in from DictionaryEntry ev in Environment.GetEnvironmentVariables() where (ev.Key.ToString().StartsWith("COR", StringComparison.InvariantCultureIgnoreCase) || ev.Key.ToString().StartsWith("OPEN", StringComparison.InvariantCultureIgnoreCase) || diff --git a/main/OpenCover.Test.Profiler/OpenCover.Test.Profiler.vcxproj b/main/OpenCover.Test.Profiler/OpenCover.Test.Profiler.vcxproj index 5382d909f..ee28cfbab 100644 --- a/main/OpenCover.Test.Profiler/OpenCover.Test.Profiler.vcxproj +++ b/main/OpenCover.Test.Profiler/OpenCover.Test.Profiler.vcxproj @@ -14,6 +14,8 @@ {0FBC382D-AB5A-4C10-B573-10B4FFB02EFC} Win32Proj OpenCoverTestProfiler + v4.5.2 + @@ -43,13 +45,13 @@ true - ..\..\tools\gtest-1.6.0\include;$(IncludePath) + $(IncludePath) $(MSBuildProjectDirectory)\..\..\tools\gtest-1.6.0\msvc\gtest\$(Configuration);$(LibraryPath) $(SolutionDir)bin\$(Configuration)\ false - ..\..\tools\gtest-1.6.0\include;$(IncludePath) + $(IncludePath) $(MSBuildProjectDirectory)\..\..\tools\gtest-1.6.0\msvc\gtest\$(Configuration);$(LibraryPath) $(SolutionDir)bin\$(Configuration)\ @@ -60,11 +62,12 @@ Disabled TEST_FRAMEWORK;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions);_VARIADIC_MAX=10 MultiThreadedDebug + ..\..\tools\gtest-1.6.0\include;..\..\tools\gtest-1.6.0;%(AdditionalIncludeDirectories) Console true - gtestd.lib;gtest_maind.lib;%(AdditionalDependencies) + %(AdditionalDependencies) %(IgnoreSpecificDefaultLibraries) @@ -77,13 +80,14 @@ true TEST_FRAMEWORK;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);_VARIADIC_MAX=10 MultiThreaded + ..\..\tools\gtest-1.6.0\include;..\..\tools\gtest-1.6.0;%(AdditionalIncludeDirectories) Console true true true - gtest.lib;gtest_main.lib;%(AdditionalDependencies) + %(AdditionalDependencies) %(IgnoreSpecificDefaultLibraries) @@ -106,6 +110,9 @@ Create + + + diff --git a/main/OpenCover.Test.Profiler/OpenCover.Test.Profiler.vcxproj.filters b/main/OpenCover.Test.Profiler/OpenCover.Test.Profiler.vcxproj.filters index d4de491c6..e1ac2621a 100644 --- a/main/OpenCover.Test.Profiler/OpenCover.Test.Profiler.vcxproj.filters +++ b/main/OpenCover.Test.Profiler/OpenCover.Test.Profiler.vcxproj.filters @@ -1,5 +1,5 @@  - + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} diff --git a/main/OpenCover.Test.Profiler/app.config b/main/OpenCover.Test.Profiler/app.config new file mode 100644 index 000000000..0cc25ad48 --- /dev/null +++ b/main/OpenCover.Test.Profiler/app.config @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/main/OpenCover.Test.Profiler/stdafx.cpp b/main/OpenCover.Test.Profiler/stdafx.cpp index 15e61434f..d80d4441a 100644 --- a/main/OpenCover.Test.Profiler/stdafx.cpp +++ b/main/OpenCover.Test.Profiler/stdafx.cpp @@ -6,3 +6,15 @@ // TODO: reference any additional headers you need in STDAFX.H // and not in this file + + +// The following lines pull in the real gtest *.cc files. +#include "..\..\tools\gtest-1.6.0\src\gtest.cc" +#include "..\..\tools\gtest-1.6.0\src\gtest-death-test.cc" +#include "..\..\tools\gtest-1.6.0\src\gtest-filepath.cc" +#include "..\..\tools\gtest-1.6.0\src\gtest-port.cc" +#include "..\..\tools\gtest-1.6.0\src\gtest-printers.cc" +#include "..\..\tools\gtest-1.6.0\src\gtest-test-part.cc" +#include "..\..\tools\gtest-1.6.0\src\gtest-typed-test.cc" + +#include "..\..\tools\gtest-1.6.0\src\gtest_main.cc" \ No newline at end of file diff --git a/main/OpenCover.Test.Service/OpenCover.Test.Service.csproj b/main/OpenCover.Test.Service/OpenCover.Test.Service.csproj index 36cc46b28..daf7ffc03 100644 --- a/main/OpenCover.Test.Service/OpenCover.Test.Service.csproj +++ b/main/OpenCover.Test.Service/OpenCover.Test.Service.csproj @@ -1,5 +1,5 @@  - + Debug diff --git a/main/OpenCover.Test/App.config b/main/OpenCover.Test/App.config index 6f5c0954b..febe54331 100644 --- a/main/OpenCover.Test/App.config +++ b/main/OpenCover.Test/App.config @@ -1,11 +1,11 @@ - + -
+
- + @@ -15,9 +15,9 @@ - - + + - + diff --git a/main/OpenCover.Test/Console/OutputTests.cs b/main/OpenCover.Test/Console/OutputTests.cs new file mode 100644 index 000000000..889709cd9 --- /dev/null +++ b/main/OpenCover.Test/Console/OutputTests.cs @@ -0,0 +1,33 @@ +using System; +using System.Diagnostics; +using System.IO; +using NUnit.Framework; + +// ReSharper disable once CheckNamespace +namespace OpenCover.Test.ConsoleEx +{ + [TestFixture] + public class OutputTests + { + [Test] + public void OutputHasPreferred32BitDisabled() + { + var pi = new ProcessStartInfo() + { + FileName = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86), @"Microsoft SDKs\Windows\v8.0A\bin\NETFX 4.0 Tools\corflags.exe"), + Arguments = "OpenCover.Console.exe", + CreateNoWindow = true, + UseShellExecute = false, + RedirectStandardOutput = true + }; + + var process = Process.Start(pi); + Assert.IsNotNull(process); + var output = process.StandardOutput.ReadToEnd(); + process.WaitForExit(); + Console.WriteLine(output); + + Assert.IsTrue(output.Contains("32BITPREF : 0")); + } + } +} diff --git a/main/OpenCover.Test/Extensions/Strategy/TrackMSTestTestMethodsTests.cs b/main/OpenCover.Test/Extensions/Strategy/TrackMSTestTestMethodsTests.cs index 4f92b0fad..3c6d2571e 100644 --- a/main/OpenCover.Test/Extensions/Strategy/TrackMSTestTestMethodsTests.cs +++ b/main/OpenCover.Test/Extensions/Strategy/TrackMSTestTestMethodsTests.cs @@ -20,7 +20,7 @@ public void Can_Identify_Methods() var methods = strategy.GetTrackedMethods(def.MainModule.Types); // assert - Assert.True(methods.Any(x => x.Name.EndsWith("SimpleMsTest::BasePersistenceTests_All()"))); + Assert.True(methods.Any(x => x.FullName.EndsWith("SimpleMsTest::BasePersistenceTests_All()"))); } } } diff --git a/main/OpenCover.Test/Extensions/Strategy/TrackNUnitTestMethodsTests.cs b/main/OpenCover.Test/Extensions/Strategy/TrackNUnitTestMethodsTests.cs index 7a1a6d784..650664873 100644 --- a/main/OpenCover.Test/Extensions/Strategy/TrackNUnitTestMethodsTests.cs +++ b/main/OpenCover.Test/Extensions/Strategy/TrackNUnitTestMethodsTests.cs @@ -26,7 +26,7 @@ public void Can_Identify_Methods() var methods = strategy.GetTrackedMethods(assemblyDefinition.MainModule.Types); // assert - Assert.True(methods.Any(x => x.Name.EndsWith("SimpleNUnit::ASingleTest()"))); + Assert.True(methods.Any(x => x.FullName.EndsWith("SimpleNUnit::ASingleTest()"))); } [Test] @@ -38,7 +38,7 @@ public void TestAttribute_Is_Recognized() var methods = strategy.GetTrackedMethods(assemblyDefinition.MainModule.Types); // assert - Assert.True(methods.Any(x => x.Name.EndsWith("SimpleNUnit::ASingleTestCase()"))); + Assert.True(methods.Any(x => x.FullName.EndsWith("SimpleNUnit::ASingleTestCase()"))); } @@ -51,7 +51,7 @@ public void TheoryAttribute_Is_Recognized() var methods = strategy.GetTrackedMethods(assemblyDefinition.MainModule.Types); // assert - Assert.True(methods.Any(x => x.Name.EndsWith("SimpleNUnit::TheoryTest(System.Double)"))); + Assert.True(methods.Any(x => x.FullName.EndsWith("SimpleNUnit::TheoryTest(System.Double)"))); } @@ -64,7 +64,7 @@ public void Repeat_Is_Not_Recognized() var methods = strategy.GetTrackedMethods(assemblyDefinition.MainModule.Types); // assert - Assert.False(methods.Any(x => x.Name.EndsWith("SimpleNUnit::RepeatWithoutTest()"))); + Assert.False(methods.Any(x => x.FullName.EndsWith("SimpleNUnit::RepeatWithoutTest()"))); } } } \ No newline at end of file diff --git a/main/OpenCover.Test/Extensions/Strategy/TrackXUnitTestMethodsTests.cs b/main/OpenCover.Test/Extensions/Strategy/TrackXUnitTestMethodsTests.cs index d310dc8b7..02f7b3775 100644 --- a/main/OpenCover.Test/Extensions/Strategy/TrackXUnitTestMethodsTests.cs +++ b/main/OpenCover.Test/Extensions/Strategy/TrackXUnitTestMethodsTests.cs @@ -20,7 +20,7 @@ public void Can_Identify_Methods() var methods = strategy.GetTrackedMethods(def.MainModule.Types); // assert - Assert.True(methods.Any(x => x.Name.EndsWith("SimpleXUnit::AddAttributeExclusionFilters_Handles_Null_Elements()"))); + Assert.True(methods.Any(x => x.FullName.EndsWith("SimpleXUnit::AddAttributeExclusionFilters_Handles_Null_Elements()"))); } } } \ No newline at end of file diff --git a/main/OpenCover.Test/Framework/CommandLineParserBaseTests.cs b/main/OpenCover.Test/Framework/CommandLineParserBaseTests.cs index b7ff4c6a3..c4a30e6f9 100644 --- a/main/OpenCover.Test/Framework/CommandLineParserBaseTests.cs +++ b/main/OpenCover.Test/Framework/CommandLineParserBaseTests.cs @@ -16,6 +16,7 @@ class CommandLineParserStub : CommandLineParserBase public CommandLineParserStub(string[] arguments) : base(arguments) { + ParseArguments(); } } @@ -56,6 +57,15 @@ public void CanParseOneArgument() Assert.IsTrue(parser.HasArgument("arg")); } + [Test] + public void ThrowsExceptionWhenArgumentDoesNotBeginWithExpectedPrefix() + { + // arrange + + // act + Assert.Throws(() => new CommandLineParserStub(new[] { "/arg" })); + } + [Test] public void CanParseManyArguments() { @@ -139,7 +149,7 @@ public void GetArgumentValue_ReturnsEmpty_WhenArgumentUnknown() // arrange // act - var parser = new CommandLineParserStub(new[] { "" }); + var parser = new CommandLineParserStub(new[] { "-arg1" }); // assert Assert.AreEqual(String.Empty, parser.GetArgumentValue("xxxx")); diff --git a/main/OpenCover.Test/Framework/CommandLineParserTests.cs b/main/OpenCover.Test/Framework/CommandLineParserTests.cs index 73ab1dcfe..f72ca523a 100644 --- a/main/OpenCover.Test/Framework/CommandLineParserTests.cs +++ b/main/OpenCover.Test/Framework/CommandLineParserTests.cs @@ -1,4 +1,6 @@ using System; +using System.Collections.Generic; +using System.IO; using System.Linq; using NUnit.Framework; using OpenCover.Framework; @@ -142,6 +144,50 @@ public void HandlesTheTargetDirArgumentWithSuppliedValue() Assert.AreEqual("XXX", parser.TargetDir); } + [Test] + public void HandlesTheSearchDirsArgumentWithSuppliedValue() + { + // arrange + var parser = new CommandLineParser(new[] { "-searchdirs:XXX;YYY", RequiredArgs }); + + // act + parser.ExtractAndValidateArguments(); + + // assert + Assert.AreEqual(2, parser.SearchDirs.Length); + Assert.AreEqual("XXX", parser.SearchDirs[0]); + Assert.AreEqual("YYY", parser.SearchDirs[1]); + } + + [Test] + public void HandlesTheExcludeDirsArgumentWithSuppliedValue() + { + // arrange + var parser = new CommandLineParser(new[] { string.Format("-excludedirs:{0};{1}", Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86), Environment.GetFolderPath(Environment.SpecialFolder.CommonProgramFiles)), RequiredArgs }); + + // act + parser.ExtractAndValidateArguments(); + + // assert + Assert.AreEqual(2, parser.ExcludeDirs.Length); + Assert.IsTrue(Directory.Exists(parser.ExcludeDirs[0])); + Assert.IsTrue(Directory.Exists(parser.ExcludeDirs[1])); + } + + [Test] + public void HandlesTheExcludeDirsArgumentWithSuppliedValueRemovesDuplicates() + { + // arrange + var parser = new CommandLineParser(new[] { string.Format("-excludedirs:{0};{1}", Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86), Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86)), RequiredArgs }); + + // act + parser.ExtractAndValidateArguments(); + + // assert + Assert.AreEqual(1, parser.ExcludeDirs.Length); + Assert.IsTrue(Directory.Exists(parser.ExcludeDirs[0])); + } + [Test] public void HandlesTheTargetArgsArgumentWithSuppliedValue() { @@ -718,6 +764,7 @@ public void HandlesServiceStartTimeout(string timeAsString, int expectedMinutes, Assert.That(parser.ServiceStartTimeout, Is.EqualTo(new TimeSpan(0, expectedMinutes, expectedSeconds))); } + [Test] [TestCase("10")] [TestCase("NaNs")] [TestCase("indifferenttext")] @@ -733,5 +780,152 @@ public void InvalidServiceStartTimeoutThrowsException(string invalidTimeout) Assert.That(thrownException.Message, Contains.Substring("servicestarttimeout")); Assert.That(thrownException.Message, Contains.Substring(invalidTimeout)); } + + [Test] + [TestCase(10000, 10000)] + [TestCase(30000, 30000)] + [TestCase(60000, 60000)] + [TestCase(100, 10000)] + [TestCase(70000, 60000)] + public void HandlesCommunicationTimeout(int suppliedMillisconds, int expectedMiliseconds) + { + // arrange + var parser = new CommandLineParser(new[] { string.Format("-communicationtimeout:{0}", suppliedMillisconds), RequiredArgs }); + + // act + parser.ExtractAndValidateArguments(); + + // assert + Assert.That(parser.CommunicationTimeout, Is.EqualTo(expectedMiliseconds)); + + } + + [Test] + [TestCase("NaNs")] + [TestCase("indifferenttext")] + public void InvalidServiceCommunicationTimeoutThrowsException(string invalidTimeout) + { + // arrange + var parser = new CommandLineParser(new[] { "-communicationtimeout:" + invalidTimeout, RequiredArgs }); + + // act + var thrownException = Assert.Throws(parser.ExtractAndValidateArguments); + + // assert + Assert.That(thrownException.Message, Contains.Substring("communication timeout")); + Assert.That(thrownException.Message, Contains.Substring(invalidTimeout)); + } + + [Test] + [TestCase("-[*]* -[*]* -[*]*", + "-[*]*", + "-[*]*", + "-[*]*")] + [TestCase("-[System*]* -[Xyz*]* -[Zap*]*", + "-[System*]*", + "-[Xyz*]*", + "-[Zap*]*")] + [TestCase("-[System*]* -[Xyz*]* -[Zap*]*", + "-[System*]*", + "-[Xyz*]*", + "-[Zap*]*")] + [TestCase(" -[System*]* -[Xyz*]* -[Zap*]*", + "-[System*]*", + "-[Xyz*]*", + "-[Zap*]*")] + [TestCase(" -[System*]* -[Xyz*]* -[Zap*]*\"", + "-[System*]*", + "-[Xyz*]*", + "-[Zap*]*")] + + // accepts filters not separated by single space + [TestCase("-[System*]*-[Xyz*]*-[Zap*]*\"", + "-[System*]*", + "-[Xyz*]*", + "-[Zap*]*")] + [TestCase(" -[System*]*-[Xyz*]* -[Zap*]* \" ", + "-[System*]*", + "-[Xyz*]*", + "-[Zap*]*")] + [TestCase(" -<>[]*+[Xyz*]-[Zap*]* \" ", + "-<>[]*", + "+[Xyz*]", + "-[Zap*]*")] + [TestCase(" -<>[]+[Xyz*]-[Zap*]* \" ", + "-<>[]", + "+[Xyz*]", + "-[Zap*]*")] + [TestCase(" \"-<>[]+[]abc*\"-[]\" ", + "-<>[]", + "+[]abc*", + "-[]")] + [TestCase("+<>[]+[]abc*\"-[]", + "+<>[]", + "+[]abc*", + "-[]")] + + // accepts any character sequence between <> or [] (for regex expression) + [TestCase("+<()>[()]+[()]abc*\"-[]", + "+<()>[()]", + "+[()]abc*", + "-[]")] + [TestCase(@" +<([\[{}-<(>)>mx<)>[[[[+[]]+[]abc*""-<(nunit-agent.*)>[([])]", + @"+<([\[{}-<(>)>mx<)>[[[[+[]]", + "+[]abc*", + "-<(nunit-agent.*)>[([])]")] + [TestCase(@" ""+<([\[{ }]"" -<(>)>mx<)>[[[[+[]abc.*""+[]abc*""-<(nunit-agent.*)>[([])]", + @"+<([\[{ }]"" -<(>)>mx<)>[[[[+[]abc.*", + "+[]abc*", + "-<(nunit-agent.*)>[([])]")] + + public void FilterParsing_NonGreedy(string filterArg, string filter0, string filter1, string filter2) + { + var parser = new CommandLineParser(GetFilter(filterArg, false).ToArray()).Do(_ => _.ExtractAndValidateArguments()); + + // assert + Assert.AreEqual(3, parser.Filters.Count, filterArg); + Assert.AreEqual (filter0, parser.Filters[0], parser.Filters[0]); + Assert.AreEqual (filter1, parser.Filters[1], parser.Filters[1]); + Assert.AreEqual (filter2, parser.Filters[2], parser.Filters[2]); + } + + static IEnumerable GetFilter(string filterArg, bool defaultFilters) + { + yield return "-target:t"; + yield return string.Format("-filter:\"{0}\"", filterArg); + if (!defaultFilters) yield return "-nodefaultfilters"; + } + + [Test] + [TestCase("wibble")] + [TestCase("argh")] + public void InvalidSafeModeThrowsException(string invalidSafeMode) + { + // arrange + var parser = new CommandLineParser(new[] { "-safemode:" + invalidSafeMode, RequiredArgs }); + + // act + var thrownException = Assert.Throws(parser.ExtractAndValidateArguments); + + // assert + Assert.That(thrownException.Message, Contains.Substring("safemode")); + } + + [Test] + [TestCase("no", false)] + [TestCase("yes", true)] + [TestCase("on", true)] + [TestCase("off", false)] + public void ValidSafeModeIsParsedCorrectly(string validSafeMode, bool expectedValue) + { + // arrange + var parser = new CommandLineParser(new[] { "-safemode:" + validSafeMode, RequiredArgs }); + + // act + Assert.DoesNotThrow(parser.ExtractAndValidateArguments); + + // assert + Assert.AreEqual(expectedValue, parser.SafeMode); + } } } diff --git a/main/OpenCover.Test/Framework/Communication/CommunicationManagerTests.cs b/main/OpenCover.Test/Framework/Communication/CommunicationManagerTests.cs index b187b61b6..0d3697f4b 100644 --- a/main/OpenCover.Test/Framework/Communication/CommunicationManagerTests.cs +++ b/main/OpenCover.Test/Framework/Communication/CommunicationManagerTests.cs @@ -33,23 +33,24 @@ public void When_Complete_Casacde_Call() public void HandleMemoryBlock_Returns_Block_Informs_Profiler_When_Read() { // arrange - var wait = new AutoResetEvent(false); - using (var mcb = new MemoryManager.ManagedMemoryBlock("Local", "XYZ", 100, 0, Enumerable.Empty())) - { - // act - byte[] data = null; - mcb.StreamAccessorResults.Seek(0, SeekOrigin.Begin); - mcb.StreamAccessorResults.Write(BitConverter.GetBytes(24), 0, 4); // count + 24 entries == 100 bytes - ThreadPool.QueueUserWorkItem(state => - { - data = Instance.HandleMemoryBlock(mcb); - wait.Set(); - }); - wait.WaitOne(); - - // assert - Assert.IsTrue(mcb.ResultsHaveBeenReceived.WaitOne(new TimeSpan(0, 0, 0, 4)), "Profiler wasn't signalled"); - Assert.AreEqual(100, data.Count()); + using (var wait = new AutoResetEvent(false)) { + using (var mcb = new MemoryManager.ManagedMemoryBlock("Local", "XYZ", 100, 0, Enumerable.Empty())) + { + // act + byte[] data = null; + mcb.StreamAccessorResults.Seek(0, SeekOrigin.Begin); + mcb.StreamAccessorResults.Write(BitConverter.GetBytes(24), 0, 4); // count + 24 entries == 100 bytes + ThreadPool.QueueUserWorkItem(state => + { + data = Instance.HandleMemoryBlock(mcb); + wait.Set(); + }); + wait.WaitOne(); + + // assert + Assert.IsTrue(mcb.ResultsHaveBeenReceived.WaitOne(new TimeSpan(0, 0, 0, 4)), "Profiler wasn't signalled"); + Assert.AreEqual(100, data.Count()); + } } } @@ -63,7 +64,7 @@ public void HandleCommunicationBlock_Informs_Profiler_When_Data_Is_Ready() // act ThreadPool.QueueUserWorkItem(state => { - Instance.HandleCommunicationBlock(mcb, (block, memoryBlock) => { }); + Instance.HandleCommunicationBlock(mcb, block => { }); wait.Set(); }); @@ -74,7 +75,7 @@ public void HandleCommunicationBlock_Informs_Profiler_When_Data_Is_Ready() Container.GetMock().Verify(x => x.StandardMessage(It.IsAny(), mcb, It.IsAny>(), - It.IsAny>()), Times.Once()); + It.IsAny>()), Times.Once()); } } diff --git a/main/OpenCover.Test/Framework/Communication/MessageHandlerTests.cs b/main/OpenCover.Test/Framework/Communication/MessageHandlerTests.cs index bfde65227..d073d7d08 100644 --- a/main/OpenCover.Test/Framework/Communication/MessageHandlerTests.cs +++ b/main/OpenCover.Test/Framework/Communication/MessageHandlerTests.cs @@ -45,11 +45,11 @@ public void Handles_MSG_TrackAssembly() .Returns(new MSG_TrackAssembly_Request()); // act - Instance.StandardMessage(MSG_Type.MSG_TrackAssembly, _mockCommunicationBlock.Object, (i, block) => { }, (block, memoryBlock) => { }); + Instance.StandardMessage(MSG_Type.MSG_TrackAssembly, _mockCommunicationBlock.Object, (i, block) => { }, block => { }); // assert Container.GetMock() - .Verify(x=>x.TrackAssembly(It.IsAny(), It.IsAny()), Times.Once()); + .Verify(x => x.TrackAssembly(It.IsAny(), It.IsAny(), It.IsAny()), Times.Once()); } @@ -62,7 +62,7 @@ public void Handles_MSG_TrackMethod() .Returns(new MSG_TrackMethod_Request()); // act - Instance.StandardMessage(MSG_Type.MSG_TrackMethod, _mockCommunicationBlock.Object, (i, block) => { }, (block, memoryBlock) => { }); + Instance.StandardMessage(MSG_Type.MSG_TrackMethod, _mockCommunicationBlock.Object, (i, block) => { }, block => { }); // assert uint uniqueId; @@ -78,18 +78,17 @@ public void Handles_MSG_AllocateMemoryBuffer() Container.GetMock() .Setup(x => x.PtrToStructure(It.IsAny())) .Returns(new MSG_AllocateBuffer_Request()); - + uint bufferId; Container.GetMock() - .Setup(x => x.AllocateMemoryBuffer(It.IsAny(), It.IsAny())) - .Returns(new Tuple(null, null)); + .Setup(x => x.AllocateMemoryBuffer(It.IsAny(), out bufferId)) + .Returns(new ManagedBufferBlock()); // act - Instance.StandardMessage(MSG_Type.MSG_AllocateMemoryBuffer, _mockCommunicationBlock.Object, (i, block) => { }, (block, memoryBlock) => { }); + Instance.StandardMessage(MSG_Type.MSG_AllocateMemoryBuffer, _mockCommunicationBlock.Object, (i, block) => { }, block => { }); // assert - uint uniqueId; Container.GetMock() - .Verify(x => x.AllocateMemoryBuffer(It.IsAny(), It.IsAny()), Times.Once()); + .Verify(x => x.AllocateMemoryBuffer(It.IsAny(), out bufferId), Times.Once()); } @@ -102,12 +101,12 @@ public void Handles_MSG_GetSequencePoints() .Returns(new MSG_GetSequencePoints_Request()); // act - Instance.StandardMessage(MSG_Type.MSG_GetSequencePoints, _mockCommunicationBlock.Object, (i, block) => { }, (block, memoryBlock) => { }); + Instance.StandardMessage(MSG_Type.MSG_GetSequencePoints, _mockCommunicationBlock.Object, (i, block) => { }, block => { }); // assert InstrumentationPoint[] points; Container.GetMock() - .Verify(x => x.GetSequencePoints(It.IsAny(), It.IsAny(), It.IsAny(), out points), Times.Once()); + .Verify(x => x.GetSequencePoints(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), out points), Times.Once()); } @@ -120,12 +119,13 @@ public void Handles_MSG_GetSequencePoints_Small() .Returns(new MSG_GetSequencePoints_Request()); var points = Enumerable.Repeat(new InstrumentationPoint(), 2).ToArray(); + Assert.NotNull(points); Container.GetMock() - .Setup(x => x.GetSequencePoints(It.IsAny(), It.IsAny(), It.IsAny(), out points)); + .Setup(x => x.GetSequencePoints(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), out points)); var chunked = false; // act - Instance.StandardMessage(MSG_Type.MSG_GetSequencePoints, _mockCommunicationBlock.Object, (i, block) => { chunked = true; }, (block, memoryBlock) => { }); + Instance.StandardMessage(MSG_Type.MSG_GetSequencePoints, _mockCommunicationBlock.Object, (i, block) => { chunked = true; }, block => { }); // assert Container.GetMock() @@ -142,19 +142,20 @@ public void Handles_MSG_GetSequencePoints_Large_StartsToChunk() .Setup(x => x.PtrToStructure(It.IsAny())) .Returns(new MSG_GetSequencePoints_Request()); - var points = Enumerable.Repeat(new InstrumentationPoint(), 100).ToArray(); + var points = Enumerable.Repeat(new InstrumentationPoint(), 10000).ToArray(); + Assert.NotNull(points); //var points = new[] { new SequencePoint(), new SequencePoint(), new SequencePoint(), new SequencePoint(), new SequencePoint(), new SequencePoint() }; Container.GetMock() - .Setup(x => x.GetSequencePoints(It.IsAny(), It.IsAny(), It.IsAny(), out points)); + .Setup(x => x.GetSequencePoints(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), out points)); var chunked = false; // act - Instance.StandardMessage(MSG_Type.MSG_GetSequencePoints, _mockCommunicationBlock.Object, (i, block) => { chunked = true; }, (block, memoryBlock) => { }); + Instance.StandardMessage(MSG_Type.MSG_GetSequencePoints, _mockCommunicationBlock.Object, (i, block) => { chunked = true; }, block => { }); // assert Container.GetMock() - .Verify(x => x.StructureToPtr(It.IsAny(), It.IsAny(), It.IsAny()), Times.Exactly(100)); + .Verify(x => x.StructureToPtr(It.IsAny(), It.IsAny(), It.IsAny()), Times.Exactly(10000)); Assert.True(chunked); @@ -169,12 +170,12 @@ public void Handles_MSG_GetBranchPoints() .Returns(new MSG_GetBranchPoints_Request()); // act - Instance.StandardMessage(MSG_Type.MSG_GetBranchPoints, _mockCommunicationBlock.Object, (i, block) => { }, (block, memoryBlock) => { }); + Instance.StandardMessage(MSG_Type.MSG_GetBranchPoints, _mockCommunicationBlock.Object, (i, block) => { }, block => { }); // assert BranchPoint[] points; Container.GetMock() - .Verify(x => x.GetBranchPoints(It.IsAny(), It.IsAny(), It.IsAny(), out points), Times.Once()); + .Verify(x => x.GetBranchPoints(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), out points), Times.Once()); } @@ -187,12 +188,14 @@ public void Handles_MSG_GetBranchPoints_Small() .Returns(new MSG_GetBranchPoints_Request()); var points = Enumerable.Repeat(new BranchPoint(), 2).ToArray(); + Assert.NotNull(points); + Container.GetMock() - .Setup(x => x.GetBranchPoints(It.IsAny(), It.IsAny(), It.IsAny(), out points)); + .Setup(x => x.GetBranchPoints(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), out points)); var chunked = false; // act - Instance.StandardMessage(MSG_Type.MSG_GetBranchPoints, _mockCommunicationBlock.Object, (i, block) => { chunked = true; }, (block, memoryBlock) => { }); + Instance.StandardMessage(MSG_Type.MSG_GetBranchPoints, _mockCommunicationBlock.Object, (i, block) => { chunked = true; }, block => { }); // assert Container.GetMock() @@ -209,18 +212,19 @@ public void Handles_MSG_GetBranchPoints_Large_StartsToChunk() .Setup(x => x.PtrToStructure(It.IsAny())) .Returns(new MSG_GetBranchPoints_Request()); - var points = Enumerable.Repeat(new BranchPoint(), 100).ToArray(); + var points = Enumerable.Repeat(new BranchPoint(), 10000).ToArray(); + Assert.NotNull(points); Container.GetMock() - .Setup(x => x.GetBranchPoints(It.IsAny(), It.IsAny(), It.IsAny(), out points)); + .Setup(x => x.GetBranchPoints(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), out points)); var chunked = false; // act - Instance.StandardMessage(MSG_Type.MSG_GetBranchPoints, _mockCommunicationBlock.Object, (i, block) => { chunked = true; }, (block, memoryBlock) => { }); + Instance.StandardMessage(MSG_Type.MSG_GetBranchPoints, _mockCommunicationBlock.Object, (i, block) => { chunked = true; }, block => { }); // assert Container.GetMock() - .Verify(x => x.StructureToPtr(It.IsAny(), It.IsAny(), It.IsAny()), Times.Exactly(100)); + .Verify(x => x.StructureToPtr(It.IsAny(), It.IsAny(), It.IsAny()), Times.Exactly(10000)); Assert.True(chunked); } @@ -230,6 +234,9 @@ public void ReadSize_Returns() { var size = Instance.ReadSize; Assert.AreNotEqual(0, size); + size = Instance.ReadSize; // cover cached size by reading twice + Assert.AreNotEqual(0, size); + } [Test] @@ -241,5 +248,258 @@ public void WhenComplete_Stop_ProfilerCommunication() // assert Container.GetMock().Verify(x => x.Stopping(), Times.Once()); } + + [Test] + public void Handles_MSG_CloseChannel_ReturnsDoneAsTrue() + { + // arrange + Container.GetMock() + .Setup(x => x.PtrToStructure(It.IsAny())) + .Returns(new MSG_CloseChannel_Request()); + + var response = new MSG_CloseChannel_Response { done = false }; + Container.GetMock() + .Setup(x => x.StructureToPtr(It.IsAny(), It.IsAny(), It.IsAny())) + .Callback((msg, ptr, b) => { response = msg; }); + + // act + Instance.StandardMessage(MSG_Type.MSG_CloseChannel, _mockCommunicationBlock.Object, + (i, block) => { }, + block => { }); + + // assert + Assert.AreEqual(true, response.done); + Container.GetMock() + .Verify(x => x.DeactivateMemoryBuffer(It.IsAny()), Times.Once); + + } + + [Test] + public void ExceptionDuring_MSG_GetSequencePoints_ReturnsLastBlockAsEmpty() + { + // arrange + Container.GetMock() + .Setup(x => x.PtrToStructure(It.IsAny())) + .Returns(new MSG_GetSequencePoints_Request()); + + var points = Enumerable.Repeat(new SequencePoint(), 100).ToArray(); + Assert.NotNull(points); + + Container.GetMock() + .Setup(x => x.GetSequencePoints(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), out points)) + .Throws(); + + var response = new MSG_GetSequencePoints_Response{count = -1, more = true}; + Container.GetMock() + .Setup(x => x.StructureToPtr(It.IsAny(), It.IsAny(), It.IsAny())) + .Callback((msg, ptr, b) => { response = msg; }); + + var chunked = false; + + // act + Instance.StandardMessage(MSG_Type.MSG_GetSequencePoints, _mockCommunicationBlock.Object, + (i, block) => { chunked = true; }, + block => { }); + + // assert + Assert.False(chunked); + Assert.AreEqual(0, response.count); + Assert.AreEqual(false, response.more); + } + + [Test] + public void ExceptionDuring_MSG_GetBranchPoints_ReturnsLastBlockAsEmpty() + { + // arrange + Container.GetMock() + .Setup(x => x.PtrToStructure(It.IsAny())) + .Returns(new MSG_GetBranchPoints_Request()); + + var points = Enumerable.Repeat(new BranchPoint(), 100).ToArray(); + Assert.NotNull(points); + + Container.GetMock() + .Setup(x => x.GetBranchPoints(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), out points)) + .Throws(); + + var response = new MSG_GetBranchPoints_Response { count = -1, more = true }; + Container.GetMock() + .Setup(x => x.StructureToPtr(It.IsAny(), It.IsAny(), It.IsAny())) + .Callback((msg, ptr, b) => { response = msg; }); + + var chunked = false; + + // act + Instance.StandardMessage(MSG_Type.MSG_GetBranchPoints, _mockCommunicationBlock.Object, + (i, block) => { chunked = true; }, + block => { }); + + // assert + Assert.False(chunked); + Assert.AreEqual(0, response.count); + Assert.AreEqual(false, response.more); + } + + [Test] + public void ExceptionDuring_MSG_AllocateMemoryBuffer_ReturnsAllocatedAsFalse() + { + // arrange + Container.GetMock() + .Setup(x => x.PtrToStructure(It.IsAny())) + .Returns(new MSG_AllocateBuffer_Request()); + + var response = new MSG_AllocateBuffer_Response { allocated = true }; + Container.GetMock() + .Setup(x => x.StructureToPtr(It.IsAny(), It.IsAny(), It.IsAny())) + .Callback((msg, ptr, b) => { response = msg; }); + + uint bufferId; + Container.GetMock() + .Setup(x => x.AllocateMemoryBuffer(It.IsAny(), out bufferId)) + .Throws(); + + // act + Instance.StandardMessage(MSG_Type.MSG_AllocateMemoryBuffer, _mockCommunicationBlock.Object, + (i, block) => { }, + block => { }); + + // assert + Assert.AreEqual(false, response.allocated); + } + + [Test] + public void ExceptionDuring_MSG_CloseChannel_ReturnsDoneAsTrue() + { + // arrange + Container.GetMock() + .Setup(x => x.PtrToStructure(It.IsAny())) + .Returns(new MSG_CloseChannel_Request()); + + var response = new MSG_CloseChannel_Response { done = false }; + Container.GetMock() + .Setup(x => x.StructureToPtr(It.IsAny(), It.IsAny(), It.IsAny())) + .Callback((msg, ptr, b) => { response = msg; }); + + Container.GetMock() + .Setup(x => x.DeactivateMemoryBuffer(It.IsAny())) + .Throws(); + + // act + Instance.StandardMessage(MSG_Type.MSG_CloseChannel, _mockCommunicationBlock.Object, + (i, block) => { }, + block => { }); + + // assert + Assert.AreEqual(true, response.done); + } + + [Test] + public void ExceptionDuring_MSG_TrackMethod_ReturnsTrackAsFalse() + { + // arrange + Container.GetMock() + .Setup(x => x.PtrToStructure(It.IsAny())) + .Returns(new MSG_TrackMethod_Request()); + + var response = new MSG_TrackMethod_Response { track = true }; + Container.GetMock() + .Setup(x => x.StructureToPtr(It.IsAny(), It.IsAny(), It.IsAny())) + .Callback((msg, ptr, b) => { response = msg; }); + + uint uniqueId; + Container.GetMock() + .Setup(x => x.TrackMethod(It.IsAny(), It.IsAny(), It.IsAny(), out uniqueId)) + .Throws(); + + // act + Instance.StandardMessage(MSG_Type.MSG_TrackMethod, _mockCommunicationBlock.Object, + (i, block) => { }, + block => { }); + + // assert + Assert.AreEqual(false, response.track); + } + + [Test] + public void ExceptionDuring_MSG_TrackAssembly_ReturnsTrackAsFalse() + { + // arrange + Container.GetMock() + .Setup(x => x.PtrToStructure(It.IsAny())) + .Returns(new MSG_TrackAssembly_Request()); + + var response = new MSG_TrackAssembly_Response { track = true }; + Container.GetMock() + .Setup(x => x.StructureToPtr(It.IsAny(), It.IsAny(), It.IsAny())) + .Callback((msg, ptr, b) => { response = msg; }); + + Container.GetMock() + .Setup(x => x.TrackAssembly(It.IsAny(), It.IsAny(), It.IsAny())) + .Throws(); + + // act + Instance.StandardMessage(MSG_Type.MSG_TrackAssembly, _mockCommunicationBlock.Object, + (i, block) => { }, + block => { }); + + // assert + Assert.AreEqual(false, response.track); + } + + [Test] + public void Handles_MSG_TrackProcess() + { + // arrange + Container.GetMock() + .Setup(x => x.PtrToStructure(It.IsAny())) + .Returns(new MSG_TrackProcess_Request()); + + // act + Instance.StandardMessage(MSG_Type.MSG_TrackProcess, _mockCommunicationBlock.Object, (i, block) => { }, block => { }); + + // assert + Container.GetMock() + .Verify(x => x.TrackProcess(It.IsAny()), Times.Once()); + + } + + [Test] + public void ExceptionDuring_MSG_TrackProcess_ReturnsTrackAsFalse() + { + // arrange + Container.GetMock() + .Setup(x => x.PtrToStructure(It.IsAny())) + .Returns(new MSG_TrackProcess_Request()); + + var response = new MSG_TrackProcess_Response { track = true }; + Container.GetMock() + .Setup(x => x.StructureToPtr(It.IsAny(), It.IsAny(), It.IsAny())) + .Callback((msg, ptr, b) => { response = msg; }); + + Container.GetMock() + .Setup(x => x.TrackProcess(It.IsAny())) + .Throws(); + + // act + Instance.StandardMessage(MSG_Type.MSG_TrackProcess, _mockCommunicationBlock.Object, + (i, block) => { }, + block => { }); + + // assert + Assert.AreEqual(false, response.track); + } + + [Test] + public void Unsupported_MSG_Type_Throws_Exception() + { + // arrange + Container.GetMock() + .Setup(x => x.PtrToStructure(It.IsAny())) + .Returns(new MSG_TrackMethod_Request()); + + // act + Assert.Throws(() => Instance.StandardMessage(MSG_Type.MSG_Unknown, _mockCommunicationBlock.Object, (i, block) => { }, block => { })); + + } } } diff --git a/main/OpenCover.Test/Framework/FilterTests.cs b/main/OpenCover.Test/Framework/FilterTests.cs index 6707633cf..b9741d428 100644 --- a/main/OpenCover.Test/Framework/FilterTests.cs +++ b/main/OpenCover.Test/Framework/FilterTests.cs @@ -1,5 +1,4 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; using System.Linq; using Mono.Cecil; using Mono.Collections.Generic; @@ -15,97 +14,132 @@ public class FilterTests { #region TestData for AddFilter tests - public class AssemblyClassData + public class FilterData { - public string AssemblyClass { get; set; } + public FilterData() + { + ProcessResult = ".*"; + } + + public string FilterExpression { get; set; } + public string ProcessResult { get; set; } public string AssemblyResult { get; set; } public string ClassResult { get; set; } public FilterType FilterTypeResult { get; set; } } -#pragma warning disable 169 - - private readonly string[] _invalidAssemblyClassPairs = { "Garbage", "+[]", "-[ ]", "[ ", " ]", "+[]]", "-[][", @"-[\]", @"+[X]\", "-[X]]", "+[X][" }; - - private readonly AssemblyClassData[] _assemblyClassPairs = - { - new AssemblyClassData - { - AssemblyClass = "+[System]Console", - AssemblyResult = "System", - ClassResult = "Console", - FilterTypeResult = FilterType.Inclusion, - }, - new AssemblyClassData - { - AssemblyClass = "+[My App]Namespace", - AssemblyResult = "My App", - ClassResult = "Namespace", - FilterTypeResult = FilterType.Inclusion, - }, - new AssemblyClassData - { - AssemblyClass = "+[System]", - AssemblyResult = "System", - ClassResult = "", - FilterTypeResult = FilterType.Inclusion, - }, - new AssemblyClassData - { - AssemblyClass = "-[System.*]Console", - AssemblyResult = @"System\..*", - ClassResult = "Console", - FilterTypeResult = FilterType.Exclusion, - }, - new AssemblyClassData - { - AssemblyClass = "+[System]Console.*", - AssemblyResult = "System", - ClassResult = @"Console\..*", - FilterTypeResult = FilterType.Inclusion, - }, - new AssemblyClassData - { - AssemblyClass = "-[System.*]Console.*", - AssemblyResult = @"System\..*", - ClassResult = @"Console\..*", - FilterTypeResult = FilterType.Exclusion, - } - }; -#pragma warning restore 169 + private readonly string[] _invalidFilterExpressions = + { + "Garbage", "+[]", "-[ ]", "[ ", " ]", "+[]]", "-[][", + @"-[\]", @"+[X]\", "-[X]]", "+[X][", "-<[*]*", "+>[*]*", + "+<>[*]*", "-[*]", "-[]*", "-<*>[*]", "-<*>[]*", "-[\u00a0]*" + }; + + private readonly FilterData[] _filterExpressions = + { + new FilterData + { + FilterExpression = "+[My App]Namespace", + AssemblyResult = "My App", + ClassResult = "Namespace", + FilterTypeResult = FilterType.Inclusion, + }, + new FilterData + { + FilterExpression = "-[System.*]Console", + AssemblyResult = @"System\..*", + ClassResult = "Console", + FilterTypeResult = FilterType.Exclusion, + }, + new FilterData + { + FilterExpression = "+[System]Console.*", + AssemblyResult = "System", + ClassResult = @"Console\..*", + FilterTypeResult = FilterType.Inclusion, + }, + new FilterData + { + FilterExpression = "-[System.*]Console.*", + AssemblyResult = @"System\..*", + ClassResult = @"Console\..*", + FilterTypeResult = FilterType.Exclusion, + }, + new FilterData + { + FilterExpression = "+<*>[System.*]Console.*", + AssemblyResult = @"System\..*", + ClassResult = @"Console\..*", + ProcessResult = ".*", + FilterTypeResult = FilterType.Inclusion, + }, + new FilterData + { + FilterExpression = "+[*]*", + AssemblyResult = ".*", + ClassResult = ".*", + FilterTypeResult = FilterType.Inclusion, + }, + new FilterData + { + FilterExpression = "+<*>[*]*", + AssemblyResult = ".*", + ClassResult = ".*", + ProcessResult = ".*", + FilterTypeResult = FilterType.Inclusion, + }, + new FilterData + { + FilterExpression = "-[*]*", + AssemblyResult = ".*", + ClassResult = ".*", + ProcessResult = @"MyApplication\..*", + FilterTypeResult = FilterType.Exclusion, + } + + }; #endregion [Test] public void AddFilter_ThrowsException_WhenInvalid_AssemblyClassPair( - [ValueSource("_invalidAssemblyClassPairs")]string assemblyClassPair) + [ValueSource("_invalidFilterExpressions")]string assemblyClassPair) { // arrange - var filter = new Filter(); + var filter = new Filter(false); // act/assert - Assert.Catch(() => filter.AddFilter(assemblyClassPair), + Assert.Catch(() => filter.AddFilter(assemblyClassPair), "'{0}' should be invalid", assemblyClassPair); } [Test] public void AddFilter_Adds_ValidAssemblyClassPair( - [ValueSource("_assemblyClassPairs")]AssemblyClassData assemblyClassPair) + [ValueSource("_filterExpressions")]FilterData assemblyClassPair) { // arrange - var filter = new Filter(); + var filter = new Filter(false); // act - filter.AddFilter(assemblyClassPair.AssemblyClass); + filter.AddFilter(assemblyClassPair.FilterExpression); // assert Assert.AreEqual(1, assemblyClassPair.FilterTypeResult == FilterType.Inclusion ? filter.InclusionFilters.Count : filter.ExclusionFilters.Count); - Assert.AreEqual(assemblyClassPair.AssemblyResult, assemblyClassPair.FilterTypeResult == FilterType.Inclusion ? - filter.InclusionFilters[0].AssemblyName : filter.ExclusionFilters[0].AssemblyName); + Assert.AreEqual(assemblyClassPair.ProcessResult, + assemblyClassPair.FilterTypeResult == FilterType.Inclusion ? + filter.InclusionFilters[0].ProcessName + : filter.ExclusionFilters[0].ProcessName); + + Assert.AreEqual(assemblyClassPair.AssemblyResult, + assemblyClassPair.FilterTypeResult == FilterType.Inclusion ? + filter.InclusionFilters[0].AssemblyName + : filter.ExclusionFilters[0].AssemblyName); - Assert.AreEqual(assemblyClassPair.ClassResult, assemblyClassPair.FilterTypeResult == FilterType.Inclusion ? - filter.InclusionFilters[0].ClassName : filter.ExclusionFilters[0].ClassName); + Assert.AreEqual(assemblyClassPair.ClassResult, + assemblyClassPair.FilterTypeResult == FilterType.Inclusion ? + filter.InclusionFilters[0].ClassName + : filter.ExclusionFilters[0].ClassName); } #region Test Data for UseAssembly tests @@ -169,11 +203,11 @@ public void UseAssembly_Tests( [ValueSource("_useAssemblyData")]UseAssemblyData data) { // arrange - var filter = new Filter(); + var filter = new Filter(false); data.Filters.ForEach(filter.AddFilter); // act - var result = filter.UseAssembly(data.Assembly); + var result = filter.UseAssembly("processName", data.Assembly); // result Assert.AreEqual(data.ExpectedResult, result, @@ -306,8 +340,8 @@ public class InstrumentClassData public void InstrumentClass_Tests( [ValueSource("_instrumentClassData")]InstrumentClassData data) { - //// arrange - var filter = new Filter(); + // arrange + var filter = new Filter(false); data.Filters.ForEach(filter.AddFilter); // act @@ -322,7 +356,7 @@ public void InstrumentClass_Tests( [Test] public void AddAttributeExclusionFilters_HandlesNull() { - var filter = new Filter(); + var filter = new Filter(false); filter.AddAttributeExclusionFilters(null); @@ -332,7 +366,7 @@ public void AddAttributeExclusionFilters_HandlesNull() [Test] public void AddAttributeExclusionFilters_Handles_Null_Elements() { - var filter = new Filter(); + var filter = new Filter(false); filter.AddAttributeExclusionFilters(new[] { null, "" }); @@ -342,7 +376,7 @@ public void AddAttributeExclusionFilters_Handles_Null_Elements() [Test] public void AddAttributeExclusionFilters_Escapes_Elements_And_Matches() { - var filter = new Filter(); + var filter = new Filter(false); filter.AddAttributeExclusionFilters(new[] { ".*" }); @@ -352,7 +386,7 @@ public void AddAttributeExclusionFilters_Escapes_Elements_And_Matches() [Test] public void Entity_Is_Not_Excluded_If_No_Filters_Set() { - var filter = new Filter(); + var filter = new Filter(false); var entity = new Mock(); Assert.IsFalse(filter.ExcludeByAttribute(entity.Object)); @@ -361,7 +395,7 @@ public void Entity_Is_Not_Excluded_If_No_Filters_Set() [Test] public void AddFileExclusionFilters_HandlesNull() { - var filter = new Filter(); + var filter = new Filter(false); filter.AddFileExclusionFilters(null); @@ -371,7 +405,7 @@ public void AddFileExclusionFilters_HandlesNull() [Test] public void AddFileExclusionFilters_Handles_Null_Elements() { - var filter = new Filter(); + var filter = new Filter(false); filter.AddFileExclusionFilters(new[] { null, "" }); @@ -381,7 +415,7 @@ public void AddFileExclusionFilters_Handles_Null_Elements() [Test] public void AddFileExclusionFilters_Escapes_Elements_And_Matches() { - var filter = new Filter(); + var filter = new Filter(false); filter.AddFileExclusionFilters(new[] { ".*" }); @@ -391,7 +425,7 @@ public void AddFileExclusionFilters_Escapes_Elements_And_Matches() [Test] public void AddTestFileFilters_HandlesNull() { - var filter = new Filter(); + var filter = new Filter(false); filter.AddTestFileFilters(null); @@ -401,7 +435,7 @@ public void AddTestFileFilters_HandlesNull() [Test] public void AssemblyIsIncludedForTestMethodGatheringWhenFilterMatches() { - var filter = new Filter(); + var filter = new Filter(false); filter.AddTestFileFilters(new[] { "A*" }); @@ -413,7 +447,7 @@ public void AssemblyIsIncludedForTestMethodGatheringWhenFilterMatches() [Test] public void AddTestFileFilters_Handles_Null_Elements() { - var filter = new Filter(); + var filter = new Filter(false); filter.AddTestFileFilters(new[] { null, "" }); @@ -423,7 +457,7 @@ public void AddTestFileFilters_Handles_Null_Elements() [Test] public void AddTestFileFilters_Escapes_Elements_And_Matches() { - var filter = new Filter(); + var filter = new Filter(false); filter.AddTestFileFilters(new[] { ".*" }); @@ -470,7 +504,7 @@ public void AddTestFileFilters_DoesNotWrap_ForRegexFilters() [Test] public void File_Is_Not_Excluded_If_No_Filters_Set() { - var filter = new Filter(); + var filter = new Filter(false); Assert.IsFalse(filter.ExcludeByFile("xyz.cs")); } @@ -478,7 +512,7 @@ public void File_Is_Not_Excluded_If_No_Filters_Set() [Test] public void File_Is_Not_Excluded_If_No_File_Not_Supplied() { - var filter = new Filter(); + var filter = new Filter(false); Assert.IsFalse(filter.ExcludeByFile("")); } @@ -486,7 +520,7 @@ public void File_Is_Not_Excluded_If_No_File_Not_Supplied() [Test] public void File_Is_Not_Excluded_If_Does_Not_Match_Filter() { - var filter = new Filter(); + var filter = new Filter(false); filter.AddFileExclusionFilters(new[] { "XXX.*" }); Assert.IsFalse(filter.ExcludeByFile("YYY.cs")); @@ -495,7 +529,7 @@ public void File_Is_Not_Excluded_If_Does_Not_Match_Filter() [Test] public void File_Is_Excluded_If_Matches_Filter() { - var filter = new Filter(); + var filter = new Filter(false); filter.AddFileExclusionFilters(new[] { "XXX.*" }); Assert.IsTrue(filter.ExcludeByFile("XXX.cs")); @@ -508,7 +542,7 @@ public void Can_Identify_Excluded_Methods() var type = sourceAssembly.MainModule.Types.First(x => x.FullName == typeof(Samples.Concrete).FullName); - var filter = new Filter(); + var filter = new Filter(false); filter.AddAttributeExclusionFilters(new[] { "*ExcludeMethodAttribute" }); foreach (var methodDefinition in type.Methods) @@ -526,7 +560,7 @@ public void Can_Identify_Excluded_Properties() var type = sourceAssembly.MainModule.Types.First(x => x.FullName == typeof(Samples.Concrete).FullName); - var filter = new Filter(); + var filter = new Filter(false); filter.AddAttributeExclusionFilters(new[] { "*ExcludeMethodAttribute" }); foreach (var propertyDefinition in type.Properties) @@ -542,7 +576,7 @@ public void Can_Identify_Excluded_Anonymous_Issue99() var type = sourceAssembly.MainModule.Types.First(x => x.FullName == typeof(Samples.Anonymous).FullName); - var filter = new Filter(); + var filter = new Filter(false); filter.AddAttributeExclusionFilters(new[] { "*ExcludeMethodAttribute" }); foreach (var methodDefinition in type.Methods.Where(x => x.Name.Contains("EXCLUDE"))) @@ -559,7 +593,7 @@ public void Can_Identify_Included_Anonymous_Issue99() var type = sourceAssembly.MainModule.Types.First(x => x.FullName == typeof(Samples.Anonymous).FullName); - var filter = new Filter(); + var filter = new Filter(false); filter.AddAttributeExclusionFilters(new[] { "*ExcludeMethodAttribute" }); foreach (var methodDefinition in type.Methods.Where(x => x.Name.Contains("INCLUDE"))) @@ -572,7 +606,7 @@ public void Can_Identify_Included_Anonymous_Issue99() [Test] public void Handles_Issue117() { - var filter = new Filter(); + var filter = new Filter(false); filter.AddAttributeExclusionFilters(new[] { "*ExcludeMethodAttribute" }); var mockDefinition = new Mock(); @@ -592,7 +626,7 @@ public void Can_Identify_Excluded_Assemblies() var sourceAssembly = AssemblyDefinition.ReadAssembly(typeof(Samples.Concrete).Assembly.Location); // act - var filter = new Filter(); + var filter = new Filter(false); Assert.False(filter.ExcludeByAttribute(sourceAssembly)); // assert @@ -600,24 +634,58 @@ public void Can_Identify_Excluded_Assemblies() Assert.True(filter.ExcludeByAttribute(sourceAssembly)); } + static IEnumerable AllNestedTypes(TypeDefinition typeDefinition) + { + if (typeDefinition.NestedTypes == null) yield break; + foreach (var nestedTypeDefinition in typeDefinition.NestedTypes) + { + yield return nestedTypeDefinition; + foreach (var allNestedType in AllNestedTypes(nestedTypeDefinition)) + { + yield return allNestedType; + } + } + } + + static IEnumerable AllTypes(ModuleDefinition module) + { + foreach (var typeDefinition in module.Types) + { + yield return typeDefinition; + foreach (var allNestedType in AllNestedTypes(typeDefinition)) + { + yield return allNestedType; + } + } + } + [Test] - public void Can_Identify_Excluded_Types() + [TestCase("Concrete")] + [TestCase("InnerConcrete")] + [TestCase("InnerInnerConcrete")] + public void Can_Identify_Excluded_Types(string typeName) { // arrange var sourceAssembly = AssemblyDefinition.ReadAssembly(typeof(Samples.Concrete).Assembly.Location); // act - var filter = new Filter(); - foreach (var typeDefinition in sourceAssembly.MainModule.Types.Where(x => x.Name == "Concrete")) - { - Assert.False(filter.ExcludeByAttribute(typeDefinition)); - } + var filter = new Filter(false); + var allTypes = AllTypes(sourceAssembly.MainModule); + var typeDefinition = allTypes.First(x => x.Name == typeName); + + Assert.False(filter.ExcludeByAttribute(typeDefinition)); // assert filter.AddAttributeExclusionFilters(new[] { "*ExcludeClassAttribute" }); - foreach (var typeDefinition in sourceAssembly.MainModule.Types.Where(x => x.Name == "Concrete")) + foreach (var methodDefinition in typeDefinition.Methods) { - Assert.True(filter.ExcludeByAttribute(typeDefinition)); + if (methodDefinition.IsSetter || methodDefinition.IsGetter) continue; + Assert.True(filter.ExcludeByAttribute(methodDefinition)); + } + Assert.True(filter.ExcludeByAttribute(typeDefinition)); + foreach (var nestedType in AllNestedTypes(typeDefinition)) + { + Assert.True(filter.ExcludeByAttribute(nestedType)); } } @@ -629,7 +697,7 @@ public void CanIdentify_AutoImplementedProperties() var type = sourceAssembly.MainModule.Types.First(x => x.FullName == typeof(Samples.DeclaredMethodClass).FullName); // act/assert - var filter = new Filter(); + var filter = new Filter(false); var wasTested = false; foreach (var methodDefinition in type.Methods .Where(x => x.IsGetter || x.IsSetter).Where(x => x.Name.EndsWith("AutoProperty"))) @@ -664,7 +732,7 @@ public void CanHandle_AssemblyFilters_ExpressedAs_RegularExpressions(string asse // act // assert - Assert.AreEqual(canUse, filter.UseAssembly(assembly)); + Assert.AreEqual(canUse, filter.UseAssembly("processName", assembly)); } [Test] @@ -702,6 +770,18 @@ public void Can_Identify_Excluded_Methods_UsingRegularExpressions() } } + [Test] + public void ModulesInExcludedFoldersAreIdentifiedCorrectly() + { + // arrange + var filter = new Filter(true); + filter.AddExcludedFolder("ABC"); + + // act + Assert.IsFalse(filter.UseModule(@"ABC\m.dll")); + Assert.IsTrue(filter.UseModule(@"DEF\m.dll")); + } + [Test] public void File_Is_Excluded_If_Matches_Filter_UsingRegularExpressions() { @@ -723,7 +803,109 @@ public void Can_BuildFilter_From_CommandLine(string[] commandLine, bool matchAss { var filter = Filter.BuildFilter(new CommandLineParser(commandLine).Do(_ => _.ExtractAndValidateArguments())); Assert.IsNotNull(filter); - Assert.AreEqual(matchAssembly, filter.UseAssembly("System")); + Assert.AreEqual(matchAssembly, filter.UseAssembly("processName", "System")); + } + + [Test] + // TestCase semantic changed! + // first boolean is expected value when default filters disabled + // second boolean is expected value when default filters enabled + + #region Initial test set + [TestCase("+<*>[*]*", null, false, false)] + [TestCase("-<*>[*]*", "process", false, false)] + [TestCase("-[*]*", "process", false, false)] + [TestCase("-<*cess>[*]*", "process", false, false)] + [TestCase("+<*>[*]*", "process", true, true)] + [TestCase("+[*]*", "process", true, true)] + [TestCase("+<*cess>[*]*", "process", true, true)] + [TestCase("+[ABC*]*", "nunit-executable", true, true)] + [TestCase("+[*]DEF.*", "nunit-executable", true, true)] + [TestCase("+[*]*", "process", true, true)] + [TestCase("-[ABC*]*", "nunit-executable", true, true)] + [TestCase("-[*]DEF.*", "nunit-executable", true, true)] + [TestCase("-[*]*", "process", false, false)] + [TestCase("-<*>[*]* +[*]*", "process", false, false)] + [TestCase("+[*]* +[*]*", "process", true, true)] + [TestCase("-<*>[ABC*]* +[*]*", "process", true, true)] + [TestCase("-<*>[ABC*]* +<*>[*]*", "process", true, true)] + [TestCase("-[D*F]* +[*]*", "process", true, true)] + [TestCase("-<*cess>[*GHI]* +[*]*", "process", true, true)] + [TestCase("+[*]*", "process", false, false)] + [TestCase("+[*]*", "process", true, true)] + #endregion + + #region match when both filters, when no exclude filters, or when no include filters or when no filters at all + + // 1/1 match include filter if not excluded + [TestCase(@"-[*]* +[*]*", "noprocess", false, false)] + [TestCase(@"-[*]* +[*]*", "noprocess", true, true)] + + // 1/0 include if not excluded and no include filters + [TestCase(@"-[*]*", "noprocess", true, true)] + + // 0/1 match include filter if no exclude filters exists + [TestCase(@"+[*]*", "noprocess", false, false)] + [TestCase(@"+[*]*", "process", true, true)] + + // 0/0 always include if no exclude and no include filters + [TestCase(@"", @"C:\Release\process.exe", true, true)] + + #endregion + + #region exclude only when filter does not ends with [*]* + + [TestCase(@"-<*>[*]*", "process", false, false)] + [TestCase(@"-<*>[*x*]*", "process", true, true)] + [TestCase(@"-<*>[*]*x*", "process", true, true)] + [TestCase(@"-<*>[*x*]*x*", "process", true, true)] + + #endregion + + #region always include matching process regardless how process filter ends ([*]*|[*x*]*x*) + + [TestCase(@"+<*>[*]*", "process", true, true)] + [TestCase(@"+<*>[*x*]*", "process", true, true)] + [TestCase(@"+<*>[*]*x*", "process", true, true)] + [TestCase(@"+<*>[*x*]*x*", "process", true, true)] + + #endregion + + #region never exclude proces that matches default-assembly-exclusion-filters (ie "mscorlib" when exclusion filters enabled) + + [TestCase(@"-[*]*", @"C:\dotNet\mscorlib.dll", true, true)] + + // issue found by user #329 + [TestCase(@"+[Open*]* -[OpenCover.T*]* -[*nunit*]*", "nunit-console", true, true)] + + #endregion + + public void CanFilterByProcessName(string filterArg, string processName, bool expectedNoDefaultFilters, bool expectedWithDefaultFilters) + { + // arrange without default filters + var filter = Filter.BuildFilter(new CommandLineParser(GetFilter(filterArg, false).ToArray()).Do(_ => _.ExtractAndValidateArguments())); + + // act + var instrument = filter.InstrumentProcess(processName); + + // assert + Assert.AreEqual(expectedNoDefaultFilters, instrument); + + // arrange again with default filters + filter = Filter.BuildFilter(new CommandLineParser(GetFilter(filterArg, true).ToArray()).Do(_ => _.ExtractAndValidateArguments())); + + // act + instrument = filter.InstrumentProcess(processName); + + // assert + Assert.AreEqual(expectedWithDefaultFilters, instrument); + } + + static IEnumerable GetFilter(string filterArg, bool defaultFilters) + { + yield return "-target:t"; + yield return string.Format("-filter:\"{0}\"", filterArg); + if (!defaultFilters) yield return "-nodefaultfilters"; } } } diff --git a/main/OpenCover.Test/Framework/Manager/MemoryManagerTests.cs b/main/OpenCover.Test/Framework/Manager/MemoryManagerTests.cs new file mode 100644 index 000000000..8d1f6057c --- /dev/null +++ b/main/OpenCover.Test/Framework/Manager/MemoryManagerTests.cs @@ -0,0 +1,209 @@ +using System; +using System.Diagnostics; +using System.Linq; +using NUnit.Framework; +using OpenCover.Framework.Manager; + +namespace OpenCover.Test.Framework.Manager +{ + [TestFixture] + public class MemoryManagerTests + { + private MemoryManager _manager; + + [SetUp] + public void SetUp() + { + _manager = new MemoryManager(); + _manager.Initialise("Local", "C#", new String[0]); + } + + [TearDown] + public void Teardown() + { + _manager.Dispose(); + } + + [Test] + public void DeactivateMemoryBuffer_SetsActive_ForBlock_False() + { + // arrange + uint bufferId; + _manager.AllocateMemoryBuffer(100, out bufferId); + Assert.AreEqual(1, _manager.GetBlocks.Count); + Assert.IsTrue(_manager.GetBlocks.First().Active); + + // act + _manager.DeactivateMemoryBuffer(bufferId); + + // assert + Assert.IsFalse(_manager.GetBlocks.First().Active); + } + + [Test] + public void RemoveDeactivatedBlocs_RemovesNonActiveBlock() + { + // arrange + uint bufferId; + _manager.AllocateMemoryBuffer(100, out bufferId); + _manager.AllocateMemoryBuffer(100, out bufferId); + Assert.AreEqual(2, _manager.GetBlocks.Count); + Assert.AreEqual(2, _manager.GetBlocks.Count(b => b.Active)); + _manager.DeactivateMemoryBuffer(bufferId); + Assert.AreEqual(2, _manager.GetBlocks.Count); + Assert.AreEqual(1, _manager.GetBlocks.Count(b => b.Active)); + + // act + var block = _manager.GetBlocks.First(b => !b.Active); + _manager.RemoveDeactivatedBlock(block); + + // assert + Assert.AreEqual(1, _manager.GetBlocks.Count); + Assert.AreEqual(1, _manager.GetBlocks.Count(b => b.Active)); + } + + [Test] + public void Cannot_RemoveDeactivatedBlock_OnActiveBlock() + { + // arrange + uint bufferId; + _manager.AllocateMemoryBuffer(100, out bufferId); + Assert.AreEqual(1, _manager.GetBlocks.Count); + Assert.AreEqual(1, _manager.GetBlocks.Count(b => b.Active)); + + // act + var block = _manager.GetBlocks.First(); + _manager.RemoveDeactivatedBlock(block); + + // assert + Assert.AreEqual(1, _manager.GetBlocks.Count); + Assert.AreEqual(1, _manager.GetBlocks.Count(b => b.Active)); + } + + [Test] + public void AllocateMemoryBuffer_WhenManagerNotInitialised_Ignored_OK() + { + using (var manager = new MemoryManager()) + { + // not initialised + + // arrange + uint bufferId; + + // act & assert + Assert.That(() => manager.AllocateMemoryBuffer(100, out bufferId), Throws.Nothing); + } + } + + [Test] + public void InitialiseMemoryManagerTwice_Ignored_OK() + { + // act & assert + Assert.That(() => _manager.Initialise("Local", "C#", new String[0]), Throws.Nothing); + } + + [Test] + public void AllocateMemoryBufferTwice_NewBufferAllocated_OK() + { + // arrange + uint bufferId; + + // act + _manager.AllocateMemoryBuffer(100, out bufferId); + _manager.AllocateMemoryBuffer(100, out bufferId); + + // assert + Assert.AreEqual(2, _manager.GetBlocks.Count); + } + + [Test] + public void DeactivateMemoryBufferTwice_Ignored_OK() + { + // arrange + uint bufferId; + _manager.AllocateMemoryBuffer(100, out bufferId); + Assert.AreEqual(1, _manager.GetBlocks.Count); + Assert.IsTrue(_manager.GetBlocks.First().Active); + + // act + _manager.DeactivateMemoryBuffer(bufferId); + + // act & assert + Assert.That(() => _manager.DeactivateMemoryBuffer(bufferId), Throws.Nothing); + } + + + [Test] + public void DeactivateMemoryBufferAfterDisposed_Ignored_OK() + { + // arrange + uint bufferId; + _manager.AllocateMemoryBuffer(100, out bufferId); + Assert.AreEqual(1, _manager.GetBlocks.Count); + Assert.IsTrue(_manager.GetBlocks.First().Active); + + // act + _manager.Dispose(); + + // act & assert + Assert.That(() => _manager.DeactivateMemoryBuffer(bufferId), Throws.Nothing); + } + + [Test] + public void WaitForBlocksToClose_WaitsUntilBufferWaitCountExceededIfAnyActiveBlocks() + { + // arrange + uint bufferId; + _manager.AllocateMemoryBuffer(100, out bufferId); + + var timeAction = new Func(actionToTime => + { + var t = Stopwatch.StartNew(); + actionToTime(); + t.Stop(); + return t.ElapsedMilliseconds; + }); + + Assert.That(timeAction(() => _manager.WaitForBlocksToClose(0)), Is.LessThan(500)); + Assert.That(timeAction(() => _manager.WaitForBlocksToClose(1)), Is.GreaterThanOrEqualTo(500).And.LessThan(1000)); + Assert.That(timeAction(() => _manager.WaitForBlocksToClose(2)), Is.GreaterThanOrEqualTo(1000).And.LessThan(1500)); + + } + + [Test] + public void WaitForBlocksToClose_StopsWaitingWhenNoActiveBlocks() + { + // arrange + uint bufferId; + _manager.AllocateMemoryBuffer(100, out bufferId); + + var timeAction = new Func(actionToTime => + { + var t = Stopwatch.StartNew(); + actionToTime(); + t.Stop(); + return t.ElapsedMilliseconds; + }); + + Assert.That(timeAction(() => _manager.WaitForBlocksToClose(1)), Is.GreaterThanOrEqualTo(500).And.LessThan(1000)); + _manager.GetBlocks.First().Active = false; + Assert.That(timeAction(() => _manager.WaitForBlocksToClose(1)), Is.LessThan(500)); + + } + + [Test] + public void FetchRemainingBufferData_CallsActionForEachActiveBlock() + { + // arrange + uint bufferId; + _manager.AllocateMemoryBuffer(100, out bufferId); + _manager.AllocateMemoryBuffer(100, out bufferId); + + uint count = 0; + _manager.FetchRemainingBufferData( data => count++ ); + + Assert.That(count, Is.EqualTo(2)); + Assert.That(_manager.GetBlocks.Count, Is.EqualTo(0)); + } + } +} \ No newline at end of file diff --git a/main/OpenCover.Test/Framework/Manager/ProfilerManagerTests.cs b/main/OpenCover.Test/Framework/Manager/ProfilerManagerTests.cs index 5220227d0..6c3635a8d 100644 --- a/main/OpenCover.Test/Framework/Manager/ProfilerManagerTests.cs +++ b/main/OpenCover.Test/Framework/Manager/ProfilerManagerTests.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Specialized; -using System.Diagnostics; using System.Linq; using System.Security.AccessControl; using System.Security.Principal; @@ -27,7 +26,8 @@ public override void OnSetup() _key = (new Random().Next()).ToString(); _manager = new MemoryManager(); _manager.Initialise("Local", _key, Enumerable.Empty()); - _manager.AllocateMemoryBuffer(65536, 0); + uint bufferId; + _manager.AllocateMemoryBuffer(65536, out bufferId); Container.RegisterInstance(_manager); } @@ -77,6 +77,33 @@ public void Manager_Adds_Supplied_Threshold_EnvironmentVariable() Assert.NotNull(dict[@"OpenCover_Profiler_Threshold"]); Assert.AreEqual("500", dict[@"OpenCover_Profiler_Threshold"]); } + [Test] + public void Manager_DoesNotAdd_ShortWait_EnvironmentVariable() + { + // arrange + var dict = new StringDictionary(); + + // act + RunSimpleProcess(dict); + + // assert + Assert.Null(dict[@"OpenCover_Profiler_ShortWait"]); + } + + [Test] + public void Manager_Adds_Supplied_ShortWait_EnvironmentVariable() + { + // arrange + var dict = new StringDictionary(); + Container.GetMock().SetupGet(x => x.CommunicationTimeout).Returns(10000); + + // act + RunSimpleProcess(dict); + + // assert + Assert.NotNull(dict[@"OpenCover_Profiler_ShortWait"]); + Assert.AreEqual("10000", dict[@"OpenCover_Profiler_ShortWait"]); + } [Test] public void Manager_Adds_TraceByTest_EnvironmentVariable_When_Tracing_Enabled() @@ -146,8 +173,8 @@ public void Manager_DoesNotAdd_Cor_Profiler_Path_EnvironmentVariable_WithNormalR RunSimpleProcess(dict); // assert - Assert.IsFalse(dict.ContainsKey(@"Cor_Profiler_Path")); - Assert.IsFalse(dict.ContainsKey(@"CorClr_Profiler_Path")); + Assert.IsFalse(!(dict.ContainsKey(@"Cor_Profiler_Path") || !string.IsNullOrEmpty(dict[@"Cor_Profiler_Path"]))); + Assert.IsFalse(!(dict.ContainsKey(@"CorClr_Profiler_Path") || !string.IsNullOrEmpty(dict[@"CorClr_Profiler_Path"]))); } [Test] @@ -161,8 +188,8 @@ public void Manager_DoesNotAdd_Cor_Profiler_Path_EnvironmentVariable_WithUserReg RunSimpleProcess(dict); // assert - Assert.IsFalse(dict.ContainsKey(@"Cor_Profiler_Path")); - Assert.IsFalse(dict.ContainsKey(@"CorClr_Profiler_Path")); + Assert.IsFalse(!(dict.ContainsKey(@"Cor_Profiler_Path") || !string.IsNullOrEmpty(dict[@"Cor_Profiler_Path"]))); + Assert.IsFalse(!(dict.ContainsKey(@"CorClr_Profiler_Path") || !string.IsNullOrEmpty(dict[@"CorClr_Profiler_Path"]))); } [Test] @@ -203,7 +230,7 @@ public void Manager_Handles_Shared_StandardMessageEvent() EventWaitHandle offloadComplete = new AutoResetEvent(false); Container.GetMock() - .Setup(x => x.HandleCommunicationBlock(It.IsAny(), It.IsAny>())) + .Setup(x => x.HandleCommunicationBlock(It.IsAny(), It.IsAny>())) .Callback(() => { if (standardMessageReady != null) @@ -220,8 +247,8 @@ public void Manager_Handles_Shared_StandardMessageEvent() // assert Container.GetMock() - .Verify(x => x.HandleCommunicationBlock(It.IsAny(), - It.IsAny>()), Times.Once()); + .Verify(x => x.HandleCommunicationBlock(It.IsAny(), + It.IsAny>()), Times.Once()); } [Test, RequiresMTA, Repeat(10)] @@ -246,12 +273,12 @@ public void Manager_Handles_Profiler_StandardMessageEvent() using (var mmb = new MemoryManager.ManagedMemoryBlock("Local", _key, 100, -5, Enumerable.Empty())) { Container.GetMock() - .Setup(x => x.HandleCommunicationBlock(It.IsAny(), It.IsAny>())) - .Callback>((_, offload) => + .Setup(x => x.HandleCommunicationBlock(It.IsAny(), It.IsAny>())) + .Callback>((_, offload) => { standardMessageReady.Reset(); - offload(mcb, mmb); + offload(new ManagedBufferBlock { CommunicationBlock = mcb, MemoryBlock = mmb }); offloadComplete.Set(); }); @@ -277,17 +304,17 @@ public void Manager_Handles_Profiler_ResultsReady() EventWaitHandle standardMessageReady = null; EventWaitHandle offloadComplete = new AutoResetEvent(false); - using (var mcb = new MemoryManager.ManagedCommunicationBlock("Local", _key, 100, 1, Enumerable.Empty())) - using (var mmb = new MemoryManager.ManagedMemoryBlock("Local", _key, 100, 1, Enumerable.Empty())) + using (var mcb = new MemoryManager.ManagedCommunicationBlock("Local", _key, 100, 2, Enumerable.Empty())) + using (var mmb = new MemoryManager.ManagedMemoryBlock("Local", _key, 100, 2, Enumerable.Empty())) { Container.GetMock() - .Setup(x => x.HandleCommunicationBlock(It.IsAny(), It.IsAny>())) - .Callback>((_, offload) => + .Setup(x => x.HandleCommunicationBlock(It.IsAny(), It.IsAny>())) + .Callback>((_, offload) => { standardMessageReady.Reset(); mcb.ProfilerRequestsInformation.Reset(); - offload(mcb, mmb); + offload(new ManagedBufferBlock{CommunicationBlock = mcb, MemoryBlock = mmb}); offloadComplete.Set(); }); @@ -304,7 +331,7 @@ public void Manager_Handles_Profiler_ResultsReady() // assert Container.GetMock() .Verify(x => x.HandleCommunicationBlock(It.IsAny(), - It.IsAny>()), Times.Exactly(2)); + It.IsAny>()), Times.Exactly(2)); } [Test] @@ -330,8 +357,8 @@ public void Manager_Sets_Service_ACLs_On_Events() var self = WindowsIdentity.GetCurrent().User; // act - using (var mcb = new MemoryManager.ManagedCommunicationBlock("Local", _key, 100, 1, servicePrincipal)) - using (var mmb = new MemoryManager.ManagedMemoryBlock("Local", _key, 100, 1, servicePrincipal)) + using (var mcb = new MemoryManager.ManagedCommunicationBlock("Local", _key, 100, 2, servicePrincipal)) + using (var mmb = new MemoryManager.ManagedMemoryBlock("Local", _key, 100, 2, servicePrincipal)) { var phrRules = mmb.ProfilerHasResults.GetAccessControl().GetAccessRules(true, false, typeof(SecurityIdentifier)); var rhbrRules = mmb.ResultsHaveBeenReceived.GetAccessControl().GetAccessRules(true, false, typeof(SecurityIdentifier)); @@ -369,8 +396,8 @@ public void Manager_Sets_Service_ACLs_On_Memory() var self = WindowsIdentity.GetCurrent().User; // act - using (var mcb = new MemoryManager.ManagedCommunicationBlock("Local", _key, 100, 1, servicePrincipal)) - using (var mmb = new MemoryManager.ManagedMemoryBlock("Local", _key, 100, 1, servicePrincipal)) + using (var mcb = new MemoryManager.ManagedCommunicationBlock("Local", _key, 100, 2, servicePrincipal)) + using (var mmb = new MemoryManager.ManagedMemoryBlock("Local", _key, 100, 2, servicePrincipal)) { var mcbRules = mcb.MemoryAcl.GetAccessRules(true, false, typeof(SecurityIdentifier)); var mmbRules = mmb.MemoryAcl.GetAccessRules(true, false, typeof(SecurityIdentifier)); @@ -395,6 +422,35 @@ public void Manager_Sets_Service_ACLs_On_Memory() } } + [Test] + public void Manager_Adds_SafeMode_EnvironmentVariable_When_SafemodeOn() + { + // arrange + var dict = new StringDictionary(); + Container.GetMock().SetupGet(x => x.SafeMode).Returns(true); + + // act + RunSimpleProcess(dict); + + // assert + Assert.NotNull(dict[@"OpenCover_Profiler_SafeMode"]); + Assert.AreEqual("1", dict[@"OpenCover_Profiler_SafeMode"]); + } + + [Test] + public void Manager_DoesNotAdd_SafeMode_EnvironmentVariable_When_SafemodeOff() + { + // arrange + var dict = new StringDictionary(); + Container.GetMock().SetupGet(x => x.SafeMode).Returns(false); + + // act + RunSimpleProcess(dict); + + // assert + Assert.IsNull(dict[@"OpenCover_Profiler_SafeMode"]); + } + private void RunSimpleProcess(StringDictionary dict) { RunProcess(dict, standardMessageDataReady => { }, () => { }); @@ -402,6 +458,8 @@ private void RunSimpleProcess(StringDictionary dict) private void RunProcess(StringDictionary dict, Action getStandardMessageDataReady, Action doExtraWork) { + ProfilerManager.BufferWaitCount = 0; + // arrange EventWaitHandle standardMessageDataReady = null; diff --git a/main/OpenCover.Test/Framework/Model/InstrumentationModelBuilderTests.cs b/main/OpenCover.Test/Framework/Model/InstrumentationModelBuilderTests.cs index 8766f346b..92f7b3758 100644 --- a/main/OpenCover.Test/Framework/Model/InstrumentationModelBuilderTests.cs +++ b/main/OpenCover.Test/Framework/Model/InstrumentationModelBuilderTests.cs @@ -23,7 +23,7 @@ public void BuildModuleModel_Gets_ModulePath_From_SymbolReader() .Returns("ModulePath"); Container.GetMock() - .Setup(x => x.UseAssembly(It.IsAny())) + .Setup(x => x.UseAssembly(It.IsAny(), It.IsAny())) .Returns(true); // act @@ -31,7 +31,7 @@ public void BuildModuleModel_Gets_ModulePath_From_SymbolReader() // assert Assert.IsNotNull(module); - Assert.AreEqual("ModulePath", module.FullName); + Assert.AreEqual("ModulePath", module.ModulePath); Assert.AreEqual("ModulePath", module.Aliases[0]); } @@ -44,7 +44,7 @@ public void BuildModuleModel_Gets_ModuleName_From_SymbolReader() .Returns("ModuleName"); Container.GetMock() - .Setup(x => x.UseAssembly(It.IsAny())) + .Setup(x => x.UseAssembly(It.IsAny(), It.IsAny())) .Returns(true); // act @@ -64,7 +64,7 @@ public void BuildModuleModel_GetsClasses_From_SymbolReader() .Returns(new[] {@class}); Container.GetMock() - .Setup(x => x.UseAssembly(It.IsAny())) + .Setup(x => x.UseAssembly(It.IsAny(), It.IsAny())) .Returns(true); // act @@ -88,7 +88,7 @@ public void BuildModuleModel_DoesNotGetMethods_For_SkippedClasses() .Returns(new[] { @class }); Container.GetMock() - .Setup(x => x.UseAssembly(It.IsAny())) + .Setup(x => x.UseAssembly(It.IsAny(), It.IsAny())) .Returns(true); // act @@ -119,7 +119,7 @@ public void BuildModuleModel_Gets_DeclaredMethods_From_SymbolReader() .Returns(new[] { new SequencePoint() }); Container.GetMock() - .Setup(x => x.UseAssembly(It.IsAny())) + .Setup(x => x.UseAssembly(It.IsAny(), It.IsAny())) .Returns(true); // act @@ -150,7 +150,7 @@ public void BuildModuleModel_Gets_SequencePoints_From_SymbolReader() .Returns(new[] { seqPoint }); Container.GetMock() - .Setup(x => x.UseAssembly(It.IsAny())) + .Setup(x => x.UseAssembly(It.IsAny(), It.IsAny())) .Returns(true); // act @@ -204,7 +204,7 @@ public void CanBuildModelOf_RealAssembly() .Returns(System.IO.Path.Combine(Environment.CurrentDirectory, "OpenCover.Test.dll")); Container.GetMock() - .Setup(x => x.UseAssembly(It.IsAny())) + .Setup(x => x.UseAssembly(It.IsAny(), It.IsAny())) .Returns(true); // act @@ -273,7 +273,7 @@ public void BuildModuleModel_MethodPoint_WhenOffsetZero() .Returns(new[] { seqPoint }); Container.GetMock() - .Setup(x => x.UseAssembly(It.IsAny())) + .Setup(x => x.UseAssembly(It.IsAny(), It.IsAny())) .Returns(true); // act @@ -304,7 +304,7 @@ public void BuildModuleModel_MethodPoint_WhenOffsetGreaterThanZero() .Returns(new[] { seqPoint }); Container.GetMock() - .Setup(x => x.UseAssembly(It.IsAny())) + .Setup(x => x.UseAssembly(It.IsAny(), It.IsAny())) .Returns(true); // act @@ -340,7 +340,7 @@ public void BuildModuleModel_Gets_BranchPoints_WhenHaveSequencePoints() .Returns(new[] { brPoint }); Container.GetMock() - .Setup(x => x.UseAssembly(It.IsAny())) + .Setup(x => x.UseAssembly(It.IsAny(), It.IsAny())) .Returns(true); // act @@ -371,7 +371,7 @@ public void BuildModuleModel_Gets_NoBranchPoints_WhenNoSequencePoints() .Returns(new[] { brPoint }); Container.GetMock() - .Setup(x => x.UseAssembly(It.IsAny())) + .Setup(x => x.UseAssembly(It.IsAny(), It.IsAny())) .Returns(true); // act diff --git a/main/OpenCover.Test/Framework/Model/MethodTest.cs b/main/OpenCover.Test/Framework/Model/MethodTest.cs new file mode 100644 index 000000000..a2fb58905 --- /dev/null +++ b/main/OpenCover.Test/Framework/Model/MethodTest.cs @@ -0,0 +1,195 @@ +/* + * Created by SharpDevelop. + * User: ddur + * Date: 8.1.2016. + * Time: 7:52 + * + */ +using System; +using NUnit.Framework; +using OpenCover.Framework.Model; + +namespace OpenCover.Test.Framework.Model +{ + [TestFixture] + public class MethodTest + { + [Test] + public void MethodIsGenerated() + { + // arrange + var method = new Method + { + FullName = "System.Boolean DD.Collections.BitSetArray::BitSetArray_<_SetItems>b__b_0(System.Int32)" + }; + + // act + var result = method.IsGenerated; + + // assert + Assert.True (result); + } + + [Test] + public void MethodIsGenerated2() + { + // arrange + var method = new Method + { + FullName = "System.Boolean DD.Collections.BitSetArray::BitSetArray_<_SetItems>b__b_0(System.Int32)" + }; + + // act twice to cover cached result + var result = method.IsGenerated; + result = method.IsGenerated; + + // assert + Assert.True (result); + } + + [Test] + public void MethodIsNotGenerated() + { + // arrange + var method = new Method + { + FullName = "System.Void DD.Collections.BitSetArray::_SetItems(System.Collections.Generic.IEnumerable`1)" + }; + + // act + var result = method.IsGenerated; + + // assert + Assert.False (result); + } + + [Test] + public void MethodIsNotGeneratedFullNameIsNull() + { + // arrange + var method = new Method + { + FullName = null + }; + + // act + var result = method.IsGenerated; + + // assert + Assert.False (result); + } + + [Test] + public void MethodIsNotGeneratedFullNameIsEmpty() + { + // arrange + var method = new Method + { + FullName = string.Empty + }; + + // act + var result = method.IsGenerated; + + // assert + Assert.False (result); + } + + [Test] + public void MethodCallNameGenerated() + { + // arrange + var method = new Method + { + FullName = "System.Boolean DD.Collections.BitSetArray::BitSetArray_<_SetItems>b__b_0(System.Int32)" + }; + + // act + var result = method.CallName; + + // assert + Assert.True (result == "BitSetArray_<_SetItems>b__b_0"); + } + + [Test] + public void MethodCallnameStandard() + { + // arrange + var method = new Method + { + FullName = "System.Void DD.Collections.BitSetArray::_SetItems(System.Collections.Generic.IEnumerable`1)" + }; + + // act + var result = method.CallName; + + // assert + Assert.True (result == "_SetItems"); + } + + [Test] + public void MethodCallNameTwice() + { + // arrange + var method = new Method + { + FullName = "System.Boolean DD.Collections.BitSetArray::BitSetArray_<_SetItems>b__b_0(System.Int32)" + }; + + // act twice to cover cached result + var result = method.CallName; + result = method.CallName; + + // assert + Assert.True (result == "BitSetArray_<_SetItems>b__b_0"); + } + + [Test] + public void MethodCallNameWhenFullNameIsNull() + { + // arrange + var method = new Method + { + FullName = null + }; + + // act + var result = method.CallName; + + // assert + Assert.True (result == ""); + } + + [Test] + public void MethodCallNameWhenFullNameIsEmpty() + { + // arrange + var method = new Method + { + FullName = string.Empty + }; + + // act + var result = method.CallName; + + // assert + Assert.True (result == ""); + } + + [Test] + public void MethodCallNameWhenFullNameIsInvalid() + { + // arrange + var method = new Method + { + FullName = "a::c" + }; + + // act + var result = method.CallName; // now covers all branches + + // assert + Assert.True (result == ""); + } + } +} diff --git a/main/OpenCover.Test/Framework/Model/SequencePointTests.cs b/main/OpenCover.Test/Framework/Model/SequencePointTests.cs index 891f36cf5..eedc8d25d 100644 --- a/main/OpenCover.Test/Framework/Model/SequencePointTests.cs +++ b/main/OpenCover.Test/Framework/Model/SequencePointTests.cs @@ -3,6 +3,7 @@ using System.Linq; using System.Text; using NUnit.Framework; +using NUnit.Framework.Constraints; using OpenCover.Framework.Model; namespace OpenCover.Test.Framework.Model @@ -88,5 +89,13 @@ public void TrackedMethodCountIsLimitedToMax() Assert.IsTrue(InstrumentationPoint.AddVisitCount(1, 1, 200)); Assert.AreEqual(int.MaxValue, list.First(x => x.UniqueSequencePoint == 1).TrackedMethodRefs.First(x => x.UniqueId == 1).VisitCount); } + + [Test] + public void CanDetermineSingleCharSequencePoint() + { + Assert.IsTrue(new SequencePoint { FileId = 1, StartLine = 1, StartColumn = 1, EndLine = 1, EndColumn = 2 }.IsSingleCharSequencePoint); + Assert.IsFalse(new SequencePoint { FileId = 1, StartLine = 1, StartColumn = 1, EndLine = 1, EndColumn = 3 }.IsSingleCharSequencePoint); + Assert.IsFalse(new SequencePoint { FileId = 1, StartLine = 1, StartColumn = 1, EndLine = 2, EndColumn = 2 }.IsSingleCharSequencePoint); + } } } diff --git a/main/OpenCover.Test/Framework/Persistance/BasePersistenceTests.cs b/main/OpenCover.Test/Framework/Persistance/BasePersistenceTests.cs index 698f10c63..029dc4992 100644 --- a/main/OpenCover.Test/Framework/Persistance/BasePersistenceTests.cs +++ b/main/OpenCover.Test/Framework/Persistance/BasePersistenceTests.cs @@ -24,7 +24,7 @@ public BasePersistanceStub(ICommandLine commandLine, ILog logger) public class BasePersistenceTests : UnityAutoMockContainerBase { - private readonly SkippedMethod[] _skippedReasonsModules = {SkippedMethod.Filter, SkippedMethod.MissingPdb}; + private readonly SkippedMethod[] _skippedReasonsModules = {SkippedMethod.Filter, SkippedMethod.MissingPdb, SkippedMethod.FolderExclusion, }; private readonly SkippedMethod[] _skippedReasonsClasses = { @@ -52,9 +52,9 @@ public void Can_Add_SeveralModules_To_Session() //arrange // act - var module1 = new Module {ModuleHash = "123", FullName = "Path1", Classes = new Class[0]}; + var module1 = new Module {ModuleHash = "123", ModulePath = "Path1", Classes = new Class[0]}; module1.Aliases.Add("Path1"); - var module2 = new Module {ModuleHash = "123", FullName = "Path2", Classes = new Class[0]}; + var module2 = new Module {ModuleHash = "123", ModulePath = "Path2", Classes = new Class[0]}; module2.Aliases.Add("Path2"); Instance.PersistModule(module1); Instance.PersistModule(module2); @@ -84,7 +84,7 @@ public void Can_GetBranchPoints_Of_MethodByToken() BranchPoint[] pts; var module = new Module { - FullName = "ModulePath", + ModulePath = "ModulePath", Classes = new[] { new Class @@ -118,7 +118,7 @@ public void Can_GetFullClassName_Of_MethodByToken() // arrange var module = new Module { - FullName = "ModulePath", + ModulePath = "ModulePath", Classes = new[] { new Class {FullName = "namespace.class", Methods = new[] {new Method {MetadataToken = 1001}}} @@ -143,7 +143,7 @@ public void Can_GetSequencePoints_Of_MethodByToken() InstrumentationPoint[] pts; var module = new Module { - FullName = "ModulePath", + ModulePath = "ModulePath", Classes = new[] { new Class @@ -181,9 +181,9 @@ public void Can_Merge_Modules_In_Session_When_HashMatched() .Returns(true); // act - var module1 = new Module {ModuleHash = "123", FullName = "Path1", Classes = new Class[0]}; + var module1 = new Module {ModuleHash = "123", ModulePath = "Path1", Classes = new Class[0]}; module1.Aliases.Add("Path1"); - var module2 = new Module {ModuleHash = "123", FullName = "Path2", Classes = new Class[0]}; + var module2 = new Module {ModuleHash = "123", ModulePath = "Path2", Classes = new Class[0]}; module2.Aliases.Add("Path2"); Instance.PersistModule(module1); Instance.PersistModule(module2); @@ -340,8 +340,8 @@ public void Commit_With_WithBranchPointsOnly() Assert.AreEqual(0, Instance.CoverageSession.Modules[0].Classes[0].Methods[0].Summary.NumSequencePoints); Assert.AreEqual(0, Instance.CoverageSession.Modules[0].Classes[0].Methods[0].Summary.VisitedSequencePoints); - Assert.AreEqual(1, Instance.CoverageSession.Modules[0].Classes[0].Methods[0].Summary.NumBranchPoints); - Assert.AreEqual(1, Instance.CoverageSession.Modules[0].Classes[0].Methods[0].Summary.VisitedBranchPoints); + Assert.AreEqual(0, Instance.CoverageSession.Modules[0].Classes[0].Methods[0].Summary.NumBranchPoints); + Assert.AreEqual(0, Instance.CoverageSession.Modules[0].Classes[0].Methods[0].Summary.VisitedBranchPoints); } [Test] @@ -416,7 +416,7 @@ public void GeBranchPoints_GetsZeroPoints_When_FunctionNotKnown() // arrange var module = new Module { - FullName = "ModuleName", + ModulePath = "ModuleName", Classes = new[] { new Class @@ -445,7 +445,7 @@ public void GetSequencePoints_GetsPoints_When_ModuleAndFunctionKnown_FirstPointI var methodPoint = new InstrumentationPoint {VisitCount = 2000}; var module = new Module { - FullName = "ModulePath", + ModulePath = "ModulePath", Classes = new[] { @@ -486,7 +486,7 @@ public void GetSequencePoints_GetsPoints_When_ModuleAndFunctionKnown_FirstPointI var seqPoint = new SequencePoint {VisitCount = 1000}; var module = new Module { - FullName = "ModulePath", + ModulePath = "ModulePath", Classes = new[] { @@ -525,7 +525,7 @@ public void GetSequencePoints_GetsZeroPoints_When_FunctionNotKnown() // arrange var module = new Module { - FullName = "ModuleName", + ModulePath = "ModuleName", Classes = new[] { new Class @@ -553,7 +553,7 @@ public void GetSequencePoints_GetsZeroPoints_When_ModuleNotKnown() // arrange Instance.PersistModule(new Module { - FullName = "ModuleName", + ModulePath = "ModuleName", Classes = new[] { @@ -590,7 +590,7 @@ public void GetTrackingMethod_RetrievesId_For_TrackedMethod() TrackedMethods = new[] { - new TrackedMethod {MetadataToken = 1234, Name = "MethodName", UniqueId = 5678} + new TrackedMethod {MetadataToken = 1234, FullName = "MethodName", UniqueId = 5678} } }; module.Aliases.Add("ModulePath"); @@ -614,7 +614,7 @@ public void GetTrackingMethod_ReturnsFase_For_UnTrackedMethod() TrackedMethods = new[] { - new TrackedMethod {MetadataToken = 1234, Name = "MethodName", UniqueId = 5678} + new TrackedMethod {MetadataToken = 1234, FullName = "MethodName", UniqueId = 5678} } }; module.Aliases.Add("ModulePath"); @@ -639,7 +639,7 @@ public void HideSkipped_With_File_Removes_EmptyClasses() var module = new Module { - FullName = "Keep", + ModulePath = "Keep", Classes = new[] { new Class @@ -650,7 +650,7 @@ public void HideSkipped_With_File_Removes_EmptyClasses() new Class { FullName = "RemoveClassThoughSkippedAttribute", - Methods = new[] {new Method {Name = "SkippedMethod", FileRef = new FileRef()}} + Methods = new[] {new Method {FullName = "SkippedMethod", FileRef = new FileRef()}} }, new Class { @@ -658,8 +658,8 @@ public void HideSkipped_With_File_Removes_EmptyClasses() Methods = new[] { - new Method {Name = "SkippedMethod", FileRef = new FileRef()}, - new Method {Name = "KeepMethod", FileRef = new FileRef()} + new Method {FullName = "SkippedMethod", FileRef = new FileRef()}, + new Method {FullName = "KeepMethod", FileRef = new FileRef()} } } } @@ -678,7 +678,7 @@ public void HideSkipped_With_File_Removes_EmptyClasses() // assert Assert.AreEqual(2, Instance.CoverageSession.Modules[0].Classes.Count()); Assert.AreEqual(1, Instance.CoverageSession.Modules[0].Classes[1].Methods.Count()); - Assert.AreEqual("KeepMethod", Instance.CoverageSession.Modules[0].Classes[1].Methods[0].Name); + Assert.AreEqual("KeepMethod", Instance.CoverageSession.Modules[0].Classes[1].Methods[0].FullName); } [Test] @@ -689,12 +689,12 @@ public void HideSkipped_With_File_Removes_UnreferencedFiles() .SetupGet(x => x.HideSkipped) .Returns(new List {SkippedMethod.File}); - var method = new Method {Name = "SkippedMethod", FileRef = new FileRef {UniqueId = 2}}; + var method = new Method {FullName = "SkippedMethod", FileRef = new FileRef {UniqueId = 2}}; method.MarkAsSkipped(SkippedMethod.File); Instance.PersistModule(new Module { - FullName = "Keep", + ModulePath = "Keep", Files = new[] {new File {UniqueId = 1, FullPath = "KeepFile"}, new File {UniqueId = 2}}, Classes = new[] { @@ -705,7 +705,7 @@ public void HideSkipped_With_File_Removes_UnreferencedFiles() new[] { method, - new Method {Name = "KeepMethod", FileRef = new FileRef {UniqueId = 1}} + new Method {FullName = "KeepMethod", FileRef = new FileRef {UniqueId = 1}} } } } @@ -734,7 +734,7 @@ public void HideSkipped_With_X_Removes_SkippedClasses( @class.MarkAsSkipped(reason); Instance.PersistModule(new Module { - FullName = "Keep", + ModulePath = "Keep", Classes = new[] { @class, @@ -759,12 +759,12 @@ public void HideSkipped_With_X_Removes_SkippedMethods( .SetupGet(x => x.HideSkipped) .Returns(new List {reason}); - var method = new Method {Name = "SkippedMethod", FileRef = new FileRef()}; + var method = new Method {FullName = "SkippedMethod", FileRef = new FileRef()}; method.MarkAsSkipped(reason); var module = new Module { - FullName = "Keep", + ModulePath = "Keep", Classes = new[] { new Class @@ -775,7 +775,7 @@ public void HideSkipped_With_X_Removes_SkippedMethods( new Class { FullName = "KeepClass", - Methods = new[] {method, new Method {Name = "KeepMethod", FileRef = new FileRef()}} + Methods = new[] {method, new Method {FullName = "KeepMethod", FileRef = new FileRef()}} } } }; @@ -790,7 +790,7 @@ public void HideSkipped_With_X_Removes_SkippedMethods( // assert Assert.AreEqual(1, Instance.CoverageSession.Modules[0].Classes.Count()); Assert.AreEqual(1, Instance.CoverageSession.Modules[0].Classes[0].Methods.Count()); - Assert.AreEqual("KeepMethod", Instance.CoverageSession.Modules[0].Classes[0].Methods[0].Name); + Assert.AreEqual("KeepMethod", Instance.CoverageSession.Modules[0].Classes[0].Methods[0].FullName); } [Test] @@ -802,17 +802,17 @@ public void HideSkipped_With_X_Removes_SkippedModules( .SetupGet(x => x.HideSkipped) .Returns(new List {reason}); - var module = new Module {FullName = "Skipped"}; + var module = new Module {ModulePath = "Skipped"}; module.MarkAsSkipped(reason); Instance.PersistModule(module); - Instance.PersistModule(new Module {FullName = "Keep"}); + Instance.PersistModule(new Module {ModulePath = "Keep"}); // act Instance.Commit(); // assert Assert.AreEqual(1, Instance.CoverageSession.Modules.Count()); - Assert.AreEqual("Keep", Instance.CoverageSession.Modules[0].FullName); + Assert.AreEqual("Keep", Instance.CoverageSession.Modules[0].ModulePath); } /// @@ -827,7 +827,7 @@ public void var point = new InstrumentationPoint {IsSkipped = false}; var module = new Module { - FullName = "Keep", + ModulePath = "Keep", Classes = new[] { new Class {Methods = new[] {new Method {MethodPoint = point}, new Method()}}, @@ -864,7 +864,7 @@ public void public void IsTracking_Fase_IfModuleSkipped() { // arrange - var module = new Module {FullName = "ModulePath"}; + var module = new Module {ModulePath = "ModulePath"}; module.MarkAsSkipped(SkippedMethod.Filter); module.Aliases.Add("ModulePath"); @@ -881,7 +881,7 @@ public void IsTracking_Fase_IfModuleSkipped() public void IsTracking_True_IfModuleKnown() { // arrange - var module = new Module {FullName = "ModulePath", Classes = new Class[0]}; + var module = new Module {ModulePath = "ModulePath", Classes = new Class[0]}; module.Aliases.Add("ModulePath"); Instance.PersistModule(module); @@ -1000,6 +1000,29 @@ public void SaveVisitPoints_Aggregates_Visits() Assert.AreEqual(3, InstrumentationPoint.GetVisitCount(pt2.UniqueSequencePoint)); } + [Test] + public void SaveVisitPoints_DoesNotProcessBufferWhenCountExceedsAvailableBufferSize() + { + // arrange + var pt1 = new SequencePoint(); + var pt2 = new SequencePoint(); + + var data = new List(); + + var points = new[] { pt1.UniqueSequencePoint, pt2.UniqueSequencePoint, pt2.UniqueSequencePoint, pt2.UniqueSequencePoint }; + data.AddRange(BitConverter.GetBytes((UInt32)points.Count() + 1)); + foreach (uint point in points) + data.AddRange(BitConverter.GetBytes(point)); + + // act + Instance.SaveVisitData(data.ToArray()); + + // assert + // no counts should exist for these points + Assert.AreEqual(0, InstrumentationPoint.GetVisitCount(pt1.UniqueSequencePoint)); + Assert.AreEqual(0, InstrumentationPoint.GetVisitCount(pt2.UniqueSequencePoint)); + } + [Test] public void SaveVisitPoints_Aggregates_Visits_ForTrackedMethods() { @@ -1044,7 +1067,7 @@ public void SaveVisitPoints_Warns_WhenPointID_IsOutOfRange_High() Instance.SaveVisitData(data.ToArray()); //assert - Container.GetMock().Verify(x => x.DebugFormat(It.IsAny(), + Container.GetMock().Verify(x => x.ErrorFormat(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny()), Times.Once()); } @@ -1060,7 +1083,7 @@ public void SaveVisitPoints_Warns_WhenPointID_IsOutOfRange_Low() Instance.SaveVisitData(data.ToArray()); //assert - Container.GetMock().Verify(x => x.DebugFormat(It.IsAny(), + Container.GetMock().Verify(x => x.ErrorFormat(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny()), Times.Once()); } diff --git a/main/OpenCover.Test/Framework/Persistance/FilePersistenceTests.cs b/main/OpenCover.Test/Framework/Persistance/FilePersistenceTests.cs index f536041e5..e3bcabfbf 100644 --- a/main/OpenCover.Test/Framework/Persistance/FilePersistenceTests.cs +++ b/main/OpenCover.Test/Framework/Persistance/FilePersistenceTests.cs @@ -2,7 +2,6 @@ using System.Collections.Generic; using System.IO; using System.Text; -using System.Threading; using Moq; using NUnit.Framework; using OpenCover.Framework; @@ -62,7 +61,9 @@ public void CanLoadExistingFileWhenInitialising() var moduleHash = Guid.NewGuid().ToString(); var persistence = new FilePersistance(_mockCommandLine.Object, _mockLogger.Object); persistence.Initialise(_filePath, false); - var point = new SequencePoint(); + var point = new SequencePoint() + // BranchPoints within SequencePoint shorther than 3 characters will be removed + {StartLine = 1, EndLine = 1, StartColumn = 1, EndColumn = 4}; var branchPoint = new BranchPoint{Path = 0, OffsetPoints = new List()}; var branchPoint2 = new BranchPoint { Path = 1, OffsetPoints = new List{1,2}}; var file = new OpenCover.Framework.Model.File(); @@ -125,5 +126,42 @@ public void CanLoadExistingFileWhenInitialising() Assert.AreEqual(0, persistence2.CoverageSession.Modules[0].Classes[0].Summary.NumSequencePoints); Assert.AreEqual(0, persistence2.CoverageSession.Modules[0].Classes[0].Methods[0].Summary.NumSequencePoints); } + + [Test] + public void HandleFileAccess_SuppliedActionSuccess_ReturnsTrue() + { + // arrange + var persistence = new FilePersistance(_mockCommandLine.Object, _mockLogger.Object); + + // act + Assert.IsTrue(persistence.HandleFileAccess(() => { }, "file_name")); + } + + [Test] + public void HandleFileAccess_SuppliedActionThrows_Exception_ReturnsException() + { + // arrange + var persistence = new FilePersistance(_mockCommandLine.Object, _mockLogger.Object); + + // act + var expected = new Exception(); + var actual = Assert.Throws(() => persistence.HandleFileAccess(() => { throw expected; }, "file_name")); + + // assert + Assert.AreSame(expected, actual); + } + + [Test] + [TestCase(typeof(DirectoryNotFoundException))] + [TestCase(typeof(IOException))] + [TestCase(typeof(UnauthorizedAccessException))] + public void HandleFileAccess_SuppliedActionThrows_Exception_ReturnsFalse(Type exception) + { + // arrange + var persistence = new FilePersistance(_mockCommandLine.Object, _mockLogger.Object); + + // act + Assert.IsFalse(persistence.HandleFileAccess(() => { throw (Exception) Activator.CreateInstance(exception); }, "file_name")); + } } } diff --git a/main/OpenCover.Test/Framework/Service/ProfilerCommunicationTests.cs b/main/OpenCover.Test/Framework/Service/ProfilerCommunicationTests.cs index 9286c6f7f..1245ff2be 100644 --- a/main/OpenCover.Test/Framework/Service/ProfilerCommunicationTests.cs +++ b/main/OpenCover.Test/Framework/Service/ProfilerCommunicationTests.cs @@ -18,7 +18,11 @@ public void TrackAssembly_Adds_AssemblyToModel_If_FilterUseAssembly_Returns_True { // arrange Container.GetMock() - .Setup(x => x.UseAssembly(It.IsAny())) + .Setup(x => x.UseAssembly(It.IsAny(), It.IsAny())) + .Returns(true); + + Container.GetMock() + .Setup(x => x.UseModule(It.IsAny())) .Returns(true); Container.GetMock() @@ -39,7 +43,7 @@ public void TrackAssembly_Adds_AssemblyToModel_If_FilterUseAssembly_Returns_True .Returns(new Module()); // act - var track = Instance.TrackAssembly("moduleName", "assemblyName"); + var track = Instance.TrackAssembly("processName", "moduleName", "assemblyName"); // assert Assert.IsTrue(track); @@ -68,7 +72,7 @@ public void TrackAssembly_Adds_AssemblyToModel_If_FilterUseTestAssembly_Returns_ .Returns((m, f) => m); // act - var track = Instance.TrackAssembly("moduleName", "assemblyName"); + var track = Instance.TrackAssembly("processName", "moduleName", "assemblyName"); // assert Assert.IsFalse(track); @@ -81,9 +85,13 @@ public void TrackAssembly_Adds_AssemblyToModel_AsSkipped_If_FilterUseAssembly_Re { // arrange Container.GetMock() - .Setup(x => x.UseAssembly(It.IsAny())) + .Setup(x => x.UseAssembly(It.IsAny(), It.IsAny())) .Returns(false); + Container.GetMock() + .Setup(x => x.UseModule(It.IsAny())) + .Returns(true); + var mockModelBuilder = new Mock(); Container.GetMock() .Setup(x => x.CreateModelBuilder(It.IsAny(), It.IsAny())) @@ -94,7 +102,7 @@ public void TrackAssembly_Adds_AssemblyToModel_AsSkipped_If_FilterUseAssembly_Re .Returns(new Module()); // act - var track = Instance.TrackAssembly("moduleName", "assemblyName"); + var track = Instance.TrackAssembly("processName", "moduleName", "assemblyName"); // assert Assert.IsFalse(track); @@ -107,7 +115,11 @@ public void TrackAssembly_Adds_AssemblyToModel_AsSkipped_If_CanInstrument_Return { // arrange Container.GetMock() - .Setup(x => x.UseAssembly(It.IsAny())) + .Setup(x => x.UseAssembly(It.IsAny(), It.IsAny())) + .Returns(true); + + Container.GetMock() + .Setup(x => x.UseModule(It.IsAny())) .Returns(true); Container.GetMock() @@ -128,7 +140,7 @@ public void TrackAssembly_Adds_AssemblyToModel_AsSkipped_If_CanInstrument_Return .Returns(false); // act - var track = Instance.TrackAssembly("moduleName", "assemblyName"); + var track = Instance.TrackAssembly("processName", "moduleName", "assemblyName"); // assembly Assert.IsFalse(track); @@ -137,12 +149,51 @@ public void TrackAssembly_Adds_AssemblyToModel_AsSkipped_If_CanInstrument_Return } + [Test] + public void TrackAssembly_Adds_AssemblyToModel_AsSkipped_If_UseModuleIsFalse() + { + // arrange + Container.GetMock() + .Setup(x => x.UseModule(It.IsAny())) + .Returns(false); + + Container.GetMock() + .Setup(x => x.ExcludeByAttribute(It.IsAny())) + .Returns(false); + + var mockModelBuilder = new Mock(); + Container.GetMock() + .Setup(x => x.CreateModelBuilder(It.IsAny(), It.IsAny())) + .Returns(mockModelBuilder.Object); + + mockModelBuilder + .Setup(x => x.BuildModuleModel(It.IsAny())) + .Returns(new Module()); + + mockModelBuilder + .SetupGet(x => x.CanInstrument) + .Returns(false); + + // act + var track = Instance.TrackAssembly("processName", "moduleName", "assemblyName"); + + // assembly + Assert.IsFalse(track); + Container.GetMock() + .Verify(x => x.PersistModule(It.Is(m => m.SkippedDueTo == SkippedMethod.FolderExclusion)), Times.Once()); + + } + [Test] public void TrackAssembly_Adds_AssemblyToModel_AsSkipped_If_ExcludedByAttribute() { // arrange Container.GetMock() - .Setup(x => x.UseAssembly(It.IsAny())) + .Setup(x => x.UseAssembly(It.IsAny(), It.IsAny())) + .Returns(true); + + Container.GetMock() + .Setup(x => x.UseModule(It.IsAny())) .Returns(true); Container.GetMock() @@ -163,7 +214,7 @@ public void TrackAssembly_Adds_AssemblyToModel_AsSkipped_If_ExcludedByAttribute( .Returns(true); // act - var track = Instance.TrackAssembly("moduleName", "assemblyName"); + var track = Instance.TrackAssembly("processName", "moduleName", "assemblyName"); // assembly Assert.IsFalse(track); @@ -198,12 +249,12 @@ public void GetSequencePoints_Returns_False_When_No_Data_In_Model() .Setup(x => x.IsTracking(It.IsAny())) .Returns(true); Container.GetMock() - .Setup(x => x.InstrumentClass(It.IsAny(), It.IsAny())) + .Setup(x => x.InstrumentClass(It.IsAny(), It.IsAny(), It.IsAny())) .Returns(true); // act InstrumentationPoint[] instrumentPoints; - var result = Instance.GetSequencePoints("moduleName", "moduleName", 1, out instrumentPoints); + var result = Instance.GetSequencePoints("processName", "moduleName", "moduleName", 1, out instrumentPoints); // assert Assert.IsFalse(result); @@ -224,7 +275,7 @@ public void GetSequencePoints_Returns_False_When_Not_Tracking_Assembly() // act InstrumentationPoint[] instrumentPoints; - var result = Instance.GetSequencePoints("moduleName", "moduleName", 1, out instrumentPoints); + var result = Instance.GetSequencePoints("processName", "moduleName", "moduleName", 1, out instrumentPoints); // assert Assert.IsFalse(result); @@ -249,7 +300,7 @@ public void GetSequencePoints_Returns_False_When_Not_Tracking_Class() // act InstrumentationPoint[] instrumentPoints; - var result = Instance.GetSequencePoints("moduleName", "moduleName", 1, out instrumentPoints); + var result = Instance.GetSequencePoints("processName", "moduleName", "moduleName", 1, out instrumentPoints); // assert Assert.IsFalse(result); @@ -270,12 +321,12 @@ public void GetSequencePoints_Returns_SequencePoints_When_Data_In_Model() .Setup(x => x.IsTracking(It.IsAny())) .Returns(true); Container.GetMock() - .Setup(x => x.InstrumentClass(It.IsAny(), It.IsAny())) + .Setup(x => x.InstrumentClass(It.IsAny(), It.IsAny(), It.IsAny())) .Returns(true); // act InstrumentationPoint[] instrumentPoints; - var result = Instance.GetSequencePoints("moduleName", "moduleName", 1, out instrumentPoints); + var result = Instance.GetSequencePoints("processName", "moduleName", "moduleName", 1, out instrumentPoints); // assert Assert.IsTrue(result); @@ -296,12 +347,12 @@ public void GetBranchPoints_Returns_False_When_No_Data_In_Model() .Setup(x => x.IsTracking(It.IsAny())) .Returns(true); Container.GetMock() - .Setup(x => x.InstrumentClass(It.IsAny(), It.IsAny())) + .Setup(x => x.InstrumentClass(It.IsAny(), It.IsAny(), It.IsAny())) .Returns(true); // act BranchPoint[] instrumentPoints; - var result = Instance.GetBranchPoints("moduleName", "moduleName", 1, out instrumentPoints); + var result = Instance.GetBranchPoints("processName", "moduleName", "moduleName", 1, out instrumentPoints); // assert Assert.IsFalse(result); @@ -312,7 +363,7 @@ public void GetBranchPoints_Returns_False_When_No_Data_In_Model() public void GetBranchPoints_Returns_SequencePoints_When_Data_In_Model() { // arrange - var points = new[] { new BranchPoint(), }; + var points = new[] { new BranchPoint() }; Container.GetMock() .Setup(x => x.GetBranchPointsForFunction(It.IsAny(), It.IsAny(), out points)) .Returns(true) @@ -321,12 +372,12 @@ public void GetBranchPoints_Returns_SequencePoints_When_Data_In_Model() .Setup(x => x.IsTracking(It.IsAny())) .Returns(true); Container.GetMock() - .Setup(x => x.InstrumentClass(It.IsAny(), It.IsAny())) + .Setup(x => x.InstrumentClass(It.IsAny(), It.IsAny(), It.IsAny())) .Returns(true); // act BranchPoint[] instrumentPoints; - var result = Instance.GetBranchPoints("moduleName", "moduleName", 1, out instrumentPoints); + var result = Instance.GetBranchPoints("processName", "moduleName", "moduleName", 1, out instrumentPoints); // assert Assert.IsTrue(result); @@ -344,7 +395,7 @@ public void TrackMethod_True_WhenMethodIsTracked() .Returns(true); // act - uint uniqueId = 0; + uint uniqueId; var result = Instance.TrackMethod("", "", 0, out uniqueId); // assert @@ -356,18 +407,32 @@ public void TrackMethod_True_WhenMethodIsTracked() public void TrackMethod_False_When_MethodNotTracked() { // arrange - uint trackid = 0; + uint trackid; Container.GetMock() .Setup(x => x.GetTrackingMethod(It.IsAny(), It.IsAny(), It.IsAny(), out trackid)) .Returns(false); // act - uint uniqueId = 0; + uint uniqueId; var result = Instance.TrackMethod("", "", 0, out uniqueId); // assert Assert.IsFalse(result); } + [Test] + [TestCase(true)] + [TestCase(false)] + public void TrackProcessResponse_IsFulfilledByFilter(bool expected) + { + // arrange + Container.GetMock().Setup(x => x.InstrumentProcess(It.IsAny())).Returns(expected); + + // action + var response = Instance.TrackProcess("abc"); + + // assert + Assert.AreEqual(expected, response); + } } } diff --git a/main/OpenCover.Test/Framework/Symbols/CecilSymbolManagerTests.cs b/main/OpenCover.Test/Framework/Symbols/CecilSymbolManagerTests.cs index 1371ae6d2..77fb938d3 100644 --- a/main/OpenCover.Test/Framework/Symbols/CecilSymbolManagerTests.cs +++ b/main/OpenCover.Test/Framework/Symbols/CecilSymbolManagerTests.cs @@ -161,7 +161,7 @@ public void GetBranchPointsForMethodToken_OneBranch() var methods = _reader.GetMethodsForType(type, new File[0]); // act - var points = _reader.GetBranchPointsForToken(methods.First(x => x.Name.Contains("::HasSingleDecision")).MetadataToken); + var points = _reader.GetBranchPointsForToken(methods.First(x => x.FullName.Contains("::HasSingleDecision")).MetadataToken); // assert Assert.IsNotNull(points); @@ -188,11 +188,29 @@ public void GetBranchPointsForMethodToken_Using_Where_GeneratedBranchesIgnored() var methods = _reader.GetMethodsForType(type, new File[0]); // act - var points = _reader.GetBranchPointsForToken(methods.First(x => x.Name.Contains("::HasSimpleUsingStatement")).MetadataToken); + var points = _reader.GetBranchPointsForToken(methods.First(x => x.FullName.Contains("::HasSimpleUsingStatement")).MetadataToken); Assert.AreEqual(2, points.Length); } + [Test] + public void GetBranchPointsForMethodToken_GeneratedBranches_DueToCachedAnonymousMethodDelegate_Ignored() + { + // arrange + _mockFilter + .Setup(x => x.InstrumentClass(It.IsAny(), It.IsAny())) + .Returns(true); + + var types = _reader.GetInstrumentableTypes(); + var type = types.First(x => x.FullName == typeof(DeclaredConstructorClass).FullName); + var methods = _reader.GetMethodsForType(type, new File[0]); + + // act + var points = _reader.GetBranchPointsForToken(methods.First(x => x.FullName.Contains("::HasSimpleTaskWithLambda")).MetadataToken); + + Assert.AreEqual(0, points.Length); + } + [Test] public void GetBranchPointsForMethodToken_TwoBranch() { @@ -206,7 +224,7 @@ public void GetBranchPointsForMethodToken_TwoBranch() var methods = _reader.GetMethodsForType(type, new File[0]); // act - var points = _reader.GetBranchPointsForToken(methods.First(x => x.Name.Contains("::HasTwoDecisions")).MetadataToken); + var points = _reader.GetBranchPointsForToken(methods.First(x => x.FullName.Contains("::HasTwoDecisions")).MetadataToken); // assert Assert.IsNotNull(points); @@ -230,7 +248,7 @@ public void GetBranchPointsForMethodToken_CompleteIf() var methods = _reader.GetMethodsForType(type, new File[0]); // act - var points = _reader.GetBranchPointsForToken(methods.First(x => x.Name.Contains("::HasCompleteIf")).MetadataToken); + var points = _reader.GetBranchPointsForToken(methods.First(x => x.FullName.Contains("::HasCompleteIf")).MetadataToken); // assert Assert.IsNotNull(points); @@ -253,7 +271,7 @@ public void GetBranchPointsForMethodToken_Switch() var methods = _reader.GetMethodsForType(type, new File[0]); // act - var points = _reader.GetBranchPointsForToken(methods.First(x => x.Name.Contains("::HasSwitch")).MetadataToken); + var points = _reader.GetBranchPointsForToken(methods.First(x => x.FullName.Contains("::HasSwitch")).MetadataToken); // assert Assert.IsNotNull(points); @@ -281,7 +299,7 @@ public void GetBranchPointsForMethodToken_SwitchWithDefault() var methods = _reader.GetMethodsForType(type, new File[0]); // act - var points = _reader.GetBranchPointsForToken(methods.First(x => x.Name.Contains("::HasSwitchWithDefault")).MetadataToken); + var points = _reader.GetBranchPointsForToken(methods.First(x => x.FullName.Contains("::HasSwitchWithDefault")).MetadataToken); // assert Assert.IsNotNull(points); @@ -309,7 +327,7 @@ public void GetBranchPointsForMethodToken_SwitchWithBreaks() var methods = _reader.GetMethodsForType(type, new File[0]); // act - var points = _reader.GetBranchPointsForToken(methods.First(x => x.Name.Contains("::HasSwitchWithBreaks")).MetadataToken); + var points = _reader.GetBranchPointsForToken(methods.First(x => x.FullName.Contains("::HasSwitchWithBreaks")).MetadataToken); // assert Assert.IsNotNull(points); @@ -337,7 +355,7 @@ public void GetBranchPointsForMethodToken_SwitchWithMultipleCases() var methods = _reader.GetMethodsForType(type, new File[0]); // act - var points = _reader.GetBranchPointsForToken(methods.First(x => x.Name.Contains("::HasSwitchWithMultipleCases")).MetadataToken); + var points = _reader.GetBranchPointsForToken(methods.First(x => x.FullName.Contains("::HasSwitchWithMultipleCases")).MetadataToken); // assert Assert.IsNotNull(points); @@ -370,7 +388,7 @@ public void GetBranchPointsForMethodToken_AssignsNegativeLineNumberToBranchesInM var methods = _reader.GetMethodsForType(type, new File[0]); // act - var points = _reader.GetBranchPointsForToken(methods.First(x => x.Name.Contains("::Equals")).MetadataToken); + var points = _reader.GetBranchPointsForToken(methods.First(x => x.FullName.Contains("::Equals")).MetadataToken); // assert Assert.IsNotNull(points); @@ -434,11 +452,11 @@ public void GetComplexityForMethodToken_TwoBranch() .Returns(true); var types = _reader.GetInstrumentableTypes(); - var type = types.Where(x => x.FullName == typeof(DeclaredConstructorClass).FullName).First(); + var type = types.First(x => x.FullName == typeof(DeclaredConstructorClass).FullName); var methods = _reader.GetMethodsForType(type, new File[0]); // act - var complexity = _reader.GetCyclomaticComplexityForToken(methods.Where(x => x.Name.Contains("::HasTwoDecisions")).First().MetadataToken); + var complexity = _reader.GetCyclomaticComplexityForToken(methods.First(x => x.FullName.Contains("::HasTwoDecisions")).MetadataToken); // assert Assert.AreEqual(3, complexity); @@ -453,7 +471,7 @@ public void AbstractPropertyGetters_AreNotReturned() .Returns(true); var types = _reader.GetInstrumentableTypes(); - var type = types.Where(x => x.FullName == typeof(AbstractBase).FullName).First(); + var type = types.First(x => x.FullName == typeof(AbstractBase).FullName); // act var methods = _reader.GetMethodsForType(type, new File[0]); @@ -471,7 +489,7 @@ public void AbstractPropertySetters_AreNotReturned() .Returns(true); var types = _reader.GetInstrumentableTypes(); - var type = types.Where(x => x.FullName == typeof(AbstractBase).FullName).First(); + var type = types.First(x => x.FullName == typeof(AbstractBase).FullName); // act var methods = _reader.GetMethodsForType(type, new File[0]); @@ -489,7 +507,7 @@ public void AbstractMethods_AreNotReturned() .Returns(true); var types = _reader.GetInstrumentableTypes(); - var type = types.Where(x => x.FullName == typeof(AbstractBase).FullName).First(); + var type = types.First(x => x.FullName == typeof(AbstractBase).FullName); // act var methods = _reader.GetMethodsForType(type, new File[0]); @@ -507,7 +525,7 @@ public void GetSequencePointsFor_OverridePropertyGetter() .Returns(true); var types = _reader.GetInstrumentableTypes(); - var type = types.Where(x => x.FullName == typeof(Concrete).FullName).First(); + var type = types.First(x => x.FullName == typeof(Concrete).FullName); var methods = _reader.GetMethodsForType(type, new File[0]); // act @@ -574,7 +592,7 @@ public void Can_Exclude_A_Property_By_An_Attribute() var methods = _reader.GetMethodsForType(target, new File[0]); Assert.True(methods.Any()); - Assert.True(methods.First(y => y.Name.EndsWith("::get_Name()")).SkippedDueTo == SkippedMethod.Attribute); + Assert.True(methods.First(y => y.FullName.EndsWith("::get_Name()")).SkippedDueTo == SkippedMethod.Attribute); } [Test] @@ -595,7 +613,7 @@ public void Can_Exclude_A_Ctor_By_An_Attribute() var methods = _reader.GetMethodsForType(target, new File[0]); Assert.True(methods.Any()); - Assert.True(methods.First(y => y.Name.EndsWith("::.ctor()")).SkippedDueTo == SkippedMethod.Attribute); + Assert.True(methods.First(y => y.FullName.EndsWith("::.ctor()")).SkippedDueTo == SkippedMethod.Attribute); } [Test] @@ -616,7 +634,7 @@ public void Can_Exclude_A_Method_By_An_Attribute() var methods = _reader.GetMethodsForType(target, new File[0] ); Assert.True(methods.Any()); - Assert.True(methods.First(y => y.Name.EndsWith("::Method()")).SkippedDueTo == SkippedMethod.Attribute); + Assert.True(methods.First(y => y.FullName.EndsWith("::Method()")).SkippedDueTo == SkippedMethod.Attribute); } [Test] @@ -636,21 +654,21 @@ public void Can_Exclude_A_Method_By_An_FileFilter() var methods = _reader.GetMethodsForType(target, new File[0]); Assert.True(methods.Any()); - Assert.True(methods.First(y => y.Name.EndsWith("::Method()")).SkippedDueTo == SkippedMethod.File); + Assert.True(methods.First(y => y.FullName.EndsWith("::Method()")).SkippedDueTo == SkippedMethod.File); } [Test] public void Can_Exclude_AutoImplmentedProperties() { // arrange - var filter = new Filter(); + var filter = new Filter(false); _mockFilter .Setup(x => x.InstrumentClass(It.IsAny(), It.IsAny())) .Returns(true); _mockFilter .Setup(x => x.IsAutoImplementedProperty(It.IsAny())) - .Returns(x => filter.IsAutoImplementedProperty(x)); + .Returns(filter.IsAutoImplementedProperty); _mockCommandLine.Setup(x => x.SkipAutoImplementedProperties).Returns(true); @@ -662,8 +680,8 @@ public void Can_Exclude_AutoImplmentedProperties() // assert Assert.True(methods.Any()); - Assert.AreEqual(SkippedMethod.AutoImplementedProperty, methods.First(y => y.Name.EndsWith("AutoProperty()")).SkippedDueTo); - Assert.AreEqual((SkippedMethod)0, methods.First(y => y.Name.EndsWith("PropertyWithBackingField()")).SkippedDueTo); + Assert.AreEqual(SkippedMethod.AutoImplementedProperty, methods.First(y => y.FullName.EndsWith("AutoProperty()")).SkippedDueTo); + Assert.AreEqual((SkippedMethod)0, methods.First(y => y.FullName.EndsWith("PropertyWithBackingField()")).SkippedDueTo); } [Test] @@ -771,13 +789,13 @@ public void GetBranchPointsForMethodToken_UsingWithException_Issue243_IgnoresBra var types = _reader.GetInstrumentableTypes(); var type = types.First(x => x.FullName == typeof(DeclaredConstructorClass).FullName); var methods = _reader.GetMethodsForType(type, new File[0]); - var token = methods.First(x => x.Name.Contains("::UsingWithException_Issue243")).MetadataToken; + var token = methods.First(x => x.FullName.Contains("::UsingWithException_Issue243")).MetadataToken; var assembly = AssemblyDefinition.ReadAssembly(_location); var md = assembly.MainModule.GetTypes() .SelectMany(s => s.Methods) .First(m => m.MetadataToken.ToInt32() == token); - // check that the method is laid out the way we discovered it t be during the defect + // check that the method is laid out the way we discovered it to be during the defect Assert.AreEqual(1, md.Body.ExceptionHandlers.Count); Assert.NotNull(md.Body.ExceptionHandlers[0].HandlerStart); Assert.Null(md.Body.ExceptionHandlers[0].HandlerEnd); @@ -791,5 +809,27 @@ public void GetBranchPointsForMethodToken_UsingWithException_Issue243_IgnoresBra Assert.IsNotNull(points); Assert.AreEqual(0, points.Count(), "The branch point in the 'generated' finally block should be ignored"); } + + [Test] + public void GetBranchPointsForMethodToken_IgnoresSwitchIn_GeneratedMoveNext() + { + // arrange + _mockFilter + .Setup(x => x.InstrumentClass(It.IsAny(), It.IsAny())) + .Returns(true); + + var types = _reader.GetInstrumentableTypes(); + var nested = typeof (Iterator).GetNestedTypes(BindingFlags.NonPublic).First(); + var type = types.First(x => x.FullName.EndsWith(nested.Name)); + var methods = _reader.GetMethodsForType(type, new File[0]); + var method = methods.First(x => x.FullName.EndsWith("::MoveNext()")); + + // act + var points = _reader.GetBranchPointsForToken(method.MetadataToken); + + // assert + Assert.AreEqual(0, points.Count()); + + } } } \ No newline at end of file diff --git a/main/OpenCover.Test/Framework/Utility/CodeCoverageStringTextSourceTest.cs b/main/OpenCover.Test/Framework/Utility/CodeCoverageStringTextSourceTest.cs new file mode 100644 index 000000000..898d9953d --- /dev/null +++ b/main/OpenCover.Test/Framework/Utility/CodeCoverageStringTextSourceTest.cs @@ -0,0 +1,437 @@ +/* + * Created by SharpDevelop. + * User: ddur + * Date: 8.1.2016. + * Time: 15:14 + * + */ +using System; +using NUnit.Framework; +using OpenCover.Framework.Model; +using OpenCover.Framework.Utility; + +namespace OpenCover.Test.Framework.Utility +{ + [TestFixture] + public class CodeCoverageStringTextSourceTest + { + [Test] + public void ConstructWithNullString() + { + // arrange + var source = new CodeCoverageStringTextSource(null, ""); + + // assert + Assert.True (source.LinesCount == 0); + + // act + var result = source.GetLine(1); // not existing line index + + // assert + Assert.True (result == string.Empty); + + // act + result = source.GetLine(0); // invalid line index + + // assert + Assert.True (result == string.Empty); + } + + [Test] + public void ConstructWithEmptyString() + { + // arrange + var source = new CodeCoverageStringTextSource(string.Empty, ""); + + // assert + Assert.True (source.LinesCount == 0); + + // act + var result = source.GetLine(1); // not existing line index + + // assert + Assert.True (result == string.Empty); + + // act + result = source.GetLine(0); // invalid line index + + // assert + Assert.True (result == string.Empty); + + // act + var sp = new SequencePoint { StartLine = 1, StartColumn = 1, EndLine = 1, EndColumn = 6}; + result = source.GetText(sp); + + // assert + Assert.True (result == string.Empty); + + // act + sp = new SequencePoint { StartLine = -1, StartColumn = -1, EndLine = -2, EndColumn = 6}; + result = source.GetText(sp); + + // assert + Assert.True (result == string.Empty); + } + + [Test] + public void ConstructWithSingleLine() + { + // arrange + const string input = "single line"; + var source = new CodeCoverageStringTextSource(input, ""); + + // assert + Assert.True (source.LinesCount == 1); + + // act + var result = source.GetLine(1); // existing line index + + // assert + Assert.True (result == input); + + // act + result = source.GetLine(0); // invalid line index + + // assert + Assert.True (result == string.Empty); + + // act + var sp = new SequencePoint { StartLine = 1, StartColumn = 1, EndLine = 1, EndColumn = 7}; + result = source.GetText(sp); + + // assert + Assert.True (result == "single"); + + // act with too small StartColumn + sp = new SequencePoint { StartLine = 1, StartColumn = -1, EndLine = 1, EndColumn = 7}; + result = source.GetText(sp); + + // assert + Assert.True (result == "single"); + + // act with too large StartColumn + sp = new SequencePoint { StartLine = 1, StartColumn = 19, EndLine = 1, EndColumn = 20}; + result = source.GetText(sp); + + // assert + Assert.True (result == ""); + + // act with too small EndColumn + sp = new SequencePoint { StartLine = 1, StartColumn = 1, EndLine = 1, EndColumn = 0}; + result = source.GetText(sp); + + // assert + Assert.True (result == ""); + + // act with too large EndColumn + sp = new SequencePoint { StartLine = 1, StartColumn = 1, EndLine = 1, EndColumn = 20}; + result = source.GetText(sp); + + // assert + Assert.True (result == "single line"); + } + + [Test] + public void ConstructWithTwoLines() + { + // arrange + const string input = "\tfirst line\n\tsecond line\r"; + var source = new CodeCoverageStringTextSource(input, ""); + + // assert + Assert.True (source.LinesCount == 2); + + // act with existing line index + var result = source.GetLine(1); + + // assert + Assert.True (result == "\tfirst line\n"); + + // act with existing line index + result = source.GetLine(2); + + // assert + Assert.True (result == "\tsecond line\r"); + + // act with invalid line index + result = source.GetLine(0); + + // assert + Assert.True (result == string.Empty); + + // act + var sp = new SequencePoint { StartLine = 2, StartColumn = 9, EndLine = 2, EndColumn = 13}; + result = source.GetText(sp); + + // assert + Assert.True (result == "line"); + + // act with two lines request + sp = new SequencePoint { StartLine = 1, StartColumn = 8, EndLine = 2, EndColumn = 13}; + result = source.GetText(sp); + + // assert + Assert.True (result == "line\n\tsecond line"); + + // act with extended two lines request + sp = new SequencePoint { StartLine = 1, StartColumn = -8, EndLine = 2, EndColumn = 30}; + result = source.GetText(sp); + + // assert + Assert.True (result == "\tfirst line\n\tsecond line\r"); + + // act with invalid first line request + sp = new SequencePoint { StartLine = 1, StartColumn = 28, EndLine = 2, EndColumn = 30}; + result = source.GetText(sp); + + // assert + Assert.True (result == "\tsecond line\r"); + + // act with invalid first line and invalid second line request + sp = new SequencePoint { StartLine = 1, StartColumn = 28, EndLine = 2, EndColumn = 0}; + result = source.GetText(sp); + + // assert + Assert.True (result == ""); + } + + [Test] + public void ConstructWithTwoLinesNoCrLfAtEof() + { + // arrange + const string input = "\tfirst line\r\tsecond line"; + var source = new CodeCoverageStringTextSource(input, ""); + + // assert + Assert.True (source.LinesCount == 2); + + // act + var result = source.GetLine(1); // existing line index + + // assert + Assert.True (result == "\tfirst line\r"); + + // act + result = source.GetLine(2); // existing line index + + // assert + Assert.True (result == "\tsecond line"); + + // act + result = source.GetLine(0); // invalid line index + + // assert + Assert.True (result == string.Empty); + + // act on first line + var sp = new SequencePoint { StartLine = 1, StartColumn = 8, EndLine = 1, EndColumn = 12}; + result = source.GetText(sp); + + // assert + Assert.True (result == "line"); + + // act on second line + sp = new SequencePoint { StartLine = 2, StartColumn = 9, EndLine = 2, EndColumn = 13}; + result = source.GetText(sp); + + // assert + Assert.True (result == "line"); + } + + [Test] + public void ConstructWithFiveLines() + { + // arrange + const string input = "\tfirst line\n \n\tthird line\r\n \r fifth line\r"; + var source = new CodeCoverageStringTextSource(input, ""); + + // assert + Assert.True (source.LinesCount == 5); + + // act + var result = source.GetLine(1); // existing line index + + // assert + Assert.True (result == "\tfirst line\n"); + + // act + result = source.GetLine(2); // existing line index + + // assert + Assert.True (result == " \n"); + + // act + result = source.GetLine(3); // existing line index + + // assert + Assert.True (result == "\tthird line\r\n"); + + // act + result = source.GetLine(4); // existing line index + + // assert + Assert.True (result == " \r"); + + // act + result = source.GetLine(5); // existing line index + + // assert + Assert.True (result == " fifth line\r"); + + // act + result = source.GetLine(9); // invalid line index + + // assert + Assert.True (result == string.Empty); + + // act third line request + var sp = new SequencePoint { StartLine = 3, StartColumn = 8, EndLine = 3, EndColumn = 12}; + result = source.GetText(sp); + + // assert + Assert.True (result == "line"); + + // act invalid two lines request + sp = new SequencePoint { StartLine = 1, StartColumn = 8, EndLine = 2, EndColumn = 13}; + result = source.GetText(sp); + + // assert + Assert.True (result == "line\n \n"); + + // act valid two lines request + sp = new SequencePoint { StartLine = 1, StartColumn = 8, EndLine = 2, EndColumn = 2}; + result = source.GetText(sp); + + // assert + Assert.True (result == "line\n "); + + // act three lines request + sp = new SequencePoint { StartLine = 1, StartColumn = 8, EndLine = 3, EndColumn = 12}; + result = source.GetText(sp); + + // assert + Assert.True (result == "line\n \n\tthird line"); + } + + [Test] + public void CountLinesWithLineFeed() + { + + // arrange + const string input = "\n\n\n\n\n\n\n"; + var source = new CodeCoverageStringTextSource(input, ""); + + // assert + Assert.True (source.LinesCount == 7); + + // act + var result = source.GetLine(1); // existing line index + + // assert + Assert.True (result == "\n"); + + } + + [Test] + public void CountLinesWithCrLf() + { + + // arrange + const string input = "\r\n\r\n\r\n\r\n"; + var source = new CodeCoverageStringTextSource(input, ""); + + // assert + Assert.True (source.LinesCount == 4); + + // act + var result = source.GetLine(1); // existing line index + + // assert + Assert.True (result == "\r\n"); + + } + + [Test] + public void CountLinesWithMixedLineEnd() + { + + // arrange + const string input = "\r\r\r\n \r\n \r\n \r \n \n\n\n\r\n\n"; + // 1 2 3 4 5 6 7 8 910 1112 + var source = new CodeCoverageStringTextSource(input, ""); + + // assert + Assert.True (source.LinesCount == 12); + + // act + var result = source.GetLine(1); // existing line index + + // assert + Assert.True (result == "\r"); + + } + + [Test] + public void GetSource() + { + var timeReference = DateTime.UtcNow; System.Threading.Thread.Sleep(100); + string fileName = System.IO.Path.GetTempPath() + Guid.NewGuid(); + string cSharpFileName = fileName+".cs"; + string vBasicFileName = fileName+".vb"; + string[] lines = { "First line", "Second line", "Third line" }; + + // act on not existing file + var source = CodeCoverageStringTextSource.GetSource(cSharpFileName); + + // assert + Assert.True (!ReferenceEquals(source, null)); + Assert.True (source.FileType == FileType.CSharp); + Assert.True (source.FilePath == cSharpFileName); + Assert.False (source.FileFound); + Assert.True (source.FileTime == DateTime.MinValue); + Assert.False (source.IsChanged (source.FileTime)); + Assert.False (source.IsChanged (DateTime.MinValue)); + Assert.False (source.IsChanged (DateTime.Now)); + Assert.False (source.IsChanged (timeReference)); + + // arrange + System.IO.File.WriteAllLines(cSharpFileName, lines); + + // act on existing file + source = CodeCoverageStringTextSource.GetSource(cSharpFileName); + + // assert + Assert.True (!ReferenceEquals(source, null)); + Assert.True (source.FileType == FileType.CSharp); + Assert.True (source.FilePath == cSharpFileName); + Assert.True (source.FileFound); + Assert.True (source.FileTime == System.IO.File.GetLastWriteTimeUtc (cSharpFileName)); + Assert.False (source.IsChanged (source.FileTime)); + Assert.False (source.IsChanged (DateTime.MinValue)); + Assert.False (source.IsChanged (DateTime.Now)); + Assert.True (source.IsChanged (timeReference)); + + // destroy temp file + System.IO.File.Delete(cSharpFileName); + + // arrange + System.IO.File.WriteAllLines(vBasicFileName, lines); + // act on existing file + source = CodeCoverageStringTextSource.GetSource(vBasicFileName); + + // assert + Assert.True (!ReferenceEquals(source, null)); + Assert.True (source.FileType == FileType.Unsupported); + Assert.True (source.FilePath == vBasicFileName); + Assert.True (source.FileFound); + Assert.True (source.FileTime == System.IO.File.GetLastWriteTimeUtc (vBasicFileName)); + Assert.False (source.IsChanged (source.FileTime)); + Assert.False (source.IsChanged (DateTime.MinValue)); + Assert.False (source.IsChanged (DateTime.Now)); + Assert.True (source.IsChanged (timeReference)); + + // destroy temp file + System.IO.File.Delete(vBasicFileName); + } + } +} diff --git a/main/OpenCover.Test/Framework/Utility/SequencePointComparerTest.cs b/main/OpenCover.Test/Framework/Utility/SequencePointComparerTest.cs new file mode 100644 index 000000000..508577ae9 --- /dev/null +++ b/main/OpenCover.Test/Framework/Utility/SequencePointComparerTest.cs @@ -0,0 +1,87 @@ +/* + * Created by SharpDevelop. + * User: ddur + * Date: 9.1.2016. + * Time: 15:11 + * + */ +using System; +using System.Collections.Generic; +using NUnit.Framework; +using OpenCover.Framework.Model; +using OpenCover.Framework.Utility; + +namespace OpenCover.Test.Framework.Utility +{ + [TestFixture] + public class SequencePointComparerTest + { + SequencePointComparer comparer = new SequencePointComparer(); + + [Test] + public void DoesNotEqualNull() + { + var point = new SequencePoint(); + + Assert.IsFalse(comparer.Equals(point, null)); + } + + [Test] + public void DoesEqualSelf() + { + var point = new SequencePoint(); + + Assert.IsTrue(comparer.Equals(point, point)); + } + + [Test] + public void DoesEqualSimilar() + { + var point1 = new SequencePoint {FileId = 1, StartLine = 1, StartColumn = 1, EndLine = 1, EndColumn = 1}; + var point2 = new SequencePoint {FileId = 1, StartLine = 1, StartColumn = 1, EndLine = 1, EndColumn = 1}; + + Assert.IsTrue(comparer.Equals(point1, point2)); + } + + [Test] + [TestCase(0, 1, 1, 1, 1)] + [TestCase(1, 2, 1, 1, 1)] + [TestCase(1, 1, 3, 1, 1)] + [TestCase(1, 1, 1, 4, 1)] + [TestCase(1, 1, 1, 1, 5)] + public void DoesNotEqualDisimilar(int fileId, int startLine, int startColumn, int endLine, int endColumn) + { + var point1 = new SequencePoint { FileId = 1, StartLine = 1, StartColumn = 1, EndLine = 1, EndColumn = 1 }; + var point2 = new SequencePoint + { + FileId = (uint)fileId, + StartLine = startLine, + StartColumn = startColumn, + EndLine = endLine, + EndColumn = endColumn + }; + + Assert.IsFalse(comparer.Equals(point1, point2)); + + } + + [Test] + public void UsageThatCoversGetHashCode() { + + var sequencePointsSet = new HashSet(comparer); + var point1 = new SequencePoint {FileId = 1, StartLine = 1, StartColumn = 1, EndLine = 1, EndColumn = 1}; + var point2 = new SequencePoint {FileId = 1, StartLine = 1, StartColumn = 1, EndLine = 1, EndColumn = 1}; + var point3 = new SequencePoint {FileId = 2, StartLine = 1, StartColumn = 1, EndLine = 1, EndColumn = 1}; + + Assert.True (sequencePointsSet.Add(point1)); + Assert.False (sequencePointsSet.Add(point1)); + + Assert.True (sequencePointsSet.Contains(point2)); + Assert.False (sequencePointsSet.Add(point2)); + + Assert.False (sequencePointsSet.Contains(point3)); + Assert.True (sequencePointsSet.Add(point3)); + + } + } +} diff --git a/main/OpenCover.Test/Framework/Utility/SourceRepositoryTest.cs b/main/OpenCover.Test/Framework/Utility/SourceRepositoryTest.cs new file mode 100644 index 000000000..6ae6190b8 --- /dev/null +++ b/main/OpenCover.Test/Framework/Utility/SourceRepositoryTest.cs @@ -0,0 +1,196 @@ +/* + * Created by SharpDevelop. + * User: ddur + * Date: 9.1.2016. + * Time: 17:52 + * + */ +using System; +using System.Collections; +using System.Collections.Generic; +using NUnit.Framework; +using OpenCover.Framework.Model; +using OpenCover.Framework.Utility; + +namespace OpenCover.Test.Framework.Utility +{ + [TestFixture] + public class SourceRepositoryTest + { + + [Test] + public void Create() + { + var sRepo = new SourceRepository(); + Assert.True (sRepo.IsReadOnly == false); + Assert.True (sRepo.Count == 0); + + } + + [Test] + public void CreateAddRemoveKeyAndValue() + { + var sRepo = new SourceRepository(); + var source = new CodeCoverageStringTextSource("", ""); + const uint fileId = 1; + sRepo.Add (fileId, source); + Assert.True (sRepo.Count == 1); + + Assert.True (sRepo.ContainsKey(fileId)); + Assert.True (sRepo.Remove(fileId)); + Assert.True (sRepo.Count == 0); + Assert.False (sRepo.Remove(fileId)); + Assert.True (sRepo.Count == 0); + } + + [Test] + public void CreateAddIndexerTryGetValue() + { + var sRepo = new SourceRepository(); + Assert.True (sRepo.Count == 0); + + var source = new CodeCoverageStringTextSource("", ""); + const uint fileId = 1; + + Assert.That ( delegate { sRepo[fileId] = source; }, Throws.Nothing ); + Assert.True (sRepo.Count == 1); + Assert.True (ReferenceEquals(sRepo[fileId], source)); + + CodeCoverageStringTextSource getSource = null; + sRepo.TryGetValue (fileId, out getSource); + Assert.True (ReferenceEquals(getSource, source)); + } + + [Test] + public void CreateAddRemoveKeyValuePair() + { + var sRepo = new SourceRepository(); + Assert.True (sRepo.Count == 0); + + var source = new CodeCoverageStringTextSource("", ""); + const uint fileId = 1; + + sRepo.Add (new KeyValuePair(fileId, source)); + Assert.True (sRepo.Contains(new KeyValuePair(fileId, source))); + Assert.True (sRepo.Remove(new KeyValuePair(fileId, source))); + Assert.False (sRepo.Remove(new KeyValuePair(fileId, source))); + + sRepo.Clear(); + Assert.True (sRepo.Count == 0); + + } + + [Test] + public void CreateAddClear() + { + var sRepo = new SourceRepository(); + Assert.True (sRepo.Count == 0); + + var source = new CodeCoverageStringTextSource("", ""); + const uint fileId = 1; + + sRepo.Add (fileId, source); + Assert.True (sRepo.Count == 1); + + sRepo.Clear(); + Assert.True (sRepo.Count == 0); + + } + + [Test] + public void CreateGetKeysValuesCopyEnumerate() + { + var sRepo = new SourceRepository(); + Assert.True (sRepo.IsReadOnly == false); + Assert.True (sRepo.Count == 0); + + var source1 = new CodeCoverageStringTextSource("abc", ""); + const uint fileId1 = 1; + sRepo.Add (fileId1, source1); + Assert.True (sRepo.Count == 1); + Assert.True (sRepo.Keys.Count == 1); + Assert.True (sRepo.Values.Count == 1); + + var source2 = new CodeCoverageStringTextSource("def", ""); + const uint fileId2 = 2; + sRepo.Add (fileId2, source2); + Assert.True (sRepo.Count == 2); + + var array = new KeyValuePair[2]; + Assert.That (delegate { sRepo.CopyTo(array, 0); }, Throws.Nothing); + + // IDictionary is not ordered + Assert.True (array[0].Key == fileId1 || array[1].Key == fileId2); + Assert.True (array[0].Value == source1 || array[1].Value == source2); + + Assert.True (array[1].Key != default(uint)); + Assert.True (array[1].Value != default(CodeCoverageStringTextSource)); + + // covers generic enumerator + int count = 0; + foreach (var item in sRepo) { + Assert.True (item.Key != default(uint)); + Assert.True (item.Value != default(CodeCoverageStringTextSource)); + count += 1; + } + Assert.True (count == 2); + + // covers GetEnumerator + count = 0; + var e = ((IEnumerable)sRepo).GetEnumerator(); + while (e.MoveNext()) { + count += 1; + } + Assert.True (count == 2); + } + + + [Test] + public void CreateGetSourceAndSequencePoints() + { + const uint fileId1 = 1; + const string sourceString = "abc { def }"; + var source = new CodeCoverageStringTextSource(sourceString, ""); + + var sRepo = new SourceRepository(); + sRepo[fileId1] = source; + + var spLeft = new SequencePoint() { + FileId = 1, + StartLine = 1, + EndLine = 1, + StartColumn = 5, + EndColumn = 6 + }; + + var spRight = new SequencePoint() { + FileId = 1, + StartLine = 1, + EndLine = 1, + StartColumn = 11, + EndColumn = 12 + }; + + var spInvalid = new SequencePoint() { + FileId = 2, + StartLine = 1, + EndLine = 1, + StartColumn = 11, + EndColumn = 12 + }; + + Assert.True (sRepo.GetCodeCoverageStringTextSource(0) == null); + Assert.True (sRepo.GetCodeCoverageStringTextSource(1) == source); + Assert.True (sRepo.GetCodeCoverageStringTextSource(2) == null); + Assert.True (sRepo.GetCodeCoverageStringTextSource(1).GetLine(1) == sourceString); + Assert.True (sRepo.GetCodeCoverageStringTextSource(1).GetText(spLeft) == "{"); + Assert.True (sRepo.GetCodeCoverageStringTextSource(1).GetText(spRight) == "}"); + + Assert.True (sRepo.GetSequencePointText(null) == ""); + Assert.True (sRepo.GetSequencePointText(spInvalid) == ""); + + Assert.True (sRepo.GetSequencePointText(spLeft) == "{"); + Assert.True (sRepo.GetSequencePointText(spRight) == "}"); + } + } +} diff --git a/main/OpenCover.Test/Integration/ThreadingTests.cs b/main/OpenCover.Test/Integration/ThreadingTests.cs new file mode 100644 index 000000000..af48c7148 --- /dev/null +++ b/main/OpenCover.Test/Integration/ThreadingTests.cs @@ -0,0 +1,58 @@ +using System; +using System.Diagnostics; +using System.Linq; +using System.Threading; +using NUnit.Framework; +using OpenCover.Framework; + +namespace OpenCover.Test.Integration +{ + /// + /// Replicates issue with threads as reported in issue #366 + /// + [TestFixture] + public class ThreadingTests + { + const int NB_THREADS = 50; + static readonly ManualResetEvent[] ResetEvents = new ManualResetEvent[NB_THREADS]; + + [Test] + public void RunManyThreads() + { + //Thread.Sleep(15000); + for (int i = 0; i < NB_THREADS; i++) + { + ResetEvents[i] = new ManualResetEvent(false); + new Thread(DoWork).Start(ResetEvents[i]); + } + var chrono = Stopwatch.StartNew(); + long n = 0; + while (n < 2000) + { + if (++n % 200 == 0) + Console.WriteLine(n.ToString()); + var current = WaitHandle.WaitAny(ResetEvents.ToArray()); + ResetEvents[current].Reset(); + new Thread(DoWork).Start(ResetEvents[current]); + } + Console.WriteLine("Took {0} seconds", chrono.Elapsed.TotalSeconds); + Assert.Pass(); + } + + public static void DoWork(object o) + { + var resetEvent = (ManualResetEvent)o; + resetEvent.Do(re => + { + var rnd = new Random(); + double res = 0; + for (var i = 0; i < 10000; i++) + res += rnd.NextDouble(); + re.Set(); + }); + + + } + + } +} diff --git a/main/OpenCover.Test/OpenCover.Test.csproj b/main/OpenCover.Test/OpenCover.Test.csproj index 6abc8db8f..fc1ac316c 100644 --- a/main/OpenCover.Test/OpenCover.Test.csproj +++ b/main/OpenCover.Test/OpenCover.Test.csproj @@ -1,5 +1,5 @@  - + Debug AnyCPU @@ -10,7 +10,7 @@ Properties OpenCover.Test OpenCover.Test - v4.0 + v4.5.2 512 ..\ @@ -139,6 +139,7 @@ MoqFramework\UnityAutoMockContainer.cs + @@ -147,10 +148,12 @@ + + @@ -164,8 +167,12 @@ + + + + @@ -191,9 +198,7 @@ OpenCover.Support - - - + @@ -303,6 +308,9 @@ + + + diff --git a/main/cmdline/dogfood.cmd b/main/cmdline/dogfood.cmd index 0dc450f87..85d8ca982 100644 --- a/main/cmdline/dogfood.cmd +++ b/main/cmdline/dogfood.cmd @@ -1 +1,9 @@ -OpenCover.Console.exe -register:user -target:..\..\..\main\packages\NUnit.Runners.2.6.4\tools\nunit-console-x86.exe -targetargs:"OpenCover.Test.dll /noshadow /exclude:AdminOnly" -filter:"+[Open*]* -[OpenCover.T*]*" -output:opencovertests.xml +@echo off +pushd %cd% +setlocal +@set ExcludeAdminOnly=/exclude:AdminOnly +@if "%appveyor%" == "True" set ExcludeAdminOnly= +cd %~dp0 +OpenCover.Console.exe -register:user -safemode:on -target:..\..\..\main\packages\NUnit.Runners.2.6.4\tools\nunit-console-x86.exe -targetargs:"OpenCover.Test.dll /noshadow %ExcludeAdminOnly%" -filter:"+[Open*]* -[OpenCover.T*]* -[*]* -[*]*" -output:opencovertests.xml -communicationtimeout:9999 +endlocal +popd diff --git a/main/cmdline/dogfood_exattr.cmd b/main/cmdline/dogfood_exattr.cmd index 9844ea39c..3235f0ce3 100644 --- a/main/cmdline/dogfood_exattr.cmd +++ b/main/cmdline/dogfood_exattr.cmd @@ -1 +1,9 @@ -OpenCover.Console.exe -register:user -target:..\..\..\main\packages\NUnit.Runners.2.6.4\tools\nunit-console-x86.exe -targetargs:"OpenCover.Test.dll /noshadow /exclude:AdminOnly" -excludebyattribute:*.ExcludeFromCoverageAttribute -filter:"+[Open*]* -[Open*]*Boot* -[OpenCover.T*]*" -output:opencovertests.xml +@echo off +pushd %cd% +setlocal +@set ExcludeAdminOnly=/exclude:AdminOnly +@if "%appveyor%" == "True" set ExcludeAdminOnly= +cd %~dp0 +OpenCover.Console.exe -register:user -target:..\..\..\main\packages\NUnit.Runners.2.6.4\tools\nunit-console-x86.exe -targetargs:"OpenCover.Test.dll /noshadow %ExcludeAdminOnly%" -excludebyattribute:*.ExcludeFromCoverageAttribute -filter:"+[Open*]* -[OpenCover.T*]* -{nunit-console*}[*]* -{pdb*}[*]*" -output:opencovertests.xml -mergebyhash +endlocal +popd diff --git a/main/cmdline/dogfood_filter.cmd b/main/cmdline/dogfood_filter.cmd new file mode 100644 index 000000000..f3ef3c06b --- /dev/null +++ b/main/cmdline/dogfood_filter.cmd @@ -0,0 +1,6 @@ +@echo off +pushd %cd% +cd %~dp0 +REM cover framework only +OpenCover.Console.exe -register:user -target:..\..\..\main\packages\NUnit.Runners.2.6.4\tools\nunit-console-x86.exe -targetargs:"OpenCover.Test.dll /noshadow /exclude:AdminOnly" -filter:"+[Open*]OpenCover.Framework* -[OpenCover.T*]* -{nunit-console*}[*]* -{pdb*}[*]*" -output:opencovertests-framework-filter.xml -communicationtimeout:9999 +popd \ No newline at end of file diff --git a/main/cmdline/pedigree.cmd b/main/cmdline/pedigree.cmd index 73dc91bea..9d62a8eb1 100644 --- a/main/cmdline/pedigree.cmd +++ b/main/cmdline/pedigree.cmd @@ -1 +1,5 @@ -OpenCover.Console.exe -register:user -enableperformancecounters -target:dogfood.cmd -filter:+[OpenCover*]* -output:pedigree_results.xml \ No newline at end of file +@echo off +pushd %cd% +cd %~dp0 +OpenCover.Console.exe -register:user -enableperformancecounters -target:dogfood.cmd -filter:+[OpenCover*]* -output:pedigree_results.xml +popd \ No newline at end of file diff --git a/main/cmdline/report_coverage.cmd b/main/cmdline/report_coverage.cmd index c81f1c1fc..49b7c453d 100644 --- a/main/cmdline/report_coverage.cmd +++ b/main/cmdline/report_coverage.cmd @@ -1 +1 @@ -..\..\..\main\packages\ReportGenerator.2.1.8.0\ReportGenerator.exe -reports:opencovertests.xml -targetdir:report \ No newline at end of file +..\..\..\main\packages\ReportGenerator.2.1.8.0\tools\ReportGenerator.exe -reports:opencovertests.xml -targetdir:report \ No newline at end of file diff --git a/main/cmdline/uitest.opencover.cmd b/main/cmdline/uitest.opencover.cmd index 332541c8c..8802274ae 100644 --- a/main/cmdline/uitest.opencover.cmd +++ b/main/cmdline/uitest.opencover.cmd @@ -1 +1 @@ -OpenCover.Console.exe -register:user -target:"C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\IDE\CommonExtensions\Microsoft\TestWindow\vstest.console.exe" -targetargs:"OpenCover.UITest.dll" -filter:"+[Open*]* -[OpenCover.UIT*]*" -output:opencovertests.xml -mergebyhash +OpenCover.Console.exe -register:user -target:"C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\IDE\CommonExtensions\Microsoft\TestWindow\vstest.console.exe" -targetargs:"OpenCover.UITest.dll" -excludebyattribute:*.ExcludeFromCoverageAttribute -filter:"+[Open*]* -[OpenCover.UIT*]*" -output:opencovertests.xml -mergebyhash -mergeoutput diff --git a/main/packages/repositories.config b/main/packages/repositories.config index 473154f93..a52fb8ad8 100644 --- a/main/packages/repositories.config +++ b/main/packages/repositories.config @@ -1,10 +1,11 @@  + - + \ No newline at end of file diff --git a/samples/OpenCover.Samples.CS/OpenCover.Samples.CS.csproj b/samples/OpenCover.Samples.CS/OpenCover.Samples.CS.csproj index 360451d1c..d9332e2b6 100644 --- a/samples/OpenCover.Samples.CS/OpenCover.Samples.CS.csproj +++ b/samples/OpenCover.Samples.CS/OpenCover.Samples.CS.csproj @@ -1,5 +1,5 @@  - + Debug AnyCPU diff --git a/samples/OpenCover.Samples.Framework/OpenCover.Samples.Framework.csproj b/samples/OpenCover.Samples.Framework/OpenCover.Samples.Framework.csproj index 6e1472a4c..cbb066c8f 100644 --- a/samples/OpenCover.Samples.Framework/OpenCover.Samples.Framework.csproj +++ b/samples/OpenCover.Samples.Framework/OpenCover.Samples.Framework.csproj @@ -1,5 +1,5 @@  - + Debug AnyCPU diff --git a/samples/OpenCover.Samples.Service/OpenCover.Samples.Service.csproj b/samples/OpenCover.Samples.Service/OpenCover.Samples.Service.csproj index a5dcf623f..3beb7cfe8 100644 --- a/samples/OpenCover.Samples.Service/OpenCover.Samples.Service.csproj +++ b/samples/OpenCover.Samples.Service/OpenCover.Samples.Service.csproj @@ -1,5 +1,5 @@  - + Debug x86 diff --git a/samples/OpenCover.Samples.VB/OpenCover.Samples.VB.vbproj b/samples/OpenCover.Samples.VB/OpenCover.Samples.VB.vbproj index 46910d379..c43423074 100644 --- a/samples/OpenCover.Samples.VB/OpenCover.Samples.VB.vbproj +++ b/samples/OpenCover.Samples.VB/OpenCover.Samples.VB.vbproj @@ -1,5 +1,5 @@  - + Debug AnyCPU diff --git a/samples/SampleSln/Bom/Bom.csproj b/samples/SampleSln/Bom/Bom.csproj index c0480510b..400bb251a 100644 --- a/samples/SampleSln/Bom/Bom.csproj +++ b/samples/SampleSln/Bom/Bom.csproj @@ -1,5 +1,5 @@  - + Debug diff --git a/samples/SampleSln/BomTest/BomTest.csproj b/samples/SampleSln/BomTest/BomTest.csproj index 2c75f4745..4942e9f28 100644 --- a/samples/SampleSln/BomTest/BomTest.csproj +++ b/samples/SampleSln/BomTest/BomTest.csproj @@ -1,5 +1,5 @@  - + Debug diff --git a/tools/CrashReporterSigned/CrashReporter.NET.dll b/tools/CrashReporterSigned/CrashReporter.NET.dll new file mode 100644 index 000000000..f2d05ec7a Binary files /dev/null and b/tools/CrashReporterSigned/CrashReporter.NET.dll differ diff --git a/tools/CxxSonarQubeMsbuidRunner.exe b/tools/CxxSonarQubeMsbuidRunner.exe new file mode 100644 index 000000000..509030959 Binary files /dev/null and b/tools/CxxSonarQubeMsbuidRunner.exe differ diff --git a/tools/CxxSonarQubeMsbuidRunner.zip b/tools/CxxSonarQubeMsbuidRunner.zip new file mode 100644 index 000000000..f54ac865a Binary files /dev/null and b/tools/CxxSonarQubeMsbuidRunner.zip differ diff --git a/tools/RunSxS/RunSxS.vcxproj b/tools/RunSxS/RunSxS.vcxproj index 65aaa4aa4..472f717a4 100644 --- a/tools/RunSxS/RunSxS.vcxproj +++ b/tools/RunSxS/RunSxS.vcxproj @@ -1,5 +1,5 @@  - + Debug diff --git a/tools/gtest-1.6.0.zip b/tools/gtest-1.6.0.zip index 591fe709b..de4708f1e 100644 Binary files a/tools/gtest-1.6.0.zip and b/tools/gtest-1.6.0.zip differ diff --git a/tools/sonarqube/runner/MSBuild.SonarQube.Runner.exe b/tools/sonarqube/runner/MSBuild.SonarQube.Runner.exe new file mode 100644 index 000000000..8823dac26 Binary files /dev/null and b/tools/sonarqube/runner/MSBuild.SonarQube.Runner.exe differ diff --git a/tools/sonarqube/runner/SonarQube.Analysis.xml b/tools/sonarqube/runner/SonarQube.Analysis.xml new file mode 100644 index 000000000..f3c9a8942 --- /dev/null +++ b/tools/sonarqube/runner/SonarQube.Analysis.xml @@ -0,0 +1,33 @@ + + + + http://localhost:9000 + + + + + + \ No newline at end of file diff --git a/tools/sonarqube/runner/SonarQube.Common.dll b/tools/sonarqube/runner/SonarQube.Common.dll new file mode 100644 index 000000000..d9b9b1f8f Binary files /dev/null and b/tools/sonarqube/runner/SonarQube.Common.dll differ