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,282 @@
|
||||
using StellaOps.Feedser.BinaryAnalysis.Models;
|
||||
using Xunit;
|
||||
|
||||
namespace StellaOps.Feedser.BinaryAnalysis.Tests;
|
||||
|
||||
/// <summary>
|
||||
/// Tests for BinaryFingerprint and related models.
|
||||
/// </summary>
|
||||
public sealed class BinaryFingerprintTests
|
||||
{
|
||||
[Fact]
|
||||
public void BinaryFingerprint_RequiredProperties_MustBeSet()
|
||||
{
|
||||
var fingerprint = new BinaryFingerprint
|
||||
{
|
||||
FingerprintId = "fingerprint:tlsh:abc123",
|
||||
CveId = "CVE-2026-12345",
|
||||
Method = FingerprintMethod.TLSH,
|
||||
FingerprintValue = "T1E8F12345678901234567890123456789012345678901234567890",
|
||||
TargetBinary = "libssl.so.3",
|
||||
Metadata = new FingerprintMetadata
|
||||
{
|
||||
Architecture = "x86_64",
|
||||
Format = "ELF",
|
||||
HasDebugSymbols = false
|
||||
},
|
||||
ExtractedAt = DateTimeOffset.UtcNow,
|
||||
ExtractorVersion = "1.0.0"
|
||||
};
|
||||
|
||||
Assert.Equal("fingerprint:tlsh:abc123", fingerprint.FingerprintId);
|
||||
Assert.Equal("CVE-2026-12345", fingerprint.CveId);
|
||||
Assert.Equal(FingerprintMethod.TLSH, fingerprint.Method);
|
||||
Assert.Equal("libssl.so.3", fingerprint.TargetBinary);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void BinaryFingerprint_WithOptionalFunction_ContainsValue()
|
||||
{
|
||||
var fingerprint = new BinaryFingerprint
|
||||
{
|
||||
FingerprintId = "fingerprint:cfghash:def456",
|
||||
CveId = "CVE-2026-00001",
|
||||
Method = FingerprintMethod.CFGHash,
|
||||
FingerprintValue = "sha256:abcdef1234567890",
|
||||
TargetBinary = "openssl",
|
||||
TargetFunction = "SSL_read",
|
||||
Metadata = new FingerprintMetadata
|
||||
{
|
||||
Architecture = "aarch64",
|
||||
Format = "ELF",
|
||||
HasDebugSymbols = true
|
||||
},
|
||||
ExtractedAt = DateTimeOffset.UtcNow,
|
||||
ExtractorVersion = "1.0.0"
|
||||
};
|
||||
|
||||
Assert.Equal("SSL_read", fingerprint.TargetFunction);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void BinaryFingerprint_CveId_CanBeNull()
|
||||
{
|
||||
var fingerprint = new BinaryFingerprint
|
||||
{
|
||||
FingerprintId = "fingerprint:section:ghi789",
|
||||
CveId = null,
|
||||
Method = FingerprintMethod.SectionHash,
|
||||
FingerprintValue = "sha256:section123",
|
||||
TargetBinary = "myapp.exe",
|
||||
Metadata = new FingerprintMetadata
|
||||
{
|
||||
Architecture = "x86_64",
|
||||
Format = "PE",
|
||||
HasDebugSymbols = false
|
||||
},
|
||||
ExtractedAt = DateTimeOffset.UtcNow,
|
||||
ExtractorVersion = "2.0.0"
|
||||
};
|
||||
|
||||
Assert.Null(fingerprint.CveId);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(FingerprintMethod.TLSH)]
|
||||
[InlineData(FingerprintMethod.CFGHash)]
|
||||
[InlineData(FingerprintMethod.InstructionHash)]
|
||||
[InlineData(FingerprintMethod.SymbolHash)]
|
||||
[InlineData(FingerprintMethod.SectionHash)]
|
||||
public void FingerprintMethod_AllValues_AreValid(FingerprintMethod method)
|
||||
{
|
||||
var fingerprint = new BinaryFingerprint
|
||||
{
|
||||
FingerprintId = $"fingerprint:{method.ToString().ToLowerInvariant()}:test",
|
||||
CveId = "CVE-2026-TEST",
|
||||
Method = method,
|
||||
FingerprintValue = "test-value",
|
||||
TargetBinary = "test.bin",
|
||||
Metadata = new FingerprintMetadata
|
||||
{
|
||||
Architecture = "x86_64",
|
||||
Format = "ELF",
|
||||
HasDebugSymbols = false
|
||||
},
|
||||
ExtractedAt = DateTimeOffset.UtcNow,
|
||||
ExtractorVersion = "1.0.0"
|
||||
};
|
||||
|
||||
Assert.Equal(method, fingerprint.Method);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests for FingerprintMetadata record.
|
||||
/// </summary>
|
||||
public sealed class FingerprintMetadataTests
|
||||
{
|
||||
[Fact]
|
||||
public void FingerprintMetadata_RequiredProperties_MustBeSet()
|
||||
{
|
||||
var metadata = new FingerprintMetadata
|
||||
{
|
||||
Architecture = "x86_64",
|
||||
Format = "ELF",
|
||||
HasDebugSymbols = true
|
||||
};
|
||||
|
||||
Assert.Equal("x86_64", metadata.Architecture);
|
||||
Assert.Equal("ELF", metadata.Format);
|
||||
Assert.True(metadata.HasDebugSymbols);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("x86_64")]
|
||||
[InlineData("aarch64")]
|
||||
[InlineData("armv7")]
|
||||
[InlineData("riscv64")]
|
||||
[InlineData("ppc64le")]
|
||||
public void FingerprintMetadata_Architecture_SupportedValues(string architecture)
|
||||
{
|
||||
var metadata = new FingerprintMetadata
|
||||
{
|
||||
Architecture = architecture,
|
||||
Format = "ELF",
|
||||
HasDebugSymbols = false
|
||||
};
|
||||
|
||||
Assert.Equal(architecture, metadata.Architecture);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("ELF")]
|
||||
[InlineData("PE")]
|
||||
[InlineData("Mach-O")]
|
||||
public void FingerprintMetadata_Format_SupportedValues(string format)
|
||||
{
|
||||
var metadata = new FingerprintMetadata
|
||||
{
|
||||
Architecture = "x86_64",
|
||||
Format = format,
|
||||
HasDebugSymbols = false
|
||||
};
|
||||
|
||||
Assert.Equal(format, metadata.Format);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void FingerprintMetadata_WithOptionalProperties_ContainsValues()
|
||||
{
|
||||
var metadata = new FingerprintMetadata
|
||||
{
|
||||
Architecture = "x86_64",
|
||||
Format = "ELF",
|
||||
HasDebugSymbols = true,
|
||||
Compiler = "gcc-13.2.0",
|
||||
OptimizationLevel = "-O2",
|
||||
FileOffset = 0x1000,
|
||||
RegionSize = 4096
|
||||
};
|
||||
|
||||
Assert.Equal("gcc-13.2.0", metadata.Compiler);
|
||||
Assert.Equal("-O2", metadata.OptimizationLevel);
|
||||
Assert.Equal(0x1000, metadata.FileOffset);
|
||||
Assert.Equal(4096, metadata.RegionSize);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void FingerprintMetadata_OptionalProperties_AreNullByDefault()
|
||||
{
|
||||
var metadata = new FingerprintMetadata
|
||||
{
|
||||
Architecture = "aarch64",
|
||||
Format = "Mach-O",
|
||||
HasDebugSymbols = false
|
||||
};
|
||||
|
||||
Assert.Null(metadata.Compiler);
|
||||
Assert.Null(metadata.OptimizationLevel);
|
||||
Assert.Null(metadata.FileOffset);
|
||||
Assert.Null(metadata.RegionSize);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests for FingerprintMatchResult record.
|
||||
/// </summary>
|
||||
public sealed class FingerprintMatchResultTests
|
||||
{
|
||||
[Fact]
|
||||
public void FingerprintMatchResult_SuccessfulMatch_ContainsData()
|
||||
{
|
||||
var result = new FingerprintMatchResult
|
||||
{
|
||||
IsMatch = true,
|
||||
Similarity = 0.95,
|
||||
Confidence = 0.92,
|
||||
MatchedFingerprintId = "fingerprint:tlsh:matched123",
|
||||
Method = FingerprintMethod.TLSH,
|
||||
MatchDetails = new Dictionary<string, object>
|
||||
{
|
||||
["distance"] = 15,
|
||||
["threshold"] = 50
|
||||
}
|
||||
};
|
||||
|
||||
Assert.True(result.IsMatch);
|
||||
Assert.Equal(0.95, result.Similarity);
|
||||
Assert.Equal(0.92, result.Confidence);
|
||||
Assert.Equal("fingerprint:tlsh:matched123", result.MatchedFingerprintId);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void FingerprintMatchResult_NoMatch_HasZeroSimilarity()
|
||||
{
|
||||
var result = new FingerprintMatchResult
|
||||
{
|
||||
IsMatch = false,
|
||||
Similarity = 0.0,
|
||||
Confidence = 0.0,
|
||||
Method = FingerprintMethod.CFGHash
|
||||
};
|
||||
|
||||
Assert.False(result.IsMatch);
|
||||
Assert.Equal(0.0, result.Similarity);
|
||||
Assert.Null(result.MatchedFingerprintId);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void FingerprintMatchResult_PartialMatch_HasIntermediateSimilarity()
|
||||
{
|
||||
var result = new FingerprintMatchResult
|
||||
{
|
||||
IsMatch = false,
|
||||
Similarity = 0.45,
|
||||
Confidence = 0.30,
|
||||
Method = FingerprintMethod.InstructionHash
|
||||
};
|
||||
|
||||
Assert.False(result.IsMatch);
|
||||
Assert.Equal(0.45, result.Similarity);
|
||||
Assert.Equal(0.30, result.Confidence);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(0.0)]
|
||||
[InlineData(0.5)]
|
||||
[InlineData(0.75)]
|
||||
[InlineData(1.0)]
|
||||
public void FingerprintMatchResult_Similarity_InValidRange(double similarity)
|
||||
{
|
||||
var result = new FingerprintMatchResult
|
||||
{
|
||||
IsMatch = similarity >= 0.8,
|
||||
Similarity = similarity,
|
||||
Confidence = similarity * 0.9,
|
||||
Method = FingerprintMethod.SymbolHash
|
||||
};
|
||||
|
||||
Assert.InRange(result.Similarity, 0.0, 1.0);
|
||||
Assert.InRange(result.Confidence, 0.0, 1.0);
|
||||
}
|
||||
}
|
||||
@@ -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="..\..\StellaOps.Feedser.BinaryAnalysis\StellaOps.Feedser.BinaryAnalysis.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