Skip to content

Commit a8382fb

Browse files
committed
Add environment variables in tests to force X11 and Wayland services to register.
1 parent d317bfb commit a8382fb

File tree

6 files changed

+137
-83
lines changed

6 files changed

+137
-83
lines changed

Tests/ControlR.DesktopClient.Linux.CaptureSample/Program.cs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11

22
using ControlR.DesktopClient.Common.ServiceInterfaces;
3-
using ControlR.DesktopClient.Linux;
43
using ControlR.DesktopClient.Linux.Services;
54
using ControlR.Libraries.DevicesCommon.Services;
65
using ControlR.Libraries.NativeInterop.Unix;
7-
using ControlR.Libraries.Shared.Helpers;
86
using Microsoft.Extensions.DependencyInjection;
97
using Microsoft.Extensions.Hosting;
108
using Microsoft.Extensions.Logging;

Tests/ControlR.DesktopClient.Tests/Startup/RemoteControlHostDependencyTests.cs

Lines changed: 40 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -2,77 +2,63 @@
22
using ControlR.DesktopClient.Common.ServiceInterfaces;
33
using ControlR.DesktopClient.Services;
44
using ControlR.Libraries.Shared.Dtos.IpcDtos;
5-
using Microsoft.Extensions.Hosting;
5+
using ControlR.Tests.TestingUtilities;
6+
using Microsoft.Extensions.Logging;
67
using Microsoft.Extensions.Options;
78
using Moq;
89

910
namespace ControlR.DesktopClient.Tests.Startup;
1011

1112
public class RemoteControlHostDependencyTests
1213
{
13-
[Fact]
14-
internal void CreateRemoteControlHostBuilder_InDevelopment_ValidatesDependencyGraph()
14+
[LinuxOnlyTheory]
15+
[InlineData(DesktopEnvironmentType.X11, "Development")]
16+
[InlineData(DesktopEnvironmentType.Wayland, "Development")]
17+
[InlineData(DesktopEnvironmentType.X11, "Production")]
18+
[InlineData(DesktopEnvironmentType.Wayland, "Production")]
19+
internal void CreateRemoteControlHostBuilder_InDevelopment_ValidatesDependencyGraph_Linux(DesktopEnvironmentType desktopEnvironment, string environment)
1520
{
16-
// Arrange
17-
var mockIpcAccessor = new Mock<IIpcClientAccessor>();
18-
var mockUserInteractionService = new Mock<IUserInteractionService>();
19-
var mockDesktopClientOptions = new Mock<IOptionsMonitor<DesktopClientOptions>>();
20-
var mockLogger = new Mock<Microsoft.Extensions.Logging.ILogger<RemoteControlHostManager>>();
21-
22-
mockDesktopClientOptions
23-
.Setup(x => x.CurrentValue)
24-
.Returns(new DesktopClientOptions { InstanceId = Guid.NewGuid().ToString() });
25-
26-
var hostManager = new RemoteControlHostManager(
27-
mockUserInteractionService.Object,
28-
mockDesktopClientOptions.Object,
29-
mockIpcAccessor.Object,
30-
mockLogger.Object);
31-
32-
var requestDto = new RemoteControlRequestIpcDto(
33-
SessionId: Guid.NewGuid(),
34-
WebsocketUri: new Uri("wss://localhost:5001"),
35-
TargetSystemSession: 1,
36-
TargetProcessId: 1234,
37-
ViewerConnectionId: "test-connection-id",
38-
DeviceId: Guid.NewGuid(),
39-
NotifyUserOnSessionStart: false,
40-
RequireConsent: false,
41-
DataFolder: Path.GetTempPath(),
42-
ViewerName: "Test Viewer");
43-
44-
// Configure environment as Development for validation
45-
Environment.SetEnvironmentVariable("DOTNET_ENVIRONMENT", Environments.Development);
46-
47-
try
21+
switch (desktopEnvironment)
4822
{
49-
// Act - Get the builder using the internal method
50-
var builder = hostManager.CreateRemoteControlHostBuilder(requestDto);
23+
case DesktopEnvironmentType.X11:
24+
Environment.SetEnvironmentVariable("DISPLAY", ":0");
25+
Environment.SetEnvironmentVariable("WAYLAND_DISPLAY", null);
26+
break;
27+
case DesktopEnvironmentType.Wayland:
28+
Environment.SetEnvironmentVariable("WAYLAND_DISPLAY", "wayland-0");
29+
Environment.SetEnvironmentVariable("DISPLAY", null);
30+
break;
31+
}
32+
CreateRemoteControlHostBuilder_ValidatesDependencyGraph(environment);
33+
}
5134

52-
// Assert - In Development, Build() validates the entire dependency graph
53-
// and throws if any registered services have unresolved dependencies.
54-
using var host = builder.Build();
35+
[MacOnlyTheory]
36+
[InlineData("Development")]
37+
[InlineData("Production")]
38+
internal void CreateRemoteControlHostBuilder_InDevelopment_ValidatesDependencyGraph_Mac(string environment)
39+
{
40+
CreateRemoteControlHostBuilder_ValidatesDependencyGraph(environment);
41+
}
5542

56-
Assert.NotNull(host);
57-
}
58-
finally
59-
{
60-
Environment.SetEnvironmentVariable("DOTNET_ENVIRONMENT", null);
61-
}
43+
[WindowsOnlyTheory]
44+
[InlineData("Development")]
45+
[InlineData("Production")]
46+
internal void CreateRemoteControlHostBuilder_InDevelopment_ValidatesDependencyGraph_Windows(string environment)
47+
{
48+
CreateRemoteControlHostBuilder_ValidatesDependencyGraph(environment);
6249
}
6350

