Restructure solution layout by module

This commit is contained in:
master
2025-10-28 15:10:40 +02:00
parent 95daa159c4
commit d870da18ce
4103 changed files with 192899 additions and 187024 deletions

View File

@@ -0,0 +1,102 @@
using System.IO.Compression;
using System.Threading;
using StellaOps.Scanner.Analyzers.Lang.Java.Internal;
using StellaOps.Scanner.Analyzers.Lang.Java.Internal.ClassPath;
using StellaOps.Scanner.Analyzers.Lang.Java.Internal.Reflection;
using StellaOps.Scanner.Analyzers.Lang.Tests.TestUtilities;
namespace StellaOps.Scanner.Analyzers.Lang.Java.Tests;
public sealed class JavaReflectionAnalyzerTests
{
[Fact]
public void Analyze_ClassForNameLiteral_ProducesEdge()
{
var root = TestPaths.CreateTemporaryDirectory();
try
{
var jarPath = Path.Combine(root, "libs", "reflect.jar");
Directory.CreateDirectory(Path.GetDirectoryName(jarPath)!);
using (var archive = new ZipArchive(new FileStream(jarPath, FileMode.Create, FileAccess.ReadWrite, FileShare.None), ZipArchiveMode.Create, leaveOpen: false))
{
var entry = archive.CreateEntry("com/example/Reflective.class");
var bytes = JavaClassFileFactory.CreateClassForNameInvoker("com/example/Reflective", "com.example.Plugin");
using var stream = entry.Open();
stream.Write(bytes);
}
var cancellationToken = TestContext.Current.CancellationToken;
var context = new LanguageAnalyzerContext(root, TimeProvider.System);
var workspace = JavaWorkspaceNormalizer.Normalize(context, cancellationToken);
var classPath = JavaClassPathBuilder.Build(workspace, cancellationToken);
var analysis = JavaReflectionAnalyzer.Analyze(classPath, cancellationToken);
var edge = Assert.Single(analysis.Edges);
Assert.Equal("com.example.Reflective", edge.SourceClass);
Assert.Equal("com.example.Plugin", edge.TargetType);
Assert.Equal(JavaReflectionReason.ClassForName, edge.Reason);
Assert.Equal(JavaReflectionConfidence.High, edge.Confidence);
}
finally
{
TestPaths.SafeDelete(root);
}
}
[Fact]
public void Analyze_TcclUsage_ProducesWarning()
{
var root = TestPaths.CreateTemporaryDirectory();
try
{
var jarPath = Path.Combine(root, "libs", "tccl.jar");
Directory.CreateDirectory(Path.GetDirectoryName(jarPath)!);
using (var archive = new ZipArchive(new FileStream(jarPath, FileMode.Create, FileAccess.ReadWrite, FileShare.None), ZipArchiveMode.Create, leaveOpen: false))
{
var entry = archive.CreateEntry("com/example/Tccl.class");
var bytes = JavaClassFileFactory.CreateTcclChecker("com/example/Tccl");
using var stream = entry.Open();
stream.Write(bytes);
}
var cancellationToken = TestContext.Current.CancellationToken;
var context = new LanguageAnalyzerContext(root, TimeProvider.System);
var workspace = JavaWorkspaceNormalizer.Normalize(context, cancellationToken);
var classPath = JavaClassPathBuilder.Build(workspace, cancellationToken);
var analysis = JavaReflectionAnalyzer.Analyze(classPath, cancellationToken);
Assert.Empty(analysis.Edges);
var warning = Assert.Single(analysis.Warnings);
Assert.Equal("tccl", warning.WarningCode);
Assert.Equal("com.example.Tccl", warning.SourceClass);
}
finally
{
TestPaths.SafeDelete(root);
}
}
[Fact]
public void Analyze_SpringBootFatJar_ScansEmbeddedAndBootSegments()
{
var root = TestPaths.CreateTemporaryDirectory();
try
{
JavaFixtureBuilder.CreateSpringBootFatJar(root, "apps/app-fat.jar");
var cancellationToken = TestContext.Current.CancellationToken;
var context = new LanguageAnalyzerContext(root, TimeProvider.System);
var workspace = JavaWorkspaceNormalizer.Normalize(context, cancellationToken);
var classPath = JavaClassPathBuilder.Build(workspace, cancellationToken);
var analysis = JavaReflectionAnalyzer.Analyze(classPath, cancellationToken);
// Expect at least one edge originating from BOOT-INF classes
Assert.Contains(analysis.Edges, edge => edge.SourceClass == "com.example.App" && edge.Reason == JavaReflectionReason.ClassForName);
Assert.Contains(analysis.Edges, edge => edge.SourceClass == "com.example.Lib" && edge.Reason == JavaReflectionReason.ClassForName);
}
finally
{
TestPaths.SafeDelete(root);
}
}
}