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,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; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user