Skip to content

Commit 1068af2

Browse files
authored
tests: restore DescriptorParserTests in a separate SamRockProtocol.UnitTests project (#17)
* tests: restore DescriptorParserTests in a separate SamRockProtocol.UnitTests project PR #15 deleted DescriptorParserTests because the compile-time refs to SamRockProtocol.Services types triggered a JIT-time assembly load in the SamRockProtocol.Tests integration assembly, which then poisoned BTCPay's PluginManager AppDomain scan and locked out MVC controller registration for the plugin under test. Restore them in a dedicated SamRockProtocol.UnitTests project that references ONLY the plugin csproj (no BTCPayServer test fixtures). The integration test assembly (SamRockProtocol.Tests) stays disentangled - it does not reference this new project, and this new project does not reference any BTCPay test types, so the poison-via-AppDomain-load path stays closed. - New SamRockProtocol.UnitTests/SamRockProtocol.UnitTests.csproj (net8.0, xunit + xunit.runner.visualstudio + Microsoft.NET.Test.Sdk). - New SamRockProtocol.UnitTests/DescriptorParserTests.cs - 16 restored tests from c881ef2's original PR #13 content, namespace renamed to SamRockProtocol.UnitTests. 25 distinct test cases including the [Theory] parametrizations. - SamRockProtocol.sln gets the new project. - .github/workflows/playwright.yml splits the test step into two: unit tests run first (~1s, no Docker), integration tests after. Keeps the fast unit-test feedback loop separate from the heavy ServerTester boot path. * tests: remove DescriptorParserTests + plugin ProjectReference from integration assembly PR #15 squash-merge only landed the AppDomain force-load removal from SharedPluginTestFixture - it did NOT land the DescriptorParserTests deletion that the PR branch carried. As a result, master still has: - SamRockProtocol.Tests/DescriptorParserTests.cs with `using SamRockProtocol.Services;` compile-time refs - a `<ProjectReference Include="..\Plugins\SamRockProtocol\..." />` in SamRockProtocol.Tests.csproj Either is enough to trigger a JIT-time load of the SamRockProtocol assembly into the integration test process's AppDomain at xunit- discovery time, before PluginManager.AddPlugins runs. PluginManager then scans AppDomain.CurrentDomain.GetAssemblies(), finds the plugin already present, registers with Loader=null, and the dedup at PluginManager.cs:204 locks out the file-based PluginLoader path. mvcBuilder.AddPluginLoader is skipped because Loader is null - MVC ApplicationParts never includes the plugin's controllers - every plugin route 404s. Master CI #26 on 14a4389 reproduces exactly this: plugin in DI list, OTP create 404 x20 attempts, test fails. Removing both the file + the ProjectReference from the integration assembly closes the AppDomain-poison path by construction. The plugin DLL is still produced by the solution build (the .sln + the new SamRockProtocol.UnitTests project both still reference it), and the "Configure plugin path for tests" workflow step still copies it to ~/.btcpayserver/Plugins/SamRockProtocol/ so the runtime PluginLoader path can load it cleanly. The new SamRockProtocol.UnitTests project (added in this PR) keeps the DescriptorParser unit tests alive in a process-isolated assembly that has no compile-time relation to SamRockProtocol.Tests, so it cannot re-poison the integration AppDomain. Validation: - Solution build clean (0 errors) - SamRockProtocol.UnitTests: 25/25 passing locally - Integration test runs via separate `dotnet test SamRockProtocol.Tests` step in CI, in its own process, with no plugin metadata reference * ci: run unit tests before Docker boot so fast-feedback claim is honest Hermes nit on PR #17 review: workflow comment said unit tests don't need Docker, but YAML ordering had Docker boot before unit tests so the fast-feedback loop wasn't actually delivered. Reorder to: Run unit tests -> Start Docker containers -> Run integration tests Unit tests fail fast (~1s) without paying the Docker boot cost. --------- Co-authored-by: r1ckstardev <r1ckstardev@users.noreply.github.com>
1 parent 14a4389 commit 1068af2

5 files changed

Lines changed: 68 additions & 3 deletions

File tree

.github/workflows/playwright.yml

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,13 +79,20 @@ jobs:
7979
dotnet tool install --global Microsoft.Playwright.CLI
8080
export PATH="$PATH:$HOME/.dotnet/tools"
8181
82+
- name: Run unit tests
83+
# Pure-unit-tests project. Runs BEFORE Docker boot because it
84+
# doesn't need the BTCPay test stack - completes in ~1s. Keeps
85+
# the unit-test feedback loop fast even when the integration
86+
# test below takes minutes.
87+
run: dotnet test SamRockProtocol.UnitTests --logger "console;verbosity=normal" /p:EnableBoltzSupport=false
88+
8289
- name: Start Docker containers
8390
env:
8491
DOCKER_BUILDKIT: 1
8592
COMPOSE_DOCKER_CLI_BUILD: 1
8693
run: docker compose -f "submodules/btcpayserver/BTCPayServer.Tests/docker-compose.yml" up -d dev --build
8794

88-
- name: Run tests
95+
- name: Run integration tests
8996
run: dotnet test SamRockProtocol.Tests --logger "console;verbosity=detailed" /p:EnableBoltzSupport=false
9097

9198
- name: Cleanup Docker

SamRockProtocol.Tests/SamRockProtocol.Tests.csproj

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@
3232
<ProjectReference Include="..\submodules\btcpayserver\BTCPayServer.Tests\BTCPayServer.Tests.csproj">
3333
<PrivateAssets>all</PrivateAssets>
3434
</ProjectReference>
35-
<ProjectReference Include="..\Plugins\SamRockProtocol\SamRockProtocol.csproj" />
3635
</ItemGroup>
3736

3837
</Project>

SamRockProtocol.Tests/DescriptorParserTests.cs renamed to SamRockProtocol.UnitTests/DescriptorParserTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
using SamRockProtocol.Services;
22
using Xunit;
33

4-
namespace BTCPayServer.Plugins.Tests;
4+
namespace SamRockProtocol.UnitTests;
55

66
/// <summary>
77
/// Pure unit tests for SamRockProtocol's descriptor parsing helpers. No DI,
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<TargetFramework>net8.0</TargetFramework>
5+
<ImplicitUsings>enable</ImplicitUsings>
6+
<Nullable>enable</Nullable>
7+
8+
<IsPackable>false</IsPackable>
9+
<StaticWebAssetsEnabled>false</StaticWebAssetsEnabled>
10+
<RootNamespace>SamRockProtocol.UnitTests</RootNamespace>
11+
</PropertyGroup>
12+
13+
<ItemDefinitionGroup>
14+
<ProjectReference>
15+
<Properties>StaticWebAssetsEnabled=false</Properties>
16+
</ProjectReference>
17+
</ItemDefinitionGroup>
18+
19+
<ItemGroup>
20+
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.12.0" />
21+
<PackageReference Include="xunit" Version="2.9.3" />
22+
<PackageReference Include="xunit.runner.visualstudio" Version="3.0.0">
23+
<PrivateAssets>all</PrivateAssets>
24+
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
25+
</PackageReference>
26+
</ItemGroup>
27+
28+
<!--
29+
Deliberately references ONLY the SamRockProtocol plugin project, NOT
30+
the BTCPayServer test fixtures. The integration-test project
31+
(SamRockProtocol.Tests) must stay disentangled from any compile-time
32+
reference to plugin-internal types, because BTCPay's PluginManager
33+
scans AppDomain.CurrentDomain.GetAssemblies() before its file-based
34+
PluginLoader path and dedup-locks out anything already in AppDomain
35+
(PluginManager.cs:155-256). A plugin loaded that way registers with
36+
Loader=null and skips mvcBuilder.AddPluginLoader, so its controller
37+
routes 404 on the integration test. Keeping the pure unit tests in
38+
their own assembly lets us cover DescriptorParser without poisoning
39+
the integration test.
40+
-->
41+
<ItemGroup>
42+
<ProjectReference Include="..\Plugins\SamRockProtocol\SamRockProtocol.csproj" />
43+
</ItemGroup>
44+
45+
</Project>

SamRockProtocol.sln

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "AResources", "AResources",
3535
EndProject
3636
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SamRockProtocol.Tests", "SamRockProtocol.Tests\SamRockProtocol.Tests.csproj", "{E70B0FF3-63AD-4812-83D2-C83FDC2D95E3}"
3737
EndProject
38+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SamRockProtocol.UnitTests", "SamRockProtocol.UnitTests\SamRockProtocol.UnitTests.csproj", "{9968594F-24FD-4AD0-86F5-E747D10BD468}"
39+
EndProject
3840
Global
3941
GlobalSection(SolutionConfigurationPlatforms) = preSolution
4042
Debug|Any CPU = Debug|Any CPU
@@ -189,6 +191,18 @@ Global
189191
{E70B0FF3-63AD-4812-83D2-C83FDC2D95E3}.Release|x64.Build.0 = Release|Any CPU
190192
{E70B0FF3-63AD-4812-83D2-C83FDC2D95E3}.Release|x86.ActiveCfg = Release|Any CPU
191193
{E70B0FF3-63AD-4812-83D2-C83FDC2D95E3}.Release|x86.Build.0 = Release|Any CPU
194+
{9968594F-24FD-4AD0-86F5-E747D10BD468}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
195+
{9968594F-24FD-4AD0-86F5-E747D10BD468}.Debug|Any CPU.Build.0 = Debug|Any CPU
196+
{9968594F-24FD-4AD0-86F5-E747D10BD468}.Debug|x64.ActiveCfg = Debug|Any CPU
197+
{9968594F-24FD-4AD0-86F5-E747D10BD468}.Debug|x64.Build.0 = Debug|Any CPU
198+
{9968594F-24FD-4AD0-86F5-E747D10BD468}.Debug|x86.ActiveCfg = Debug|Any CPU
199+
{9968594F-24FD-4AD0-86F5-E747D10BD468}.Debug|x86.Build.0 = Debug|Any CPU
200+
{9968594F-24FD-4AD0-86F5-E747D10BD468}.Release|Any CPU.ActiveCfg = Release|Any CPU
201+
{9968594F-24FD-4AD0-86F5-E747D10BD468}.Release|Any CPU.Build.0 = Release|Any CPU
202+
{9968594F-24FD-4AD0-86F5-E747D10BD468}.Release|x64.ActiveCfg = Release|Any CPU
203+
{9968594F-24FD-4AD0-86F5-E747D10BD468}.Release|x64.Build.0 = Release|Any CPU
204+
{9968594F-24FD-4AD0-86F5-E747D10BD468}.Release|x86.ActiveCfg = Release|Any CPU
205+
{9968594F-24FD-4AD0-86F5-E747D10BD468}.Release|x86.Build.0 = Release|Any CPU
192206
EndGlobalSection
193207
GlobalSection(SolutionProperties) = preSolution
194208
HideSolutionNode = FALSE

0 commit comments

Comments
 (0)