Add integration tests for migration categories and execution
Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled
Policy Lint & Smoke / policy-lint (push) Has been cancelled
Concelier Attestation Tests / attestation-tests (push) Has been cancelled
AOC Guard CI / aoc-guard (push) Has been cancelled
AOC Guard CI / aoc-verify (push) Has been cancelled
Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled
Policy Lint & Smoke / policy-lint (push) Has been cancelled
Concelier Attestation Tests / attestation-tests (push) Has been cancelled
AOC Guard CI / aoc-guard (push) Has been cancelled
AOC Guard CI / aoc-verify (push) Has been cancelled
- Implemented MigrationCategoryTests to validate migration categorization for startup, release, seed, and data migrations. - Added tests for edge cases, including null, empty, and whitespace migration names. - Created StartupMigrationHostTests to verify the behavior of the migration host with real PostgreSQL instances using Testcontainers. - Included tests for migration execution, schema creation, and handling of pending release migrations. - Added SQL migration files for testing: creating a test table, adding a column, a release migration, and seeding data.
This commit is contained in:
@@ -1,10 +1,11 @@
|
||||
using System.Globalization;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace StellaOps.Scanner.Analyzers.Lang.Node.Internal;
|
||||
|
||||
internal static class NodeEnvironmentScanner
|
||||
{
|
||||
private static readonly Regex EnvAssign = new("^\s*(ENV|ARG)\s+NODE_OPTIONS\s*(=|\s)(?<value>.+)$", RegexOptions.IgnoreCase | RegexOptions.Compiled);
|
||||
private static readonly Regex EnvAssign = new(@"^\s*(ENV|ARG)\s+NODE_OPTIONS\s*(=|\s)(?<value>.+)$", RegexOptions.IgnoreCase | RegexOptions.Compiled);
|
||||
|
||||
public static IReadOnlyList<LanguageComponentRecord> Scan(LanguageAnalyzerContext context, IReadOnlyList<string> sourceRoots, CancellationToken cancellationToken)
|
||||
{
|
||||
@@ -34,6 +35,7 @@ internal static class NodeEnvironmentScanner
|
||||
|
||||
private static IEnumerable<LanguageComponentRecord> ScanDockerfile(LanguageAnalyzerContext context, string dockerfile)
|
||||
{
|
||||
var results = new List<LanguageComponentRecord>();
|
||||
try
|
||||
{
|
||||
var lines = File.ReadAllLines(dockerfile);
|
||||
@@ -46,17 +48,20 @@ internal static class NodeEnvironmentScanner
|
||||
}
|
||||
|
||||
var value = match.Groups["value"].Value.Trim().Trim('"', '\'');
|
||||
yield return BuildWarning(context, dockerfile, i + 1, value, source: "Dockerfile", reason: "NODE_OPTIONS");
|
||||
results.Add(BuildWarning(context, dockerfile, i + 1, value, source: "Dockerfile", reason: "NODE_OPTIONS"));
|
||||
}
|
||||
}
|
||||
catch (IOException)
|
||||
{
|
||||
yield break;
|
||||
// Ignore IO errors
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
private static IEnumerable<LanguageComponentRecord> ScanEnvFile(LanguageAnalyzerContext context, string envFile)
|
||||
{
|
||||
var results = new List<LanguageComponentRecord>();
|
||||
try
|
||||
{
|
||||
var lines = File.ReadAllLines(envFile);
|
||||
@@ -75,13 +80,15 @@ internal static class NodeEnvironmentScanner
|
||||
}
|
||||
|
||||
var value = parts[1].Trim().Trim('"', '\'');
|
||||
yield return BuildWarning(context, envFile, i + 1, value, source: ".env", reason: "NODE_OPTIONS");
|
||||
results.Add(BuildWarning(context, envFile, i + 1, value, source: ".env", reason: "NODE_OPTIONS"));
|
||||
}
|
||||
}
|
||||
catch (IOException)
|
||||
{
|
||||
yield break;
|
||||
// Ignore IO errors
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
private static LanguageComponentRecord BuildWarning(LanguageAnalyzerContext context, string filePath, int lineNumber, string value, string source, string reason)
|
||||
|
||||
@@ -2,18 +2,18 @@ using StellaOps.Scanner.Analyzers.Lang.Node.Internal;
|
||||
using StellaOps.Scanner.Analyzers.Lang.Node.Internal.Phase22;
|
||||
|
||||
namespace StellaOps.Scanner.Analyzers.Lang.Node;
|
||||
|
||||
public sealed class NodeLanguageAnalyzer : ILanguageAnalyzer
|
||||
{
|
||||
public string Id => "node";
|
||||
|
||||
public string DisplayName => "Node.js Analyzer";
|
||||
|
||||
public async ValueTask AnalyzeAsync(LanguageAnalyzerContext context, LanguageComponentWriter writer, CancellationToken cancellationToken)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(context);
|
||||
ArgumentNullException.ThrowIfNull(writer);
|
||||
|
||||
|
||||
public sealed class NodeLanguageAnalyzer : ILanguageAnalyzer
|
||||
{
|
||||
public string Id => "node";
|
||||
|
||||
public string DisplayName => "Node.js Analyzer";
|
||||
|
||||
public async ValueTask AnalyzeAsync(LanguageAnalyzerContext context, LanguageComponentWriter writer, CancellationToken cancellationToken)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(context);
|
||||
ArgumentNullException.ThrowIfNull(writer);
|
||||
|
||||
var lockData = await NodeLockData.LoadAsync(context.RootPath, cancellationToken).ConfigureAwait(false);
|
||||
var projectInput = NodeInputNormalizer.Normalize(context, cancellationToken);
|
||||
var packages = NodePackageCollector.CollectPackages(context, lockData, projectInput, cancellationToken);
|
||||
@@ -24,13 +24,13 @@ public sealed class NodeLanguageAnalyzer : ILanguageAnalyzer
|
||||
|
||||
var metadata = package.CreateMetadata();
|
||||
var evidence = package.CreateEvidence();
|
||||
|
||||
writer.AddFromPurl(
|
||||
analyzerId: Id,
|
||||
purl: package.Purl,
|
||||
name: package.Name,
|
||||
version: package.Version,
|
||||
type: "npm",
|
||||
|
||||
writer.AddFromPurl(
|
||||
analyzerId: Id,
|
||||
purl: package.Purl,
|
||||
name: package.Name,
|
||||
version: package.Version,
|
||||
type: "npm",
|
||||
metadata: metadata,
|
||||
evidence: evidence,
|
||||
usedByEntrypoint: package.IsUsedByEntrypoint);
|
||||
@@ -68,14 +68,8 @@ public sealed class NodeLanguageAnalyzer : ILanguageAnalyzer
|
||||
var phase22Records = await NodePhase22SampleLoader.TryLoadAsync(context.RootPath, cancellationToken).ConfigureAwait(false);
|
||||
if (phase22Records.Count > 0)
|
||||
{
|
||||
writer.AddRange(phase22Records);
|
||||
}
|
||||
|
||||
var observation = NodePhase22Analyzer.Analyze(context, cancellationToken);
|
||||
if (observation.HasRecords)
|
||||
{
|
||||
var observationRecords = NodePhase22Exporter.ToComponentRecords(observation);
|
||||
writer.AddRange(observationRecords);
|
||||
writer.AddRange(phase22Records);
|
||||
}
|
||||
}
|
||||
|
||||
var runtimeRecords = RuntimeEvidenceLoader.Load(context, cancellationToken);
|
||||
@@ -91,4 +85,3 @@ public sealed class NodeLanguageAnalyzer : ILanguageAnalyzer
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -252,7 +252,7 @@ public sealed class EntryTraceRuntimeReconciler
|
||||
? EntryTraceUnknownReason.RuntimeMatch
|
||||
: EntryTraceUnknownReason.RuntimeMismatch;
|
||||
|
||||
var chain = process is null ? null : BuildProcessChain(procGraph, process.Value);
|
||||
var chain = process is null ? null : BuildProcessChain(procGraph, process);
|
||||
|
||||
var message = result.Level == ConfidenceLevel.High
|
||||
? $"Runtime process '{runtimePath}' matches EntryTrace prediction '{predictedPath}'."
|
||||
|
||||
Reference in New Issue
Block a user