nuget reorganization

This commit is contained in:
master
2025-11-18 23:45:25 +02:00
parent 77cee6a209
commit d3ecd7f8e6
7712 changed files with 13963 additions and 10007504 deletions

View File

@@ -0,0 +1,26 @@
using StellaOps.Scanner.Analyzers.Lang.Deno.Internal.Runtime;
namespace StellaOps.Scanner.Analyzers.Lang.Deno.Tests.Deno;
public sealed class DenoRuntimeShimTests
{
[Fact]
public async Task WritesShimToDirectory()
{
var root = TestPaths.CreateTemporaryDirectory();
try
{
var path = await DenoRuntimeShim.WriteAsync(root, TestContext.Current.CancellationToken);
Assert.True(File.Exists(path));
var content = await File.ReadAllTextAsync(path, TestContext.Current.CancellationToken);
Assert.Contains("deno-runtime.ndjson", content);
Assert.Contains("deno.module.load", content);
Assert.Contains("deno.permission.use", content);
}
finally
{
TestPaths.SafeDelete(root);
}
}
}

View File

@@ -0,0 +1,32 @@
using System.Text;
using StellaOps.Scanner.Analyzers.Lang.Deno.Internal.Runtime;
namespace StellaOps.Scanner.Analyzers.Lang.Deno.Tests.Deno;
public sealed class DenoRuntimeTraceProbeTests
{
[Fact]
public void ComputesMetadataAndHashFromNdjson()
{
const string ndjson =
@"{\""type\"":\"\"deno.module.load\"",\""ts\"":\"\"2025-11-17T12:00:00Z\"",\""reason\"":\"\"dynamic-import\"",\""permissions\"":[\"\"fs\""],\""origin\"":\"\"https://deno.land\""}
{\""type\"":\"\"deno.permission.use\"",\""ts\"":\"\"2025-11-17T12:00:01Z\"",\""permission\"":\"\"NET\""}
{\""type\"":\"\"deno.npm.resolution\"",\""ts\"":\"\"2025-11-17T12:00:02Z\""}
{\""type\"":\"\"deno.wasm.load\"",\""ts\"":\"\"2025-11-17T12:00:03Z\""}
";
var bytes = Encoding.UTF8.GetBytes(ndjson);
var (metadata, hash) = DenoRuntimeTraceProbe.Analyze(bytes);
Assert.Equal(4, metadata.EventCount);
Assert.Equal(1, metadata.ModuleLoads);
Assert.Equal(1, metadata.PermissionUses);
Assert.Equal(1, metadata.NpmResolutions);
Assert.Equal(1, metadata.WasmLoads);
Assert.Equal(1, metadata.DynamicImports);
Assert.Equal(new[] { "https://deno.land" }, metadata.RemoteOrigins);
Assert.Equal(new[] { "fs", "net" }, metadata.UniquePermissions);
Assert.Equal("8f67e4b77f2ea4155d9101c5e6a45922e4ac1e19006955c3e6c2afe1938f0a8d", hash);
}
}

View File

