up
Some checks failed
AOC Guard CI / aoc-guard (push) Has been cancelled
AOC Guard CI / aoc-verify (push) Has been cancelled
Docs CI / lint-and-preview (push) Has been cancelled
Mirror Thin Bundle Sign & Verify / mirror-sign (push) Has been cancelled
api-governance / spectral-lint (push) Has been cancelled

This commit is contained in:
StellaOps Bot
2025-11-24 07:52:25 +02:00
parent 5970f0d9bd
commit 150b3730ef
215 changed files with 8119 additions and 740 deletions

View File

@@ -0,0 +1,39 @@
using System;
using System.Collections.Concurrent;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using StellaOps.Scanner.Cache.Abstractions;
namespace StellaOps.Scanner.Reachability.Tests;
internal sealed class FakeFileContentAddressableStore : IFileContentAddressableStore
{
private readonly ConcurrentDictionary<string, byte[]> store = new();
public ValueTask<FileCasEntry?> TryGetAsync(string sha256, CancellationToken cancellationToken = default)
{
if (store.TryGetValue(sha256, out var bytes))
{
return ValueTask.FromResult<FileCasEntry?>(new FileCasEntry(sha256, bytes.LongLength, DateTimeOffset.UtcNow, DateTimeOffset.UtcNow, sha256 + ".zip"));
}
return ValueTask.FromResult<FileCasEntry?>(null);
}
public Task<FileCasEntry> PutAsync(FileCasPutRequest request, CancellationToken cancellationToken = default)
{
using var ms = new MemoryStream();
request.Content.CopyTo(ms);
store[request.Sha256] = ms.ToArray();
return Task.FromResult(new FileCasEntry(request.Sha256, ms.Length, DateTimeOffset.UtcNow, DateTimeOffset.UtcNow, request.Sha256 + ".zip"));
}
public Task<bool> RemoveAsync(string sha256, CancellationToken cancellationToken = default)
=> Task.FromResult(store.TryRemove(sha256, out _));
public Task<int> EvictExpiredAsync(CancellationToken cancellationToken = default) => Task.FromResult(0);
public Task<int> ExportAsync(string destinationDirectory, CancellationToken cancellationToken = default) => Task.FromResult(0);
public Task<int> ImportAsync(string sourceDirectory, CancellationToken cancellationToken = default) => Task.FromResult(0);
public Task<int> CompactAsync(CancellationToken cancellationToken = default) => Task.FromResult(0);
}

View File

@@ -0,0 +1,27 @@
using System.Threading.Tasks;
using StellaOps.Scanner.Reachability;
using Xunit;
namespace StellaOps.Scanner.Reachability.Tests;
public class ReachabilityUnionPublisherTests
{
[Fact]
public async Task PublishesZipToCas()
{
var graph = new ReachabilityUnionGraph(
Nodes: new[] { new ReachabilityUnionNode("sym:dotnet:A", "dotnet", "method") },
Edges: new ReachabilityUnionEdge[0]);
using var temp = new TempDir();
var cas = new FakeFileContentAddressableStore();
var publisher = new ReachabilityUnionPublisher(new ReachabilityUnionWriter());
var result = await publisher.PublishAsync(graph, cas, temp.Path, "analysis-pub-1");
Assert.False(string.IsNullOrWhiteSpace(result.Sha256));
var entry = await cas.TryGetAsync(result.Sha256);
Assert.NotNull(entry);
Assert.True(entry!.SizeBytes > 0);
}
}

View File

@@ -0,0 +1,41 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text.Json;
using System.Threading.Tasks;
using StellaOps.Scanner.Reachability;
using Xunit;
namespace StellaOps.Scanner.Reachability.Tests;
public class ReachabilityUnionWriterTests
{
[Fact]
public async Task WritesDeterministicNdjson()
{
var writer = new ReachabilityUnionWriter();
using var temp = new TempDir();
var graph = new ReachabilityUnionGraph(
Nodes: new[]
{
new ReachabilityUnionNode("sym:dotnet:B", "dotnet", "method"),
new ReachabilityUnionNode("sym:dotnet:A", "dotnet", "method")
},
Edges: new[]
{
new ReachabilityUnionEdge("sym:dotnet:A", "sym:dotnet:B", "call")
});
var result = await writer.WriteAsync(graph, temp.Path, "analysis-x");
var meta = await JsonDocument.ParseAsync(File.OpenRead(result.MetaPath));
var files = meta.RootElement.GetProperty("files").EnumerateArray().ToList();
Assert.Equal(2, files.Count); // nodes + edges
// Deterministic order
var nodeLines = await File.ReadAllLinesAsync(Path.Combine(temp.Path, "reachability_graphs/analysis-x/nodes.ndjson"));
Assert.Contains(nodeLines, l => l.Contains("sym:dotnet:A"));
}
}

View File

@@ -0,0 +1,19 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<LangVersion>preview</LangVersion>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<IsPackable>false</IsPackable>
<UseConcelierTestInfra>false</UseConcelierTestInfra>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.14.0" />
<PackageReference Include="xunit" Version="2.9.2" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.8.2" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\__Libraries\StellaOps.Scanner.Reachability\StellaOps.Scanner.Reachability.csproj" />
<ProjectReference Include="..\..\__Libraries\StellaOps.Scanner.Cache\StellaOps.Scanner.Cache.csproj" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,27 @@
using System;
using System.IO;
namespace StellaOps.Scanner.Reachability.Tests;
internal sealed class TempDir : IDisposable
{
public string Path { get; }
public TempDir()
{
Path = System.IO.Path.Combine(System.IO.Path.GetTempPath(), "reach-tests-" + Guid.NewGuid().ToString("N"));
Directory.CreateDirectory(Path);
}
public void Dispose()
{
try
{
Directory.Delete(Path, recursive: true);
}
catch
{
// best-effort cleanup only
}
}
}