fix(core-scripting): resolve Low code-review findings (Core.Scripting-005,006,008,009,011)
- Core.Scripting-005: DependencyExtractor.HandleTagCall now recognises raw-string literal paths by checking the StringLiteralExpression node kind instead of the legacy StringLiteralToken kind. - Core.Scripting-006: scope CompiledScriptCache failed-compile eviction with TryRemove(KeyValuePair) so a racing retry entry is not evicted. - Core.Scripting-008: document the per-publish assembly accretion as an accepted limitation in docs/VirtualTags.md. - Core.Scripting-009: enumerate the authoritative deny-list (namespace prefixes + type-granular denies) in the Phase 7 decision-#6 entry to match ForbiddenTypeAnalyzer. - Core.Scripting-011: pin ScriptSandbox.Build, ScriptContext.Deadband boundary semantics, and end-to-end factory + companion-sink integration. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -152,4 +152,47 @@ public sealed class ScriptLogCompanionSinkTests
|
||||
scriptLogger.ForContext(ScriptLoggerFactory.ScriptNameProperty, "X").Fatal("fatal");
|
||||
mainSink.Events.Count.ShouldBe(1);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Factory_plus_companion_sink_integration_surfaces_script_error_in_both_logs()
|
||||
{
|
||||
// End-to-end Core.Scripting-011 coverage: an Error-level emission from a logger
|
||||
// built by ScriptLoggerFactory must land in BOTH the per-script sink (acting as
|
||||
// the scripts-*.log substitute here) AND the main-log companion at Warning level,
|
||||
// tagged with the originating ScriptName property. This is the integration the
|
||||
// server's logger pipeline relies on so operators see script failures in the
|
||||
// primary log without monitoring the scripts file separately.
|
||||
var scriptsSink = new CapturingSink();
|
||||
var mainSink = new CapturingSink();
|
||||
|
||||
// Main pipeline — receives only Error+ events forwarded by the companion sink.
|
||||
var mainLogger = new LoggerConfiguration()
|
||||
.MinimumLevel.Verbose().WriteTo.Sink(mainSink).CreateLogger();
|
||||
|
||||
// Root script pipeline — fans out to the scripts sink (stand-in for the
|
||||
// rolling scripts-*.log file) AND the companion sink that forwards Error+
|
||||
// to the main logger.
|
||||
var rootScriptLogger = new LoggerConfiguration()
|
||||
.MinimumLevel.Verbose()
|
||||
.WriteTo.Sink(scriptsSink)
|
||||
.WriteTo.Sink(new ScriptLogCompanionSink(mainLogger))
|
||||
.CreateLogger();
|
||||
|
||||
// Factory binds the per-script ScriptName property — this is the only way the
|
||||
// mirror knows which script raised the event.
|
||||
var factory = new ScriptLoggerFactory(rootScriptLogger);
|
||||
var perScript = factory.Create("HighTemp");
|
||||
perScript.Error("threshold exceeded");
|
||||
|
||||
// Scripts sink saw the Error at its original level with the ScriptName bound.
|
||||
scriptsSink.Events.Count.ShouldBe(1);
|
||||
scriptsSink.Events[0].Level.ShouldBe(LogEventLevel.Error);
|
||||
((ScalarValue)scriptsSink.Events[0].Properties[ScriptLoggerFactory.ScriptNameProperty]).Value.ShouldBe("HighTemp");
|
||||
|
||||
// Main sink saw a Warning-level companion entry tagged with the same ScriptName.
|
||||
mainSink.Events.Count.ShouldBe(1);
|
||||
mainSink.Events[0].Level.ShouldBe(LogEventLevel.Warning);
|
||||
((ScalarValue)mainSink.Events[0].Properties[ScriptLoggerFactory.ScriptNameProperty]).Value.ShouldBe("HighTemp");
|
||||
((ScalarValue)mainSink.Events[0].Properties["OriginalLevel"]).Value.ShouldBe(LogEventLevel.Error);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user