unity-mcp/TestProjects/UnityMCPTests/Assets/Tests/EditMode/Services/Server/ProcessTerminatorTests.cs

160 lines
4.5 KiB
C#

using NUnit.Framework;
using MCPForUnity.Editor.Services.Server;
namespace MCPForUnityTests.Editor.Services.Server
{
/// <summary>
/// Unit tests for ProcessTerminator component.
/// Note: Most tests avoid actually terminating processes to prevent test instability.
/// Uses ProcessDetector which executes subprocess commands (ps, tasklist, etc.), so marked as [Explicit].
/// </summary>
[TestFixture]
[Explicit]
public class ProcessTerminatorTests
{
private ProcessTerminator _terminator;
private ProcessDetector _detector;
[SetUp]
public void SetUp()
{
_detector = new ProcessDetector();
_terminator = new ProcessTerminator(_detector);
}
#region Constructor Tests
[Test]
public void Constructor_NullDetector_ThrowsArgumentNullException()
{
// Act & Assert
Assert.Throws<System.ArgumentNullException>(() =>
{
new ProcessTerminator(null);
});
}
[Test]
public void Constructor_ValidDetector_Succeeds()
{
// Act & Assert
Assert.DoesNotThrow(() =>
{
new ProcessTerminator(_detector);
});
}
#endregion
#region Terminate Tests
[Test]
public void Terminate_InvalidPid_ReturnsFalse()
{
// Act
bool result = _terminator.Terminate(-1);
// Assert
Assert.IsFalse(result, "Invalid PID should fail to terminate");
}
[Test]
public void Terminate_ZeroPid_ReturnsFalse()
{
// Act
bool result = _terminator.Terminate(0);
// Assert
Assert.IsFalse(result, "Zero PID should fail to terminate");
}
[Test]
public void Terminate_Pid1_ReturnsFalse()
{
// PID 1 is init/launchd and must never be killed
// Act
bool result = _terminator.Terminate(1);
// Assert
Assert.IsFalse(result, "PID 1 (init/launchd) should never be terminated");
}
[Test]
public void Terminate_CurrentProcessPid_ReturnsFalse()
{
// Should never kill the Unity Editor process
// Act
int currentPid = _detector.GetCurrentProcessId();
bool result = _terminator.Terminate(currentPid);
// Assert
Assert.IsFalse(result, "Current process PID should never be terminated");
}
[Test]
public void Terminate_NonExistentPid_ReturnsFalseOrHandlesGracefully()
{
// Act - Use a very high PID unlikely to exist
bool result = _terminator.Terminate(9999999);
// Assert - Should not terminate non-existent PID
Assert.IsFalse(result, $"Terminate returned {result} for non-existent PID");
}
[Test]
public void Terminate_DoesNotThrow()
{
// Act & Assert - Should handle any PID gracefully
Assert.DoesNotThrow(() =>
{
_terminator.Terminate(int.MaxValue);
});
}
#endregion
#region Interface Implementation Tests
[Test]
public void ProcessTerminator_ImplementsIProcessTerminator()
{
// Assert
Assert.IsInstanceOf<IProcessTerminator>(_terminator);
}
[Test]
public void ProcessTerminator_CanBeUsedViaInterface()
{
// Arrange
IProcessTerminator terminator = new ProcessTerminator(_detector);
// Act & Assert - Should be callable via interface
Assert.DoesNotThrow(() =>
{
// Don't actually terminate anything
terminator.Terminate(-1);
});
}
#endregion
#region Integration Tests (with real detector)
[Test]
public void Terminate_WithRealDetector_HandlesMissingProcess()
{
// Arrange
var realDetector = new ProcessDetector();
var terminator = new ProcessTerminator(realDetector);
// Act - Try to terminate a PID that definitely doesn't exist
bool result = terminator.Terminate(int.MaxValue);
// Assert - Should return false without throwing
Assert.IsFalse(result, "Terminating non-existent process should return false");
}
#endregion
}
}