64-
[Fact]
65-
internal void CreateRemoteControlHostBuilder_InProduction_Succeeds()
51+
private void CreateRemoteControlHostBuilder_ValidatesDependencyGraph(string environment)
6652
{
6753
// Arrange
6854
var mockIpcAccessor = new Mock<IIpcClientAccessor>();
6955
var mockUserInteractionService = new Mock<IUserInteractionService>();
7056
var mockDesktopClientOptions = new Mock<IOptionsMonitor<DesktopClientOptions>>();
71-
var mockLogger = new Mock<Microsoft.Extensions.Logging.ILogger<RemoteControlHostManager>>();
57+
var mockLogger = new Mock<ILogger<RemoteControlHostManager>>();
7258

7359
mockDesktopClientOptions
7460
.Setup(x => x.CurrentValue)
75-
.Returns(new DesktopClientOptions { InstanceId = Guid.NewGuid().ToString() });
61+
.Returns(new DesktopClientOptions { InstanceId = $"test-{Guid.NewGuid()}" });
7662

7763
var hostManager = new RemoteControlHostManager(
7864
mockUserInteractionService.Object,
@@ -92,16 +78,16 @@ internal void CreateRemoteControlHostBuilder_InProduction_Succeeds()
9278
DataFolder: Path.GetTempPath(),
9379
ViewerName: "Test Viewer");
9480

95-
// Configure environment as Production
96-
Environment.SetEnvironmentVariable("DOTNET_ENVIRONMENT", Environments.Production);
81+
// Configure environment as Development for validation
82+
Environment.SetEnvironmentVariable("DOTNET_ENVIRONMENT", environment);
9783

9884
try
9985
{
10086
// Act - Get the builder using the internal method
10187
var builder = hostManager.CreateRemoteControlHostBuilder(requestDto);
10288

103-
// Assert - In Production, Build() does not validate the dependency graph,
104-
// but we still verify it builds successfully.
89+
// Assert - In Development, Build() validates the entire dependency graph
90+
// and throws if any registered services have unresolved dependencies.
10591
using var host = builder.Build();
10692

10793
Assert.NotNull(host);
Lines changed: 46 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
using Avalonia.Controls.ApplicationLifetimes;
2+
using ControlR.DesktopClient.Common.ServiceInterfaces;
3+
using ControlR.Tests.TestingUtilities;
24
using Microsoft.Extensions.DependencyInjection;
35
using Microsoft.Extensions.Hosting;
46
using Moq;
@@ -7,51 +9,68 @@ namespace ControlR.DesktopClient.Tests.Startup;
79

810
public class StaticServiceProviderTests
911
{
10-
[Fact]
11-
internal void Build_InDevelopment_ValidatesDependencyGraph()
12+
[LinuxOnlyTheory]
13+
[InlineData(DesktopEnvironmentType.X11, "Development")]
14+
[InlineData(DesktopEnvironmentType.Wayland, "Development")]
15+
[InlineData(DesktopEnvironmentType.X11, "Production")]
16+
[InlineData(DesktopEnvironmentType.Wayland, "Production")]
17+
internal void Build_ValidatesDependencyGraph_Linux(DesktopEnvironmentType desktopEnvironment, string environment)
1218
{
13-
// Arrange
14-
// Configure environment as Development for validation
15-
Environment.SetEnvironmentVariable("DOTNET_ENVIRONMENT", Environments.Development);
16-
var builder = Host.CreateApplicationBuilder(new HostApplicationBuilderSettings
19+
switch (desktopEnvironment)
1720
{
18-
EnvironmentName = Environments.Development
19-
});
20-
21-
22-
var instanceId = $"test-{Guid.NewGuid()}";
23-
var mockLifetime = new Mock<IControlledApplicationLifetime>();
24-
25-
builder.Services.AddSingleton(mockLifetime.Object);
26-
builder.Services.AddSingleton(mockLifetime.Object);
27-
builder.Services.AddControlrDesktop(instanceId);
21+
case DesktopEnvironmentType.X11:
22+
Environment.SetEnvironmentVariable("DISPLAY", ":0");
23+
Environment.SetEnvironmentVariable("WAYLAND_DISPLAY", null);
24+
break;
25+
case DesktopEnvironmentType.Wayland:
26+
Environment.SetEnvironmentVariable("WAYLAND_DISPLAY", "wayland-0");
27+
Environment.SetEnvironmentVariable("DISPLAY", null);
28+
break;
29+
}
30+
Build_ValidatesDependencyGraph(environment);
31+
}
2832

29-
using var host = builder.Build();
33+
[MacOnlyTheory]
34+
[InlineData("Development")]
35+
[InlineData("Production")]
36+
internal void Build_ValidatesDependencyGraph_Mac(string environment)
37+
{
38+
Build_ValidatesDependencyGraph(environment);
39+
}
3040

31-
Assert.True(true, "Dependency graph should be valid in Development environment.");
41+
[WindowsOnlyTheory]
42+
[InlineData("Development")]
43+
[InlineData("Production")]
44+
internal void Build_ValidatesDependencyGraph_Windows(string environment)
45+
{
46+
Build_ValidatesDependencyGraph(environment);
3247
}
3348

34-
[Fact]
35-
internal void Build_InProduction_Succeeds()
49+
private static void Build_ValidatesDependencyGraph(string environment)
3650
{
3751
// Arrange
38-
// Configure environment as Production for validation
39-
Environment.SetEnvironmentVariable("DOTNET_ENVIRONMENT", Environments.Production);
52+
Environment.SetEnvironmentVariable("DOTNET_ENVIRONMENT", environment);
4053
var builder = Host.CreateApplicationBuilder(new HostApplicationBuilderSettings
4154
{
42-
EnvironmentName = Environments.Production
55+
EnvironmentName = environment
4356
});
4457

45-
4658
var instanceId = $"test-{Guid.NewGuid()}";
4759
var mockLifetime = new Mock<IControlledApplicationLifetime>();
4860

4961
builder.Services.AddSingleton(mockLifetime.Object);
5062
builder.Services.AddSingleton(mockLifetime.Object);
5163
builder.Services.AddControlrDesktop(instanceId);
5264

53-
using var host = builder.Build();
54-
55-
Assert.True(true, "Dependency graph should be valid in Production environment.");
65+
try
66+
{
67+
// Act & Assert
68+
using var host = builder.Build();
69+
Assert.NotNull(host);
70+
}
71+
finally
72+
{
73+
Environment.SetEnvironmentVariable("DOTNET_ENVIRONMENT", null);
74+
}
5675
}
5776
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
using Xunit;
2+
3+
namespace ControlR.Tests.TestingUtilities;
4+
5+
/// <summary>
6+
/// Xunit attribute to skip tests when not running on Linux.
7+
/// </summary>
8+
public class LinuxOnlyTheoryAttribute : TheoryAttribute
9+
{
10+
public LinuxOnlyTheoryAttribute()
11+
{
12+
if (!OperatingSystem.IsLinux())
13+
{
14+
Skip = "Test only runs on Linux";
15+
}
16+
}
17+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
using Xunit;
2+
3+
namespace ControlR.Tests.TestingUtilities;
4+
5+
/// <summary>
6+
/// Xunit attribute to skip tests when not running on Mac.
7+
/// </summary>
8+
public class MacOnlyTheoryAttribute : TheoryAttribute
9+
{
10+
public MacOnlyTheoryAttribute()
11+
{
12+
if (!OperatingSystem.IsMacOS())
13+
{
14+
Skip = "Test only runs on MacOS";
15+
}
16+
}
17+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
using Xunit;
2+
3+
namespace ControlR.Tests.TestingUtilities;
4+
5+
/// <summary>
6+
/// Xunit attribute to skip tests when not running on Windows.
7+
/// </summary>
8+
public class WindowsOnlyTheoryAttribute : TheoryAttribute
9+
{
10+
public WindowsOnlyTheoryAttribute()
11+
{
12+
if (!OperatingSystem.IsWindows())
13+
{
14+
Skip = "Test only runs on Windows";
15+
}
16+
}
17+
}

0 commit comments

Comments
 (0)