Skip to content

Commit 3aefe4c

Browse files
authored
Map local build path during WSL run (#729)
1 parent ced30c2 commit 3aefe4c

File tree

12 files changed

+217
-15
lines changed

12 files changed

+217
-15
lines changed

docs/TestExplorerEnvironments.png

18.2 KB
Loading

readme.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -505,6 +505,26 @@ Verify follows [Semantic Versioning](https://semver.org/). The same applies for
505505
Snapshot changes do not trigger a major version change to avoid causing [Diamond dependency](https://en.wikipedia.org/wiki/Dependency_hell#Problems) issues for downstream extensions.
506506

507507

508+
## Unit testing inside virtualized environment
509+
510+
Unit tests referencing `Verify` (including unit tests within this repository as well as any other code referencing `Verify`) can be run and debugged on a local virtualized environment supported by [Visual Studio Remote Testing](https://learn.microsoft.com/en-us/visualstudio/test/remote-testing?view=vs-2022).
511+
Initial configurations have been added for `WSL` and net 7.0 linux docker via `testenvironments.json` (for third party code, the file needs to be copied or recreated next to the `.sln` solution file for solution to leverage the functionality).
512+
Upon opening the Tests Explorer the advanced environments are available in the GUI:
513+
514+
![TestExplorerEnvironments](/docs/TestExplorerEnvironments.png)
515+
516+
This readme will not discuss definitive list of details for proper setup of the environments instead refer the following information sources and warn about particular gotchas:
517+
518+
* WSL runs
519+
* Install [WSL](https://learn.microsoft.com/en-us/windows/wsl/about).
520+
* Install a [distribution](https://aka.ms/wslstore).
521+
* [Install .NET Runtime](https://learn.microsoft.com/en-us/dotnet/core/install/linux-ubuntu)
522+
* Docker runs
523+
* Install [Docker Desktop](https://www.docker.com/products/docker-desktop/)
524+
* First run of docker scenario might need elevation ([Test project does not reference any .NET NuGet adapter](https://developercommunity.visualstudio.com/t/test-project-does-not-reference-any-net-nuget-adap/1311698) error)
525+
* Third party test runners might not support this feature. Use [Visual Studio Test Explorer](https://learn.microsoft.com/en-us/visualstudio/test/run-unit-tests-with-test-explorer).
526+
527+
508528
## Media
509529

510530
* [Compare object values in xUnit C# with Verify - Pierre Belin](https://goatreview.com/compare-object-values-xunit-csharp-verify/)

readme.source.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,26 @@ Verify follows [Semantic Versioning](https://semver.org/). The same applies for
240240
Snapshot changes do not trigger a major version change to avoid causing [Diamond dependency](https://en.wikipedia.org/wiki/Dependency_hell#Problems) issues for downstream extensions.
241241

242242

243+
## Unit testing inside virtualized environment
244+
245+
Unit tests referencing `Verify` (including unit tests within this repository as well as any other code referencing `Verify`) can be run and debugged on a local virtualized environment supported by [Visual Studio Remote Testing](https://learn.microsoft.com/en-us/visualstudio/test/remote-testing?view=vs-2022).
246+
Initial configurations have been added for `WSL` and net 7.0 linux docker via `testenvironments.json` (for third party code, the file needs to be copied or recreated next to the `.sln` solution file for solution to leverage the functionality).
247+
Upon opening the Tests Explorer the advanced environments are available in the GUI:
248+
249+
![TestExplorerEnvironments](/docs/TestExplorerEnvironments.png)
250+
251+
This readme will not discuss definitive list of details for proper setup of the environments instead refer the following information sources and warn about particular gotchas:
252+
253+
* WSL runs
254+
* Install [WSL](https://learn.microsoft.com/en-us/windows/wsl/about).
255+
* Install a [distribution](https://aka.ms/wslstore).
256+
* [Install .NET Runtime](https://learn.microsoft.com/en-us/dotnet/core/install/linux-ubuntu)
257+
* Docker runs
258+
* Install [Docker Desktop](https://www.docker.com/products/docker-desktop/)
259+
* First run of docker scenario might need elevation ([Test project does not reference any .NET NuGet adapter](https://developercommunity.visualstudio.com/t/test-project-does-not-reference-any-net-nuget-adap/1311698) error)
260+
* Third party test runners might not support this feature. Use [Visual Studio Test Explorer](https://learn.microsoft.com/en-us/visualstudio/test/run-unit-tests-with-test-explorer).
261+
262+
243263
## Media
244264

245265
* [Compare object values in xUnit C# with Verify - Pierre Belin](https://goatreview.com/compare-object-values-xunit-csharp-verify/)

src/Verify.Expecto/Verifier.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ static InnerVerifier GetVerifier(VerifySettings settings, string sourceFile, str
1919
settings.UseUniqueDirectory();
2020
}
2121

22+
sourceFile = IoHelpers.GetMappedBuildPath(sourceFile) ?? sourceFile;
2223
var fileName = Path.GetFileNameWithoutExtension(sourceFile);
2324

2425
var pathInfo = GetPathInfo(sourceFile, fileName, methodName);

src/Verify.sln

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
1515
global.json = global.json
1616
mdsnippets.json = mdsnippets.json
1717
..\readme.source.md = ..\readme.source.md
18+
testenvironments.json = testenvironments.json
1819
EndProjectSection
1920
EndProject
2021
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Verify", "Verify\Verify.csproj", "{A017D3FD-7DA5-4DF4-A169-72DE4AF76048}"
@@ -72,11 +73,11 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NullComparer", "NullCompare
7273
EndProject
7374
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AutoVerifyTests", "AutoVerifyTests\AutoVerifyTests.csproj", "{6E3F9E6E-72D9-4D40-90EE-933B4B1C26DD}"
7475
EndProject
75-
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SingleTfmTests", "SingleTfmTests\SingleTfmTests.csproj", "{63CFAA91-CEC2-4D21-BEEE-3EB970776E0E}"
76+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SingleTfmTests", "SingleTfmTests\SingleTfmTests.csproj", "{63CFAA91-CEC2-4D21-BEEE-3EB970776E0E}"
7677
EndProject
77-
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SplitUniqueDirectoryMode", "SplitUniqueDirectoryMode\SplitUniqueDirectoryMode.csproj", "{02684D47-1A14-4D1A-9B26-387E3F45FEFC}"
78+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SplitUniqueDirectoryMode", "SplitUniqueDirectoryMode\SplitUniqueDirectoryMode.csproj", "{02684D47-1A14-4D1A-9B26-387E3F45FEFC}"
7879
EndProject
79-
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SortedJsonTest", "SortedJsonTest\SortedJsonTest.csproj", "{DEC5A717-0914-4798-B68C-F848B6205B64}"
80+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SortedJsonTest", "SortedJsonTest\SortedJsonTest.csproj", "{DEC5A717-0914-4798-B68C-F848B6205B64}"
8081
EndProject
8182
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "NugetUsage", "NugetUsage", "{55ADD9F3-FD0D-4A98-8723-1348FF605944}"
8283
EndProject

src/Verify/DerivePaths/AttributeReader.cs

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,37 +18,47 @@ public static string GetProjectDirectory() =>
1818
GetProjectDirectory(Assembly.GetCallingAssembly());
1919

2020
public static string GetProjectDirectory(Assembly assembly) =>
21-
GetValue(assembly, "Verify.ProjectDirectory");
21+
GetValue(assembly, "Verify.ProjectDirectory", true);
2222

2323
public static bool TryGetProjectDirectory([NotNullWhen(true)] out string? projectDirectory) =>
2424
TryGetProjectDirectory(Assembly.GetCallingAssembly(), out projectDirectory);
2525

2626
public static bool TryGetProjectDirectory(Assembly assembly, [NotNullWhen(true)] out string? projectDirectory) =>
27-
TryGetValue(assembly, "Verify.ProjectDirectory", out projectDirectory);
27+
TryGetValue(assembly, "Verify.ProjectDirectory", out projectDirectory, true);
2828

2929
public static string GetSolutionDirectory() =>
3030
GetSolutionDirectory(Assembly.GetCallingAssembly());
3131

3232
public static string GetSolutionDirectory(Assembly assembly) =>
33-
GetValue(assembly, "Verify.SolutionDirectory");
33+
GetValue(assembly, "Verify.SolutionDirectory", true);
3434

3535
public static bool TryGetSolutionDirectory([NotNullWhen(true)] out string? solutionDirectory) =>
36-
TryGetSolutionDirectory(Assembly.GetCallingAssembly(), out solutionDirectory);
36+
TryGetSolutionDirectory(Assembly.GetCallingAssembly(), true, out solutionDirectory);
3737

3838
public static bool TryGetSolutionDirectory(Assembly assembly, [NotNullWhen(true)] out string? solutionDirectory) =>
39-
TryGetValue(assembly, "Verify.SolutionDirectory", out solutionDirectory);
39+
TryGetSolutionDirectory(assembly, true, out solutionDirectory);
4040

41-
static bool TryGetValue(Assembly assembly, string key, [NotNullWhen(true)] out string? value)
41+
internal static bool TryGetSolutionDirectory(bool mapPathForVirtualizedRun, [NotNullWhen(true)] out string? solutionDirectory) =>
42+
TryGetSolutionDirectory(Assembly.GetCallingAssembly(), mapPathForVirtualizedRun, out solutionDirectory);
43+
44+
internal static bool TryGetSolutionDirectory(Assembly assembly, bool mapPathForVirtualizedRun, [NotNullWhen(true)] out string? solutionDirectory) =>
45+
TryGetValue(assembly, "Verify.SolutionDirectory", out solutionDirectory, mapPathForVirtualizedRun);
46+
47+
static bool TryGetValue(Assembly assembly, string key, [NotNullWhen(true)] out string? value, bool isSourcePath = false)
4248
{
4349
value = assembly.GetCustomAttributes<AssemblyMetadataAttribute>()
4450
.SingleOrDefault(_ => _.Key == key)
4551
?.Value;
52+
if (isSourcePath)
53+
{
54+
value = value == null ? null : IoHelpers.GetMappedBuildPath(value, assembly);
55+
}
4656
return value is not null;
4757
}
4858

49-
static string GetValue(Assembly assembly, string key)
59+
static string GetValue(Assembly assembly, string key, bool isSourcePath = false)
5060
{
51-
if (TryGetValue(assembly, key, out var value))
61+
if (TryGetValue(assembly, key, out var value, isSourcePath))
5262
{
5363
return value;
5464
}

src/Verify/DerivePaths/PathInfo.cs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,9 @@ internal static PathInfo DeriveDefault(
2828
Type type,
2929
MethodInfo method) =>
3030
new(
31-
directory: Path.GetDirectoryName(sourceFile)!,
31+
directory: IoHelpers.GetDirectoryName(sourceFile)!,
3232
typeName: type.NameWithParent(),
3333
methodName: method.Name);
34-
3534
#endregion
3635

3736
internal static PathInfo DeriveDefault(
@@ -40,7 +39,7 @@ internal static PathInfo DeriveDefault(
4039
string typeName,
4140
string methodName) =>
4241
new(
43-
directory: Path.GetDirectoryName(sourceFile)!,
42+
directory: IoHelpers.GetDirectoryName(sourceFile)!,
4443
typeName: typeName,
4544
methodName: methodName);
4645
}

src/Verify/IoHelpers.cs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,25 @@ public static string GetRelativePath(string directory, string file)
185185

186186
}
187187

188+
static VirtualizedRunHelper? virtualizedRunHelper;
189+
static ConcurrentDictionary<Assembly, VirtualizedRunHelper> virtualizedRunHelpers = new();
190+
191+
internal static void MapPathsForCallingAssembly(Assembly assembly) =>
192+
virtualizedRunHelper = GetForAssembly(assembly);
193+
194+
internal static string? GetMappedBuildPath(string? path, Assembly? assembly = null)
195+
{
196+
VirtualizedRunHelper? helper = assembly != null ? GetForAssembly(assembly) : virtualizedRunHelper;
197+
198+
return helper == null ? path : helper.GetMappedBuildPath(path);
199+
}
200+
201+
private static VirtualizedRunHelper GetForAssembly(Assembly assembly) =>
202+
virtualizedRunHelpers.GetOrAdd(assembly, a => new(a));
203+
204+
public static string? GetDirectoryName(string? path) =>
205+
Path.GetDirectoryName(GetMappedBuildPath(path));
206+
188207
#if NET5_0_OR_GREATER || NETCOREAPP3_0_OR_GREATER
189208

190209
public static async Task<StringBuilder> ReadStringBuilderWithFixedLines(string path)

src/Verify/TargetAssembly.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ public static void Assign(Assembly assembly)
1313
}
1414

1515
Namer.UseAssembly(assembly);
16+
IoHelpers.MapPathsForCallingAssembly(assembly);
1617
ProjectDir = AttributeReader.GetProjectDirectory(assembly);
1718
AttributeReader.TryGetSolutionDirectory(assembly, out var solutionDir);
1819
SolutionDir = solutionDir;

src/Verify/Verifier/InnerVerifier.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,7 @@ static string GetUniquenessVerified(string sharedUniqueness, Namer namer)
223223

224224
static string ResolveDirectory(string sourceFile, VerifySettings settings, PathInfo pathInfo)
225225
{
226-
var sourceFileDirectory = Path.GetDirectoryName(sourceFile)!;
226+
var sourceFileDirectory = IoHelpers.GetDirectoryName(sourceFile)!;
227227
var pathInfoDirectory = pathInfo.Directory;
228228
if (ContinuousTestingDetector.IsNCrunch)
229229
{
@@ -234,6 +234,7 @@ static string ResolveDirectory(string sourceFile, VerifySettings settings, PathI
234234
}
235235

236236
var settingsOrInfoDirectory = settings.Directory ?? pathInfoDirectory;
237+
settingsOrInfoDirectory = IoHelpers.GetMappedBuildPath(settingsOrInfoDirectory);
237238

238239
if (settingsOrInfoDirectory is null)
239240
{

0 commit comments

Comments
 (0)