From 2f156ec73c27ceebe0d1f5c08b600cadf188904d Mon Sep 17 00:00:00 2001 From: Samar Farooqi Date: Thu, 15 Oct 2026 21:58:48 +0000 Subject: [PATCH 1/2] Report $out command failures through the assertion in out tests Signed-off-by: Samar Farooqi --- .../stages/out/test_out_acceptance.py | 36 +++++++++++-------- .../stages/out/test_out_timeseries.py | 36 +++++++++++-------- 2 files changed, 44 insertions(+), 28 deletions(-) diff --git a/documentdb_tests/compatibility/tests/core/operator/stages/out/test_out_acceptance.py b/documentdb_tests/compatibility/tests/core/operator/stages/out/test_out_acceptance.py index 32dc1943f..a3deb9741 100644 --- a/documentdb_tests/compatibility/tests/core/operator/stages/out/test_out_acceptance.py +++ b/documentdb_tests/compatibility/tests/core/operator/stages/out/test_out_acceptance.py @@ -236,23 +236,31 @@ def test_out_acceptance(collection, test_case: OutTestCase): populate_collection(collection, test_case) target = target_name(collection, test_case) out_stage = test_case.build_out_stage(collection) - execute_command( + out_result = execute_command( collection, {"aggregate": collection.name, "pipeline": [out_stage], "cursor": {}}, ) - result = execute_command( - collection, - {"listCollections": 1, "filter": {"name": target}}, - ) - raw_doc = cast(dict, result)["cursor"]["firstBatch"][0] - expected_info: dict[str, Any] = { - "name": target, - "type": test_case.expected_type, - "options": test_case.expected_options, - "info": raw_doc["info"], - } - if "idIndex" in raw_doc: - expected_info["idIndex"] = raw_doc["idIndex"] + result: Any + expected_info: Any + if isinstance(out_result, Exception): + # The $out command itself failed; surface that error through the + # assertion rather than crashing on an empty listCollections batch. + result = out_result + expected_info = [] + else: + result = execute_command( + collection, + {"listCollections": 1, "filter": {"name": target}}, + ) + raw_doc = cast(dict, result)["cursor"]["firstBatch"][0] + expected_info = { + "name": target, + "type": test_case.expected_type, + "options": test_case.expected_options, + "info": raw_doc["info"], + } + if "idIndex" in raw_doc: + expected_info["idIndex"] = raw_doc["idIndex"] assertSuccess(result, [expected_info], msg=test_case.msg) diff --git a/documentdb_tests/compatibility/tests/core/operator/stages/out/test_out_timeseries.py b/documentdb_tests/compatibility/tests/core/operator/stages/out/test_out_timeseries.py index 35b976ee0..a63b9b982 100644 --- a/documentdb_tests/compatibility/tests/core/operator/stages/out/test_out_timeseries.py +++ b/documentdb_tests/compatibility/tests/core/operator/stages/out/test_out_timeseries.py @@ -373,23 +373,31 @@ def test_out_timeseries(collection, test_case: OutTestCase): """Test $out writes results and creates the correct collection type.""" populate_collection(collection, test_case) out_stage = test_case.build_out_stage(collection) - execute_command( + out_result = execute_command( collection, {"aggregate": collection.name, "pipeline": [out_stage], "cursor": {}}, ) - result = execute_command( - collection, - {"listCollections": 1, "filter": {"name": target_name(collection, test_case)}}, - ) - raw_doc = cast(dict, result)["cursor"]["firstBatch"][0] - expected_info: dict[str, Any] = { - "name": target_name(collection, test_case), - "type": test_case.expected_type, - "options": test_case.expected_options, - "info": raw_doc["info"], - } - if "idIndex" in raw_doc: - expected_info["idIndex"] = raw_doc["idIndex"] + result: Any + expected_info: Any + if isinstance(out_result, Exception): + # The $out command itself failed; surface that error through the + # assertion rather than crashing on an empty listCollections batch. + result = out_result + expected_info = [] + else: + result = execute_command( + collection, + {"listCollections": 1, "filter": {"name": target_name(collection, test_case)}}, + ) + raw_doc = cast(dict, result)["cursor"]["firstBatch"][0] + expected_info = { + "name": target_name(collection, test_case), + "type": test_case.expected_type, + "options": test_case.expected_options, + "info": raw_doc["info"], + } + if "idIndex" in raw_doc: + expected_info["idIndex"] = raw_doc["idIndex"] assertSuccess(result, [expected_info], msg=test_case.msg) From dff5182cc9b0b1f0b5d6a7ebecad25c9b76ad73e Mon Sep 17 00:00:00 2001 From: Samar Farooqi Date: Thu, 15 Oct 2026 21:58:49 +0000 Subject: [PATCH 2/2] Report missing indexFilterSet through the assertion in planCacheSetFilter tests Signed-off-by: Samar Farooqi --- .../test_planCacheSetFilter_cross_command.py | 2 +- .../test_planCacheSetFilter_effectiveness.py | 10 +++++----- .../test_planCacheSetFilter_partial_sparse.py | 8 ++++---- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/documentdb_tests/compatibility/tests/core/query_planning/commands/planCacheSetFilter/test_planCacheSetFilter_cross_command.py b/documentdb_tests/compatibility/tests/core/query_planning/commands/planCacheSetFilter/test_planCacheSetFilter_cross_command.py index dc036fd9c..8d2c0cd5a 100644 --- a/documentdb_tests/compatibility/tests/core/query_planning/commands/planCacheSetFilter/test_planCacheSetFilter_cross_command.py +++ b/documentdb_tests/compatibility/tests/core/query_planning/commands/planCacheSetFilter/test_planCacheSetFilter_cross_command.py @@ -110,7 +110,7 @@ def test_cross_command_filter( node = node.get("inputStage") assertProperties( - {"indexFilterSet": qp["indexFilterSet"], "winningIndex": winning_index}, + {"indexFilterSet": qp.get("indexFilterSet"), "winningIndex": winning_index}, {"indexFilterSet": Eq(True), "winningIndex": Eq(expected_index)}, msg=f"filter should force {expected_index}", raw_res=True, diff --git a/documentdb_tests/compatibility/tests/core/query_planning/commands/planCacheSetFilter/test_planCacheSetFilter_effectiveness.py b/documentdb_tests/compatibility/tests/core/query_planning/commands/planCacheSetFilter/test_planCacheSetFilter_effectiveness.py index 2ec6470f9..435bab3b0 100644 --- a/documentdb_tests/compatibility/tests/core/query_planning/commands/planCacheSetFilter/test_planCacheSetFilter_effectiveness.py +++ b/documentdb_tests/compatibility/tests/core/query_planning/commands/planCacheSetFilter/test_planCacheSetFilter_effectiveness.py @@ -55,7 +55,7 @@ def test_filter_forces_index(collection, filter_indexes, expected_index): node = node.get("inputStage") assertProperties( - {"indexFilterSet": qp["indexFilterSet"], "winningIndex": winning_index}, + {"indexFilterSet": qp.get("indexFilterSet"), "winningIndex": winning_index}, {"indexFilterSet": Eq(True), "winningIndex": Eq(expected_index)}, msg=f"filter should force {expected_index} for query {{a: 1}}", raw_res=True, @@ -98,7 +98,7 @@ def test_multiple_allowed_indexes(collection): allowed = ["a_1", "c_1"] assertProperties( { - "indexFilterSet": qp["indexFilterSet"], + "indexFilterSet": qp.get("indexFilterSet"), "inAllowedSet": winning_index in allowed if winning_index else False, }, {"indexFilterSet": Eq(True), "inAllowedSet": Eq(True)}, @@ -157,7 +157,7 @@ def test_hint_overridden_by_filter(collection, filter_indexes, hint, expected_in node = node.get("inputStage") assertProperties( - {"indexFilterSet": qp["indexFilterSet"], "winningIndex": winning_index}, + {"indexFilterSet": qp.get("indexFilterSet"), "winningIndex": winning_index}, {"indexFilterSet": Eq(True), "winningIndex": Eq(expected_index)}, msg=f"filter should override hint and force {expected_index}", raw_res=True, @@ -190,7 +190,7 @@ def test_collscan_fallback(collection): qp = result["queryPlanner"] assertProperties( { - "indexFilterSet": qp["indexFilterSet"], + "indexFilterSet": qp.get("indexFilterSet"), "topStage": qp["winningPlan"].get("stage", ""), }, {"indexFilterSet": Eq(True), "topStage": Eq("COLLSCAN")}, @@ -231,7 +231,7 @@ def test_filter_scoped_to_exact_shape(collection, query, expected_filter_set): }, ) assertProperties( - {"indexFilterSet": result["queryPlanner"]["indexFilterSet"]}, + {"indexFilterSet": result["queryPlanner"].get("indexFilterSet")}, {"indexFilterSet": Eq(expected_filter_set)}, msg=f"indexFilterSet should be {expected_filter_set} for query {query}", raw_res=True, diff --git a/documentdb_tests/compatibility/tests/core/query_planning/commands/planCacheSetFilter/test_planCacheSetFilter_partial_sparse.py b/documentdb_tests/compatibility/tests/core/query_planning/commands/planCacheSetFilter/test_planCacheSetFilter_partial_sparse.py index c844394ea..8369a5df5 100644 --- a/documentdb_tests/compatibility/tests/core/query_planning/commands/planCacheSetFilter/test_planCacheSetFilter_partial_sparse.py +++ b/documentdb_tests/compatibility/tests/core/query_planning/commands/planCacheSetFilter/test_planCacheSetFilter_partial_sparse.py @@ -55,7 +55,7 @@ def test_partial_index_qualifying(collection): node = node.get("inputStage") assertProperties( - {"indexFilterSet": qp["indexFilterSet"], "winningIndex": winning_index}, + {"indexFilterSet": qp.get("indexFilterSet"), "winningIndex": winning_index}, {"indexFilterSet": Eq(True), "winningIndex": Eq("a_partial")}, msg="qualifying query should use the partial index", raw_res=True, @@ -95,7 +95,7 @@ def test_partial_index_non_qualifying(collection): qp = result["queryPlanner"] assertProperties( { - "indexFilterSet": qp["indexFilterSet"], + "indexFilterSet": qp.get("indexFilterSet"), "topStage": qp["winningPlan"].get("stage", ""), }, {"indexFilterSet": Eq(True), "topStage": Eq("COLLSCAN")}, @@ -143,7 +143,7 @@ def test_sparse_index_qualifying(collection): node = node.get("inputStage") assertProperties( - {"indexFilterSet": qp["indexFilterSet"], "winningIndex": winning_index}, + {"indexFilterSet": qp.get("indexFilterSet"), "winningIndex": winning_index}, {"indexFilterSet": Eq(True), "winningIndex": Eq("a_sparse")}, msg="$exists:true should use the sparse index", raw_res=True, @@ -182,7 +182,7 @@ def test_sparse_index_non_qualifying(collection): qp = result["queryPlanner"] assertProperties( { - "indexFilterSet": qp["indexFilterSet"], + "indexFilterSet": qp.get("indexFilterSet"), "topStage": qp["winningPlan"].get("stage", ""), }, {"indexFilterSet": Eq(True), "topStage": Eq("COLLSCAN")},