Refactor code structure and optimize performance across multiple modules

This commit is contained in:
StellaOps Bot
2025-12-26 20:03:22 +02:00
parent c786faae84
commit b4fc66feb6
3353 changed files with 88254 additions and 1590657 deletions

View File

@@ -9,7 +9,7 @@
<Description>Ground-truth corpus benchmarking infrastructure for reachability analysis</Description>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="System.Text.Json" Version="10.0.0-preview.1.25105.2" />
<PackageReference Include="System.Text.Json" Version="10.0.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="../StellaOps.Scanner.Reachability/StellaOps.Scanner.Reachability.csproj" />

View File

@@ -15,5 +15,8 @@
<ProjectReference Include="../../../Authority/StellaOps.Authority/StellaOps.Auth.Client/StellaOps.Auth.Client.csproj" />
<ProjectReference Include="../../../__Libraries/StellaOps.Auth.Security/StellaOps.Auth.Security.csproj" />
<ProjectReference Include="../../../__Libraries/StellaOps.Cryptography/StellaOps.Cryptography.csproj" />
<ProjectReference Include="../../../__Libraries/StellaOps.Replay.Core/StellaOps.Replay.Core.csproj" />
<ProjectReference Include="../StellaOps.Scanner.ProofSpine/StellaOps.Scanner.ProofSpine.csproj" />
<ProjectReference Include="../../../Attestor/StellaOps.Attestor.Envelope/StellaOps.Attestor.Envelope.csproj" />
</ItemGroup>
</Project>

View File

@@ -9,6 +9,6 @@
<RootNamespace>StellaOps.Scanner.Orchestration</RootNamespace>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="10.0.0-preview.7.24407.6" />
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="10.0.0" />
</ItemGroup>
</Project>

View File

@@ -13,5 +13,8 @@
Use SliceDataDto and JsonElement instead of ReachabilitySlice type. -->
<ItemGroup>
<ProjectReference Include="..\..\..\__Libraries\StellaOps.Cryptography\StellaOps.Cryptography.csproj" />
<ProjectReference Include="..\..\..\__Libraries\StellaOps.Replay.Core\StellaOps.Replay.Core.csproj" />
<ProjectReference Include="..\StellaOps.Scanner.Evidence\StellaOps.Scanner.Evidence.csproj" />
<ProjectReference Include="..\..\..\Attestor\StellaOps.Attestor.Envelope\StellaOps.Attestor.Envelope.csproj" />
</ItemGroup>
</Project>

View File

