Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 9 additions & 8 deletions Darling/Darling.Tests/PgTargetDeadlockDrillDownTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -118,8 +118,9 @@ public void TheDrillDown_AttachesOnEitherDeadlockRoot_ReusesTheRootFactCounter_A
[Fact]
public void AStoredFindingsExemplars_ReadBackNormalized_AndNameTheirReportByTimeAndPid()
{
const string rawStatement = "UPDATE accounts SET pin = '4721' WHERE card = 4111111111111111";
const string rawGraph = "Process 11 waits for ShareLock on transaction 900; blocked by process 12.\nProcess 12 waits for ShareLock on transaction 901; blocked by process 11.\nProcess 11: UPDATE accounts SET pin = '4721' WHERE card = 4111111111111111\nProcess 12: UPDATE accounts SET pin = '9034' WHERE card = 5500005555555559";
/* The planted literals are sentinels: their letters lie outside a-f, so a timestamp, an id or a hash can't contain them. */
const string rawStatement = "UPDATE accounts SET pin = 'qx4721' WHERE card = 4111111111111111";
const string rawGraph = "Process 11 waits for ShareLock on transaction 900; blocked by process 12.\nProcess 12 waits for ShareLock on transaction 901; blocked by process 11.\nProcess 11: UPDATE accounts SET pin = 'qx4721' WHERE card = 4111111111111111\nProcess 12: UPDATE accounts SET pin = 'qx9034' WHERE card = 5500005555555559";
var rawHash = PgDeadlockLogParser.HashOf(rawGraph);
var lastSeen = new DateTime(2026, 9, 1, 12, 30, 15, 250);
var sentence = $"Exemplars: 1 report captured. The most frequent 2-participant shape involves ShareLock on transaction with the victim `{rawStatement}`, seen 1 time.";
Expand Down Expand Up @@ -164,7 +165,7 @@ public void AStoredFindingsExemplars_ReadBackNormalized_AndNameTheirReportByTime

foreach (var text in new[] { once.Item1, finding.StoryText })
{
foreach (var secret in new[] { "4721", "9034", "4111111111111111", "5500005555555559", rawHash })
foreach (var secret in new[] { "qx4721", "qx9034", "4111111111111111", "5500005555555559", rawHash })
Assert.DoesNotContain(secret, text, StringComparison.Ordinal);
}

Expand Down Expand Up @@ -368,7 +369,7 @@ public async Task APlantedCounterDeltaBesideFourCapturedRows_CarriesTheExemplarD
const string resourcesA = "relation orders, tuple orders";
/* The later report of shape A as a build before #4005 stored it: a literal in the graph, and a hash
over that raw graph. The exemplar carries neither (#4005). */
var graphA = "Process 11 waits for ShareLock on transaction 900; blocked by process 12.\nProcess 12 waits for ShareLock on transaction 901; blocked by process 11.\nProcess 11: UPDATE orders SET status = $1 WHERE id = $2\nProcess 12: UPDATE orders SET status = 'held-4721' WHERE id = 7";
var graphA = "Process 11 waits for ShareLock on transaction 900; blocked by process 12.\nProcess 12 waits for ShareLock on transaction 901; blocked by process 11.\nProcess 11: UPDATE orders SET status = $1 WHERE id = $2\nProcess 12: UPDATE orders SET status = 'held-qx4721' WHERE id = 7";
var rawHashA2 = PgDeadlockLogParser.HashOf(graphA);
await PlantDeadlockAsync(connection, windowStart.AddMinutes(10), "hash-a1", 2, modesA, resourcesA, "UPDATE orders SET status = $1 WHERE id = $2", graphA, ct);
await PlantDeadlockAsync(connection, windowStart.AddMinutes(45), rawHashA2, 2, modesA, resourcesA, "UPDATE orders\n SET status = $1 WHERE id = $2", graphA, ct);
Expand Down Expand Up @@ -418,9 +419,9 @@ twice under ONE hash (the overlapping tail re-read). */
Assert.False(a.GetProperty("victim_statement_may_be_truncated").GetBoolean());
Assert.Equal(4, a.GetProperty("graph_text_lines_total").GetInt32());
Assert.False(a.GetProperty("graph_text_truncated").GetBoolean());
Assert.Equal(graphA.Replace("'held-4721' WHERE id = 7", "'?' WHERE id = ?", StringComparison.Ordinal), a.GetProperty("graph_text").GetString());
Assert.Equal(graphA.Replace("'held-qx4721' WHERE id = 7", "'?' WHERE id = ?", StringComparison.Ordinal), a.GetProperty("graph_text").GetString());
Assert.DoesNotContain(rawHashA2, analysis, StringComparison.Ordinal);
Assert.DoesNotContain("4721", analysis, StringComparison.Ordinal);
Assert.DoesNotContain("qx4721", analysis, StringComparison.Ordinal);

/* Shape B: one report seen twice; both bounds cut and both say so. */
var b = shapes[1];
Expand Down Expand Up @@ -457,7 +458,7 @@ same drill-down from the OTHER counter spelling and this read's own row total. *
/* #4005: a finding a build before #4005 stored (an anchored run like the one above persists nothing)
reads back through PgFindingStore, get_analysis_findings' read, normalized and naming its report by
timestamp and pid, never by the stored hash. */
var rawStatement = "UPDATE orders SET status = 'held-4721' WHERE id = 7";
var rawStatement = "UPDATE orders SET status = 'held-qx4721' WHERE id = 7";
var preFix = new AnalysisFinding
{
FindingId = CollectionIdGenerator.Next(),
Expand Down Expand Up @@ -497,7 +498,7 @@ same drill-down from the OTHER counter spelling and this read's own row total. *

var stored = await DarlingMcpTools.GetAnalysisFindings(service, postgres, ServerName, 24, include_drilldown: true);
Assert.Contains("4005-pre-fix-exemplar", stored, StringComparison.Ordinal);
Assert.DoesNotContain("4721", stored, StringComparison.Ordinal);
Assert.DoesNotContain("qx4721", stored, StringComparison.Ordinal);
Assert.DoesNotContain(rawHashA2, stored, StringComparison.Ordinal);
Assert.Contains(PgDeadlockLogParser.ReportIdentity(windowStart.AddMinutes(45), 4242), stored, StringComparison.Ordinal);

Expand Down
Loading