Add unit tests for RancherHubConnector and various exporters

- Implemented tests for RancherHubConnector to validate fetching documents, handling errors, and managing state.
- Added tests for CsafExporter to ensure deterministic serialization of CSAF documents.
- Created tests for CycloneDX exporters and reconciler to verify correct handling of VEX claims and output structure.
- Developed OpenVEX exporter tests to confirm the generation of canonical OpenVEX documents and statement merging logic.
- Introduced Rust file caching and license scanning functionality, including a cache key structure and hash computation.
- Added sample Cargo.toml and LICENSE files for testing Rust license scanning functionality.
This commit is contained in:
2025-10-30 07:52:39 +02:00
parent 7600caea63
commit 02e384a7d6
62 changed files with 3631 additions and 423 deletions

View File

@@ -1,3 +1,4 @@
using System.Collections.Concurrent;
using System.Text.Json;
namespace StellaOps.Scanner.Analyzers.Lang.Rust.Internal;
@@ -13,6 +14,7 @@ internal static class RustFingerprintScanner
};
private static readonly string FingerprintSegment = $"{Path.DirectorySeparatorChar}.fingerprint{Path.DirectorySeparatorChar}";
private static readonly ConcurrentDictionary<RustFileCacheKey, RustFingerprintRecord?> Cache = new();
public static IReadOnlyList<RustFingerprintRecord> Scan(string rootPath, CancellationToken cancellationToken)
{
@@ -31,7 +33,17 @@ internal static class RustFingerprintScanner
continue;
}
if (TryParse(path, out var record))
if (!RustFileCacheKey.TryCreate(path, out var key))
{
continue;
}
var record = Cache.GetOrAdd(
key,
static (_, state) => ParseFingerprint(state),
path);
if (record is not null)
{
results.Add(record);
}
@@ -40,10 +52,8 @@ internal static class RustFingerprintScanner
return results;
}
private static bool TryParse(string path, out RustFingerprintRecord record)
private static RustFingerprintRecord? ParseFingerprint(string path)
{
record = default!;
try
{
using var stream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read);
@@ -57,33 +67,31 @@ internal static class RustFingerprintScanner
var (name, version, source) = ParseIdentity(pkgId, path);
if (string.IsNullOrWhiteSpace(name))
{
return false;
return null;
}
var profile = TryGetString(root, "profile");
var targetKind = TryGetKind(root);
record = new RustFingerprintRecord(
return new RustFingerprintRecord(
Name: name!,
Version: version,
Source: source,
TargetKind: targetKind,
Profile: profile,
AbsolutePath: path);
return true;
}
catch (JsonException)
{
return false;
return null;
}
catch (IOException)
{
return false;
return null;
}
catch (UnauthorizedAccessException)
{
return false;
return null;
}
}