325 lines
9.6 KiB
C#
325 lines
9.6 KiB
C#
using Common.Utils;
|
|
|
|
namespace Common.Test;
|
|
|
|
/// <summary>
|
|
/// SystemHelper 测试
|
|
/// 展示系统相关的实用工具方法
|
|
/// </summary>
|
|
[TestClass]
|
|
public class SystemHelperTests
|
|
{
|
|
#region GetAvailablePort 测试
|
|
|
|
/// <summary>
|
|
/// 测试:获取可用端口返回有效端口号
|
|
/// </summary>
|
|
[TestMethod]
|
|
public void GetAvailablePort_ReturnsValidPort()
|
|
{
|
|
// Act
|
|
var port = SystemHelper.GetAvailablePort();
|
|
|
|
// Assert: 端口应该在有效范围内
|
|
Assert.IsTrue(port > 0);
|
|
Assert.IsTrue(port <= 65535);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 测试:多次调用获取不同的可用端口
|
|
/// </summary>
|
|
[TestMethod]
|
|
public void GetAvailablePort_MultipleCallsReturnDifferentPorts()
|
|
{
|
|
// Act: 多次获取端口
|
|
var port1 = SystemHelper.GetAvailablePort();
|
|
var port2 = SystemHelper.GetAvailablePort();
|
|
var port3 = SystemHelper.GetAvailablePort();
|
|
|
|
// Assert: 每次应该返回不同的端口(由操作系统分配)
|
|
var ports = new[] { port1, port2, port3 };
|
|
Assert.AreEqual(3, ports.Distinct().Count(), "Should get different ports");
|
|
}
|
|
|
|
/// <summary>
|
|
/// 测试:获取的端口确实可用
|
|
/// 演示如何验证端口是否真的可以使用
|
|
/// </summary>
|
|
[TestMethod]
|
|
public void GetAvailablePort_PortIsActuallyAvailable()
|
|
{
|
|
// Act: 获取可用端口
|
|
var port = SystemHelper.GetAvailablePort();
|
|
|
|
// Assert: 尝试在该端口上创建监听器
|
|
using var listener = new System.Net.Sockets.TcpListener(
|
|
System.Net.IPAddress.Loopback,
|
|
port
|
|
);
|
|
|
|
// 如果端口被占用,Start 会抛出异常
|
|
listener.Start();
|
|
listener.Stop();
|
|
|
|
// 如果没有抛出异常,说明端口确实可用
|
|
Assert.IsTrue(true);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region IsAdministrator 测试
|
|
|
|
/// <summary>
|
|
/// 测试:IsAdministrator 在 Windows 上正常工作
|
|
/// 注意:此测试在非 Windows 平台会被跳过
|
|
/// </summary>
|
|
[TestMethod]
|
|
public void IsAdministrator_OnWindows_ReturnsBoolean()
|
|
{
|
|
// Arrange: 检查是否为 Windows 平台
|
|
if (!OperatingSystem.IsWindows())
|
|
{
|
|
Assert.Inconclusive("This test only runs on Windows");
|
|
return;
|
|
}
|
|
|
|
// Act
|
|
var isAdmin = SystemHelper.IsAdministrator();
|
|
|
|
// Assert: 应该返回布尔值(无论是 true 还是 false 都是有效的)
|
|
Assert.IsInstanceOfType(isAdmin, typeof(bool));
|
|
|
|
// 输出结果供参考
|
|
Console.WriteLine($"Running as administrator: {isAdmin}");
|
|
}
|
|
|
|
/// <summary>
|
|
/// 测试:IsAdministrator 在非 Windows 平台抛出异常
|
|
/// 注意:此测试在 Windows 平台会被跳过
|
|
/// </summary>
|
|
[TestMethod]
|
|
public void IsAdministrator_OnNonWindows_ThrowsException()
|
|
{
|
|
// Arrange: 检查是否为非 Windows 平台
|
|
if (OperatingSystem.IsWindows())
|
|
{
|
|
Assert.Inconclusive("This test only runs on non-Windows platforms");
|
|
return;
|
|
}
|
|
|
|
// Act & Assert: 在非 Windows 平台应该抛出异常
|
|
var exception = Assert.ThrowsException<PlatformNotSupportedException>(() =>
|
|
{
|
|
SystemHelper.IsAdministrator();
|
|
});
|
|
|
|
Assert.IsTrue(exception.Message.Contains("Windows"));
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region 实际应用场景测试
|
|
|
|
/// <summary>
|
|
/// 场景测试:为开发服务器分配端口
|
|
/// 演示如何在启动服务器时动态分配端口
|
|
/// </summary>
|
|
[TestMethod]
|
|
public void Scenario_AllocatePortForDevelopmentServer()
|
|
{
|
|
// Arrange: 需要启动多个开发服务器
|
|
var serverCount = 3;
|
|
var allocatedPorts = new List<int>();
|
|
|
|
// Act: 为每个服务器分配端口
|
|
for (var i = 0; i < serverCount; i++)
|
|
{
|
|
var port = SystemHelper.GetAvailablePort();
|
|
allocatedPorts.Add(port);
|
|
Console.WriteLine($"Server {i + 1} allocated port: {port}");
|
|
}
|
|
|
|
// Assert: 所有端口都应该是唯一的
|
|
Assert.AreEqual(serverCount, allocatedPorts.Distinct().Count());
|
|
Assert.IsTrue(allocatedPorts.All(p => p > 0 && p <= 65535));
|
|
}
|
|
|
|
/// <summary>
|
|
/// 场景测试:检查权限后执行特权操作
|
|
/// 演示如何在需要管理员权限的功能中使用 IsAdministrator
|
|
/// </summary>
|
|
[TestMethod]
|
|
public void Scenario_CheckAdminBeforePrivilegedOperation()
|
|
{
|
|
// 跳过非 Windows 平台
|
|
if (!OperatingSystem.IsWindows())
|
|
{
|
|
Assert.Inconclusive("This test only runs on Windows");
|
|
return;
|
|
}
|
|
|
|
// Arrange: 定义需要管理员权限的操作
|
|
void PrivilegedOperation()
|
|
{
|
|
if (!SystemHelper.IsAdministrator())
|
|
throw new UnauthorizedAccessException(
|
|
"This operation requires administrator privileges"
|
|
);
|
|
|
|
// 执行需要管理员权限的操作...
|
|
Console.WriteLine("Executing privileged operation");
|
|
}
|
|
|
|
// Act & Assert: 根据当前权限决定行为
|
|
if (SystemHelper.IsAdministrator())
|
|
{
|
|
// 如果是管理员,操作应该成功
|
|
PrivilegedOperation();
|
|
Assert.IsTrue(true);
|
|
}
|
|
else
|
|
{
|
|
// 如果不是管理员,应该抛出异常
|
|
Assert.ThrowsException<UnauthorizedAccessException>(() => { PrivilegedOperation(); });
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 场景测试:动态端口绑定用于测试
|
|
/// 演示如何在集成测试中使用动态端口避免冲突
|
|
/// </summary>
|
|
[TestMethod]
|
|
public void Scenario_DynamicPortForIntegrationTesting()
|
|
{
|
|
// Arrange: 模拟需要启动测试服务器的场景
|
|
var testServers = new List<TestServer>();
|
|
|
|
try
|
|
{
|
|
// Act: 启动多个测试服务器
|
|
for (var i = 0; i < 3; i++)
|
|
{
|
|
var port = SystemHelper.GetAvailablePort();
|
|
var server = new TestServer($"TestServer{i + 1}", port);
|
|
server.Start();
|
|
testServers.Add(server);
|
|
|
|
Console.WriteLine($"{server.Name} started on port {server.Port}");
|
|
}
|
|
|
|
// Assert: 所有服务器都应该成功启动
|
|
Assert.AreEqual(3, testServers.Count);
|
|
Assert.IsTrue(testServers.All(s => s.IsRunning));
|
|
|
|
// 验证端口都不相同
|
|
var ports = testServers.Select(s => s.Port).ToList();
|
|
Assert.AreEqual(3, ports.Distinct().Count());
|
|
}
|
|
finally
|
|
{
|
|
// Cleanup: 停止所有测试服务器
|
|
foreach (var server in testServers) server.Stop();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 场景测试:端口范围检查
|
|
/// 演示验证分配的端口在合理范围内
|
|
/// </summary>
|
|
[TestMethod]
|
|
public void Scenario_VerifyPortRange()
|
|
{
|
|
// Arrange: 获取多个端口样本
|
|
var sampleSize = 10;
|
|
var ports = new List<int>();
|
|
|
|
// Act: 收集端口样本
|
|
for (var i = 0; i < sampleSize; i++) ports.Add(SystemHelper.GetAvailablePort());
|
|
|
|
// Assert: 验证所有端口都在合理范围内
|
|
// 动态端口范围通常是 49152-65535
|
|
Assert.IsTrue(ports.All(p => p > 0), "All ports should be positive");
|
|
Assert.IsTrue(ports.All(p => p <= 65535), "All ports should be <= 65535");
|
|
|
|
// 统计信息
|
|
Console.WriteLine($"Port range: {ports.Min()} - {ports.Max()}");
|
|
Console.WriteLine($"Average port: {ports.Average():F0}");
|
|
}
|
|
|
|
/// <summary>
|
|
/// 场景测试:跨平台兼容性处理
|
|
/// 演示如何编写跨平台友好的代码
|
|
/// </summary>
|
|
[TestMethod]
|
|
public void Scenario_CrossPlatformCompatibility()
|
|
{
|
|
// Act: 尝试检查管理员权限,优雅处理不同平台
|
|
bool? isAdmin = null;
|
|
Exception? caughtException = null;
|
|
|
|
try
|
|
{
|
|
isAdmin = SystemHelper.IsAdministrator();
|
|
}
|
|
catch (PlatformNotSupportedException ex)
|
|
{
|
|
caughtException = ex;
|
|
}
|
|
|
|
// Assert: 根据平台验证行为
|
|
if (OperatingSystem.IsWindows())
|
|
{
|
|
// Windows: 应该返回结果
|
|
Assert.IsNotNull(isAdmin);
|
|
Assert.IsNull(caughtException);
|
|
Console.WriteLine($"Windows platform - Is Admin: {isAdmin}");
|
|
}
|
|
else
|
|
{
|
|
// 非 Windows: 应该抛出异常
|
|
Assert.IsNull(isAdmin);
|
|
Assert.IsNotNull(caughtException);
|
|
Console.WriteLine($"Non-Windows platform - Exception caught: {caughtException.Message}");
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region 测试辅助类型
|
|
|
|
/// <summary>
|
|
/// 测试用的简单服务器模拟
|
|
/// </summary>
|
|
private class TestServer
|
|
{
|
|
public string Name { get; }
|
|
public int Port { get; }
|
|
public bool IsRunning { get; private set; }
|
|
|
|
private System.Net.Sockets.TcpListener? _listener;
|
|
|
|
public TestServer(string name, int port)
|
|
{
|
|
Name = name;
|
|
Port = port;
|
|
}
|
|
|
|
public void Start()
|
|
{
|
|
_listener = new System.Net.Sockets.TcpListener(
|
|
System.Net.IPAddress.Loopback,
|
|
Port
|
|
);
|
|
_listener.Start();
|
|
IsRunning = true;
|
|
}
|
|
|
|
public void Stop()
|
|
{
|
|
_listener?.Stop();
|
|
IsRunning = false;
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
} |