audit work, fixed StellaOps.sln warnings/errors, fixed tests, sprints work, new advisories
This commit is contained in:
@@ -0,0 +1,22 @@
|
||||
# BinaryIndex Benchmarks Charter
|
||||
|
||||
## Mission
|
||||
- Maintain deterministic benchmark and accuracy tests for BinaryIndex analyzers.
|
||||
|
||||
## Responsibilities
|
||||
- Keep benchmark datasets local and fixed.
|
||||
- Ensure benchmark thresholds are stable and documented.
|
||||
- Separate benchmark runs from unit coverage.
|
||||
|
||||
## Required Reading
|
||||
- docs/modules/binary-index/architecture.md
|
||||
- docs/modules/platform/architecture-overview.md
|
||||
- docs/07_HIGH_LEVEL_ARCHITECTURE.md
|
||||
|
||||
## Working Agreement
|
||||
- No network calls; offline fixtures only.
|
||||
- Fixed seeds and deterministic ordering.
|
||||
- Avoid machine-specific timing assertions; use bounded thresholds.
|
||||
|
||||
## Definition of Done
|
||||
- Benchmarks reproducible on CI and offline environments.
|
||||
@@ -12,8 +12,8 @@
|
||||
<ItemGroup>
|
||||
<PackageReference Include="FluentAssertions" />
|
||||
<PackageReference Include="Moq" />
|
||||
<PackageReference Include="NSubstitute" />
|
||||
<PackageReference Include="Testcontainers" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -0,0 +1,162 @@
|
||||
// -----------------------------------------------------------------------------
|
||||
// NameDemanglerTests.cs
|
||||
// Sprint: SPRINT_20260106_001_003_BINDEX_symbol_table_diff
|
||||
// Tasks: SYM-016, SYM-017 - Unit tests for name demangling
|
||||
// Description: Unit tests for C++ and Rust name demangler
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
using StellaOps.BinaryIndex.Builders.SymbolDiff;
|
||||
using Xunit;
|
||||
|
||||
namespace StellaOps.BinaryIndex.Builders.Tests.SymbolDiff;
|
||||
|
||||
[Trait("Category", "Unit")]
|
||||
public sealed class NameDemanglerTests
|
||||
{
|
||||
private readonly NameDemangler _demangler = new();
|
||||
|
||||
// Scheme detection tests
|
||||
|
||||
[Theory]
|
||||
[InlineData("_Z3foov", ManglingScheme.ItaniumCxx)]
|
||||
[InlineData("_ZN3foo3barEv", ManglingScheme.ItaniumCxx)]
|
||||
[InlineData("?foo@@YAXXZ", ManglingScheme.MicrosoftCxx)]
|
||||
[InlineData("?foo@bar@@YAXXZ", ManglingScheme.MicrosoftCxx)]
|
||||
[InlineData("_ZN4test17h0123456789abcdefE", ManglingScheme.Rust)]
|
||||
[InlineData("_RNvC5crate4main", ManglingScheme.Rust)]
|
||||
[InlineData("$s4main3fooyyF", ManglingScheme.Swift)]
|
||||
[InlineData("_$s4main3fooyyF", ManglingScheme.Swift)]
|
||||
[InlineData("foo", ManglingScheme.None)]
|
||||
[InlineData("printf", ManglingScheme.None)]
|
||||
[InlineData("", ManglingScheme.None)]
|
||||
public void DetectScheme_IdentifiesCorrectScheme(string name, ManglingScheme expected)
|
||||
{
|
||||
var result = _demangler.DetectScheme(name);
|
||||
Assert.Equal(expected, result);
|
||||
}
|
||||
|
||||
// C++ Itanium ABI tests
|
||||
|
||||
[Theory]
|
||||
[InlineData("_Z3foov", "foo")]
|
||||
[InlineData("_Z3bari", "bar")]
|
||||
[InlineData("_Z6myFunc", "myFunc")]
|
||||
public void Demangle_ItaniumCxx_SimpleNames(string mangled, string expected)
|
||||
{
|
||||
var result = _demangler.Demangle(mangled);
|
||||
Assert.Equal(expected, result);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("_ZN3foo3barEv", "foo::bar")]
|
||||
[InlineData("_ZN5outer5inner4funcEv", "outer::inner::func")]
|
||||
public void Demangle_ItaniumCxx_NestedNames(string mangled, string expected)
|
||||
{
|
||||
var result = _demangler.Demangle(mangled);
|
||||
Assert.Equal(expected, result);
|
||||
}
|
||||
|
||||
// Microsoft C++ tests
|
||||
|
||||
[Theory]
|
||||
[InlineData("?foo@@YAXXZ", "foo")]
|
||||
[InlineData("?bar@MyClass@@QAEXXZ", "MyClass::bar")]
|
||||
public void Demangle_MicrosoftCxx_SimpleNames(string mangled, string expected)
|
||||
{
|
||||
var result = _demangler.Demangle(mangled);
|
||||
Assert.Equal(expected, result);
|
||||
}
|
||||
|
||||
// Rust legacy mangling tests
|
||||
|
||||
[Fact]
|
||||
public void Demangle_RustLegacy_BasicName()
|
||||
{
|
||||
// _ZN<len>name...E format
|
||||
var mangled = "_ZN4test4mainE";
|
||||
var result = _demangler.Demangle(mangled);
|
||||
|
||||
Assert.NotNull(result);
|
||||
Assert.Contains("test", result);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Demangle_RustLegacy_WithHash_StripsHash()
|
||||
{
|
||||
// Rust hashes are 17h + 16 hex digits
|
||||
var mangled = "_ZN4core3ptr17h0123456789abcdefE";
|
||||
var result = _demangler.Demangle(mangled);
|
||||
|
||||
Assert.NotNull(result);
|
||||
Assert.DoesNotContain("h0123456789abcdef", result);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Demangle_RustLegacy_DecodesEscapes()
|
||||
{
|
||||
// Test Rust escape sequences
|
||||
var mangled = "_ZN4test8$LT$impl$GT$E";
|
||||
var result = _demangler.Demangle(mangled);
|
||||
|
||||
Assert.NotNull(result);
|
||||
// Should decode $LT$ to < and $GT$ to >
|
||||
Assert.Contains("<", result);
|
||||
Assert.Contains(">", result);
|
||||
}
|
||||
|
||||
// Rust v0 mangling tests
|
||||
|
||||
[Fact]
|
||||
public void Demangle_RustV0_ReturnsPlaceholder()
|
||||
{
|
||||
// Rust v0 starts with _R
|
||||
var mangled = "_RNvC5crate4main";
|
||||
var result = _demangler.Demangle(mangled);
|
||||
|
||||
Assert.NotNull(result);
|
||||
Assert.StartsWith("<rust-v0>", result);
|
||||
}
|
||||
|
||||
// Swift tests
|
||||
|
||||
[Fact]
|
||||
public void Demangle_Swift_ReturnsPlaceholder()
|
||||
{
|
||||
var mangled = "$s4main3fooyyF";
|
||||
var result = _demangler.Demangle(mangled);
|
||||
|
||||
Assert.NotNull(result);
|
||||
Assert.StartsWith("<swift>", result);
|
||||
}
|
||||
|
||||
// Edge cases
|
||||
|
||||
[Fact]
|
||||
public void Demangle_NullInput_ReturnsNull()
|
||||
{
|
||||
var result = _demangler.Demangle(null!);
|
||||
Assert.Null(result);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Demangle_EmptyInput_ReturnsNull()
|
||||
{
|
||||
var result = _demangler.Demangle(string.Empty);
|
||||
Assert.Null(result);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Demangle_PlainCName_ReturnsNull()
|
||||
{
|
||||
var result = _demangler.Demangle("printf");
|
||||
Assert.Null(result);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Demangle_InvalidMangledName_ReturnsNull()
|
||||
{
|
||||
// Invalid Itanium format (no proper length prefix)
|
||||
var result = _demangler.Demangle("_Zinvalid");
|
||||
Assert.Null(result);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,334 @@
|
||||
// -----------------------------------------------------------------------------
|
||||
// SymbolTableDiffAnalyzerTests.cs
|
||||
// Sprint: SPRINT_20260106_001_003_BINDEX_symbol_table_diff
|
||||
// Tasks: SYM-020 to SYM-025 - Unit tests for symbol diff
|
||||
// Description: Unit tests for symbol table diff analyzer
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
using StellaOps.BinaryIndex.Builders.SymbolDiff;
|
||||
using Xunit;
|
||||
using NSubstitute;
|
||||
|
||||
namespace StellaOps.BinaryIndex.Builders.Tests.SymbolDiff;
|
||||
|
||||
[Trait("Category", "Unit")]
|
||||
public sealed class SymbolTableDiffAnalyzerTests
|
||||
{
|
||||
private readonly ISymbolExtractor _mockExtractor;
|
||||
private readonly INameDemangler _demangler;
|
||||
private readonly TimeProvider _timeProvider;
|
||||
private readonly SymbolTableDiffAnalyzer _analyzer;
|
||||
|
||||
public SymbolTableDiffAnalyzerTests()
|
||||
{
|
||||
_mockExtractor = Substitute.For<ISymbolExtractor>();
|
||||
_demangler = new NameDemangler();
|
||||
_timeProvider = TimeProvider.System;
|
||||
_analyzer = new SymbolTableDiffAnalyzer(
|
||||
_mockExtractor,
|
||||
_demangler,
|
||||
_timeProvider,
|
||||
NullLogger<SymbolTableDiffAnalyzer>.Instance);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ComputeDiffAsync_DetectsAddedSymbols()
|
||||
{
|
||||
// Arrange
|
||||
var baseTable = CreateSymbolTable("base.so", [
|
||||
CreateSymbol("foo", SymbolType.Function)
|
||||
]);
|
||||
var targetTable = CreateSymbolTable("target.so", [
|
||||
CreateSymbol("foo", SymbolType.Function),
|
||||
CreateSymbol("bar", SymbolType.Function)
|
||||
]);
|
||||
|
||||
_mockExtractor.ExtractAsync("base.so", Arg.Any<CancellationToken>()).Returns(baseTable);
|
||||
_mockExtractor.ExtractAsync("target.so", Arg.Any<CancellationToken>()).Returns(targetTable);
|
||||
|
||||
// Act
|
||||
var diff = await _analyzer.ComputeDiffAsync("base.so", "target.so");
|
||||
|
||||
// Assert
|
||||
Assert.Single(diff.Exports.Added);
|
||||
Assert.Equal("bar", diff.Exports.Added[0].Name);
|
||||
Assert.Empty(diff.Exports.Removed);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ComputeDiffAsync_DetectsRemovedSymbols()
|
||||
{
|
||||
// Arrange
|
||||
var baseTable = CreateSymbolTable("base.so", [
|
||||
CreateSymbol("foo", SymbolType.Function),
|
||||
CreateSymbol("bar", SymbolType.Function)
|
||||
]);
|
||||
var targetTable = CreateSymbolTable("target.so", [
|
||||
CreateSymbol("foo", SymbolType.Function)
|
||||
]);
|
||||
|
||||
_mockExtractor.ExtractAsync("base.so", Arg.Any<CancellationToken>()).Returns(baseTable);
|
||||
_mockExtractor.ExtractAsync("target.so", Arg.Any<CancellationToken>()).Returns(targetTable);
|
||||
|
||||
// Act
|
||||
var diff = await _analyzer.ComputeDiffAsync("base.so", "target.so");
|
||||
|
||||
// Assert
|
||||
Assert.Empty(diff.Exports.Added);
|
||||
Assert.Single(diff.Exports.Removed);
|
||||
Assert.Equal("bar", diff.Exports.Removed[0].Name);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ComputeDiffAsync_DetectsModifiedSymbols()
|
||||
{
|
||||
// Arrange
|
||||
var baseTable = CreateSymbolTable("base.so", [
|
||||
CreateSymbol("foo", SymbolType.Function, size: 100)
|
||||
]);
|
||||
var targetTable = CreateSymbolTable("target.so", [
|
||||
CreateSymbol("foo", SymbolType.Function, size: 200)
|
||||
]);
|
||||
|
||||
_mockExtractor.ExtractAsync("base.so", Arg.Any<CancellationToken>()).Returns(baseTable);
|
||||
_mockExtractor.ExtractAsync("target.so", Arg.Any<CancellationToken>()).Returns(targetTable);
|
||||
|
||||
// Act
|
||||
var diff = await _analyzer.ComputeDiffAsync("base.so", "target.so");
|
||||
|
||||
// Assert
|
||||
Assert.Single(diff.Exports.Modified);
|
||||
Assert.Equal("foo", diff.Exports.Modified[0].Name);
|
||||
Assert.Contains(diff.Exports.Modified[0].Changes, c => c.Attribute == "size");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ComputeDiffAsync_DetectsRenames_WhenFingerprintsMatch()
|
||||
{
|
||||
// Arrange
|
||||
var fingerprint = "abc123def456";
|
||||
var baseTable = CreateSymbolTable("base.so", [
|
||||
CreateSymbol("old_name", SymbolType.Function, fingerprint: fingerprint)
|
||||
]);
|
||||
var targetTable = CreateSymbolTable("target.so", [
|
||||
CreateSymbol("new_name", SymbolType.Function, fingerprint: fingerprint)
|
||||
]);
|
||||
|
||||
_mockExtractor.ExtractAsync("base.so", Arg.Any<CancellationToken>()).Returns(baseTable);
|
||||
_mockExtractor.ExtractAsync("target.so", Arg.Any<CancellationToken>()).Returns(targetTable);
|
||||
|
||||
// Act
|
||||
var diff = await _analyzer.ComputeDiffAsync("base.so", "target.so", new SymbolDiffOptions
|
||||
{
|
||||
DetectRenames = true,
|
||||
RenameSimilarityThreshold = 0.5
|
||||
});
|
||||
|
||||
// Assert
|
||||
Assert.Single(diff.Exports.Renamed);
|
||||
Assert.Equal("old_name", diff.Exports.Renamed[0].BaseName);
|
||||
Assert.Equal("new_name", diff.Exports.Renamed[0].TargetName);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ComputeDiffAsync_ComputesDiffId_Deterministically()
|
||||
{
|
||||
// Arrange
|
||||
var baseTable = CreateSymbolTable("base.so", [
|
||||
CreateSymbol("foo", SymbolType.Function)
|
||||
]);
|
||||
var targetTable = CreateSymbolTable("target.so", [
|
||||
CreateSymbol("foo", SymbolType.Function),
|
||||
CreateSymbol("bar", SymbolType.Function)
|
||||
]);
|
||||
|
||||
_mockExtractor.ExtractAsync("base.so", Arg.Any<CancellationToken>()).Returns(baseTable);
|
||||
_mockExtractor.ExtractAsync("target.so", Arg.Any<CancellationToken>()).Returns(targetTable);
|
||||
|
||||
// Act
|
||||
var diff1 = await _analyzer.ComputeDiffAsync("base.so", "target.so");
|
||||
var diff2 = await _analyzer.ComputeDiffAsync("base.so", "target.so");
|
||||
|
||||
// Assert
|
||||
Assert.Equal(diff1.DiffId, diff2.DiffId);
|
||||
Assert.StartsWith("sha256:", diff1.DiffId);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void AssessAbiCompatibility_FullyCompatible_WhenNoBreakingChanges()
|
||||
{
|
||||
// Arrange
|
||||
var diff = CreateDiff(
|
||||
added: [CreateSymbolChange("new_func")],
|
||||
removed: [],
|
||||
modified: []);
|
||||
|
||||
// Act
|
||||
var abi = _analyzer.AssessAbiCompatibility(diff);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(AbiCompatibilityLevel.FullyCompatible, abi.Level);
|
||||
Assert.True(abi.IsBackwardCompatible);
|
||||
Assert.Empty(abi.BreakingChanges);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void AssessAbiCompatibility_Incompatible_WhenSymbolsRemoved()
|
||||
{
|
||||
// Arrange
|
||||
var diff = CreateDiff(
|
||||
added: [],
|
||||
removed: [CreateSymbolChange("removed_func", SymbolBinding.Global)],
|
||||
modified: []);
|
||||
|
||||
// Act
|
||||
var abi = _analyzer.AssessAbiCompatibility(diff);
|
||||
|
||||
// Assert
|
||||
Assert.NotEqual(AbiCompatibilityLevel.FullyCompatible, abi.Level);
|
||||
Assert.False(abi.IsBackwardCompatible);
|
||||
Assert.Single(abi.BreakingChanges);
|
||||
Assert.Equal(AbiBreakType.SymbolRemoved, abi.BreakingChanges[0].Type);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void AssessAbiCompatibility_WarningsForAddedSymbols()
|
||||
{
|
||||
// Arrange
|
||||
var diff = CreateDiff(
|
||||
added: [CreateSymbolChange("new_func")],
|
||||
removed: [],
|
||||
modified: []);
|
||||
|
||||
// Act
|
||||
var abi = _analyzer.AssessAbiCompatibility(diff);
|
||||
|
||||
// Assert
|
||||
Assert.Single(abi.Warnings);
|
||||
Assert.Equal(AbiWarningType.SymbolAdded, abi.Warnings[0].Type);
|
||||
}
|
||||
|
||||
// Helper methods
|
||||
private static SymbolTable CreateSymbolTable(string path, IReadOnlyList<ExtractedSymbol> exports)
|
||||
{
|
||||
return new SymbolTable
|
||||
{
|
||||
Binary = new BinaryRef
|
||||
{
|
||||
Path = path,
|
||||
Sha256 = $"sha256:{Guid.NewGuid():N}",
|
||||
Architecture = "x86_64",
|
||||
Format = BinaryFormat.Elf
|
||||
},
|
||||
Exports = exports,
|
||||
Imports = [],
|
||||
VersionDefinitions = [],
|
||||
VersionRequirements = [],
|
||||
NeededLibraries = [],
|
||||
ExtractedAt = DateTimeOffset.UtcNow
|
||||
};
|
||||
}
|
||||
|
||||
private static ExtractedSymbol CreateSymbol(
|
||||
string name,
|
||||
SymbolType type,
|
||||
SymbolBinding binding = SymbolBinding.Global,
|
||||
ulong size = 64,
|
||||
string? fingerprint = null)
|
||||
{
|
||||
return new ExtractedSymbol
|
||||
{
|
||||
Name = name,
|
||||
Type = type,
|
||||
Binding = binding,
|
||||
Visibility = SymbolVisibility.Default,
|
||||
Address = 0x1000,
|
||||
Size = size,
|
||||
Fingerprint = fingerprint
|
||||
};
|
||||
}
|
||||
|
||||
private static SymbolChange CreateSymbolChange(
|
||||
string name,
|
||||
SymbolBinding binding = SymbolBinding.Global)
|
||||
{
|
||||
return new SymbolChange
|
||||
{
|
||||
Name = name,
|
||||
Type = SymbolType.Function,
|
||||
Binding = binding,
|
||||
Visibility = SymbolVisibility.Default,
|
||||
Address = 0x1000,
|
||||
Size = 64
|
||||
};
|
||||
}
|
||||
|
||||
private static SymbolTableDiff CreateDiff(
|
||||
IReadOnlyList<SymbolChange> added,
|
||||
IReadOnlyList<SymbolChange> removed,
|
||||
IReadOnlyList<SymbolModification> modified)
|
||||
{
|
||||
return new SymbolTableDiff
|
||||
{
|
||||
DiffId = "sha256:test",
|
||||
Base = new BinaryRef
|
||||
{
|
||||
Path = "base.so",
|
||||
Sha256 = "sha256:base",
|
||||
Architecture = "x86_64",
|
||||
Format = BinaryFormat.Elf
|
||||
},
|
||||
Target = new BinaryRef
|
||||
{
|
||||
Path = "target.so",
|
||||
Sha256 = "sha256:target",
|
||||
Architecture = "x86_64",
|
||||
Format = BinaryFormat.Elf
|
||||
},
|
||||
Exports = new SymbolChangeSummary
|
||||
{
|
||||
Added = added,
|
||||
Removed = removed,
|
||||
Modified = modified,
|
||||
Renamed = [],
|
||||
Counts = new SymbolChangeCounts
|
||||
{
|
||||
Added = added.Count,
|
||||
Removed = removed.Count,
|
||||
Modified = modified.Count,
|
||||
TotalBase = removed.Count + modified.Count,
|
||||
TotalTarget = added.Count + modified.Count
|
||||
}
|
||||
},
|
||||
Imports = new SymbolChangeSummary
|
||||
{
|
||||
Added = [],
|
||||
Removed = [],
|
||||
Modified = [],
|
||||
Renamed = [],
|
||||
Counts = new SymbolChangeCounts()
|
||||
},
|
||||
Versions = new VersionMapDiff
|
||||
{
|
||||
DefinitionsAdded = [],
|
||||
DefinitionsRemoved = [],
|
||||
RequirementsAdded = [],
|
||||
RequirementsRemoved = [],
|
||||
AssignmentsChanged = [],
|
||||
Counts = new VersionChangeCounts()
|
||||
},
|
||||
AbiCompatibility = new AbiCompatibility
|
||||
{
|
||||
Level = AbiCompatibilityLevel.FullyCompatible,
|
||||
Score = 1.0,
|
||||
IsBackwardCompatible = true,
|
||||
IsForwardCompatible = true,
|
||||
BreakingChanges = [],
|
||||
Warnings = [],
|
||||
Summary = new AbiSummary()
|
||||
},
|
||||
ComputedAt = DateTimeOffset.UtcNow
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
# BinaryIndex.Decompiler Tests Charter
|
||||
|
||||
## Mission
|
||||
- Validate deterministic decompiler parsing and normalization.
|
||||
|
||||
## Responsibilities
|
||||
- Cover AST parsing, normalization, and comparison paths.
|
||||
- Keep fixtures deterministic and offline-safe.
|
||||
|
||||
## Required Reading
|
||||
- docs/modules/binary-index/architecture.md
|
||||
- docs/modules/binary-index/semantic-diffing.md
|
||||
- docs/modules/platform/architecture-overview.md
|
||||
- docs/07_HIGH_LEVEL_ARCHITECTURE.md
|
||||
|
||||
## Definition of Done
|
||||
- Tests are deterministic and offline-safe.
|
||||
- Coverage includes error handling and normalization edge cases.
|
||||
|
||||
## Working Agreement
|
||||
- Use fixed seeds and ids in fixtures.
|
||||
- Avoid non-deterministic ordering; assert sorted output.
|
||||
@@ -20,9 +20,6 @@
|
||||
<PackageReference Include="FluentAssertions" />
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" />
|
||||
<PackageReference Include="xunit.v3" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -18,13 +18,7 @@
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="FluentAssertions" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" />
|
||||
<PackageReference Include="Moq" />
|
||||
<PackageReference Include="xunit.v3" />
|
||||
<PackageReference Include="xunit.runner.visualstudio">
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" />
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
# BinaryIndex.Ensemble Tests Charter
|
||||
|
||||
## Mission
|
||||
- Validate deterministic ensemble decisioning and weight tuning.
|
||||
|
||||
## Responsibilities
|
||||
- Cover decision engine inputs, weights, and tie-breaking.
|
||||
- Keep fixtures deterministic and offline-safe.
|
||||
|
||||
## Required Reading
|
||||
- docs/modules/binary-index/architecture.md
|
||||
- docs/modules/binary-index/semantic-diffing.md
|
||||
- docs/modules/platform/architecture-overview.md
|
||||
- docs/07_HIGH_LEVEL_ARCHITECTURE.md
|
||||
|
||||
## Definition of Done
|
||||
- Tests are deterministic and offline-safe.
|
||||
- Coverage includes weight tuning and error handling.
|
||||
|
||||
## Working Agreement
|
||||
- Use fixed seeds and ids in fixtures.
|
||||
- Avoid non-deterministic ordering; assert sorted output.
|
||||
@@ -0,0 +1,22 @@
|
||||
# BinaryIndex.Ghidra Tests Charter
|
||||
|
||||
## Mission
|
||||
- Validate deterministic behavior of the Ghidra integration layer.
|
||||
|
||||
## Responsibilities
|
||||
- Cover service behaviors, process lifecycle, and output parsing.
|
||||
- Keep fixtures deterministic and offline-safe.
|
||||
|
||||
## Required Reading
|
||||
- docs/modules/binary-index/architecture.md
|
||||
- docs/modules/binary-index/ghidra-deployment.md
|
||||
- docs/modules/platform/architecture-overview.md
|
||||
- docs/07_HIGH_LEVEL_ARCHITECTURE.md
|
||||
|
||||
## Definition of Done
|
||||
- Tests are deterministic and offline-safe.
|
||||
- Coverage includes error handling and cleanup paths.
|
||||
|
||||
## Working Agreement
|
||||
- Use fixed ids and temp paths in fixtures.
|
||||
- Avoid non-deterministic ordering; assert sorted output.
|
||||
@@ -16,13 +16,7 @@
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="FluentAssertions" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" />
|
||||
<PackageReference Include="Moq" />
|
||||
<PackageReference Include="xunit.v3" />
|
||||
<PackageReference Include="xunit.runner.visualstudio">
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" />
|
||||
|
||||
@@ -21,9 +21,6 @@
|
||||
<PackageReference Include="FsCheck.Xunit.v3" />
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" />
|
||||
<PackageReference Include="xunit.v3" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
# BinaryIndex.Semantic Tests Charter
|
||||
|
||||
## Mission
|
||||
- Validate deterministic semantic graph extraction and matching.
|
||||
|
||||
## Responsibilities
|
||||
- Cover graph extraction, hashing, canonicalization, and matching.
|
||||
- Keep fixtures deterministic and offline-safe.
|
||||
|
||||
## Required Reading
|
||||
- docs/modules/binary-index/architecture.md
|
||||
- docs/modules/binary-index/semantic-diffing.md
|
||||
- docs/modules/platform/architecture-overview.md
|
||||
- docs/07_HIGH_LEVEL_ARCHITECTURE.md
|
||||
|
||||
## Definition of Done
|
||||
- Tests are deterministic and offline-safe.
|
||||
- Coverage includes algorithm options and edge cases.
|
||||
|
||||
## Working Agreement
|
||||
- Use fixed seeds and ids in fixtures.
|
||||
- Avoid non-deterministic ordering; assert sorted output.
|
||||
@@ -15,10 +15,6 @@
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" />
|
||||
<PackageReference Include="Microsoft.Extensions.Options" />
|
||||
<PackageReference Include="Moq" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" >
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
Reference in New Issue
Block a user