Add tests and implement timeline ingestion options with NATS and Redis subscribers
- Introduced `BinaryReachabilityLifterTests` to validate binary lifting functionality. - Created `PackRunWorkerOptions` for configuring worker paths and execution persistence. - Added `TimelineIngestionOptions` for configuring NATS and Redis ingestion transports. - Implemented `NatsTimelineEventSubscriber` for subscribing to NATS events. - Developed `RedisTimelineEventSubscriber` for reading from Redis Streams. - Added `TimelineEnvelopeParser` to normalize incoming event envelopes. - Created unit tests for `TimelineEnvelopeParser` to ensure correct field mapping. - Implemented `TimelineAuthorizationAuditSink` for logging authorization outcomes.
This commit is contained in:
@@ -0,0 +1,62 @@
|
||||
using System.Security.Cryptography;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using StellaOps.Scanner.Reachability;
|
||||
using StellaOps.Scanner.Reachability.Lifters;
|
||||
using Xunit;
|
||||
|
||||
namespace StellaOps.Scanner.Reachability.Tests;
|
||||
|
||||
public class BinaryReachabilityLifterTests
|
||||
{
|
||||
[Fact]
|
||||
public async Task EmitsSymbolAndCodeIdForBinary()
|
||||
{
|
||||
using var temp = new TempDir();
|
||||
var binaryPath = System.IO.Path.Combine(temp.Path, "sample.so");
|
||||
var bytes = CreateMinimalElf();
|
||||
await System.IO.File.WriteAllBytesAsync(binaryPath, bytes);
|
||||
|
||||
var context = new ReachabilityLifterContext
|
||||
{
|
||||
RootPath = temp.Path,
|
||||
AnalysisId = "analysis-42"
|
||||
};
|
||||
|
||||
var builder = new ReachabilityGraphBuilder();
|
||||
var lifter = new BinaryReachabilityLifter();
|
||||
|
||||
await lifter.LiftAsync(context, builder, CancellationToken.None);
|
||||
var graph = builder.ToUnionGraph(SymbolId.Lang.Binary);
|
||||
|
||||
var node = Assert.Single(graph.Nodes);
|
||||
Assert.Equal(SymbolId.Lang.Binary, node.Lang);
|
||||
|
||||
var shaHex = Convert.ToHexString(SHA256.HashData(bytes)).ToLowerInvariant();
|
||||
var expectedSymbolId = SymbolId.ForBinaryAddressed($"sha256:{shaHex}", ".text", "0x0", "sample.so", "static");
|
||||
Assert.Equal(expectedSymbolId, node.SymbolId);
|
||||
|
||||
Assert.NotNull(node.Attributes);
|
||||
var expectedCodeId = CodeId.ForBinarySegment("elf", $"sha256:{shaHex}", "0x0", bytes.LongLength, ".text");
|
||||
Assert.Equal(expectedCodeId, node.Attributes!["code_id"]);
|
||||
|
||||
var rich = RichGraphBuilder.FromUnion(graph, "test-analyzer", "1.0.0");
|
||||
var richNode = Assert.Single(rich.Nodes);
|
||||
Assert.Equal(expectedCodeId, richNode.CodeId);
|
||||
}
|
||||
|
||||
private static byte[] CreateMinimalElf()
|
||||
{
|
||||
var data = new byte[64];
|
||||
data[0] = 0x7F;
|
||||
data[1] = (byte)'E';
|
||||
data[2] = (byte)'L';
|
||||
data[3] = (byte)'F';
|
||||
data[4] = 2; // 64-bit
|
||||
data[5] = 1; // little endian
|
||||
data[7] = 0; // System V ABI
|
||||
data[18] = 0x3E; // EM_X86_64
|
||||
data[19] = 0x00;
|
||||
return data;
|
||||
}
|
||||
}
|
||||
@@ -21,7 +21,7 @@ public class RichGraphPublisherTests
|
||||
var rich = RichGraphBuilder.FromUnion(union, "test", "1.0.0");
|
||||
var result = await publisher.PublishAsync(rich, "scan-1", cas, temp.Path);
|
||||
|
||||
Assert.StartsWith("blake3:", result.GraphHash);
|
||||
Assert.StartsWith("sha256:", result.GraphHash);
|
||||
Assert.Equal(1, result.NodeCount);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user