save work

This commit is contained in:
StellaOps Bot
2025-12-19 09:40:41 +02:00
parent 2eafe98d44
commit 43882078a4
44 changed files with 3044 additions and 492 deletions

View File

@@ -13,6 +13,7 @@ using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using StellaOps.Scanner.Analyzers.Lang;
using StellaOps.Scanner.Analyzers.Lang.Plugin;
using StellaOps.Scanner.Analyzers.Native.Index;
using StellaOps.Scanner.Analyzers.OS;
using StellaOps.Scanner.Analyzers.OS.Abstractions;
using StellaOps.Scanner.Analyzers.OS.Plugin;
@@ -23,6 +24,7 @@ using StellaOps.Scanner.Surface.Secrets;
using StellaOps.Scanner.Surface.Validation;
using StellaOps.Scanner.Worker.Diagnostics;
using StellaOps.Scanner.Worker.Processing;
using StellaOps.Scanner.Emit.Native;
using StellaOps.Scanner.Worker.Tests.TestInfrastructure;
using Xunit;
using WorkerOptions = StellaOps.Scanner.Worker.Options.ScannerWorkerOptions;
@@ -104,7 +106,9 @@ public sealed class CompositeScanAnalyzerDispatcherTests
var scopeFactory = services.GetRequiredService<IServiceScopeFactory>();
var loggerFactory = services.GetRequiredService<ILoggerFactory>();
var options = Microsoft.Extensions.Options.Options.Create(new WorkerOptions());
var workerOptions = new WorkerOptions();
workerOptions.NativeAnalyzers.Enabled = false;
var options = Microsoft.Extensions.Options.Options.Create(workerOptions);
var dispatcher = new CompositeScanAnalyzerDispatcher(
scopeFactory,
osCatalog,
@@ -225,7 +229,9 @@ public sealed class CompositeScanAnalyzerDispatcherTests
var scopeFactory = services.GetRequiredService<IServiceScopeFactory>();
var loggerFactory = services.GetRequiredService<ILoggerFactory>();
var options = Microsoft.Extensions.Options.Options.Create(new WorkerOptions());
var workerOptions = new WorkerOptions();
workerOptions.NativeAnalyzers.Enabled = false;
var options = Microsoft.Extensions.Options.Options.Create(workerOptions);
var dispatcher = new CompositeScanAnalyzerDispatcher(
scopeFactory,
osCatalog,
@@ -266,6 +272,74 @@ public sealed class CompositeScanAnalyzerDispatcherTests
}
}
[Fact]
public async Task ExecuteAsync_RunsNativeAnalyzer_AppendsFileComponents()
{
using var rootfs = new TempDirectory();
var metadata = new Dictionary<string, string>(StringComparer.Ordinal)
{
{ ScanMetadataKeys.RootFilesystemPath, rootfs.Path },
{ ScanMetadataKeys.WorkspacePath, rootfs.Path },
};
var binaryPath = Path.Combine(rootfs.Path, "usr", "lib", "libdemo.so");
Directory.CreateDirectory(Path.GetDirectoryName(binaryPath)!);
var elfBytes = new byte[2048];
elfBytes[0] = 0x7F;
elfBytes[1] = (byte)'E';
elfBytes[2] = (byte)'L';
elfBytes[3] = (byte)'F';
await File.WriteAllBytesAsync(binaryPath, elfBytes, CancellationToken.None);
var serviceCollection = new ServiceCollection();
serviceCollection.AddLogging(builder => builder.SetMinimumLevel(LogLevel.Debug));
serviceCollection.AddSingleton(TimeProvider.System);
serviceCollection.AddSingleton<ScannerWorkerMetrics>();
serviceCollection.AddSingleton<IOptions<StellaOps.Scanner.Worker.Options.NativeAnalyzerOptions>>(
Microsoft.Extensions.Options.Options.Create(new StellaOps.Scanner.Worker.Options.NativeAnalyzerOptions
{
Enabled = true,
MinFileSizeBytes = 0,
MaxBinariesPerScan = 50,
MaxBinariesPerLayer = 50,
}));
serviceCollection.AddSingleton<IBuildIdIndex, EmptyBuildIdIndex>();
serviceCollection.AddSingleton<INativeComponentEmitter, NativeComponentEmitter>();
serviceCollection.AddSingleton<NativeBinaryDiscovery>();
serviceCollection.AddSingleton<NativeAnalyzerExecutor>();
await using var services = serviceCollection.BuildServiceProvider();
var scopeFactory = services.GetRequiredService<IServiceScopeFactory>();
var loggerFactory = services.GetRequiredService<ILoggerFactory>();
var metrics = services.GetRequiredService<ScannerWorkerMetrics>();
var workerOptions = new WorkerOptions();
workerOptions.NativeAnalyzers.Enabled = true;
var options = Microsoft.Extensions.Options.Options.Create(workerOptions);
var dispatcher = new CompositeScanAnalyzerDispatcher(
scopeFactory,
new FakeOsCatalog(),
new FakeLanguageCatalog(),
options,
loggerFactory.CreateLogger<CompositeScanAnalyzerDispatcher>(),
metrics,
new TestCryptoHash());
var lease = new TestJobLease(metadata);
var context = new ScanJobContext(lease, TimeProvider.System, TimeProvider.System.GetUtcNow(), CancellationToken.None);
await dispatcher.ExecuteAsync(context, CancellationToken.None);
var fragments = context.Analysis.GetLayerFragments();
Assert.True(fragments.Length > 0);
Assert.Contains(fragments, fragment => fragment.Components.Any(component => string.Equals(component.Identity.ComponentType, "file", StringComparison.Ordinal)));
Assert.Contains(fragments, fragment => fragment.Components.Any(component => string.Equals(component.Identity.Name, "libdemo.so", StringComparison.Ordinal)));
}
private sealed class FakeOsCatalog : IOSAnalyzerPluginCatalog
{
private readonly IReadOnlyList<IOSPackageAnalyzer> _analyzers;
@@ -302,6 +376,21 @@ public sealed class CompositeScanAnalyzerDispatcherTests
public IReadOnlyList<ILanguageAnalyzer> CreateAnalyzers(IServiceProvider services) => _analyzers;
}
private sealed class EmptyBuildIdIndex : IBuildIdIndex
{
public int Count => 0;
public bool IsLoaded => true;
public Task<BuildIdLookupResult?> LookupAsync(string buildId, CancellationToken cancellationToken = default)
=> Task.FromResult<BuildIdLookupResult?>(null);
public Task<IReadOnlyList<BuildIdLookupResult>> BatchLookupAsync(IEnumerable<string> buildIds, CancellationToken cancellationToken = default)
=> Task.FromResult<IReadOnlyList<BuildIdLookupResult>>(Array.Empty<BuildIdLookupResult>());
public Task LoadAsync(CancellationToken cancellationToken = default) => Task.CompletedTask;
}
private sealed class NoopSurfaceValidatorRunner : ISurfaceValidatorRunner
{
public ValueTask<SurfaceValidationResult> RunAllAsync(SurfaceValidationContext context, CancellationToken cancellationToken = default)