audit notes work completed, test fixes work (95% done), new sprints, new data sources setup and configuration

This commit is contained in:
master
2026-01-14 10:48:00 +02:00
parent d7be6ba34b
commit 95d5898650
379 changed files with 40695 additions and 19041 deletions

View File

@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<LangVersion>preview</LangVersion>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Npgsql" />
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,253 @@
using StellaOps.Graph.Core;
using Xunit;
namespace StellaOps.Graph.Core.Tests;
/// <summary>
/// Tests for ObservationState enum.
/// </summary>
public sealed class ObservationStateTests
{
[Theory]
[InlineData(ObservationState.Pending)]
[InlineData(ObservationState.Investigating)]
[InlineData(ObservationState.Affected)]
[InlineData(ObservationState.NotAffected)]
[InlineData(ObservationState.Fixed)]
[InlineData(ObservationState.Mitigated)]
[InlineData(ObservationState.Accepted)]
[InlineData(ObservationState.FalsePositive)]
public void ObservationState_AllValues_AreDefined(ObservationState state)
{
Assert.True(Enum.IsDefined(state));
}
[Fact]
public void ObservationState_AllValues_AreCounted()
{
var values = Enum.GetValues<ObservationState>();
Assert.Equal(8, values.Length);
}
}
/// <summary>
/// Tests for CveObservationNode record.
/// </summary>
public sealed class CveObservationNodeTests
{
[Fact]
public void CveObservationNode_RequiredProperties_MustBeSet()
{
var now = DateTimeOffset.UtcNow;
var node = new CveObservationNode
{
NodeId = "sha256:abc123",
CveId = "CVE-2024-0001",
Product = "pkg:deb/debian/nginx@1.18.0",
TenantId = "tenant-001",
State = ObservationState.Pending,
CreatedAt = now,
UpdatedAt = now
};
Assert.Equal("sha256:abc123", node.NodeId);
Assert.Equal("CVE-2024-0001", node.CveId);
Assert.Equal("pkg:deb/debian/nginx@1.18.0", node.Product);
Assert.Equal("tenant-001", node.TenantId);
Assert.Equal(ObservationState.Pending, node.State);
}
[Fact]
public void CveObservationNode_SchemaVersion_DefaultsTo1_0()
{
var now = DateTimeOffset.UtcNow;
var node = new CveObservationNode
{
NodeId = "sha256:xyz",
CveId = "CVE-2024-0002",
Product = "pkg:npm/lodash@4.17.0",
TenantId = "tenant-002",
State = ObservationState.Investigating,
CreatedAt = now,
UpdatedAt = now
};
Assert.Equal("1.0", node.SchemaVersion);
}
[Fact]
public void CveObservationNode_OptionalSignals_AreNullByDefault()
{
var now = DateTimeOffset.UtcNow;
var node = new CveObservationNode
{
NodeId = "sha256:def",
CveId = "CVE-2024-0003",
Product = "pkg:pypi/requests@2.28.0",
TenantId = "tenant-003",
State = ObservationState.Affected,
CreatedAt = now,
UpdatedAt = now
};
Assert.Null(node.Epss);
Assert.Null(node.Kev);
Assert.Null(node.Vex);
Assert.Null(node.Reachability);
Assert.Null(node.MissingSignals);
}
[Fact]
public void CveObservationNode_WithSignals_ContainsSnapshots()
{
var now = DateTimeOffset.UtcNow;
var epssSignal = new SignalSnapshot
{
Status = "available",
ValueSummary = "0.15",
CapturedAt = now,
Source = "FIRST EPSS"
};
var node = new CveObservationNode
{
NodeId = "sha256:ghi",
CveId = "CVE-2024-0004",
Product = "pkg:golang/github.com/example/lib@v1.0.0",
TenantId = "tenant-004",
State = ObservationState.Fixed,
CreatedAt = now,
UpdatedAt = now,
Epss = epssSignal
};
Assert.NotNull(node.Epss);
Assert.Equal("available", node.Epss.Status);
Assert.Equal("0.15", node.Epss.ValueSummary);
}
[Fact]
public void CveObservationNode_UncertaintyScore_DefaultsToZero()
{
var now = DateTimeOffset.UtcNow;
var node = new CveObservationNode
{
NodeId = "sha256:jkl",
CveId = "CVE-2024-0005",
Product = "pkg:maven/com.example/lib@1.0.0",
TenantId = "tenant-005",
State = ObservationState.NotAffected,
CreatedAt = now,
UpdatedAt = now
};
Assert.Equal(0.0, node.UncertaintyScore);
}
[Fact]
public void CveObservationNode_WithMissingSignals_ContainsSignalNames()
{
var now = DateTimeOffset.UtcNow;
var node = new CveObservationNode
{
NodeId = "sha256:mno",
CveId = "CVE-2024-0006",
Product = "pkg:nuget/Newtonsoft.Json@13.0.1",
TenantId = "tenant-006",
State = ObservationState.Investigating,
CreatedAt = now,
UpdatedAt = now,
MissingSignals = ["epss", "kev"],
UncertaintyScore = 0.5
};
Assert.NotNull(node.MissingSignals);
Assert.Equal(2, node.MissingSignals.Count);
Assert.Contains("epss", node.MissingSignals);
Assert.Contains("kev", node.MissingSignals);
Assert.Equal(0.5, node.UncertaintyScore);
}
}
/// <summary>
/// Tests for SignalSnapshot record.
/// </summary>
public sealed class SignalSnapshotTests
{
[Fact]
public void SignalSnapshot_RequiredProperties_MustBeSet()
{
var capturedAt = DateTimeOffset.UtcNow;
var snapshot = new SignalSnapshot
{
Status = "available",
CapturedAt = capturedAt
};
Assert.Equal("available", snapshot.Status);
Assert.Equal(capturedAt, snapshot.CapturedAt);
}
[Fact]
public void SignalSnapshot_OptionalProperties_CanBeNull()
{
var snapshot = new SignalSnapshot
{
Status = "unavailable",
CapturedAt = DateTimeOffset.UtcNow
};
Assert.Null(snapshot.ValueSummary);
Assert.Null(snapshot.Source);
Assert.Null(snapshot.TtlRemaining);
}
[Fact]
public void SignalSnapshot_WithAllProperties_ContainsValues()
{
var capturedAt = DateTimeOffset.UtcNow;
var ttl = TimeSpan.FromHours(24);
var snapshot = new SignalSnapshot
{
Status = "available",
ValueSummary = "{\"score\": 0.85}",
CapturedAt = capturedAt,
Source = "NVD",
TtlRemaining = ttl
};
Assert.Equal("{\"score\": 0.85}", snapshot.ValueSummary);
Assert.Equal("NVD", snapshot.Source);
Assert.Equal(ttl, snapshot.TtlRemaining);
}
[Fact]
public void SignalSnapshot_RecordEquality_WorksCorrectly()
{
var capturedAt = DateTimeOffset.UtcNow;
var s1 = new SignalSnapshot
{
Status = "available",
CapturedAt = capturedAt,
Source = "KEV"
};
var s2 = new SignalSnapshot
{
Status = "available",
CapturedAt = capturedAt,
Source = "KEV"
};
Assert.Equal(s1, s2);
}
}

View File

@@ -0,0 +1,29 @@
<?xml version="1.0" encoding="utf-8"?>
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<LangVersion>preview</LangVersion>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<IsPackable>false</IsPackable>
<OutputType>Exe</OutputType>
<UseXunitV3>true</UseXunitV3>
</PropertyGroup>
<ItemGroup>
<Using Include="Xunit" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Moq" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\__Libraries\StellaOps.Graph.Core\StellaOps.Graph.Core.csproj" />
</ItemGroup>
<ItemGroup>
<Content Include="xunit.runner.json" CopyToOutputDirectory="PreserveNewest" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,7 @@
{
"$schema": "https://xunit.net/schema/current/xunit.runner.schema.json",
"diagnosticMessages": true,
"parallelizeAssembly": true,
"parallelizeTestCollections": true,
"maxParallelThreads": -1
}