@@ -127,6 +127,13 @@ public sealed class JavaLanguageAnalyzerTests
Assert.Equal("demo-framework.jar!META-INF/services/jakarta.ws.rs.ext.RuntimeDelegate", metadata.GetProperty("config.jaxrs").GetString());
Assert.Equal("demo-framework.jar!logback.xml", metadata.GetProperty("config.logging").GetString());
Assert.Equal("demo-framework.jar!META-INF/native-image/demo/reflect-config.json", metadata.GetProperty("config.graal").GetString());
var evidence = component.GetProperty("evidence").EnumerateArray().ToArray();
Assert.Contains(evidence, e =>
string.Equals(e.GetProperty("source").GetString(), "framework-config", StringComparison.OrdinalIgnoreCase) &&
string.Equals(e.GetProperty("locator").GetString(), "demo-framework.jar!META-INF/spring.factories", StringComparison.OrdinalIgnoreCase) &&
e.TryGetProperty("sha256", out var sha) &&
!string.IsNullOrWhiteSpace(sha.GetString()));
}
finally
{

View File

@@ -0,0 +1 @@
module.exports = {};

View File

@@ -0,0 +1,22 @@
[
{
"analyzerId": "node",
"componentKey": "purl::pkg:npm/yarn-pnp-demo@1.0.0",
"purl": "pkg:npm/yarn-pnp-demo@1.0.0",
"name": "yarn-pnp-demo",
"version": "1.0.0",
"type": "npm",
"usedByEntrypoint": false,
"metadata": {
"path": ".",
"yarnPnp": "true"
},
"evidence": [
{
"kind": "file",
"source": "package.json",
"locator": "package.json"
}
]
}
]

View File

@@ -0,0 +1,4 @@
{
"name": "yarn-pnp-demo",
"version": "1.0.0"
}

View File

@@ -62,4 +62,42 @@ public sealed class NodeLanguageAnalyzerTests
analyzers,
cancellationToken);
}
[Fact]
public async Task YarnPnpCachePackagesAreParsedAsync()
{
var cancellationToken = TestContext.Current.CancellationToken;
var fixturePath = TestPaths.ResolveFixture("lang", "node", "yarn-pnp");
var goldenPath = Path.Combine(fixturePath, "expected.json");
var analyzers = new ILanguageAnalyzer[]
{
new NodeLanguageAnalyzer()
};
await LanguageAnalyzerTestHarness.AssertDeterministicAsync(
fixturePath,
goldenPath,
analyzers,
cancellationToken);
}
[Fact]
public async Task YarnPnpFlagIsEmittedAsync()
{
var cancellationToken = TestContext.Current.CancellationToken;
var fixturePath = TestPaths.ResolveFixture("lang", "node", "yarn-pnp");
var goldenPath = Path.Combine(fixturePath, "expected.json");
var analyzers = new ILanguageAnalyzer[]
{
new NodeLanguageAnalyzer()
};
await LanguageAnalyzerTestHarness.AssertDeterministicAsync(
fixturePath,
goldenPath,
analyzers,
cancellationToken);
}
}

View File

