From 9d745c347faa7e869ad5dab8ea0ce7c0af5f53a6 Mon Sep 17 00:00:00 2001 From: Federico Mon Date: Tue, 26 May 2026 07:53:45 +0000 Subject: [PATCH 01/16] wip --- ddtrace/testing/internal/api_client.py | 5 ++ tests/testing/internal/test_api_client.py | 79 +++++++++++++++++++++++ 2 files changed, 84 insertions(+) diff --git a/ddtrace/testing/internal/api_client.py b/ddtrace/testing/internal/api_client.py index 7861a3eed02..40594095553 100644 --- a/ddtrace/testing/internal/api_client.py +++ b/ddtrace/testing/internal/api_client.py @@ -144,7 +144,11 @@ def get_known_tests(self) -> set[TestRef]: for page_number in range(max_pages): # First page: empty page_info lets backend use its default max (10k). # Subsequent pages: only send page_state. + # AIDEV-NOTE: `page_info` is reused below to hold the *response* page_info after + # the request is sent. To fix: rename this to `request_page_info` and the response + # assignment to `response_page_info` (same pattern as _api_client.py fetch_known_tests). page_info: dict[str, t.Any] = {} if page_state is None else {"page_state": page_state} + log.debug("Known tests request page %d: sending page_info=%r", page_number, page_info) try: request_data: dict[str, t.Any] = { @@ -188,6 +192,7 @@ def get_known_tests(self) -> set[TestRef]: known_test_ids.add(TestRef(suite_ref, test)) page_info = attributes.get("page_info") + log.debug("Known tests response page %d: received page_info=%r", page_number, page_info) if not page_info: break if not isinstance(page_info, dict): diff --git a/tests/testing/internal/test_api_client.py b/tests/testing/internal/test_api_client.py index be1ce0b8cab..bb285bf8401 100644 --- a/tests/testing/internal/test_api_client.py +++ b/tests/testing/internal/test_api_client.py @@ -461,6 +461,85 @@ def test_get_known_tests_pagination_sends_page_info_correctly(self, mock_telemet TestRef(SuiteRef(ModuleRef("mod2"), "suite2.py"), "test_b"), } + def test_get_known_tests_pagination_full_request_payload(self, mock_telemetry: Mock) -> None: + """Second-page request must carry the same fields as the first, with only page_info differing.""" + page1_response = { + "data": { + "attributes": { + "tests": {"mod1": {"suite1.py": ["test_a"]}}, + "page_info": {"has_next": True, "cursor": "cursor-abc"}, + }, + "id": "page1-id", + "type": "ci_app_libraries_tests", + } + } + page2_response = { + "data": { + "attributes": { + "tests": {"mod2": {"suite2.py": ["test_b"]}}, + }, + "id": "page2-id", + "type": "ci_app_libraries_tests", + } + } + mock_connector = mock_backend_connector().build() + mock_connector.post_json.side_effect = [ + BackendResult(response=Mock(status=200), parsed_response=page1_response), + BackendResult(response=Mock(status=200), parsed_response=page2_response), + ] + mock_connector_setup = Mock() + mock_connector_setup.get_connector_for_subdomain.return_value = mock_connector + + api_client = APIClient( + service="my-service", + env="my-env", + env_tags={ + GitTag.REPOSITORY_URL: "http://github.com/org/repo.git", + GitTag.COMMIT_SHA: "deadbeef", + GitTag.BRANCH: "main", + GitTag.COMMIT_MESSAGE: "a commit", + }, + itr_skipping_level=ITRSkippingLevel.TEST, + configurations={"os.platform": "Linux", "os.architecture": "x86_64"}, + connector_setup=mock_connector_setup, + telemetry_api=mock_telemetry, + ) + + with patch("uuid.uuid4", return_value=uuid.UUID("00000000-0000-0000-0000-000000000000")): + known_tests = api_client.get_known_tests() + + assert len(mock_connector.post_json.call_args_list) == 2 + + expected_shared_attributes = { + "service": "my-service", + "env": "my-env", + "repository_url": "http://github.com/org/repo.git", + "configurations": {"os.platform": "Linux", "os.architecture": "x86_64"}, + } + + page1_payload = mock_connector.post_json.call_args_list[0][0][1] + assert page1_payload == { + "data": { + "id": "00000000-0000-0000-0000-000000000000", + "type": "ci_app_libraries_tests_request", + "attributes": {**expected_shared_attributes, "page_info": {}}, + } + } + + page2_payload = mock_connector.post_json.call_args_list[1][0][1] + assert page2_payload == { + "data": { + "id": "00000000-0000-0000-0000-000000000000", + "type": "ci_app_libraries_tests_request", + "attributes": {**expected_shared_attributes, "page_info": {"page_state": "cursor-abc"}}, + } + } + + assert known_tests == { + TestRef(SuiteRef(ModuleRef("mod1"), "suite1.py"), "test_a"), + TestRef(SuiteRef(ModuleRef("mod2"), "suite2.py"), "test_b"), + } + def test_get_known_tests_max_pages_limit_bails_and_disables_known_tests( self, mock_telemetry: Mock, caplog: pytest.LogCaptureFixture, monkeypatch: pytest.MonkeyPatch ) -> None: From 6a86d30496e295c7f4a2baa1ec53350291366f11 Mon Sep 17 00:00:00 2001 From: Federico Mon Date: Tue, 26 May 2026 09:57:35 +0200 Subject: [PATCH 02/16] force known tests enabled --- ddtrace/testing/internal/session_manager.py | 1 + 1 file changed, 1 insertion(+) diff --git a/ddtrace/testing/internal/session_manager.py b/ddtrace/testing/internal/session_manager.py index 6c08df4694b..d409b10c399 100644 --- a/ddtrace/testing/internal/session_manager.py +++ b/ddtrace/testing/internal/session_manager.py @@ -118,6 +118,7 @@ def __init__(self, session: TestSession) -> None: telemetry_api=self.telemetry_api, ) self.settings = self.api_client.get_settings() + self.settings.known_tests_enabled = True # DEBUG self.override_settings_with_env_vars() # Manifest mode disables test skipping: cached skippable decisions should not From 188cef75a60943adb37f96022072c58cacfe8c9e Mon Sep 17 00:00:00 2001 From: Federico Mon Date: Tue, 26 May 2026 10:22:14 +0200 Subject: [PATCH 03/16] debug to warn --- ddtrace/testing/internal/api_client.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ddtrace/testing/internal/api_client.py b/ddtrace/testing/internal/api_client.py index 40594095553..cc940e4514e 100644 --- a/ddtrace/testing/internal/api_client.py +++ b/ddtrace/testing/internal/api_client.py @@ -148,7 +148,7 @@ def get_known_tests(self) -> set[TestRef]: # the request is sent. To fix: rename this to `request_page_info` and the response # assignment to `response_page_info` (same pattern as _api_client.py fetch_known_tests). page_info: dict[str, t.Any] = {} if page_state is None else {"page_state": page_state} - log.debug("Known tests request page %d: sending page_info=%r", page_number, page_info) + log.warning("Known tests request page %d: sending page_info=%r", page_number, page_info) try: request_data: dict[str, t.Any] = { @@ -192,7 +192,7 @@ def get_known_tests(self) -> set[TestRef]: known_test_ids.add(TestRef(suite_ref, test)) page_info = attributes.get("page_info") - log.debug("Known tests response page %d: received page_info=%r", page_number, page_info) + log.warning("Known tests response page %d: received page_info=%r", page_number, page_info) if not page_info: break if not isinstance(page_info, dict): From 1fec092bdae82b4c6e76cdced2eb4c6def03147a Mon Sep 17 00:00:00 2001 From: Federico Mon Date: Tue, 26 May 2026 10:47:26 +0200 Subject: [PATCH 04/16] send has_next false at start --- ddtrace/testing/internal/api_client.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ddtrace/testing/internal/api_client.py b/ddtrace/testing/internal/api_client.py index cc940e4514e..fc9efac4476 100644 --- a/ddtrace/testing/internal/api_client.py +++ b/ddtrace/testing/internal/api_client.py @@ -147,7 +147,7 @@ def get_known_tests(self) -> set[TestRef]: # AIDEV-NOTE: `page_info` is reused below to hold the *response* page_info after # the request is sent. To fix: rename this to `request_page_info` and the response # assignment to `response_page_info` (same pattern as _api_client.py fetch_known_tests). - page_info: dict[str, t.Any] = {} if page_state is None else {"page_state": page_state} + page_info: dict[str, t.Any] = {"has_next": False} if page_state is None else {"page_state": page_state} log.warning("Known tests request page %d: sending page_info=%r", page_number, page_info) try: From 661a367074c7f12835b87d64575f3acec8c49363 Mon Sep 17 00:00:00 2001 From: Federico Mon Date: Tue, 26 May 2026 11:07:04 +0200 Subject: [PATCH 05/16] swap to initial size --- ddtrace/testing/internal/api_client.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ddtrace/testing/internal/api_client.py b/ddtrace/testing/internal/api_client.py index fc9efac4476..31589a9adf2 100644 --- a/ddtrace/testing/internal/api_client.py +++ b/ddtrace/testing/internal/api_client.py @@ -147,7 +147,7 @@ def get_known_tests(self) -> set[TestRef]: # AIDEV-NOTE: `page_info` is reused below to hold the *response* page_info after # the request is sent. To fix: rename this to `request_page_info` and the response # assignment to `response_page_info` (same pattern as _api_client.py fetch_known_tests). - page_info: dict[str, t.Any] = {"has_next": False} if page_state is None else {"page_state": page_state} + page_info: dict[str, t.Any] = {"size": 2_000} if page_state is None else {"page_state": page_state} log.warning("Known tests request page %d: sending page_info=%r", page_number, page_info) try: From bb800a6a0c589d5451a668342d21f817ec551ed1 Mon Sep 17 00:00:00 2001 From: Federico Mon Date: Wed, 27 May 2026 09:42:23 +0200 Subject: [PATCH 06/16] Apply suggestion from @gnufede --- ddtrace/testing/internal/api_client.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ddtrace/testing/internal/api_client.py b/ddtrace/testing/internal/api_client.py index 31589a9adf2..3b587bb435c 100644 --- a/ddtrace/testing/internal/api_client.py +++ b/ddtrace/testing/internal/api_client.py @@ -147,7 +147,7 @@ def get_known_tests(self) -> set[TestRef]: # AIDEV-NOTE: `page_info` is reused below to hold the *response* page_info after # the request is sent. To fix: rename this to `request_page_info` and the response # assignment to `response_page_info` (same pattern as _api_client.py fetch_known_tests). - page_info: dict[str, t.Any] = {"size": 2_000} if page_state is None else {"page_state": page_state} + page_info: dict[str, t.Any] = {"page_size": 2_000} if page_state is None else {"page_state": page_state} log.warning("Known tests request page %d: sending page_info=%r", page_number, page_info) try: From 0e5cf98e694ff32ee3e85bb778468238863e7bf6 Mon Sep 17 00:00:00 2001 From: Federico Mon Date: Wed, 27 May 2026 08:12:09 +0000 Subject: [PATCH 07/16] fix(ci_visibility): forward response size as page_size in known tests pagination When the backend returns `size` in the response `page_info`, echo it back as `page_size` in the next request's `page_info`. Also adds debug logging for request/response page_info on each page, an AIDEV-NOTE on the variable reuse issue, and a full-payload test for the second-page request shape. Co-Authored-By: Claude Sonnet 4.6 --- ddtrace/internal/ci_visibility/_api_client.py | 13 ++++++-- ddtrace/testing/internal/api_client.py | 15 +++++++-- tests/ci_visibility/api_client/_util.py | 4 +-- ...ility_api_client_unique_tests_responses.py | 31 +++++++++++++++++++ tests/testing/internal/test_api_client.py | 14 ++++++--- 5 files changed, 66 insertions(+), 11 deletions(-) diff --git a/ddtrace/internal/ci_visibility/_api_client.py b/ddtrace/internal/ci_visibility/_api_client.py index 23ef08d4ff3..3acdb1eb7aa 100644 --- a/ddtrace/internal/ci_visibility/_api_client.py +++ b/ddtrace/internal/ci_visibility/_api_client.py @@ -577,12 +577,19 @@ def fetch_known_tests(self, read_from_cache: bool = True) -> t.Optional[set[Test known_test_ids: set[TestId] = set() page_state: t.Optional[str] = None + page_size: t.Optional[int] = None max_pages = _get_known_tests_max_pages() for page_number in range(max_pages): # First page: empty page_info lets backend use its default max (10k). - # Subsequent pages: only send page_state. - request_page_info: dict[str, t.Any] = {} if page_state is None else {"page_state": page_state} + # Subsequent pages: send page_state cursor and echo back the page size the + # server reported (response field "size" → request field "page_size"). + if page_state is None: + request_page_info: dict[str, t.Any] = {} + else: + request_page_info = {"page_state": page_state} + if page_size is not None: + request_page_info["page_size"] = page_size payload = { "data": { @@ -646,6 +653,8 @@ def fetch_known_tests(self, read_from_cache: bool = True) -> t.Optional[set[Test log.debug("Known tests response missing pagination cursor on page %d", page_number + 1) record_api_request_error(metric_names.error, ERROR_TYPES.BAD_JSON) return None + + page_size = response_page_info.get("size") else: log.debug("Known tests pagination exceeded max pages: %d", max_pages) record_api_request_error(metric_names.error, ERROR_TYPES.BAD_JSON) diff --git a/ddtrace/testing/internal/api_client.py b/ddtrace/testing/internal/api_client.py index 3b587bb435c..198cd65c5e6 100644 --- a/ddtrace/testing/internal/api_client.py +++ b/ddtrace/testing/internal/api_client.py @@ -138,17 +138,24 @@ def get_known_tests(self) -> set[TestRef]: ) page_state: t.Optional[str] = None + page_size: t.Optional[int] = None known_test_ids: set[TestRef] = set() max_pages = _get_known_tests_max_pages() for page_number in range(max_pages): # First page: empty page_info lets backend use its default max (10k). - # Subsequent pages: only send page_state. + # Subsequent pages: send page_state cursor and echo back the page size the + # server reported (response field "size" → request field "page_size"). # AIDEV-NOTE: `page_info` is reused below to hold the *response* page_info after # the request is sent. To fix: rename this to `request_page_info` and the response # assignment to `response_page_info` (same pattern as _api_client.py fetch_known_tests). - page_info: dict[str, t.Any] = {"page_size": 2_000} if page_state is None else {"page_state": page_state} - log.warning("Known tests request page %d: sending page_info=%r", page_number, page_info) + if page_state is None: + page_info: dict[str, t.Any] = {"page_size": 2_000} + else: + page_info = {"page_state": page_state} + if page_size is not None: + page_info["page_size"] = page_size + log.debug("Known tests request page %d: sending page_info=%r", page_number, page_info) try: request_data: dict[str, t.Any] = { @@ -212,6 +219,8 @@ def get_known_tests(self) -> set[TestRef]: self.configuration_errors[TestTag.LIBRARY_CONFIGURATION_ERROR_KNOWN_TESTS] = "true" return set() + page_size = page_info.get("size") + except Exception: log.warning("Error getting known tests from API") telemetry.record_error(ErrorType.BAD_JSON) diff --git a/tests/ci_visibility/api_client/_util.py b/tests/ci_visibility/api_client/_util.py index 14cbd7ce81f..08b1d85901f 100644 --- a/tests/ci_visibility/api_client/_util.py +++ b/tests/ci_visibility/api_client/_util.py @@ -294,8 +294,8 @@ def _get_expected_do_request_tests_payload( if repository_url is None: repository_url = self.default_git_data.repository_url - # First page: empty page_info; subsequent pages: only page_state. - page_info = {} if page_state is None else {"page_state": page_state} + # First page: page_size only; subsequent pages: page_state (+ page_size if provided). + page_info = {"page_size": 2000} if page_state is None else {"page_state": page_state} return { "data": { diff --git a/tests/ci_visibility/api_client/test_ci_visibility_api_client_unique_tests_responses.py b/tests/ci_visibility/api_client/test_ci_visibility_api_client_unique_tests_responses.py index 0e85e3e437b..94ffc81d2c4 100644 --- a/tests/ci_visibility/api_client/test_ci_visibility_api_client_unique_tests_responses.py +++ b/tests/ci_visibility/api_client/test_ci_visibility_api_client_unique_tests_responses.py @@ -124,3 +124,34 @@ def test_civisibility_api_client_known_tests_paginated(self): assert client.fetch_known_tests(read_from_cache=False) == set( _make_fqdn_test_ids([("module1", "suite1.py", "test1"), ("module1", "suite1.py", "test2")]) ) + + def test_civisibility_api_client_known_tests_page_size_forwarded(self): + """Response 'size' is echoed back as 'page_size' in the next request's page_info.""" + import json + + client = self._get_test_client() + response_page_1 = _get_tests_api_response( + {"module1": {"suite1.py": ["test1"]}}, + page_info={"cursor": "page-2", "size": 250, "has_next": True}, + ) + response_page_2 = _get_tests_api_response( + {"module1": {"suite1.py": ["test2"]}}, + ) + + captured_payloads = [] + + def fake_do_request_with_telemetry(method, endpoint, payload, metric_names, **kwargs): + captured_payloads.append(payload) + if len(captured_payloads) == 1: + return json.loads(response_page_1.body) + return json.loads(response_page_2.body) + + with mock.patch.object(client, "_do_request_with_telemetry", side_effect=fake_do_request_with_telemetry): + client.fetch_known_tests(read_from_cache=False) + + assert len(captured_payloads) == 2 + assert captured_payloads[0]["data"]["attributes"]["page_info"] == {"page_size": 2000} + assert captured_payloads[1]["data"]["attributes"]["page_info"] == { + "page_state": "page-2", + "page_size": 250, + } diff --git a/tests/testing/internal/test_api_client.py b/tests/testing/internal/test_api_client.py index bb285bf8401..db5258ac73e 100644 --- a/tests/testing/internal/test_api_client.py +++ b/tests/testing/internal/test_api_client.py @@ -388,7 +388,7 @@ def test_get_known_tests(self, mock_telemetry: Mock) -> None: "env": "some-env", "repository_url": "http://github.com/DataDog/some-repo.git", "configurations": {"os.platform": "Linux"}, - "page_info": {}, + "page_info": {"page_size": 2000}, }, } }, @@ -462,12 +462,15 @@ def test_get_known_tests_pagination_sends_page_info_correctly(self, mock_telemet } def test_get_known_tests_pagination_full_request_payload(self, mock_telemetry: Mock) -> None: - """Second-page request must carry the same fields as the first, with only page_info differing.""" + """Second-page request carries the same fields as the first, with page_info updated. + + The response 'size' field must be echoed back as 'page_size' in the next request. + """ page1_response = { "data": { "attributes": { "tests": {"mod1": {"suite1.py": ["test_a"]}}, - "page_info": {"has_next": True, "cursor": "cursor-abc"}, + "page_info": {"has_next": True, "cursor": "cursor-abc", "size": 500}, }, "id": "page1-id", "type": "ci_app_libraries_tests", @@ -531,7 +534,10 @@ def test_get_known_tests_pagination_full_request_payload(self, mock_telemetry: M "data": { "id": "00000000-0000-0000-0000-000000000000", "type": "ci_app_libraries_tests_request", - "attributes": {**expected_shared_attributes, "page_info": {"page_state": "cursor-abc"}}, + "attributes": { + **expected_shared_attributes, + "page_info": {"page_state": "cursor-abc", "page_size": 500}, + }, } } From 70e79f95a49fd78f640db3fdd1f1f639a1694fd8 Mon Sep 17 00:00:00 2001 From: Federico Mon Date: Wed, 27 May 2026 08:14:50 +0000 Subject: [PATCH 08/16] fix(ci_visibility): restore log.warning for pagination request debug line Co-Authored-By: Claude Sonnet 4.6 --- ddtrace/testing/internal/api_client.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ddtrace/testing/internal/api_client.py b/ddtrace/testing/internal/api_client.py index 198cd65c5e6..4582f006b22 100644 --- a/ddtrace/testing/internal/api_client.py +++ b/ddtrace/testing/internal/api_client.py @@ -155,7 +155,7 @@ def get_known_tests(self) -> set[TestRef]: page_info = {"page_state": page_state} if page_size is not None: page_info["page_size"] = page_size - log.debug("Known tests request page %d: sending page_info=%r", page_number, page_info) + log.warning("Known tests request page %d: sending page_info=%r", page_number, page_info) try: request_data: dict[str, t.Any] = { From 42d46f1f4b0bc5f0bba8d09f78b061b680c53337 Mon Sep 17 00:00:00 2001 From: Federico Mon Date: Wed, 27 May 2026 09:15:26 +0000 Subject: [PATCH 09/16] fix(ci_visibility): revert _util.py first-page page_info to empty dict _get_expected_do_request_tests_payload is for _api_client.py which still sends {} on the first page. Only ddtrace/testing/internal/api_client.py sends {"page_size": 2000}. Co-Authored-By: Claude Sonnet 4.6 --- tests/ci_visibility/api_client/_util.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/ci_visibility/api_client/_util.py b/tests/ci_visibility/api_client/_util.py index 08b1d85901f..14cbd7ce81f 100644 --- a/tests/ci_visibility/api_client/_util.py +++ b/tests/ci_visibility/api_client/_util.py @@ -294,8 +294,8 @@ def _get_expected_do_request_tests_payload( if repository_url is None: repository_url = self.default_git_data.repository_url - # First page: page_size only; subsequent pages: page_state (+ page_size if provided). - page_info = {"page_size": 2000} if page_state is None else {"page_state": page_state} + # First page: empty page_info; subsequent pages: only page_state. + page_info = {} if page_state is None else {"page_state": page_state} return { "data": { From 30bb83407c8bd9c00a962384f2a1c76dab0bd8c7 Mon Sep 17 00:00:00 2001 From: Federico Mon Date: Wed, 27 May 2026 09:43:21 +0000 Subject: [PATCH 10/16] fix(ci_visibility): correct first-page page_info assertion for _api_client tests _api_client.py sends {} on the first page (no default page_size); only ddtrace/testing/internal/api_client.py sends {"page_size": 2000}. Co-Authored-By: Claude Sonnet 4.6 --- .../test_ci_visibility_api_client_unique_tests_responses.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/ci_visibility/api_client/test_ci_visibility_api_client_unique_tests_responses.py b/tests/ci_visibility/api_client/test_ci_visibility_api_client_unique_tests_responses.py index 94ffc81d2c4..31a1f8655ac 100644 --- a/tests/ci_visibility/api_client/test_ci_visibility_api_client_unique_tests_responses.py +++ b/tests/ci_visibility/api_client/test_ci_visibility_api_client_unique_tests_responses.py @@ -150,7 +150,7 @@ def fake_do_request_with_telemetry(method, endpoint, payload, metric_names, **kw client.fetch_known_tests(read_from_cache=False) assert len(captured_payloads) == 2 - assert captured_payloads[0]["data"]["attributes"]["page_info"] == {"page_size": 2000} + assert captured_payloads[0]["data"]["attributes"]["page_info"] == {} assert captured_payloads[1]["data"]["attributes"]["page_info"] == { "page_state": "page-2", "page_size": 250, From 18a3bc0d374ca00ad9f777bd4b6654a8421ed600 Mon Sep 17 00:00:00 2001 From: Federico Mon Date: Wed, 27 May 2026 13:49:00 +0000 Subject: [PATCH 11/16] fix(ci_visibility): remove hardcoded page_size from first known tests request Let the backend use its default page size instead of sending page_size: 2000. Co-Authored-By: Claude Sonnet 4.6 --- ddtrace/testing/internal/api_client.py | 2 +- tests/testing/internal/test_api_client.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ddtrace/testing/internal/api_client.py b/ddtrace/testing/internal/api_client.py index 4582f006b22..4cb14d4396c 100644 --- a/ddtrace/testing/internal/api_client.py +++ b/ddtrace/testing/internal/api_client.py @@ -150,7 +150,7 @@ def get_known_tests(self) -> set[TestRef]: # the request is sent. To fix: rename this to `request_page_info` and the response # assignment to `response_page_info` (same pattern as _api_client.py fetch_known_tests). if page_state is None: - page_info: dict[str, t.Any] = {"page_size": 2_000} + page_info: dict[str, t.Any] = {} else: page_info = {"page_state": page_state} if page_size is not None: diff --git a/tests/testing/internal/test_api_client.py b/tests/testing/internal/test_api_client.py index db5258ac73e..338b3e58af0 100644 --- a/tests/testing/internal/test_api_client.py +++ b/tests/testing/internal/test_api_client.py @@ -388,7 +388,7 @@ def test_get_known_tests(self, mock_telemetry: Mock) -> None: "env": "some-env", "repository_url": "http://github.com/DataDog/some-repo.git", "configurations": {"os.platform": "Linux"}, - "page_info": {"page_size": 2000}, + "page_info": {}, }, } }, From f0d0eedb259cf4da99a26e8524eb9de273c27f7f Mon Sep 17 00:00:00 2001 From: Federico Mon Date: Thu, 28 May 2026 09:41:19 +0000 Subject: [PATCH 12/16] fix(ci_visibility): set initial page_size to 20k in known tests request Co-Authored-By: Claude Sonnet 4.6 --- ddtrace/testing/internal/api_client.py | 2 +- tests/testing/internal/test_api_client.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ddtrace/testing/internal/api_client.py b/ddtrace/testing/internal/api_client.py index 4cb14d4396c..9ec68bd00be 100644 --- a/ddtrace/testing/internal/api_client.py +++ b/ddtrace/testing/internal/api_client.py @@ -150,7 +150,7 @@ def get_known_tests(self) -> set[TestRef]: # the request is sent. To fix: rename this to `request_page_info` and the response # assignment to `response_page_info` (same pattern as _api_client.py fetch_known_tests). if page_state is None: - page_info: dict[str, t.Any] = {} + page_info: dict[str, t.Any] = {"page_size": 20_000} else: page_info = {"page_state": page_state} if page_size is not None: diff --git a/tests/testing/internal/test_api_client.py b/tests/testing/internal/test_api_client.py index 338b3e58af0..46f94dc6b62 100644 --- a/tests/testing/internal/test_api_client.py +++ b/tests/testing/internal/test_api_client.py @@ -388,7 +388,7 @@ def test_get_known_tests(self, mock_telemetry: Mock) -> None: "env": "some-env", "repository_url": "http://github.com/DataDog/some-repo.git", "configurations": {"os.platform": "Linux"}, - "page_info": {}, + "page_info": {"page_size": 20000}, }, } }, From a2e5adf118e6c83cef60ce6e4c66061edab5c9cb Mon Sep 17 00:00:00 2001 From: Federico Mon Date: Thu, 28 May 2026 11:16:57 +0000 Subject: [PATCH 13/16] feat(ci_visibility): enable gzip compression for known tests requests Co-Authored-By: Claude Sonnet 4.6 --- ddtrace/testing/internal/api_client.py | 4 +++- tests/testing/internal/test_api_client.py | 7 +++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/ddtrace/testing/internal/api_client.py b/ddtrace/testing/internal/api_client.py index 9ec68bd00be..8a133ef2f2e 100644 --- a/ddtrace/testing/internal/api_client.py +++ b/ddtrace/testing/internal/api_client.py @@ -179,7 +179,9 @@ def get_known_tests(self) -> set[TestRef]: return set() try: - result = self.connector.post_json("/api/v2/ci/libraries/tests", request_data, telemetry=telemetry) + result = self.connector.post_json( + "/api/v2/ci/libraries/tests", request_data, send_gzip=True, telemetry=telemetry + ) result.on_error_raise_exception() except Exception as e: diff --git a/tests/testing/internal/test_api_client.py b/tests/testing/internal/test_api_client.py index 46f94dc6b62..5cef9c4defd 100644 --- a/tests/testing/internal/test_api_client.py +++ b/tests/testing/internal/test_api_client.py @@ -392,6 +392,7 @@ def test_get_known_tests(self, mock_telemetry: Mock) -> None: }, } }, + send_gzip=True, telemetry=mock_telemetry.with_request_metric_names.return_value, ) ] @@ -452,7 +453,9 @@ def test_get_known_tests_pagination_sends_page_info_correctly(self, mock_telemet known_tests = api_client.get_known_tests() assert len(mock_connector.post_json.call_args_list) == 2 - assert mock_connector.post_json.call_args_list[0][0][1]["data"]["attributes"]["page_info"] == {} + assert mock_connector.post_json.call_args_list[0][0][1]["data"]["attributes"]["page_info"] == { + "page_size": 20000 + } assert mock_connector.post_json.call_args_list[1][0][1]["data"]["attributes"]["page_info"] == { "page_state": "cursor-page-1" } @@ -525,7 +528,7 @@ def test_get_known_tests_pagination_full_request_payload(self, mock_telemetry: M "data": { "id": "00000000-0000-0000-0000-000000000000", "type": "ci_app_libraries_tests_request", - "attributes": {**expected_shared_attributes, "page_info": {}}, + "attributes": {**expected_shared_attributes, "page_info": {"page_size": 20000}}, } } From bcbb47602563694b538822f6cc8a609805206b0a Mon Sep 17 00:00:00 2001 From: Federico Mon Date: Thu, 28 May 2026 11:30:35 +0000 Subject: [PATCH 14/16] revert(ci_visibility): remove send_gzip from known tests request Backend returns 400 when Content-Encoding: gzip is sent. Accept-Encoding: gzip for compressed responses is still active via the connector's use_gzip=True default. Co-Authored-By: Claude Sonnet 4.6 --- ddtrace/testing/internal/api_client.py | 4 +--- tests/testing/internal/test_api_client.py | 1 - 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/ddtrace/testing/internal/api_client.py b/ddtrace/testing/internal/api_client.py index 8a133ef2f2e..9ec68bd00be 100644 --- a/ddtrace/testing/internal/api_client.py +++ b/ddtrace/testing/internal/api_client.py @@ -179,9 +179,7 @@ def get_known_tests(self) -> set[TestRef]: return set() try: - result = self.connector.post_json( - "/api/v2/ci/libraries/tests", request_data, send_gzip=True, telemetry=telemetry - ) + result = self.connector.post_json("/api/v2/ci/libraries/tests", request_data, telemetry=telemetry) result.on_error_raise_exception() except Exception as e: diff --git a/tests/testing/internal/test_api_client.py b/tests/testing/internal/test_api_client.py index 5cef9c4defd..d4e911947cf 100644 --- a/tests/testing/internal/test_api_client.py +++ b/tests/testing/internal/test_api_client.py @@ -392,7 +392,6 @@ def test_get_known_tests(self, mock_telemetry: Mock) -> None: }, } }, - send_gzip=True, telemetry=mock_telemetry.with_request_metric_names.return_value, ) ] From ac8e9f77f3342dcc1d0ad81373b89a01f50c1546 Mon Sep 17 00:00:00 2001 From: Federico Mon Date: Thu, 28 May 2026 11:31:37 +0000 Subject: [PATCH 15/16] feat(ci_visibility): increase known tests page_size to 50k Co-Authored-By: Claude Sonnet 4.6 --- ddtrace/testing/internal/api_client.py | 2 +- tests/testing/internal/test_api_client.py | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/ddtrace/testing/internal/api_client.py b/ddtrace/testing/internal/api_client.py index 9ec68bd00be..2f25f627477 100644 --- a/ddtrace/testing/internal/api_client.py +++ b/ddtrace/testing/internal/api_client.py @@ -150,7 +150,7 @@ def get_known_tests(self) -> set[TestRef]: # the request is sent. To fix: rename this to `request_page_info` and the response # assignment to `response_page_info` (same pattern as _api_client.py fetch_known_tests). if page_state is None: - page_info: dict[str, t.Any] = {"page_size": 20_000} + page_info: dict[str, t.Any] = {"page_size": 50_000} else: page_info = {"page_state": page_state} if page_size is not None: diff --git a/tests/testing/internal/test_api_client.py b/tests/testing/internal/test_api_client.py index d4e911947cf..428414b0a38 100644 --- a/tests/testing/internal/test_api_client.py +++ b/tests/testing/internal/test_api_client.py @@ -388,7 +388,7 @@ def test_get_known_tests(self, mock_telemetry: Mock) -> None: "env": "some-env", "repository_url": "http://github.com/DataDog/some-repo.git", "configurations": {"os.platform": "Linux"}, - "page_info": {"page_size": 20000}, + "page_info": {"page_size": 50000}, }, } }, @@ -453,7 +453,7 @@ def test_get_known_tests_pagination_sends_page_info_correctly(self, mock_telemet assert len(mock_connector.post_json.call_args_list) == 2 assert mock_connector.post_json.call_args_list[0][0][1]["data"]["attributes"]["page_info"] == { - "page_size": 20000 + "page_size": 50000 } assert mock_connector.post_json.call_args_list[1][0][1]["data"]["attributes"]["page_info"] == { "page_state": "cursor-page-1" @@ -527,7 +527,7 @@ def test_get_known_tests_pagination_full_request_payload(self, mock_telemetry: M "data": { "id": "00000000-0000-0000-0000-000000000000", "type": "ci_app_libraries_tests_request", - "attributes": {**expected_shared_attributes, "page_info": {"page_size": 20000}}, + "attributes": {**expected_shared_attributes, "page_info": {"page_size": 50000}}, } } From b01be9517d00b47a6ff42914db2281a07830924f Mon Sep 17 00:00:00 2001 From: Federico Mon Date: Thu, 28 May 2026 11:57:39 +0000 Subject: [PATCH 16/16] feat(ci_visibility): revert known tests page_size to 20k 50k caused issues; back to 20k. Co-Authored-By: Claude Sonnet 4.6 --- ddtrace/testing/internal/api_client.py | 2 +- tests/testing/internal/test_api_client.py | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/ddtrace/testing/internal/api_client.py b/ddtrace/testing/internal/api_client.py index 2f25f627477..9ec68bd00be 100644 --- a/ddtrace/testing/internal/api_client.py +++ b/ddtrace/testing/internal/api_client.py @@ -150,7 +150,7 @@ def get_known_tests(self) -> set[TestRef]: # the request is sent. To fix: rename this to `request_page_info` and the response # assignment to `response_page_info` (same pattern as _api_client.py fetch_known_tests). if page_state is None: - page_info: dict[str, t.Any] = {"page_size": 50_000} + page_info: dict[str, t.Any] = {"page_size": 20_000} else: page_info = {"page_state": page_state} if page_size is not None: diff --git a/tests/testing/internal/test_api_client.py b/tests/testing/internal/test_api_client.py index 428414b0a38..d4e911947cf 100644 --- a/tests/testing/internal/test_api_client.py +++ b/tests/testing/internal/test_api_client.py @@ -388,7 +388,7 @@ def test_get_known_tests(self, mock_telemetry: Mock) -> None: "env": "some-env", "repository_url": "http://github.com/DataDog/some-repo.git", "configurations": {"os.platform": "Linux"}, - "page_info": {"page_size": 50000}, + "page_info": {"page_size": 20000}, }, } }, @@ -453,7 +453,7 @@ def test_get_known_tests_pagination_sends_page_info_correctly(self, mock_telemet assert len(mock_connector.post_json.call_args_list) == 2 assert mock_connector.post_json.call_args_list[0][0][1]["data"]["attributes"]["page_info"] == { - "page_size": 50000 + "page_size": 20000 } assert mock_connector.post_json.call_args_list[1][0][1]["data"]["attributes"]["page_info"] == { "page_state": "cursor-page-1" @@ -527,7 +527,7 @@ def test_get_known_tests_pagination_full_request_payload(self, mock_telemetry: M "data": { "id": "00000000-0000-0000-0000-000000000000", "type": "ci_app_libraries_tests_request", - "attributes": {**expected_shared_attributes, "page_info": {"page_size": 50000}}, + "attributes": {**expected_shared_attributes, "page_info": {"page_size": 20000}}, } }