@@ -8,6 +8,8 @@ using Microsoft.Extensions.Logging.Abstractions;
using StellaOps.Scanner.VulnSurfaces.Fingerprint;
using Xunit;
using StellaOps.TestKit;
namespace StellaOps.Scanner.VulnSurfaces.Tests;
public class CecilMethodFingerprinterTests
@@ -20,20 +22,23 @@ public class CecilMethodFingerprinterTests
NullLogger<CecilMethodFingerprinter>.Instance);
}
[Fact]
[Trait("Category", TestCategories.Unit)]
[Fact]
public void Ecosystem_ReturnsNuget()
{
Assert.Equal("nuget", _fingerprinter.Ecosystem);
}
[Fact]
[Trait("Category", TestCategories.Unit)]
[Fact]
public async Task FingerprintAsync_WithNullRequest_ThrowsArgumentNullException()
{
await Assert.ThrowsAsync<ArgumentNullException>(
() => _fingerprinter.FingerprintAsync(null!));
}
[Fact]
[Trait("Category", TestCategories.Unit)]
[Fact]
public async Task FingerprintAsync_WithNonExistentPath_ReturnsEmptyResult()
{
// Arrange
@@ -53,7 +58,8 @@ public class CecilMethodFingerprinterTests
Assert.Empty(result.Methods);
}
[Fact]
[Trait("Category", TestCategories.Unit)]
[Fact]
public async Task FingerprintAsync_WithOwnAssembly_FindsMethods()
{
// Arrange - use the test assembly itself
@@ -80,7 +86,8 @@ public class CecilMethodFingerprinterTests
Assert.True(result.Methods.Count > 0, "Should find at least some methods");
}
[Fact]
[Trait("Category", TestCategories.Unit)]
[Fact]
public async Task FingerprintAsync_ComputesDeterministicHashes()
{
// Arrange - fingerprint twice
@@ -109,7 +116,8 @@ public class CecilMethodFingerprinterTests
}
}
[Fact]
[Trait("Category", TestCategories.Unit)]
[Fact]
public async Task FingerprintAsync_WithCancellation_RespectsCancellation()
{
// Arrange
@@ -142,7 +150,8 @@ public class CecilMethodFingerprinterTests
}
}
[Fact]
[Trait("Category", TestCategories.Unit)]
[Fact]
public async Task FingerprintAsync_MethodKeyFormat_IsValid()
{
// Arrange
@@ -172,7 +181,8 @@ public class CecilMethodFingerprinterTests
}
}
[Fact]
[Trait("Category", TestCategories.Unit)]
[Fact]
public async Task FingerprintAsync_IncludesSignature()
{
// Arrange

View File

@@ -8,11 +8,13 @@ using StellaOps.Scanner.VulnSurfaces.CallGraph;
using StellaOps.Scanner.VulnSurfaces.Models;
using Xunit;
using StellaOps.TestKit;
namespace StellaOps.Scanner.VulnSurfaces.Tests;
public class InternalCallGraphTests
{
[Fact]
[Trait("Category", TestCategories.Unit)]
[Fact]
public void AddMethod_StoresMethod()
{
// Arrange
@@ -38,7 +40,8 @@ public class InternalCallGraphTests
Assert.Equal(1, graph.MethodCount);
}
[Fact]
[Trait("Category", TestCategories.Unit)]
[Fact]
public void AddEdge_CreatesForwardAndReverseMapping()
{
// Arrange
@@ -63,7 +66,8 @@ public class InternalCallGraphTests
Assert.Equal(1, graph.EdgeCount);
}
[Fact]
[Trait("Category", TestCategories.Unit)]
[Fact]
public void GetPublicMethods_ReturnsOnlyPublic()
{
// Arrange
@@ -97,7 +101,8 @@ public class InternalCallGraphTests
Assert.Equal("A::Public()", publicMethods[0].MethodKey);
}
[Fact]
[Trait("Category", TestCategories.Unit)]
[Fact]
public void GetCallees_EmptyForUnknownMethod()
{
// Arrange
@@ -114,7 +119,8 @@ public class InternalCallGraphTests
Assert.Empty(callees);
}
[Fact]
[Trait("Category", TestCategories.Unit)]
[Fact]
public void GetMethod_ReturnsNullForUnknown()
{
// Arrange

View File

@@ -8,6 +8,7 @@ using Microsoft.Extensions.Logging.Abstractions;
using StellaOps.Scanner.VulnSurfaces.Fingerprint;
using Xunit;
using StellaOps.TestKit;
namespace StellaOps.Scanner.VulnSurfaces.Tests;
public class MethodDiffEngineTests
@@ -20,14 +21,16 @@ public class MethodDiffEngineTests
NullLogger<MethodDiffEngine>.Instance);
}
[Fact]
[Trait("Category", TestCategories.Unit)]
[Fact]
public async Task DiffAsync_WithNullRequest_ThrowsArgumentNullException()
{
await Assert.ThrowsAsync<ArgumentNullException>(
() => _diffEngine.DiffAsync(null!));
}
[Fact]
[Trait("Category", TestCategories.Unit)]
[Fact]
public async Task DiffAsync_WithIdenticalFingerprints_ReturnsNoChanges()
{
// Arrange
@@ -68,7 +71,8 @@ public class MethodDiffEngineTests
Assert.Equal(0, diff.TotalChanges);
}
[Fact]
[Trait("Category", TestCategories.Unit)]
[Fact]
public async Task DiffAsync_WithModifiedMethod_ReturnsModified()
{
// Arrange
@@ -112,7 +116,8 @@ public class MethodDiffEngineTests
Assert.Empty(diff.Removed);
}
[Fact]
[Trait("Category", TestCategories.Unit)]
[Fact]
public async Task DiffAsync_WithAddedMethod_ReturnsAdded()
{
// Arrange
@@ -155,7 +160,8 @@ public class MethodDiffEngineTests
Assert.Empty(diff.Removed);
}
[Fact]
[Trait("Category", TestCategories.Unit)]
[Fact]
public async Task DiffAsync_WithRemovedMethod_ReturnsRemoved()
{
// Arrange
@@ -198,7 +204,8 @@ public class MethodDiffEngineTests
Assert.Equal("Test.Class::RemovedMethod", diff.Removed[0].MethodKey);
}
[Fact]
[Trait("Category", TestCategories.Unit)]
[Fact]
public async Task DiffAsync_WithMultipleChanges_ReturnsAllChanges()
{
// Arrange - simulate a fix that modifies one method, adds one, removes one
@@ -247,7 +254,8 @@ public class MethodDiffEngineTests
Assert.Equal(3, diff.TotalChanges);
}
[Fact]
[Trait("Category", TestCategories.Unit)]
[Fact]
public async Task DiffAsync_TriggerMethods_AreModifiedOrRemoved()
{
// This test validates the key insight:
@@ -298,7 +306,8 @@ public class MethodDiffEngineTests
Assert.Empty(diff.Removed);
}
[Fact]
[Trait("Category", TestCategories.Unit)]
[Fact]
public async Task DiffAsync_WithEmptyFingerprints_ReturnsNoChanges()
{
// Arrange

View File

@@ -14,6 +14,8 @@ using Moq.Protected;
using StellaOps.Scanner.VulnSurfaces.Download;
using Xunit;
using StellaOps.TestKit;
namespace StellaOps.Scanner.VulnSurfaces.Tests;
public class NuGetPackageDownloaderTests : IDisposable
@@ -35,7 +37,8 @@ public class NuGetPackageDownloaderTests : IDisposable
}
}
[Fact]
[Trait("Category", TestCategories.Unit)]
[Fact]
public void Ecosystem_ReturnsNuget()
{
// Arrange
@@ -45,7 +48,8 @@ public class NuGetPackageDownloaderTests : IDisposable
Assert.Equal("nuget", downloader.Ecosystem);
}
[Fact]
[Trait("Category", TestCategories.Unit)]
[Fact]
public async Task DownloadAsync_WithNullRequest_ThrowsArgumentNullException()
{
// Arrange
@@ -56,7 +60,8 @@ public class NuGetPackageDownloaderTests : IDisposable
() => downloader.DownloadAsync(null!));
}
[Fact]
[Trait("Category", TestCategories.Unit)]
[Fact]
public async Task DownloadAsync_WithHttpError_ReturnsFailResult()
{
// Arrange
@@ -93,7 +98,8 @@ public class NuGetPackageDownloaderTests : IDisposable
Assert.Null(result.ExtractedPath);
}
[Fact]
[Trait("Category", TestCategories.Unit)]
[Fact]
public async Task DownloadAsync_WithValidNupkg_ReturnsSuccessResult()
{
// Arrange - create a mock .nupkg (which is just a zip file)
@@ -135,7 +141,8 @@ public class NuGetPackageDownloaderTests : IDisposable
Assert.False(result.FromCache);
}
[Fact]
[Trait("Category", TestCategories.Unit)]
[Fact]
public async Task DownloadAsync_WithCachedPackage_ReturnsCachedResult()
{
// Arrange - pre-create the cached directory
@@ -162,7 +169,8 @@ public class NuGetPackageDownloaderTests : IDisposable
Assert.Equal(packageDir, result.ExtractedPath);
}
[Fact]
[Trait("Category", TestCategories.Unit)]
[Fact]
public async Task DownloadAsync_WithCacheFalse_BypassesCache()
{
// Arrange - pre-create the cached directory
@@ -210,7 +218,8 @@ public class NuGetPackageDownloaderTests : IDisposable
ItExpr.IsAny<CancellationToken>());
}
[Fact]
[Trait("Category", TestCategories.Unit)]
[Fact]
public async Task DownloadAsync_UsesCorrectUrl()
{
// Arrange
@@ -250,7 +259,8 @@ public class NuGetPackageDownloaderTests : IDisposable
Assert.EndsWith(".nupkg", capturedRequest.RequestUri!.ToString());
}
[Fact]
[Trait("Category", TestCategories.Unit)]
[Fact]
public async Task DownloadAsync_WithCustomRegistry_UsesCustomUrl()
{
// Arrange
@@ -289,7 +299,8 @@ public class NuGetPackageDownloaderTests : IDisposable
Assert.StartsWith("https://custom.nuget.feed.example.com/v3", capturedRequest.RequestUri!.ToString());
}
[Fact]
[Trait("Category", TestCategories.Unit)]
[Fact]
public async Task DownloadAsync_WithCancellation_HonorsCancellation()
{
// Arrange

View File

@@ -20,5 +20,6 @@
<ItemGroup>
<ProjectReference Include="..\StellaOps.Scanner.VulnSurfaces\StellaOps.Scanner.VulnSurfaces.csproj" />
<ProjectReference Include="../../../__Libraries/StellaOps.TestKit/StellaOps.TestKit.csproj" />
</ItemGroup>
</Project>

View File

@@ -10,6 +10,7 @@ using StellaOps.Scanner.VulnSurfaces.Models;
using StellaOps.Scanner.VulnSurfaces.Triggers;
using Xunit;
using StellaOps.TestKit;
namespace StellaOps.Scanner.VulnSurfaces.Tests;
public class TriggerMethodExtractorTests
@@ -21,7 +22,8 @@ public class TriggerMethodExtractorTests
_extractor = new TriggerMethodExtractor(NullLogger<TriggerMethodExtractor>.Instance);
}
[Fact]
[Trait("Category", TestCategories.Unit)]
[Fact]
public async Task ExtractAsync_DirectPath_FindsTrigger()
{
// Arrange
@@ -85,7 +87,8 @@ public class TriggerMethodExtractorTests
Assert.False(trigger.IsInterfaceExpansion);
}
[Fact]
[Trait("Category", TestCategories.Unit)]
[Fact]
public async Task ExtractAsync_NoPath_ReturnsEmpty()
{
// Arrange
@@ -124,7 +127,8 @@ public class TriggerMethodExtractorTests
Assert.Empty(result.Triggers);
}
[Fact]
[Trait("Category", TestCategories.Unit)]
[Fact]
public async Task ExtractAsync_MultiplePublicMethods_FindsAllTriggers()
{
// Arrange
@@ -174,7 +178,8 @@ public class TriggerMethodExtractorTests
Assert.Contains(result.Triggers, t => t.TriggerMethodKey == "Class::Api2()");
}
[Fact]
[Trait("Category", TestCategories.Unit)]
[Fact]
public async Task ExtractAsync_MaxDepthExceeded_DoesNotFindTrigger()
{
// Arrange
@@ -231,7 +236,8 @@ public class TriggerMethodExtractorTests
Assert.Empty(result.Triggers);
}
[Fact]
[Trait("Category", TestCategories.Unit)]
[Fact]
public async Task ExtractAsync_VirtualMethod_ReducesConfidence()
{
// Arrange

View File

@@ -4,10 +4,12 @@ using StellaOps.Scanner.VulnSurfaces.Services;
using StellaOps.Scanner.VulnSurfaces.Storage;
using Xunit;
using StellaOps.TestKit;
namespace StellaOps.Scanner.VulnSurfaces.Tests;
public sealed class VulnSurfaceServiceTests
{
[Trait("Category", TestCategories.Unit)]
[Fact(DisplayName = "GetAffectedSymbolsAsync returns sinks when surface exists")]
public async Task GetAffectedSymbolsAsync_ReturnsSurfaceSinks()
{
@@ -50,6 +52,7 @@ public sealed class VulnSurfaceServiceTests
Assert.Equal(surfaceGuid, repository.LastSurfaceId);
}
[Trait("Category", TestCategories.Unit)]
[Fact(DisplayName = "GetAffectedSymbolsAsync falls back to package symbol provider")]
public async Task GetAffectedSymbolsAsync_FallsBackToPackageSymbols()
{
@@ -64,6 +67,7 @@ public sealed class VulnSurfaceServiceTests
Assert.Single(result.Symbols);
}
[Trait("Category", TestCategories.Unit)]
[Fact(DisplayName = "GetAffectedSymbolsAsync returns heuristic when no data")]
public async Task GetAffectedSymbolsAsync_ReturnsHeuristicWhenEmpty()
{