From 6d1e3952bedc59346ddd05befd54d8c2d9d36cd0 Mon Sep 17 00:00:00 2001 From: Ruben Fiszel Date: Thu, 22 Oct 2026 20:11:01 -0700 Subject: [PATCH] settle async diff tallies in workspace comparison tests (#11963) test_compare_secret_variables_by_value planted workspace_diff rows with a plain INSERT after a DELETE, but the variable creates tally those rows from a spawned git-sync task that can land between the two, failing with a workspace_diff_pkey violation. Upsert the plant instead. test_rename_records_the_vacated_path could read the inline create's `write` event, or have it overwrite `rename_from`, since both deploys tally from their own spawned task. Wait for the create's tally before the rename and poll for the event that replaces it. Co-authored-by: Claude Opus 5.5 --- ...d3b4382f863d7c84f18af64e1d3930890a210.json | 20 +++++++++++++ ...28d5c5aac9608e8f60e5b76be177e4e105b1.json} | 4 +-- ...bef3389884cdde284ed3eb3b8d6979761b98.json} | 4 +-- .../tests/workspace_comparison.rs | 28 +++++++++++++++++-- 4 files changed, 50 insertions(+), 6 deletions(-) create mode 100644 backend/.sqlx/query-420707b82c44c7a30719c4419bdd3b4382f863d7c84f18af64e1d3930890a210.json rename backend/.sqlx/{query-e57039a483e96afa69f96e36be7666e83c6ccdea5087eb194d1de17086c58952.json => query-6d856cdf841aa6fb95d82841da3b28d5c5aac9608e8f60e5b76be177e4e105b1.json} (65%) rename backend/.sqlx/{query-f0d8ebbf62a1d92f39c2f86a70236cece6d6c9e28cce9aff7fe5496bba569807.json => query-df8f616f7ace1d45cb9022d70e53bef3389884cdde284ed3eb3b8d6979761b98.json} (81%) diff --git a/backend/.sqlx/query-420707b82c44c7a30719c4419bdd3b4382f863d7c84f18af64e1d3930890a210.json b/backend/.sqlx/query-420707b82c44c7a30719c4419bdd3b4382f863d7c84f18af64e1d3930890a210.json new file mode 100644 index 0000000000..2b0a574473 --- /dev/null +++ b/backend/.sqlx/query-420707b82c44c7a30719c4419bdd3b4382f863d7c84f18af64e1d3930890a210.json @@ -0,0 +1,20 @@ +{ + "db_name": "PostgreSQL", + "query": "SELECT EXISTS (SELECT 1 FROM workspace_diff\n WHERE fork_workspace_id = 'wm-fork-renamed' AND kind = 'script'\n AND path = 'u/admin/inline' AND fork_last_event_kind = 'write')", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "exists", + "type_info": "Bool" + } + ], + "parameters": { + "Left": [] + }, + "nullable": [ + null + ] + }, + "hash": "420707b82c44c7a30719c4419bdd3b4382f863d7c84f18af64e1d3930890a210" +} diff --git a/backend/.sqlx/query-e57039a483e96afa69f96e36be7666e83c6ccdea5087eb194d1de17086c58952.json b/backend/.sqlx/query-6d856cdf841aa6fb95d82841da3b28d5c5aac9608e8f60e5b76be177e4e105b1.json similarity index 65% rename from backend/.sqlx/query-e57039a483e96afa69f96e36be7666e83c6ccdea5087eb194d1de17086c58952.json rename to backend/.sqlx/query-6d856cdf841aa6fb95d82841da3b28d5c5aac9608e8f60e5b76be177e4e105b1.json index c9507b7f22..8cfd36abd6 100644 --- a/backend/.sqlx/query-e57039a483e96afa69f96e36be7666e83c6ccdea5087eb194d1de17086c58952.json +++ b/backend/.sqlx/query-6d856cdf841aa6fb95d82841da3b28d5c5aac9608e8f60e5b76be177e4e105b1.json @@ -1,6 +1,6 @@ { "db_name": "PostgreSQL", - "query": "INSERT INTO workspace_diff\n (source_workspace_id, fork_workspace_id, path, kind, ahead, behind, has_changes)\n VALUES\n ('test-workspace', 'wm-fork-secrets', 'u/test-user/same', 'variable', 1, 1, NULL),\n ('test-workspace', 'wm-fork-secrets', 'u/test-user/different', 'variable', 1, 1, NULL)", + "query": "INSERT INTO workspace_diff\n (source_workspace_id, fork_workspace_id, path, kind, ahead, behind, has_changes)\n VALUES\n ('test-workspace', 'wm-fork-secrets', 'u/test-user/same', 'variable', 1, 1, NULL),\n ('test-workspace', 'wm-fork-secrets', 'u/test-user/different', 'variable', 1, 1, NULL)\n ON CONFLICT (source_workspace_id, fork_workspace_id, path, kind)\n DO UPDATE SET ahead = 1, behind = 1, has_changes = NULL", "describe": { "columns": [], "parameters": { @@ -8,5 +8,5 @@ }, "nullable": [] }, - "hash": "e57039a483e96afa69f96e36be7666e83c6ccdea5087eb194d1de17086c58952" + "hash": "6d856cdf841aa6fb95d82841da3b28d5c5aac9608e8f60e5b76be177e4e105b1" } diff --git a/backend/.sqlx/query-f0d8ebbf62a1d92f39c2f86a70236cece6d6c9e28cce9aff7fe5496bba569807.json b/backend/.sqlx/query-df8f616f7ace1d45cb9022d70e53bef3389884cdde284ed3eb3b8d6979761b98.json similarity index 81% rename from backend/.sqlx/query-f0d8ebbf62a1d92f39c2f86a70236cece6d6c9e28cce9aff7fe5496bba569807.json rename to backend/.sqlx/query-df8f616f7ace1d45cb9022d70e53bef3389884cdde284ed3eb3b8d6979761b98.json index 912db1a932..ed386844d4 100644 --- a/backend/.sqlx/query-f0d8ebbf62a1d92f39c2f86a70236cece6d6c9e28cce9aff7fe5496bba569807.json +++ b/backend/.sqlx/query-df8f616f7ace1d45cb9022d70e53bef3389884cdde284ed3eb3b8d6979761b98.json @@ -1,6 +1,6 @@ { "db_name": "PostgreSQL", - "query": "SELECT fork_last_event_kind, fork_last_event_origin FROM workspace_diff\n WHERE fork_workspace_id = 'wm-fork-renamed' AND kind = 'script'\n AND path = 'u/admin/inline' AND fork_last_event_kind IS NOT NULL", + "query": "SELECT fork_last_event_kind, fork_last_event_origin FROM workspace_diff\n WHERE fork_workspace_id = 'wm-fork-renamed' AND kind = 'script'\n AND path = 'u/admin/inline' AND fork_last_event_kind <> 'write'", "describe": { "columns": [ { @@ -22,5 +22,5 @@ true ] }, - "hash": "f0d8ebbf62a1d92f39c2f86a70236cece6d6c9e28cce9aff7fe5496bba569807" + "hash": "df8f616f7ace1d45cb9022d70e53bef3389884cdde284ed3eb3b8d6979761b98" } diff --git a/backend/windmill-api-integration-tests/tests/workspace_comparison.rs b/backend/windmill-api-integration-tests/tests/workspace_comparison.rs index c3cb9ff190..bef3b5dd78 100644 --- a/backend/windmill-api-integration-tests/tests/workspace_comparison.rs +++ b/backend/windmill-api-integration-tests/tests/workspace_comparison.rs @@ -2549,6 +2549,26 @@ async fn test_rename_records_the_vacated_path(db: Pool) -> anyhow::Res "script deploy failed: {status} — {hash}" ); parent_hash = Some(hash.trim().trim_matches('"').to_string()); + // Each deploy tallies from its own spawned task: let the create's `write` land + // before the rename, or it can overwrite the `rename_from` asserted below. + if path == "u/admin/inline" { + let mut written = false; + for _ in 0..40 { + tokio::time::sleep(std::time::Duration::from_millis(50)).await; + written = sqlx::query_scalar!( + "SELECT EXISTS (SELECT 1 FROM workspace_diff + WHERE fork_workspace_id = 'wm-fork-renamed' AND kind = 'script' + AND path = 'u/admin/inline' AND fork_last_event_kind = 'write')" + ) + .fetch_one(&db) + .await? + .unwrap_or(false); + if written { + break; + } + } + assert!(written, "the inline create should be tallied"); + } } let mut vacated = None; for _ in 0..40 { @@ -2556,7 +2576,7 @@ async fn test_rename_records_the_vacated_path(db: Pool) -> anyhow::Res vacated = sqlx::query!( "SELECT fork_last_event_kind, fork_last_event_origin FROM workspace_diff WHERE fork_workspace_id = 'wm-fork-renamed' AND kind = 'script' - AND path = 'u/admin/inline' AND fork_last_event_kind IS NOT NULL" + AND path = 'u/admin/inline' AND fork_last_event_kind <> 'write'" ) .fetch_optional(&db) .await?; @@ -2706,6 +2726,8 @@ async fn test_compare_secret_variables_by_value(db: Pool) -> anyhow::R "the same secret must be stored as two different ciphertexts" ); + // The creates above tally these rows from a spawned task that can land after the + // DELETE, so the plant must upsert. sqlx::query!("DELETE FROM workspace_diff WHERE fork_workspace_id = 'wm-fork-secrets'") .execute(&db) .await?; @@ -2714,7 +2736,9 @@ async fn test_compare_secret_variables_by_value(db: Pool) -> anyhow::R (source_workspace_id, fork_workspace_id, path, kind, ahead, behind, has_changes) VALUES ('test-workspace', 'wm-fork-secrets', 'u/test-user/same', 'variable', 1, 1, NULL), - ('test-workspace', 'wm-fork-secrets', 'u/test-user/different', 'variable', 1, 1, NULL)" + ('test-workspace', 'wm-fork-secrets', 'u/test-user/different', 'variable', 1, 1, NULL) + ON CONFLICT (source_workspace_id, fork_workspace_id, path, kind) + DO UPDATE SET ahead = 1, behind = 1, has_changes = NULL" ) .execute(&db) .await?;