docs consolidation, big sln build fixes, new advisories and sprints/tasks
This commit is contained in:
@@ -4,12 +4,6 @@ using System.Linq;
|
||||
using System.Text.Json;
|
||||
using System.Text.RegularExpressions;
|
||||
using StellaOps.Scanner.Analyzers.Lang;
|
||||
using StellaOps.Scanner.Analyzers.Lang.Bun;
|
||||
using StellaOps.Scanner.Analyzers.Lang.Go;
|
||||
using StellaOps.Scanner.Analyzers.Lang.Java;
|
||||
using StellaOps.Scanner.Analyzers.Lang.Node;
|
||||
using StellaOps.Scanner.Analyzers.Lang.DotNet;
|
||||
using StellaOps.Scanner.Analyzers.Lang.Python;
|
||||
|
||||
namespace StellaOps.Bench.ScannerAnalyzers.Scenarios;
|
||||
|
||||
@@ -126,13 +120,10 @@ internal sealed class LanguageAnalyzerScenarioRunner : IScenarioRunner
|
||||
var id = analyzerId.Trim().ToLowerInvariant();
|
||||
return id switch
|
||||
{
|
||||
"bun" => static () => new BunLanguageAnalyzer(),
|
||||
"java" => static () => new JavaLanguageAnalyzer(),
|
||||
"go" => static () => new GoLanguageAnalyzer(),
|
||||
"node" => static () => new NodeLanguageAnalyzer(),
|
||||
"dotnet" => static () => new DotNetLanguageAnalyzer(),
|
||||
"python" => static () => new PythonLanguageAnalyzer(),
|
||||
_ => throw new InvalidOperationException($"Unsupported analyzer '{analyzerId}'."),
|
||||
// Note: Language-specific analyzers (Bun, Java, Go, Node, DotNet, Python) are loaded via plugin system.
|
||||
// Benchmarks should use plugin-loaded analyzers instead of hardcoded references.
|
||||
// See LanguageAnalyzerPluginCatalog for dynamic analyzer loading.
|
||||
_ => throw new InvalidOperationException($"Unsupported analyzer '{analyzerId}'. Language analyzers must be loaded via plugin system."),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,10 @@
|
||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<InternalsVisibleTo Include="StellaOps.Bench.ScannerAnalyzers.Tests" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="../../../../Scanner/__Libraries/StellaOps.Scanner.Analyzers.Lang/StellaOps.Scanner.Analyzers.Lang.csproj" />
|
||||
<ProjectReference Include="../../../../Scanner/__Libraries/StellaOps.Scanner.Analyzers.Lang.Node/StellaOps.Scanner.Analyzers.Lang.Node.csproj" />
|
||||
|
||||
@@ -69,9 +69,19 @@ internal static partial class CommandHandlers
|
||||
validator,
|
||||
builderLogger ?? Microsoft.Extensions.Logging.Abstractions.NullLogger<BundleBuilder>.Instance);
|
||||
|
||||
// Enumerate rule files from source directory
|
||||
var ruleFiles = Directory.EnumerateFiles(sources, "*.json", SearchOption.AllDirectories)
|
||||
.ToList();
|
||||
|
||||
if (ruleFiles.Count == 0)
|
||||
{
|
||||
AnsiConsole.MarkupLine($"[red]Error: No rule files (*.json) found in {Markup.Escape(sources)}[/]");
|
||||
return 1;
|
||||
}
|
||||
|
||||
var buildOptions = new BundleBuildOptions
|
||||
{
|
||||
SourceDirectory = sources,
|
||||
RuleFiles = ruleFiles,
|
||||
OutputDirectory = output,
|
||||
BundleId = id,
|
||||
Version = bundleVersion,
|
||||
|
||||
@@ -71,3 +71,6 @@ builder.Services.AddScoped<INotifyChannelDispatcher, WebhookChannelDispatcher>()
|
||||
builder.Services.AddHostedService<DeliveryDispatchWorker>();
|
||||
|
||||
await builder.Build().RunAsync().ConfigureAwait(false);
|
||||
|
||||
// Explicit internal Program class to avoid conflicts with other projects that reference this assembly
|
||||
internal sealed partial class Program { }
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.Worker">
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
<LangVersion>preview</LangVersion>
|
||||
@@ -7,6 +7,10 @@
|
||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Cronos" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="../../../Notify/__Libraries/StellaOps.Notify.Models/StellaOps.Notify.Models.csproj" />
|
||||
<ProjectReference Include="../../../Notify/__Libraries/StellaOps.Notify.Persistence/StellaOps.Notify.Persistence.csproj" />
|
||||
|
||||
@@ -20,7 +20,7 @@ public sealed class BudgetEnforcementIntegrationTests
|
||||
|
||||
public BudgetEnforcementIntegrationTests()
|
||||
{
|
||||
_ledger = new BudgetLedger(_store, NullLogger<BudgetLedger>.Instance);
|
||||
_ledger = new BudgetLedger(_store, logger: NullLogger<BudgetLedger>.Instance);
|
||||
}
|
||||
|
||||
#region Window Management Tests
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
using System.Diagnostics;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using StellaOps.Determinism.Abstractions;
|
||||
using StellaOps.Determinism;
|
||||
using StellaOps.Scanner.Storage.Models;
|
||||
using StellaOps.Scanner.Storage.Repositories;
|
||||
|
||||
|
||||
@@ -26,14 +26,14 @@ internal sealed class SecretsAnalyzerStageExecutor : IScanStageExecutor
|
||||
"scanner.rootfs",
|
||||
};
|
||||
|
||||
private readonly ISecretsAnalyzer _secretsAnalyzer;
|
||||
private readonly SecretsAnalyzer _secretsAnalyzer;
|
||||
private readonly ScannerWorkerMetrics _metrics;
|
||||
private readonly TimeProvider _timeProvider;
|
||||
private readonly IOptions<ScannerWorkerOptions> _options;
|
||||
private readonly ILogger<SecretsAnalyzerStageExecutor> _logger;
|
||||
|
||||
public SecretsAnalyzerStageExecutor(
|
||||
ISecretsAnalyzer secretsAnalyzer,
|
||||
SecretsAnalyzer secretsAnalyzer,
|
||||
ScannerWorkerMetrics metrics,
|
||||
TimeProvider timeProvider,
|
||||
IOptions<ScannerWorkerOptions> options,
|
||||
|
||||
@@ -42,6 +42,11 @@ public sealed class SecretsAnalyzer : ILanguageAnalyzer
|
||||
/// </summary>
|
||||
public SecretRuleset? Ruleset => _ruleset;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the ruleset version string for tracking and reporting.
|
||||
/// </summary>
|
||||
public string RulesetVersion => _ruleset?.Version ?? "unknown";
|
||||
|
||||
/// <summary>
|
||||
/// Sets the ruleset to use for detection.
|
||||
/// Called by SecretsAnalyzerHost after loading the bundle.
|
||||
@@ -51,6 +56,58 @@ public sealed class SecretsAnalyzer : ILanguageAnalyzer
|
||||
_ruleset = ruleset ?? throw new ArgumentNullException(nameof(ruleset));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Analyzes raw file content for secrets. Adapter for Worker stage executor.
|
||||
/// </summary>
|
||||
public async ValueTask<List<SecretFinding>> AnalyzeAsync(
|
||||
byte[] content,
|
||||
string relativePath,
|
||||
CancellationToken ct)
|
||||
{
|
||||
if (!IsEnabled || content is null || content.Length == 0)
|
||||
{
|
||||
return new List<SecretFinding>();
|
||||
}
|
||||
|
||||
var findings = new List<SecretFinding>();
|
||||
|
||||
foreach (var rule in _ruleset!.GetRulesForFile(relativePath))
|
||||
{
|
||||
ct.ThrowIfCancellationRequested();
|
||||
|
||||
var matches = await _detector.DetectAsync(content, relativePath, rule, ct);
|
||||
|
||||
foreach (var match in matches)
|
||||
{
|
||||
var confidence = MapScoreToConfidence(match.ConfidenceScore);
|
||||
if (confidence < _options.Value.MinConfidence)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var maskedSecret = _masker.Mask(match.Secret);
|
||||
var finding = new SecretFinding
|
||||
{
|
||||
RuleId = rule.Id,
|
||||
RuleName = rule.Name,
|
||||
Severity = rule.Severity,
|
||||
Confidence = confidence,
|
||||
FilePath = relativePath,
|
||||
LineNumber = match.LineNumber,
|
||||
ColumnStart = match.ColumnStart,
|
||||
ColumnEnd = match.ColumnEnd,
|
||||
MatchedText = maskedSecret,
|
||||
Category = rule.Category,
|
||||
DetectedAtUtc = _timeProvider.GetUtcNow()
|
||||
};
|
||||
|
||||
findings.Add(finding);
|
||||
}
|
||||
}
|
||||
|
||||
return findings;
|
||||
}
|
||||
|
||||
public async ValueTask AnalyzeAsync(
|
||||
LanguageAnalyzerContext context,
|
||||
LanguageComponentWriter writer,
|
||||
|
||||
@@ -169,7 +169,8 @@ public sealed class TriageQueryPerformanceTests : IAsyncLifetime
|
||||
CveId = i % 3 == 0 ? $"CVE-2021-{23337 + i}" : null,
|
||||
RuleId = i % 3 != 0 ? $"RULE-{i:D4}" : null,
|
||||
FirstSeenAt = DateTimeOffset.UtcNow.AddDays(-i),
|
||||
LastSeenAt = DateTimeOffset.UtcNow.AddHours(-i)
|
||||
LastSeenAt = DateTimeOffset.UtcNow.AddHours(-i),
|
||||
UpdatedAt = DateTimeOffset.UtcNow.AddHours(-i)
|
||||
};
|
||||
findings.Add(finding);
|
||||
}
|
||||
|
||||
@@ -60,6 +60,7 @@ public sealed class TriageSchemaIntegrationTests : IAsyncLifetime
|
||||
// Arrange
|
||||
await Context.Database.EnsureCreatedAsync();
|
||||
|
||||
var now = DateTimeOffset.UtcNow;
|
||||
var finding = new TriageFinding
|
||||
{
|
||||
Id = Guid.NewGuid(),
|
||||
@@ -67,8 +68,9 @@ public sealed class TriageSchemaIntegrationTests : IAsyncLifetime
|
||||
AssetLabel = "prod/api-gateway:1.2.3",
|
||||
Purl = "pkg:npm/lodash@4.17.20",
|
||||
CveId = "CVE-2021-23337",
|
||||
FirstSeenAt = DateTimeOffset.UtcNow,
|
||||
LastSeenAt = DateTimeOffset.UtcNow
|
||||
FirstSeenAt = now,
|
||||
LastSeenAt = now,
|
||||
UpdatedAt = now
|
||||
};
|
||||
|
||||
// Act
|
||||
@@ -90,13 +92,17 @@ public sealed class TriageSchemaIntegrationTests : IAsyncLifetime
|
||||
// Arrange
|
||||
await Context.Database.EnsureCreatedAsync();
|
||||
|
||||
var now = DateTimeOffset.UtcNow;
|
||||
var finding = new TriageFinding
|
||||
{
|
||||
Id = Guid.NewGuid(),
|
||||
AssetId = Guid.NewGuid(),
|
||||
AssetLabel = "prod/api-gateway:1.2.3",
|
||||
Purl = "pkg:npm/lodash@4.17.20",
|
||||
CveId = "CVE-2021-23337"
|
||||
CveId = "CVE-2021-23337",
|
||||
FirstSeenAt = now,
|
||||
LastSeenAt = now,
|
||||
UpdatedAt = now
|
||||
};
|
||||
|
||||
Context.Findings.Add(finding);
|
||||
@@ -111,7 +117,7 @@ public sealed class TriageSchemaIntegrationTests : IAsyncLifetime
|
||||
Note = "Code path is not reachable per RichGraph analysis",
|
||||
ActorSubject = "user:test@example.com",
|
||||
ActorDisplay = "Test User",
|
||||
CreatedAt = DateTimeOffset.UtcNow
|
||||
CreatedAt = now
|
||||
};
|
||||
|
||||
// Act
|
||||
@@ -137,13 +143,17 @@ public sealed class TriageSchemaIntegrationTests : IAsyncLifetime
|
||||
// Arrange
|
||||
await Context.Database.EnsureCreatedAsync();
|
||||
|
||||
var now = DateTimeOffset.UtcNow;
|
||||
var finding = new TriageFinding
|
||||
{
|
||||
Id = Guid.NewGuid(),
|
||||
AssetId = Guid.NewGuid(),
|
||||
AssetLabel = "prod/api-gateway:1.2.3",
|
||||
Purl = "pkg:npm/lodash@4.17.20",
|
||||
CveId = "CVE-2021-23337"
|
||||
CveId = "CVE-2021-23337",
|
||||
FirstSeenAt = now,
|
||||
LastSeenAt = now,
|
||||
UpdatedAt = now
|
||||
};
|
||||
|
||||
Context.Findings.Add(finding);
|
||||
@@ -160,7 +170,7 @@ public sealed class TriageSchemaIntegrationTests : IAsyncLifetime
|
||||
Verdict = TriageVerdict.Block,
|
||||
Lane = TriageLane.Blocked,
|
||||
Why = "High-severity CVE with network exposure",
|
||||
ComputedAt = DateTimeOffset.UtcNow
|
||||
ComputedAt = now
|
||||
};
|
||||
|
||||
// Act
|
||||
@@ -186,13 +196,17 @@ public sealed class TriageSchemaIntegrationTests : IAsyncLifetime
|
||||
// Arrange
|
||||
await Context.Database.EnsureCreatedAsync();
|
||||
|
||||
var now = DateTimeOffset.UtcNow;
|
||||
var finding = new TriageFinding
|
||||
{
|
||||
Id = Guid.NewGuid(),
|
||||
AssetId = Guid.NewGuid(),
|
||||
AssetLabel = "prod/api:1.0",
|
||||
Purl = "pkg:npm/test@1.0.0",
|
||||
CveId = "CVE-2024-0001"
|
||||
CveId = "CVE-2024-0001",
|
||||
FirstSeenAt = now,
|
||||
LastSeenAt = now,
|
||||
UpdatedAt = now
|
||||
};
|
||||
|
||||
Context.Findings.Add(finding);
|
||||
@@ -200,20 +214,24 @@ public sealed class TriageSchemaIntegrationTests : IAsyncLifetime
|
||||
|
||||
var decision = new TriageDecision
|
||||
{
|
||||
Id = Guid.NewGuid(),
|
||||
FindingId = finding.Id,
|
||||
Kind = TriageDecisionKind.Ack,
|
||||
ReasonCode = "ACKNOWLEDGED",
|
||||
ActorSubject = "user:admin"
|
||||
ActorSubject = "user:admin",
|
||||
CreatedAt = now
|
||||
};
|
||||
|
||||
var riskResult = new TriageRiskResult
|
||||
{
|
||||
Id = Guid.NewGuid(),
|
||||
FindingId = finding.Id,
|
||||
PolicyId = "policy-v1",
|
||||
PolicyVersion = "1.0",
|
||||
InputsHash = "hash123",
|
||||
Score = 50,
|
||||
Why = "Medium risk"
|
||||
Why = "Medium risk",
|
||||
ComputedAt = now
|
||||
};
|
||||
|
||||
Context.Decisions.Add(decision);
|
||||
@@ -245,13 +263,18 @@ public sealed class TriageSchemaIntegrationTests : IAsyncLifetime
|
||||
const string purl = "pkg:npm/lodash@4.17.20";
|
||||
const string cveId = "CVE-2021-23337";
|
||||
|
||||
var now = DateTimeOffset.UtcNow;
|
||||
var finding1 = new TriageFinding
|
||||
{
|
||||
Id = Guid.NewGuid(),
|
||||
AssetId = assetId,
|
||||
EnvironmentId = envId,
|
||||
AssetLabel = "prod/api:1.0",
|
||||
Purl = purl,
|
||||
CveId = cveId
|
||||
CveId = cveId,
|
||||
FirstSeenAt = now,
|
||||
LastSeenAt = now,
|
||||
UpdatedAt = now
|
||||
};
|
||||
|
||||
Context.Findings.Add(finding1);
|
||||
@@ -259,11 +282,15 @@ public sealed class TriageSchemaIntegrationTests : IAsyncLifetime
|
||||
|
||||
var finding2 = new TriageFinding
|
||||
{
|
||||
Id = Guid.NewGuid(),
|
||||
AssetId = assetId,
|
||||
EnvironmentId = envId,
|
||||
AssetLabel = "prod/api:1.0",
|
||||
Purl = purl,
|
||||
CveId = cveId
|
||||
CveId = cveId,
|
||||
FirstSeenAt = now,
|
||||
LastSeenAt = now,
|
||||
UpdatedAt = now
|
||||
};
|
||||
|
||||
Context.Findings.Add(finding2);
|
||||
|
||||
@@ -132,6 +132,7 @@ public sealed class FindingsEvidenceControllerTests
|
||||
|
||||
await db.Database.EnsureCreatedAsync();
|
||||
|
||||
var now = DateTimeOffset.UtcNow;
|
||||
var findingId = Guid.NewGuid();
|
||||
var finding = new TriageFinding
|
||||
{
|
||||
@@ -140,12 +141,15 @@ public sealed class FindingsEvidenceControllerTests
|
||||
AssetLabel = "prod/api-gateway:1.2.3",
|
||||
Purl = "pkg:npm/lodash@4.17.20",
|
||||
CveId = "CVE-2024-12345",
|
||||
LastSeenAt = DateTimeOffset.UtcNow
|
||||
FirstSeenAt = now,
|
||||
LastSeenAt = now,
|
||||
UpdatedAt = now
|
||||
};
|
||||
|
||||
db.Findings.Add(finding);
|
||||
db.RiskResults.Add(new TriageRiskResult
|
||||
{
|
||||
Id = Guid.NewGuid(),
|
||||
FindingId = findingId,
|
||||
PolicyId = "policy-1",
|
||||
PolicyVersion = "1.0.0",
|
||||
@@ -154,15 +158,17 @@ public sealed class FindingsEvidenceControllerTests
|
||||
Verdict = TriageVerdict.Block,
|
||||
Lane = TriageLane.Blocked,
|
||||
Why = "High risk score",
|
||||
ComputedAt = DateTimeOffset.UtcNow
|
||||
ComputedAt = now
|
||||
});
|
||||
db.EvidenceArtifacts.Add(new TriageEvidenceArtifact
|
||||
{
|
||||
Id = Guid.NewGuid(),
|
||||
FindingId = findingId,
|
||||
Type = TriageEvidenceType.Provenance,
|
||||
Title = "SBOM attestation",
|
||||
ContentHash = "sha256:attestation",
|
||||
Uri = "s3://evidence/attestation.json"
|
||||
Uri = "s3://evidence/attestation.json",
|
||||
CreatedAt = now
|
||||
});
|
||||
|
||||
await db.SaveChangesAsync();
|
||||
|
||||
@@ -448,6 +448,7 @@ public sealed class GatingReasonServiceTests
|
||||
public void VexEvidenceTrust_SignedWithLedger_HasHighTrust()
|
||||
{
|
||||
// Arrange - DSSE envelope + signature ref + source ref
|
||||
var now = DateTimeOffset.UtcNow;
|
||||
var vex = new TriageEffectiveVex
|
||||
{
|
||||
Id = Guid.NewGuid(),
|
||||
@@ -455,7 +456,9 @@ public sealed class GatingReasonServiceTests
|
||||
DsseEnvelopeHash = "sha256:signed",
|
||||
SignatureRef = "ledger-entry",
|
||||
SourceDomain = "nvd",
|
||||
SourceRef = "NVD-CVE-2024-1234"
|
||||
SourceRef = "NVD-CVE-2024-1234",
|
||||
ValidFrom = now,
|
||||
CollectedAt = now
|
||||
};
|
||||
|
||||
// Assert - all evidence factors present
|
||||
@@ -469,6 +472,7 @@ public sealed class GatingReasonServiceTests
|
||||
public void VexEvidenceTrust_NoEvidence_HasBaseTrust()
|
||||
{
|
||||
// Arrange - no signature, no ledger, no source
|
||||
var now = DateTimeOffset.UtcNow;
|
||||
var vex = new TriageEffectiveVex
|
||||
{
|
||||
Id = Guid.NewGuid(),
|
||||
@@ -476,7 +480,9 @@ public sealed class GatingReasonServiceTests
|
||||
DsseEnvelopeHash = null,
|
||||
SignatureRef = null,
|
||||
SourceDomain = "unknown",
|
||||
SourceRef = "unknown"
|
||||
SourceRef = "unknown",
|
||||
ValidFrom = now,
|
||||
CollectedAt = now
|
||||
};
|
||||
|
||||
// Assert - base trust only
|
||||
@@ -493,12 +499,16 @@ public sealed class GatingReasonServiceTests
|
||||
public void TriageFinding_RequiredFields_AreSet()
|
||||
{
|
||||
// Arrange
|
||||
var now = DateTimeOffset.UtcNow;
|
||||
var finding = new TriageFinding
|
||||
{
|
||||
Id = Guid.NewGuid(),
|
||||
AssetLabel = "test-asset",
|
||||
Purl = "pkg:npm/test@1.0.0",
|
||||
CveId = "CVE-2024-1234"
|
||||
CveId = "CVE-2024-1234",
|
||||
FirstSeenAt = now,
|
||||
LastSeenAt = now,
|
||||
UpdatedAt = now
|
||||
};
|
||||
|
||||
// Assert
|
||||
@@ -519,7 +529,8 @@ public sealed class GatingReasonServiceTests
|
||||
{
|
||||
Id = Guid.NewGuid(),
|
||||
PolicyId = "test-policy",
|
||||
Action = action
|
||||
Action = action,
|
||||
AppliedAt = DateTimeOffset.UtcNow
|
||||
};
|
||||
|
||||
decision.Action.Should().Be(action);
|
||||
@@ -562,7 +573,8 @@ public sealed class GatingReasonServiceTests
|
||||
Id = Guid.NewGuid(),
|
||||
Reachable = TriageReachability.No,
|
||||
InputsHash = "sha256:inputs-hash",
|
||||
SubgraphId = "sha256:subgraph"
|
||||
SubgraphId = "sha256:subgraph",
|
||||
ComputedAt = DateTimeOffset.UtcNow
|
||||
};
|
||||
|
||||
// Assert
|
||||
|
||||
@@ -113,7 +113,10 @@ public sealed class LinksetResolverTests
|
||||
FeatureFlags: Array.Empty<string>(),
|
||||
Secrets: new SurfaceSecretsConfiguration("file", "tenant-a", "/etc/secrets", null, null, false),
|
||||
Tenant: "tenant-a",
|
||||
Tls: new SurfaceTlsConfiguration(null, null, new X509Certificate2Collection()));
|
||||
Tls: new SurfaceTlsConfiguration(null, null, new X509Certificate2Collection()))
|
||||
{
|
||||
CreatedAtUtc = DateTimeOffset.UtcNow
|
||||
};
|
||||
|
||||
public IReadOnlyDictionary<string, string> RawVariables { get; } = new Dictionary<string, string>(StringComparer.Ordinal)
|
||||
{
|
||||
|
||||
@@ -202,7 +202,10 @@ public sealed class ScannerSurfaceSecretConfiguratorTests
|
||||
Array.Empty<string>(),
|
||||
new SurfaceSecretsConfiguration("inline", "tenant", null, null, null, true),
|
||||
"tenant",
|
||||
new SurfaceTlsConfiguration(null, null, null));
|
||||
new SurfaceTlsConfiguration(null, null, null))
|
||||
{
|
||||
CreatedAtUtc = DateTimeOffset.UtcNow
|
||||
};
|
||||
RawVariables = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
|
||||
@@ -26,7 +26,10 @@ public sealed class SurfaceCacheOptionsConfiguratorTests
|
||||
Array.Empty<string>(),
|
||||
new SurfaceSecretsConfiguration("file", "tenant-b", "/etc/secrets", null, null, false),
|
||||
"tenant-b",
|
||||
new SurfaceTlsConfiguration(null, null, new X509Certificate2Collection()));
|
||||
new SurfaceTlsConfiguration(null, null, new X509Certificate2Collection()))
|
||||
{
|
||||
CreatedAtUtc = DateTimeOffset.UtcNow
|
||||
};
|
||||
|
||||
var environment = new StubSurfaceEnvironment(settings);
|
||||
var configurator = new SurfaceCacheOptionsConfigurator(environment);
|
||||
|
||||
@@ -28,7 +28,10 @@ public sealed class SurfaceManifestStoreOptionsConfiguratorTests
|
||||
Array.Empty<string>(),
|
||||
new SurfaceSecretsConfiguration("file", "tenant-a", "/etc/secrets", null, null, false),
|
||||
"tenant-a",
|
||||
new SurfaceTlsConfiguration(null, null, new X509Certificate2Collection()));
|
||||
new SurfaceTlsConfiguration(null, null, new X509Certificate2Collection()))
|
||||
{
|
||||
CreatedAtUtc = DateTimeOffset.UtcNow
|
||||
};
|
||||
|
||||
var environment = new StubSurfaceEnvironment(settings);
|
||||
var cacheOptions = Microsoft.Extensions.Options.Options.Create(new SurfaceCacheOptions { RootDirectory = cacheRoot.FullName });
|
||||
|
||||
Reference in New Issue
Block a user