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:
@@ -1,7 +1,7 @@
|
||||
using System.Buffers;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Immutable;
|
||||
using System.Linq;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
|
||||
namespace StellaOps.Scanner.Analyzers.Lang.Rust.Internal;
|
||||
@@ -32,6 +32,8 @@ internal static class RustBinaryClassifier
|
||||
AttributesToSkip = FileAttributes.Device | FileAttributes.ReparsePoint,
|
||||
};
|
||||
|
||||
private static readonly ConcurrentDictionary<RustFileCacheKey, ImmutableArray<string>> CandidateCache = new();
|
||||
|
||||
public static IReadOnlyList<RustBinaryInfo> Scan(string rootPath, CancellationToken cancellationToken)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(rootPath))
|
||||
@@ -49,7 +51,16 @@ internal static class RustBinaryClassifier
|
||||
continue;
|
||||
}
|
||||
|
||||
var candidates = ExtractCrateNames(path, cancellationToken);
|
||||
if (!RustFileCacheKey.TryCreate(path, out var key))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var candidates = CandidateCache.GetOrAdd(
|
||||
key,
|
||||
static (_, state) => ExtractCrateNames(state.Path, state.CancellationToken),
|
||||
(Path: path, CancellationToken: cancellationToken));
|
||||
|
||||
binaries.Add(new RustBinaryInfo(path, candidates));
|
||||
}
|
||||
|
||||
@@ -220,31 +231,13 @@ internal static class RustBinaryClassifier
|
||||
|
||||
internal sealed record RustBinaryInfo(string AbsolutePath, ImmutableArray<string> CrateCandidates)
|
||||
{
|
||||
private string? _sha256;
|
||||
|
||||
public string ComputeSha256()
|
||||
{
|
||||
if (_sha256 is not null)
|
||||
if (RustFileHashCache.TryGetSha256(AbsolutePath, out var sha256) && !string.IsNullOrEmpty(sha256))
|
||||
{
|
||||
return _sha256;
|
||||
return sha256;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
using var stream = new FileStream(AbsolutePath, FileMode.Open, FileAccess.Read, FileShare.Read);
|
||||
using var sha = SHA256.Create();
|
||||
var hash = sha.ComputeHash(stream);
|
||||
_sha256 = Convert.ToHexString(hash).ToLowerInvariant();
|
||||
}
|
||||
catch (IOException)
|
||||
{
|
||||
_sha256 = string.Empty;
|
||||
}
|
||||
catch (UnauthorizedAccessException)
|
||||
{
|
||||
_sha256 = string.Empty;
|
||||
}
|
||||
|
||||
return _sha256 ?? string.Empty;
|
||||
return string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user