fix(transport): cap LineDiffer input size — oversized script diffs degrade to summary instead of O((N+M)^2) memory
Claude-Session: https://claude.ai/code/session_01MtdgwpEeCUn6cUA5f1LMPj
This commit is contained in:
@@ -1,3 +1,5 @@
|
||||
using System.Diagnostics;
|
||||
|
||||
using ZB.MOM.WW.ScadaBridge.Transport.Import;
|
||||
|
||||
namespace ZB.MOM.WW.ScadaBridge.Transport.Tests.Import;
|
||||
@@ -189,4 +191,29 @@ public sealed class LineDifferTests
|
||||
Assert.Equal(0, result.AddedCount);
|
||||
Assert.Equal(0, result.RemovedCount);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void OversizedInputs_ZeroCommonLines_DegradesToSummary_WithoutRunningMyers()
|
||||
{
|
||||
// Two 10,000-line inputs with zero common lines. Running the Myers trace here would
|
||||
// record ~20,000 V-snapshots of ~160 KB each (multi-GB transient allocation), so the
|
||||
// input-size guard must short-circuit to a summary-only result long before that.
|
||||
var oldText = string.Join("\n", Enumerable.Range(1, 10_000).Select(i => $"old-line-{i}"));
|
||||
var newText = string.Join("\n", Enumerable.Range(1, 10_000).Select(i => $"new-line-{i}"));
|
||||
|
||||
var sw = Stopwatch.StartNew();
|
||||
var result = LineDiffer.Diff(oldText, newText);
|
||||
sw.Stop();
|
||||
|
||||
// Summary-only shape: same as the output cap — Truncated, full totals, no hunks.
|
||||
Assert.True(result.Truncated);
|
||||
Assert.Empty(result.Lines);
|
||||
Assert.Equal(10_000, result.AddedCount);
|
||||
Assert.Equal(10_000, result.RemovedCount);
|
||||
|
||||
// Must return within a small time budget; pathological slowness is a failure.
|
||||
Assert.True(
|
||||
sw.Elapsed < TimeSpan.FromSeconds(2),
|
||||
$"Diff of oversized inputs took {sw.Elapsed.TotalSeconds:F1}s — the input-size guard did not short-circuit.");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user