test(core): add system parsing and Prometheus tests
This commit is contained in:
1 parent
77ab104be3
commit
d679231fed
3 files changed
+195
No files matched your search
@@ -0,0 +1,71 @@
|
||||
using Vantage.Core.Metrics.Parsing;
|
||||
using Vantage.Core.Tests.Fixtures;
|
||||
using Xunit;
|
||||
|
||||
namespace Vantage.Core.Tests.Parsing;
|
||||
|
||||
public class ParsersTests
|
||||
{
|
||||
[Fact]
|
||||
public void LoadAvgParser_ReadsFirstThreeValues()
|
||||
{
|
||||
var load = LoadAvgParser.Parse(MetricsFixtures.Loadavg);
|
||||
Assert.Equal(0.50, load.Load1, 3);
|
||||
Assert.Equal(0.40, load.Load5, 3);
|
||||
Assert.Equal(0.30, load.Load15, 3);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void UptimeParser_ReadsSeconds()
|
||||
{
|
||||
var uptime = UptimeParser.Parse(MetricsFixtures.Uptime);
|
||||
Assert.Equal(123456.78, uptime.TotalSeconds, 2);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void MemInfoParser_UsesMemAvailable()
|
||||
{
|
||||
var memory = MemInfoParser.Parse(MetricsFixtures.Meminfo);
|
||||
Assert.Equal(8000000L * 1024, memory.TotalBytes);
|
||||
Assert.Equal(6000000L * 1024, memory.UsedBytes);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void MemInfoParser_FallsBackToMemFreeWhenNoAvailable()
|
||||
{
|
||||
var memory = MemInfoParser.Parse("MemTotal: 4000 kB\nMemFree: 1000 kB\n");
|
||||
Assert.Equal(4000L * 1024, memory.TotalBytes);
|
||||
Assert.Equal(3000L * 1024, memory.UsedBytes);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void DfParser_ReadsTotalAndUsedFromDataRow()
|
||||
{
|
||||
var disk = DfParser.Parse(MetricsFixtures.Df);
|
||||
Assert.Equal(100000000000L, disk.TotalBytes);
|
||||
Assert.Equal(40000000000L, disk.UsedBytes);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ProcStatParser_SumsTotalAndIdle()
|
||||
{
|
||||
var times = ProcStatParser.Parse(MetricsFixtures.Stat1);
|
||||
Assert.Equal(1000, times.TotalTime);
|
||||
Assert.Equal(800, times.IdleTime);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CpuUsage_ComputesBusyFractionFromTwoSnapshots()
|
||||
{
|
||||
var before = ProcStatParser.Parse(MetricsFixtures.Stat1);
|
||||
var after = ProcStatParser.Parse(MetricsFixtures.Stat2);
|
||||
Assert.Equal(80.0, CpuUsage.Compute(before, after), 1);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CpuUsage_ReturnsZeroWhenNoDelta()
|
||||
{
|
||||
var times = new CpuTimes(800, 1000);
|
||||
Assert.Equal(0, CpuUsage.Compute(times, times));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
using Vantage.Core.Prometheus;
|
||||
using Vantage.Core.Tests.Fixtures;
|
||||
using Xunit;
|
||||
|
||||
namespace Vantage.Core.Tests.Prometheus;
|
||||
|
||||
public class PrometheusParserTests
|
||||
{
|
||||
[Fact]
|
||||
public void Parse_SkipsCommentsAndBlankLines()
|
||||
{
|
||||
var samples = PrometheusTextParser.Parse(PrometheusFixtures.Mixed);
|
||||
Assert.DoesNotContain(samples, s => s.Name.StartsWith("#"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Parse_ReadsLabelsValueAndTimestamp()
|
||||
{
|
||||
var samples = PrometheusTextParser.Parse(PrometheusFixtures.Mixed);
|
||||
|
||||
var post200 = samples.Single(s =>
|
||||
s.Name == "http_requests_total" && s.HasLabel("code", "200"));
|
||||
Assert.Equal("post", post200.Label("method"));
|
||||
Assert.Equal(1027, post200.Value);
|
||||
Assert.Equal(1395066363000, post200.TimestampMs);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Parse_MetricWithoutLabels()
|
||||
{
|
||||
var samples = PrometheusTextParser.Parse(PrometheusFixtures.Mixed);
|
||||
var bare = samples.Single(s => s.Name == "metric_without_labels");
|
||||
Assert.Empty(bare.Labels);
|
||||
Assert.Equal(12.47, bare.Value, 3);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Parse_HandlesEscapedLabelValues()
|
||||
{
|
||||
var samples = PrometheusTextParser.Parse(PrometheusFixtures.Mixed);
|
||||
var msdos = samples.Single(s => s.Name == "msdos_file_access_time_seconds");
|
||||
|
||||
Assert.Equal("C:\\DIR\\FILE.TXT", msdos.Label("path"));
|
||||
Assert.Contains("\n", msdos.Label("error"));
|
||||
Assert.Contains("\"FILE.TXT\"", msdos.Label("error"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Parse_HandlesInfinityAndNaN()
|
||||
{
|
||||
var samples = PrometheusTextParser.Parse(PrometheusFixtures.Mixed);
|
||||
|
||||
Assert.True(double.IsPositiveInfinity(samples.Single(s => s.Name == "something_weird").Value));
|
||||
Assert.True(double.IsNaN(samples.Single(s => s.Name == "gauge_nan_value").Value));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
using Vantage.Core.Models;
|
||||
using Vantage.Core.Prometheus;
|
||||
using Vantage.Core.Tests.Fakes;
|
||||
using Vantage.Core.Tests.Fixtures;
|
||||
using Xunit;
|
||||
|
||||
namespace Vantage.Core.Tests.Prometheus;
|
||||
|
||||
public class PrometheusProviderTests
|
||||
{
|
||||
private static readonly DateTimeOffset Now = new(2026, 8, 26, 12, 0, 0, TimeSpan.Zero);
|
||||
|
||||
[Fact]
|
||||
public void Mapper_MapsMemoryDiskLoadAndUptime()
|
||||
{
|
||||
var samples = PrometheusTextParser.Parse(PrometheusFixtures.NodeScrape1());
|
||||
var metrics = PrometheusNodeMapper.Map(samples, "/", cpuPercent: 0, Now);
|
||||
|
||||
Assert.Equal(8_000_000_000, metrics.MemoryTotalBytes);
|
||||
Assert.Equal(6_000_000_000, metrics.MemoryUsedBytes);
|
||||
Assert.Equal(75.0, metrics.MemoryUsedPercent, 1);
|
||||
Assert.Equal(100_000_000_000, metrics.DiskTotalBytes);
|
||||
Assert.Equal(40_000_000_000, metrics.DiskUsedBytes);
|
||||
Assert.Equal(0.5, metrics.Load1, 3);
|
||||
Assert.Equal(TimeSpan.FromSeconds(86400), metrics.Uptime);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Mapper_SelectsFilesystemByMountpoint()
|
||||
{
|
||||
var samples = PrometheusTextParser.Parse(PrometheusFixtures.NodeScrape1());
|
||||
var boot = PrometheusNodeMapper.Map(samples, "/boot", cpuPercent: 0, Now);
|
||||
|
||||
Assert.Equal(500_000_000, boot.DiskTotalBytes);
|
||||
Assert.Equal(100_000_000, boot.DiskUsedBytes);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CpuPercent_ComputedFromCounterDelta()
|
||||
{
|
||||
var first = PrometheusNodeMapper.ExtractCpuCounters(PrometheusTextParser.Parse(PrometheusFixtures.NodeScrape1()));
|
||||
var second = PrometheusNodeMapper.ExtractCpuCounters(PrometheusTextParser.Parse(PrometheusFixtures.NodeScrape2()));
|
||||
|
||||
Assert.Equal(20.0, PrometheusNodeMapper.CpuPercent(first, second), 1);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Provider_FirstScrapeZeroCpu_SecondScrapeComputesCpu()
|
||||
{
|
||||
var handler = StubHttpMessageHandler.Sequence(PrometheusFixtures.NodeScrape1(), PrometheusFixtures.NodeScrape2());
|
||||
var provider = new PrometheusMetricsProvider(new HttpClient(handler), () => Now);
|
||||
var host = new HostConfig { Id = "h1", Address = "10.0.0.1", MetricsEndpoint = "http://10.0.0.1:9100/metrics" };
|
||||
|
||||
var first = await provider.GetMetricsAsync(host, CancellationToken.None);
|
||||
var second = await provider.GetMetricsAsync(host, CancellationToken.None);
|
||||
|
||||
Assert.Equal(0, first.CpuUsagePercent);
|
||||
Assert.Equal(20.0, second.CpuUsagePercent, 1);
|
||||
Assert.Equal(75.0, second.MemoryUsedPercent, 1);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ResolveMetricsEndpoint_DefaultsToNodeExporterPort()
|
||||
{
|
||||
var host = new HostConfig { Address = "10.0.0.5" };
|
||||
Assert.Equal("http://10.0.0.5:9100/metrics", host.ResolveMetricsEndpoint());
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user