audit notes work completed, test fixes work (95% done), new sprints, new data sources setup and configuration
This commit is contained in:
@@ -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>
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"$schema": "https://xunit.net/schema/current/xunit.runner.schema.json",
|
||||
"diagnosticMessages": true,
|
||||
"parallelizeAssembly": true,
|
||||
"parallelizeTestCollections": true,
|
||||
"maxParallelThreads": -1
|
||||
}
|
||||
Reference in New Issue
Block a user