-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathSshConnectionFailureTest.cs
More file actions
126 lines (105 loc) · 4.57 KB
/
SshConnectionFailureTest.cs
File metadata and controls
126 lines (105 loc) · 4.57 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Moq;
using Xunit;
using LabTracker.Ssh;
namespace LabTracker.Tests;
public class SshConnectionFailureTest
{
private readonly Mock<ILogger<Worker>> _mockLogger;
private readonly Mock<IHostApplicationLifetime> _mockHostLifetime;
private readonly Mock<IOptions<Options>> _mockOptions;
private readonly Mock<IPublisher> _mockPublisher;
private readonly Mock<IPublished> _mockPublished;
private readonly Mock<IClientInfoProvider> _mockClientProvider;
private readonly Options _testOptions;
public SshConnectionFailureTest()
{
_mockLogger = new Mock<ILogger<Worker>>();
_mockHostLifetime = new Mock<IHostApplicationLifetime>();
_mockOptions = new Mock<IOptions<Options>>();
_mockPublisher = new Mock<IPublisher>();
_mockPublished = new Mock<IPublished>();
_mockClientProvider = new Mock<IClientInfoProvider>();
_testOptions = new Options
{
Unifi = new UnifiOptions
{
AccessPoints = new[] { "192.168.1.1", "192.168.1.2" }
},
DelayMs = 1000
};
_mockOptions.Setup(x => x.Value).Returns(_testOptions);
// Setup publisher initialization
_mockPublisher.Setup(x => x.InitializeAsync()).Returns(Task.CompletedTask);
_mockPublished.Setup(x => x.ReadCurrentStatesAsync())
.ReturnsAsync(new Dictionary<string, ClientState>());
}
[Fact]
public async Task Worker_WhenSshConnectionFails_ShouldSkipProcessingAndContinue()
{
// Arrange
var cts = new CancellationTokenSource();
// Setup SSH failure for one host
_mockClientProvider.Setup(x => x.GetClientsAsync("192.168.1.1", It.IsAny<CancellationToken>()))
.ThrowsAsync(new SshConnectionException("Connection failed"));
_mockClientProvider.Setup(x => x.GetClientsAsync("192.168.1.2", It.IsAny<CancellationToken>()))
.ReturnsAsync((null, new List<ClientInfo>()));
var worker = new Worker(_mockLogger.Object, _mockHostLifetime.Object, _mockOptions.Object,
_mockPublisher.Object, _mockPublished.Object, _mockClientProvider.Object);
// Act & Assert
// The worker should catch SSH exceptions and continue (not call StopApplication)
var executeTask = worker.StartAsync(cts.Token);
// Give it a moment to start and process
await Task.Delay(100);
// Cancel to stop the worker
cts.Cancel();
try
{
await executeTask;
}
catch (OperationCanceledException)
{
// Expected when cancellation occurs
}
// Verify that StopApplication was NOT called due to SSH failure
_mockHostLifetime.Verify(x => x.StopApplication(), Times.Never);
}
[Fact]
public void SshConnectionException_ShouldBeCreatedCorrectly()
{
// Test the custom exception
var message = "Test SSH failure";
var innerException = new Exception("Inner exception");
var exception1 = new SshConnectionException(message);
var exception2 = new SshConnectionException(message, innerException);
Assert.Equal(message, exception1.Message);
Assert.Equal(message, exception2.Message);
Assert.Equal(innerException, exception2.InnerException);
}
[Fact]
public async Task SshClientProvider_WhenConnectionFails_ShouldThrowSshConnectionException()
{
// This test verifies that SSH connection failures are properly wrapped
var mockLogger = new Mock<ILogger<SshClientProvider>>();
var mockOptions = new Mock<IOptions<Options>>();
var testOptions = new Options
{
Unifi = new UnifiOptions
{
Username = "test",
PrivateKeyPath = "/nonexistent/key"
},
ConnectionTimeoutSeconds = 1,
CommandTimeoutSeconds = 1
};
mockOptions.Setup(x => x.Value).Returns(testOptions);
var provider = new SshClientProvider(mockLogger.Object, mockOptions.Object);
// This will fail because the host/key doesn't exist
var exception = await Assert.ThrowsAsync<SshConnectionException>(
() => provider.GetClientsAsync("invalid-host", CancellationToken.None));
Assert.Contains("Failed to connect to SSH host invalid-host", exception.Message);
Assert.NotNull(exception.InnerException);
}
}