@@ -65,6 +65,70 @@ public sealed class SurfaceEnvironmentBuilderTests
}
}
[Fact]
public void Build_Throws_WhenEndpointMissing_AndRequired()
{
var services = CreateServices();
var exception = Assert.Throws<SurfaceEnvironmentException>(() =>
SurfaceEnvironmentFactory.Create(services, options => options.RequireSurfaceEndpoint = true));
Assert.Equal("SURFACE_FS_ENDPOINT", exception.Variable);
}
[Fact]
public void Build_Throws_WhenEndpointInvalid()
{
Environment.SetEnvironmentVariable("SCANNER_SURFACE_FS_ENDPOINT", "not-a-uri");
try
{
var services = CreateServices();
var ex = Assert.Throws<SurfaceEnvironmentException>(() => SurfaceEnvironmentFactory.Create(services));
Assert.Equal("SURFACE_FS_ENDPOINT", ex.Variable);
}
finally
{
Environment.SetEnvironmentVariable("SCANNER_SURFACE_FS_ENDPOINT", null);
}
}
[Fact]
public void Build_Throws_WhenTlsCertificateMissing()
{
Environment.SetEnvironmentVariable("SCANNER_SURFACE_FS_ENDPOINT", "https://surface.example.test");
Environment.SetEnvironmentVariable("SCANNER_SURFACE_TLS_CERT_PATH", "/does/not/exist.pem");
try
{
var services = CreateServices();
var ex = Assert.Throws<SurfaceEnvironmentException>(() => SurfaceEnvironmentFactory.Create(services));
Assert.Equal("SURFACE_TLS_CERT_PATH", ex.Variable);
}
finally
{
Environment.SetEnvironmentVariable("SCANNER_SURFACE_TLS_CERT_PATH", null);
Environment.SetEnvironmentVariable("SCANNER_SURFACE_FS_ENDPOINT", null);
}
}
[Fact]
public void Build_UsesTenantResolver_WhenNotProvided()
{
Environment.SetEnvironmentVariable("SCANNER_SURFACE_FS_ENDPOINT", "https://surface.example.test");
try
{
var services = CreateServices();
var environment = SurfaceEnvironmentFactory.Create(services, options =>
{
options.TenantResolver = _ => "resolved-tenant";
});
Assert.Equal("resolved-tenant", environment.Settings.Tenant);
}
finally
{
Environment.SetEnvironmentVariable("SCANNER_SURFACE_FS_ENDPOINT", null);
}
}
private static IServiceProvider CreateServices(Action<IServiceCollection>? configure = null)
{
var services = new ServiceCollection();

View File

@@ -0,0 +1,54 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Security.Cryptography.X509Certificates;
using Microsoft.Extensions.Options;
using StellaOps.Scanner.Surface.Env;
using StellaOps.Scanner.Surface.FS;
using StellaOps.Scanner.WebService.Options;
using Xunit;
namespace StellaOps.Scanner.WebService.Tests;
public sealed class SurfaceManifestStoreOptionsConfiguratorTests
{
[Fact]
public void Configure_UsesSurfaceEnvironmentAndCacheRoot()
{
var cacheRoot = new DirectoryInfo(Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString("N")));
var settings = new SurfaceEnvironmentSettings(
new Uri("https://surface.example"),
"surface-bucket",
null,
cacheRoot,
1024,
false,
Array.Empty<string>(),
new SurfaceSecretsConfiguration("file", "tenant-a", "/etc/secrets", null, null, false),
"tenant-a",
new SurfaceTlsConfiguration(null, null, new X509Certificate2Collection()));
var environment = new StubSurfaceEnvironment(settings);
var cacheOptions = Options.Create(new SurfaceCacheOptions { RootDirectory = cacheRoot.FullName });
var configurator = new SurfaceManifestStoreOptionsConfigurator(environment, cacheOptions);
var options = new SurfaceManifestStoreOptions();
configurator.Configure(options);
Assert.Equal("https", options.Scheme);
Assert.Equal("surface-bucket", options.Bucket);
Assert.Equal(Path.Combine(cacheRoot.FullName, "manifests"), options.RootDirectory);
}
private sealed class StubSurfaceEnvironment : ISurfaceEnvironment
{
public StubSurfaceEnvironment(SurfaceEnvironmentSettings settings)
{
Settings = settings;
}
public SurfaceEnvironmentSettings Settings { get; }
public IReadOnlyDictionary<string, string> RawVariables { get; } = new Dictionary<string, string>();
}
}

View File

@@ -0,0 +1,54 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Security.Cryptography.X509Certificates;
using Microsoft.Extensions.Options;
using StellaOps.Scanner.Surface.Env;
using StellaOps.Scanner.Surface.FS;
using StellaOps.Scanner.Worker;
using Xunit;
namespace StellaOps.Scanner.Worker.Tests;
public sealed class SurfaceManifestStoreOptionsConfiguratorTests
{
[Fact]
public void Configure_UsesSurfaceEnvironmentEndpointAndBucket()
{
var cacheRoot = new DirectoryInfo(Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString("N")));
var settings = new SurfaceEnvironmentSettings(
new Uri("https://surface.example"),
"surface-bucket",
null,
cacheRoot,
1024,
false,
Array.Empty<string>(),
new SurfaceSecretsConfiguration("file", "tenant-a", "/etc/secrets", null, null, false),
"tenant-a",
new SurfaceTlsConfiguration(null, null, new X509Certificate2Collection()));
var environment = new StubSurfaceEnvironment(settings);
var cacheOptions = Options.Create(new SurfaceCacheOptions { RootDirectory = cacheRoot.FullName });
var configurator = new SurfaceManifestStoreOptionsConfigurator(environment, cacheOptions);
var options = new SurfaceManifestStoreOptions();
configurator.Configure(options);
Assert.Equal("https", options.Scheme);
Assert.Equal("surface-bucket", options.Bucket);
Assert.Equal(Path.Combine(cacheRoot.FullName, "manifests"), options.RootDirectory);
}
private sealed class StubSurfaceEnvironment : ISurfaceEnvironment
{
public StubSurfaceEnvironment(SurfaceEnvironmentSettings settings)
{
Settings = settings;
}
public SurfaceEnvironmentSettings Settings { get; }
public IReadOnlyDictionary<string, string> RawVariables { get; } = new Dictionary<string, string>();
}
}