Refactor code structure and optimize performance across multiple modules
This commit is contained in:
@@ -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" />
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -20,5 +20,6 @@
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\StellaOps.Scanner.VulnSurfaces\StellaOps.Scanner.VulnSurfaces.csproj" />
|
||||
<ProjectReference Include="../../../__Libraries/StellaOps.TestKit/StellaOps.TestKit.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user