Files

142 lines
4.3 KiB
C#

using FluentAssertions;
using MarketAlly.ProcessMonitor.Interfaces;
using MarketAlly.ProcessMonitor.Models;
using MarketAlly.ProcessMonitor.Services;
using MarketAlly.ProcessMonitor.Exceptions;
using Microsoft.Extensions.Logging;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
namespace MarketAlly.ProcessMonitor.Tests.Unit;
[TestClass]
public class ProcessManagerTests
{
private Mock<ILogger<ProcessManager>> _loggerMock = null!;
private Mock<IProcessValidator> _validatorMock = null!;
private ProcessManager _processManager = null!;
private AppSettings _appSettings = null!;
[TestInitialize]
public void Setup()
{
_loggerMock = new Mock<ILogger<ProcessManager>>();
_validatorMock = new Mock<IProcessValidator>();
_appSettings = new AppSettings { MaxConcurrentStarts = 5 };
_processManager = new ProcessManager(_loggerMock.Object, _validatorMock.Object, _appSettings);
}
[TestMethod]
public async Task StartProcessAsync_WithValidConfig_LogsSuccess()
{
// Arrange
var processInfo = new ProcessInfo
{
Name = "test",
Path = @"C:\test.exe",
Enable = true
};
_validatorMock.Setup(v => v.ValidateProcessInfo(It.IsAny<ProcessInfo>()))
.Returns(new ValidationResult(true, new List<string>()));
// Act & Assert
// We can't actually start a process in unit tests, so we verify the validation occurs
try
{
await _processManager.StartProcessAsync(processInfo, false);
}
catch (ProcessStartException)
{
// Expected when the process doesn't exist
}
_validatorMock.Verify(v => v.ValidateProcessInfo(processInfo), Times.Once);
}
[TestMethod]
public async Task StartProcessAsync_WithInvalidConfig_ThrowsException()
{
// Arrange
var processInfo = new ProcessInfo
{
Name = "invalid",
Path = "invalid_path",
Enable = true
};
_validatorMock.Setup(v => v.ValidateProcessInfo(It.IsAny<ProcessInfo>()))
.Returns(new ValidationResult(false, new List<string> { "Invalid path" }));
// Act & Assert
await Assert.ThrowsExceptionAsync<ProcessValidationException>(
async () => await _processManager.StartProcessAsync(processInfo, false));
}
[TestMethod]
public async Task EnsureProcessRunningAsync_LogsCorrectMessage()
{
// Arrange
var processInfo = new ProcessInfo
{
Name = "test",
Path = @"C:\test.exe",
Count = 3,
Enable = true
};
_validatorMock.Setup(v => v.ValidateProcessInfo(It.IsAny<ProcessInfo>()))
.Returns(new ValidationResult(true, new List<string>()));
// Act
try
{
await _processManager.EnsureProcessRunningAsync(processInfo, 3, false);
}
catch (ProcessStartException)
{
// Expected when the process doesn't exist
}
// Assert
_loggerMock.Verify(
l => l.Log(
LogLevel.Information,
It.IsAny<EventId>(),
It.Is<It.IsAnyType>((v, t) => v.ToString()!.Contains("Starting 3 instances")),
It.IsAny<Exception>(),
It.IsAny<Func<It.IsAnyType, Exception?, string>>()),
Times.Once);
}
[TestMethod]
public void GetRunningProcessCount_ReturnsCorrectCount()
{
// Arrange & Act
var count = _processManager.GetRunningProcessCount("System");
// Assert
count.Should().BeGreaterOrEqualTo(0);
}
[TestMethod]
public async Task StopProcessAsync_ReturnsTrue_WhenNoProcessesRunning()
{
// Arrange
var processName = "nonexistent_process";
// Act
var result = await _processManager.StopProcessAsync(processName);
// Assert
result.Should().BeTrue();
_loggerMock.Verify(
l => l.Log(
LogLevel.Information,
It.IsAny<EventId>(),
It.Is<It.IsAnyType>((v, t) => v.ToString()!.Contains("No running instances")),
It.IsAny<Exception>(),
It.IsAny<Func<It.IsAnyType, Exception?, string>>()),
Times.Once);
}
}