From c85751150a7bf340bd4224f6b0a20e106304a141 Mon Sep 17 00:00:00 2001 From: DualFroz Date: Thu, 27 Aug 2026 18:47:24 +0200 Subject: [PATCH] test(core): add sensor and systemd collector tests --- .../Collectors/SensorsTests.cs | 65 +++++++++++++++++++ .../Collectors/SystemdTests.cs | 63 ++++++++++++++++++ 2 files changed, 128 insertions(+) create mode 100644 tests/Vantage.Core.Tests/Collectors/SensorsTests.cs create mode 100644 tests/Vantage.Core.Tests/Collectors/SystemdTests.cs diff --git a/tests/Vantage.Core.Tests/Collectors/SensorsTests.cs b/tests/Vantage.Core.Tests/Collectors/SensorsTests.cs new file mode 100644 index 0000000..38b184a --- /dev/null +++ b/tests/Vantage.Core.Tests/Collectors/SensorsTests.cs @@ -0,0 +1,65 @@ +using Vantage.Core.Collectors.Sensors; +using Vantage.Core.Models; +using Vantage.Core.Tests.Fakes; +using Vantage.Core.Tests.Fixtures; +using Xunit; + +namespace Vantage.Core.Tests.Collectors; + +public class SensorsTests +{ + [Fact] + public void ThermalParser_ConvertsMilliDegreesToCelsius() + { + var readings = ThermalZoneParser.Parse(CollectorFixtures.ThermalZones); + + Assert.Equal(4, readings.Count); + Assert.Equal(52.0, readings.Single(r => r.Label == "x86_pkg_temp").Celsius, 3); + Assert.Equal(48.0, readings.Single(r => r.Label == "coretemp Core 0").Celsius, 3); + } + + [Fact] + public void NvidiaSmiParser_ParsesGpuRow() + { + var gpus = NvidiaSmiParser.Parse(CollectorFixtures.NvidiaSmiCsv); + + var gpu = Assert.Single(gpus); + Assert.Equal("NVIDIA GeForce RTX 3060", gpu.Name); + Assert.Equal(52, gpu.TemperatureCelsius, 3); + Assert.Equal(34, gpu.UtilizationPercent, 3); + Assert.Equal(3200L * 1024 * 1024, gpu.MemoryUsedBytes); + Assert.Equal(12288L * 1024 * 1024, gpu.MemoryTotalBytes); + } + + [Fact] + public void ParseBundle_SplitsThermalFromGpu() + { + var snapshot = SshSensorProvider.ParseBundle(CollectorFixtures.SensorBundle()); + + Assert.Equal(4, snapshot.Temperatures.Count); + Assert.Single(snapshot.Gpus); + Assert.Equal(52.0, snapshot.HottestCelsius); + } + + [Fact] + public void ParseBundle_WithoutGpu_ReturnsEmptyGpuList() + { + var snapshot = SshSensorProvider.ParseBundle(CollectorFixtures.ThermalZones + "@@vantage:gpu\n"); + + Assert.Empty(snapshot.Gpus); + Assert.Equal(4, snapshot.Temperatures.Count); + } + + [Fact] + public async Task SshSensorProvider_BuildsThermalAndGpuCommand() + { + var runner = new FakeSshCommandRunner(CollectorFixtures.SensorBundle()); + var provider = new SshSensorProvider(runner); + + var snapshot = await provider.GetSnapshotAsync(new HostConfig(), CancellationToken.None); + + Assert.Contains("thermal_zone", runner.Commands.Single()); + Assert.Contains("nvidia-smi", runner.Commands.Single()); + Assert.Single(snapshot.Gpus); + } +} diff --git a/tests/Vantage.Core.Tests/Collectors/SystemdTests.cs b/tests/Vantage.Core.Tests/Collectors/SystemdTests.cs new file mode 100644 index 0000000..3b64c05 --- /dev/null +++ b/tests/Vantage.Core.Tests/Collectors/SystemdTests.cs @@ -0,0 +1,63 @@ +using Vantage.Core.Collectors.Systemd; +using Vantage.Core.Models; +using Vantage.Core.Tests.Fakes; +using Vantage.Core.Tests.Fixtures; +using Xunit; + +namespace Vantage.Core.Tests.Collectors; + +public class SystemdTests +{ + [Fact] + public void Parser_ReadsUnitColumns() + { + var units = SystemdUnitParser.Parse(CollectorFixtures.SystemctlOutput); + + var docker = units.Single(u => u.Unit == "docker.service"); + Assert.Equal("loaded", docker.Load); + Assert.Equal("active", docker.Active); + Assert.Equal("running", docker.Sub); + Assert.Equal("Docker Application Container Engine", docker.Description); + Assert.True(docker.IsRunning); + } + + [Fact] + public void Parser_StripsLeadingStatusMarker() + { + var units = SystemdUnitParser.Parse(CollectorFixtures.SystemctlOutput); + + var backup = units.Single(u => u.Unit == "backup.service"); + Assert.Equal("failed", backup.Active); + Assert.True(backup.IsFailed); + } + + [Fact] + public void Parser_KeepsOnlyServiceUnits() + { + var units = SystemdUnitParser.Parse(CollectorFixtures.SystemctlOutput); + Assert.DoesNotContain(units, u => u.Unit.EndsWith(".timer")); + Assert.Equal(4, units.Count); + } + + [Fact] + public async Task SshSystemdProvider_UsesListUnitsCommand() + { + var runner = new FakeSshCommandRunner(CollectorFixtures.SystemctlOutput); + var provider = new SshSystemdProvider(runner); + + var units = await provider.GetServicesAsync(new HostConfig(), CancellationToken.None); + + Assert.Contains("list-units", runner.Commands.Single()); + Assert.Contains(units, u => u.Unit == "nginx.service"); + } + + [Fact] + public async Task MockSystemdProvider_IncludesFailedUnit() + { + var provider = new MockSystemdProvider(); + var units = await provider.GetServicesAsync(new HostConfig(), CancellationToken.None); + + Assert.Contains(units, u => u.IsFailed); + Assert.Contains(units, u => u.IsRunning); + } +}