Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion ICSharpCode.Decompiler.Tests/CorrectnessTestRunner.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,9 @@

namespace ICSharpCode.Decompiler.Tests
{
[TestFixture, Parallelizable(ParallelScope.All)]
// Order(2) enqueues these long compile+execute tests right after the roundtrip fixture,
// ahead of unordered fixtures, so they do not straggle at the end of a parallel run.
[TestFixture, Parallelizable(ParallelScope.All), Order(2)]
public class CorrectnessTestRunner
{
static readonly string TestCasePath = Tester.TestCasePath + "/Correctness";
Expand Down
11 changes: 11 additions & 0 deletions ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,17 @@
<DefineConstants>TRACE;$(DefineConstants)</DefineConstants>
</PropertyGroup>

<ItemGroup>
<!-- NUnit's default worker count (one per logical CPU) underutilizes the machine because
most matrix tests block on child processes (csc/vbc/ilasm/msbuild/test runners).
LevelOfParallelism only accepts a constant, so compute 2x logical CPUs at build time;
the machine building the tests is the machine running them. -->
<AssemblyAttribute Include="NUnit.Framework.LevelOfParallelism">
<_Parameter1>$([MSBuild]::Multiply($([System.Environment]::ProcessorCount), 2))</_Parameter1>
<_Parameter1_TypeName>System.Int32</_Parameter1_TypeName>
</AssemblyAttribute>
</ItemGroup>

<ItemGroup>
<PackageReference Include="DiffLib" />
<PackageReference Include="CliWrap" />
Expand Down
7 changes: 7 additions & 0 deletions ICSharpCode.Decompiler.Tests/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,15 @@
using System.Reflection;
using System.Runtime.InteropServices;

using NUnit.Framework;

#endregion

// Fixtures without their own Parallelizable attribute run concurrently with other fixtures;
// tests within such a fixture still run sequentially. Fixtures that share process-global
// state must opt out individually with [NonParallelizable].
[assembly: Parallelizable(ParallelScope.Fixtures)]

[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]

Expand Down
4 changes: 3 additions & 1 deletion ICSharpCode.Decompiler.Tests/RoundtripAssembly.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,9 @@

namespace ICSharpCode.Decompiler.Roundtrip
{
[TestFixture, Parallelizable(ParallelScope.All), Platform("Win")]
// Order(1) enqueues this fixture's multi-minute roundtrip tests ahead of unordered
// fixtures, so they do not straggle at the end of a parallel run.
[TestFixture, Parallelizable(ParallelScope.All), Platform("Win"), Order(1)]
public class RoundtripAssembly
{
public static readonly string TestDir = Path.GetFullPath(Path.Combine(Tester.TestCasePath, "../../ILSpy-tests"));
Expand Down
60 changes: 60 additions & 0 deletions doc/WindowsDefenderExclusions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# Windows Defender exclusions for test runs

Real-time protection scans every file the test suite writes and every process it
spawns. A full `ICSharpCode.Decompiler.Tests` run compiles thousands of fixture
assemblies and launches csc/vbc/ilasm/msbuild/test-runner child processes; while it
runs, `MsMpEng.exe` (Defender's scan engine) has been measured using 1-4 CPU cores
continuously, and each process start pays additional scan latency. Excluding the
folders below removes that overhead.

**Security tradeoff:** excluded folders are not scanned at all. Only add exclusions
on a development machine you control, and only for paths that contain code you
build yourself. If you use a third-party antivirus or backup suite with real-time
scanning (e.g. Acronis Active Protection), configure equivalent exclusions there.

## Folders to exclude

1. **The ILSpy repository clone** (e.g. `C:\src\ILSpy`). This covers everything the
build and tests write inside the repo:
- `bin\` and `obj\` of every project
- compiled test fixtures placed next to their sources under
`ICSharpCode.Decompiler.Tests\TestCases\`
- the Roslyn toolsets, reference-assembly packs, and vswhere that
`Tester.Initialize()` downloads under the test output directory
- the `ILSpy-tests\` submodule, including the `*-decompiled` / `*-output`
folders the roundtrip tests generate next to their inputs
2. **The test-assembly temp path, if you redirected it.** When
`ICSharpCode.Decompiler.Tests\DecompilerTests.config.json` sets
`TestsAssemblyTempPath`, compiled fixtures land there instead of inside the
repo - exclude that folder as well.
3. **Optional: the NuGet package cache** (`%USERPROFILE%\.nuget\packages`). Only
restore performance benefits; packages are signed and hash-verified by NuGet,
but skip this one if you prefer scanned downloads.

The user temp folder (`%TEMP%`) also receives small diff files from failing
correctness tests, but excluding all of `%TEMP%` is a poor tradeoff - malware
routinely stages there. Leave it scanned.

## Adding the exclusions

Run PowerShell **as Administrator**, adjusting the paths to your clone:

```powershell
Add-MpPreference -ExclusionPath "C:\src\ILSpy"
# only if TestsAssemblyTempPath is configured:
Add-MpPreference -ExclusionPath "D:\ILSpyTestAssemblies"
# optional:
Add-MpPreference -ExclusionPath "$env:USERPROFILE\.nuget\packages"
```

## Verifying

```powershell
Get-MpPreference | Select-Object -ExpandProperty ExclusionPath
```

## Removing

```powershell
Remove-MpPreference -ExclusionPath "C:\src\ILSpy"
```
Loading