You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
367 lines
11 KiB
C#
367 lines
11 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text.Json;
|
|
using Xunit;
|
|
using Haoliang.Models.Device;
|
|
using Haoliang.Models.DataCollection;
|
|
using Haoliang.Core.Services;
|
|
|
|
namespace Haoliang.Tests
|
|
{
|
|
public class DeviceCollectionServiceTests
|
|
{
|
|
private readonly IDeviceCollectionService _collectionService;
|
|
|
|
public DeviceCollectionServiceTests()
|
|
{
|
|
// 这里应该使用mock对象或测试数据库
|
|
_collectionService = new DeviceCollectionService(null, null, null, null, null, null);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task CollectDeviceDataAsync_ShouldParseValidJson()
|
|
{
|
|
// Arrange
|
|
var sampleJson = @"{
|
|
""device"": ""FANUC_01"",
|
|
""desc"": ""CNC Machine"",
|
|
""tags"": [
|
|
{
|
|
""id"": ""_io_status"",
|
|
""desc"": ""I/O Status"",
|
|
""quality"": 0,
|
|
""value"": 1,
|
|
""time"": ""2024-01-01T10:00:00""
|
|
},
|
|
{
|
|
""id"": ""Tag5"",
|
|
""desc"": ""NC Program"",
|
|
""quality"": 0,
|
|
""value"": ""O1234"",
|
|
""time"": ""2024-01-01T10:00:00""
|
|
},
|
|
{
|
|
""id"": ""Tag8"",
|
|
""desc"": ""Cumulative Count"",
|
|
""quality"": 0,
|
|
""value"": 12345.00000,
|
|
""time"": ""2024-01-01T10:00:00""
|
|
}
|
|
]
|
|
}";
|
|
|
|
// Act
|
|
var result = await _collectionService.CollectDeviceDataAsync(1);
|
|
|
|
// Assert
|
|
Assert.NotNull(result);
|
|
Assert.Equal("FANUC_01", result.DeviceCode);
|
|
Assert.Equal("O1234", result.NCProgram);
|
|
Assert.Equal(12345, result.CumulativeCount);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task CollectDeviceDataAsync_ShouldHandleInvalidJson()
|
|
{
|
|
// Arrange
|
|
var invalidJson = @"{
|
|
""device"": ""FANUC_01"",
|
|
""desc"": ""CNC Machine"",
|
|
""tags"": [
|
|
{
|
|
""id"": ""invalid_tag"",
|
|
""value"": ""invalid_value""
|
|
}
|
|
]
|
|
}";
|
|
|
|
// Act & Assert
|
|
await Assert.ThrowsAsync<JsonException>(() =>
|
|
_collectionService.CollectDeviceDataAsync(1));
|
|
}
|
|
|
|
[Fact]
|
|
public async Task PingDeviceAsync_ShouldReturnTrueForValidIp()
|
|
{
|
|
// Arrange
|
|
var validIp = "8.8.8.8"; // Google DNS
|
|
|
|
// Act
|
|
var result = await _collectionService.PingDeviceAsync(validIp);
|
|
|
|
// Assert
|
|
Assert.True(result);
|
|
}
|
|
}
|
|
|
|
public class ProductionServiceTests
|
|
{
|
|
private readonly IProductionService _productionService;
|
|
|
|
public ProductionServiceTests()
|
|
{
|
|
_productionService = new ProductionService(null, null, null);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task CalculateProductionAsync_ShouldCalculateDifference()
|
|
{
|
|
// Arrange
|
|
var current = new DeviceCurrentStatus
|
|
{
|
|
DeviceId = 1,
|
|
NCProgram = "O1234",
|
|
CumulativeCount = 15000,
|
|
RecordTime = DateTime.Now
|
|
};
|
|
|
|
var last = new DeviceCurrentStatus
|
|
{
|
|
DeviceId = 1,
|
|
NCProgram = "O1234",
|
|
CumulativeCount = 12000,
|
|
RecordTime = DateTime.Now.AddMinutes(-5)
|
|
};
|
|
|
|
// Act
|
|
var result = await _productionService.CalculateProductionAsync(1);
|
|
|
|
// Assert
|
|
Assert.Equal(3000, result);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task CalculateProductionAsync_ShouldHandleNegativeValues()
|
|
{
|
|
// Arrange
|
|
var current = new DeviceCurrentStatus
|
|
{
|
|
DeviceId = 1,
|
|
NCProgram = "O1234",
|
|
CumulativeCount = 10000,
|
|
RecordTime = DateTime.Now
|
|
};
|
|
|
|
var last = new DeviceCurrentStatus
|
|
{
|
|
DeviceId = 1,
|
|
NCProgram = "O1234",
|
|
CumulativeCount = 12000, // 比当前值大,应该产生负数
|
|
RecordTime = DateTime.Now.AddMinutes(-5)
|
|
};
|
|
|
|
// Act
|
|
var result = await _productionService.CalculateProductionAsync(1);
|
|
|
|
// Assert
|
|
Assert.Equal(0, result); // 负数应该被保护为0
|
|
}
|
|
|
|
[Fact]
|
|
public async Task CalculateProductionAsync_ShouldHandleProgramSwitch()
|
|
{
|
|
// Arrange
|
|
var current = new DeviceCurrentStatus
|
|
{
|
|
DeviceId = 1,
|
|
NCProgram = "O5678", // 不同的程序
|
|
CumulativeCount = 20000,
|
|
RecordTime = DateTime.Now
|
|
};
|
|
|
|
var last = new DeviceCurrentStatus
|
|
{
|
|
DeviceId = 1,
|
|
NCProgram = "O1234",
|
|
CumulativeCount = 15000,
|
|
RecordTime = DateTime.Now.AddMinutes(-5)
|
|
};
|
|
|
|
// Act
|
|
var result = await _productionService.CalculateProductionAsync(1);
|
|
|
|
// Assert
|
|
Assert.Equal(20000, result); // 新程序以当前累计数为起点
|
|
}
|
|
}
|
|
|
|
public class AlarmServiceTests
|
|
{
|
|
private readonly IAlarmService _alarmService;
|
|
|
|
public AlarmServiceTests()
|
|
{
|
|
_alarmService = new AlarmManager(null, null, null);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task CreateAlarmAsync_ShouldCreateAlarm()
|
|
{
|
|
// Arrange
|
|
var alarm = new Alarm
|
|
{
|
|
DeviceId = 1,
|
|
DeviceCode = "FANUC_01",
|
|
AlarmType = AlarmType.DeviceOffline,
|
|
Severity = AlarmSeverity.Critical,
|
|
Title = "Device Offline",
|
|
Description = "The device has been offline for more than 5 minutes",
|
|
AlarmStatus = AlarmStatus.Active
|
|
};
|
|
|
|
// Act
|
|
var result = await _alarmService.CreateAlarmAsync(alarm);
|
|
|
|
// Assert
|
|
Assert.NotNull(result);
|
|
Assert.Equal(AlarmStatus.Active, result.AlarmStatus);
|
|
Assert.NotNull(result.CreateTime);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task ResolveAlarmAsync_ShouldMarkAsResolved()
|
|
{
|
|
// Arrange
|
|
var alarm = new Alarm
|
|
{
|
|
DeviceId = 1,
|
|
DeviceCode = "FANUC_01",
|
|
AlarmType = AlarmType.DeviceOffline,
|
|
Severity = AlarmSeverity.Warning,
|
|
Title = "Device Offline",
|
|
Description = "The device has been offline",
|
|
AlarmStatus = AlarmStatus.Active
|
|
};
|
|
|
|
var createdAlarm = await _alarmService.CreateAlarmAsync(alarm);
|
|
|
|
// Act
|
|
var result = await _alarmService.ResolveAlarmAsync(createdAlarm.AlarmId, "Device reconnected");
|
|
|
|
// Assert
|
|
Assert.True(result);
|
|
|
|
// 验证状态确实改变了
|
|
var resolvedAlarm = await _alarmService.GetAlarmByIdAsync(createdAlarm.AlarmId);
|
|
Assert.Equal(AlarmStatus.Resolved, resolvedAlarm.AlarmStatus);
|
|
Assert.NotNull(resolvedAlarm.ResolvedTime);
|
|
Assert.Equal("Device reconnected", resolvedAlarm.ResolutionNote);
|
|
}
|
|
}
|
|
|
|
public class TemplateServiceTests
|
|
{
|
|
private readonly ITemplateService _templateService;
|
|
|
|
public TemplateServiceTests()
|
|
{
|
|
_templateService = new TemplateManager(null, null, null, null);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task CreateTemplateAsync_ShouldCreateValidTemplate()
|
|
{
|
|
// Arrange
|
|
var template = new CNCBrandTemplate
|
|
{
|
|
TemplateName = "FANUC Standard",
|
|
BrandName = "FANUC",
|
|
Description = "Standard FANUC template",
|
|
IsEnabled = true,
|
|
Version = "1.0",
|
|
TemplateJson = @"{
|
|
""device"": {
|
|
""status"": ""_io_status""
|
|
},
|
|
""production"": {
|
|
""program"": ""Tag5"",
|
|
""count"": ""Tag8""
|
|
}
|
|
}"
|
|
};
|
|
|
|
// Act
|
|
var result = await _templateService.CreateTemplateAsync(template);
|
|
|
|
// Assert
|
|
Assert.NotNull(result);
|
|
Assert.Equal("FANUC Standard", result.TemplateName);
|
|
Assert.True(result.IsEnabled);
|
|
Assert.NotNull(result.CreateTime);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task ValidateTemplateAsync_ShouldRejectInvalidTemplate()
|
|
{
|
|
// Arrange
|
|
var invalidTemplate = new CNCBrandTemplate
|
|
{
|
|
TemplateName = "", // 空模板名
|
|
BrandName = "FANUC",
|
|
Description = "Invalid template",
|
|
IsEnabled = true,
|
|
Version = "1.0",
|
|
TemplateJson = "" // 空JSON
|
|
};
|
|
|
|
// Act
|
|
var result = await _templateService.ValidateTemplateAsync(invalidTemplate);
|
|
|
|
// Assert
|
|
Assert.False(result);
|
|
}
|
|
}
|
|
|
|
public class SystemServiceTests
|
|
{
|
|
private readonly ISystemConfigService _configService;
|
|
private readonly ILoggingService _loggingService;
|
|
|
|
public SystemServiceTests()
|
|
{
|
|
_configService = new SystemConfigManager(null, null);
|
|
_loggingService = new LoggingManager(null, null);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task GetConfigAsync_ShouldReturnExistingConfig()
|
|
{
|
|
// Arrange
|
|
await _configService.SetConfigAsync("test.config", "test.value");
|
|
|
|
// Act
|
|
var result = await _configService.GetConfigAsync("test.config");
|
|
|
|
// Assert
|
|
Assert.NotNull(result);
|
|
Assert.Equal("test.value", result.ConfigValue);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task SetConfigAsync_ShouldUpdateConfig()
|
|
{
|
|
// Arrange
|
|
var newConfig = await _configService.SetConfigAsync("test.config", "new.value");
|
|
|
|
// Act
|
|
var result = await _configService.GetConfigAsync("test.config");
|
|
|
|
// Assert
|
|
Assert.NotNull(result);
|
|
Assert.Equal("new.value", result.ConfigValue);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task LogAsync_ShouldLogMessage()
|
|
{
|
|
// Arrange
|
|
var message = "Test log message";
|
|
|
|
// Act
|
|
await _loggingService.LogAsync(LogLevel.Information, message);
|
|
|
|
// 这里可以添加数据库验证,检查日志是否正确存储
|
|
}
|
|
}
|
|
} |