Skip to content

Commit d7dff4e

Browse files
chore(ci_visibility): add telemetry to the new plugin, part 3
1 parent 52da0eb commit d7dff4e

File tree

4 files changed

+213
-91
lines changed

4 files changed

+213
-91
lines changed

ddtrace/testing/internal/api_client.py

Lines changed: 192 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
from ddtrace.testing.internal.http import FileAttachment
1313
from ddtrace.testing.internal.settings_data import Settings
1414
from ddtrace.testing.internal.settings_data import TestProperties
15+
from ddtrace.testing.internal.telemetry import ErrorType
1516
from ddtrace.testing.internal.telemetry import TelemetryAPI
1617
from ddtrace.testing.internal.test_data import ITRSkippingLevel
1718
from ddtrace.testing.internal.test_data import ModuleRef
@@ -52,36 +53,50 @@ def get_settings(self) -> Settings:
5253
error="git_requests.settings_errors",
5354
)
5455

55-
request_data = {
56-
"data": {
57-
"id": str(uuid.uuid4()),
58-
"type": "ci_app_test_service_libraries_settings",
59-
"attributes": {
60-
"test_level": self.itr_skipping_level.value,
61-
"service": self.service,
62-
"env": self.env,
63-
"repository_url": self.env_tags[GitTag.REPOSITORY_URL],
64-
"sha": self.env_tags[GitTag.COMMIT_SHA],
65-
"branch": self.env_tags[GitTag.BRANCH],
66-
"configurations": self.configurations,
67-
},
56+
try:
57+
request_data = {
58+
"data": {
59+
"id": str(uuid.uuid4()),
60+
"type": "ci_app_test_service_libraries_settings",
61+
"attributes": {
62+
"test_level": self.itr_skipping_level.value,
63+
"service": self.service,
64+
"env": self.env,
65+
"repository_url": self.env_tags[GitTag.REPOSITORY_URL],
66+
"sha": self.env_tags[GitTag.COMMIT_SHA],
67+
"branch": self.env_tags[GitTag.BRANCH],
68+
"configurations": self.configurations,
69+
},
70+
}
6871
}
69-
}
72+
73+
except KeyError as e:
74+
log.error("Git info not available, cannot fetch settings (missing key: %s)", e)
75+
telemetry.record_error(ErrorType.UNKNOWN)
76+
return Settings()
7077

7178
try:
7279
result = self.connector.post_json(
7380
"/api/v2/libraries/tests/services/setting", request_data, telemetry=telemetry
7481
)
7582
result.on_error_raise_exception()
83+
84+
except Exception as e:
85+
log.error("Error getting settings from API: %s", e)
86+
return Settings()
87+
88+
try:
7689
attributes = result.parsed_response["data"]["attributes"]
7790
settings = Settings.from_attributes(attributes)
78-
self.telemetry_api.record_settings(settings)
79-
return settings
8091

81-
except Exception:
82-
log.exception("Error getting settings from API")
92+
except Exception as e:
93+
log.exception("Error getting settings from API: %s", e)
94+
telemetry.record_error(ErrorType.BAD_JSON)
8395
return Settings()
8496

97+
self.telemetry_api.record_settings(settings)
98+
return settings
99+
85100
def get_known_tests(self) -> t.Set[TestRef]:
86101
telemetry = self.telemetry_api.with_request_metric_names(
87102
count="known_tests.request",
@@ -90,22 +105,34 @@ def get_known_tests(self) -> t.Set[TestRef]:
90105
error="known_tests.request_errors",
91106
)
92107

93-
request_data = {
94-
"data": {
95-
"id": str(uuid.uuid4()),
96-
"type": "ci_app_libraries_tests_request",
97-
"attributes": {
98-
"service": self.service,
99-
"env": self.env,
100-
"repository_url": self.env_tags[GitTag.REPOSITORY_URL],
101-
"configurations": self.configurations,
102-
},
108+
try:
109+
request_data = {
110+
"data": {
111+
"id": str(uuid.uuid4()),
112+
"type": "ci_app_libraries_tests_request",
113+
"attributes": {
114+
"service": self.service,
115+
"env": self.env,
116+
"repository_url": self.env_tags[GitTag.REPOSITORY_URL],
117+
"configurations": self.configurations,
118+
},
119+
}
103120
}
104-
}
121+
122+
except KeyError as e:
123+
log.error("Git info not available, cannot fetch known tests (missing key: %s)", e)
124+
telemetry.record_error(ErrorType.UNKNOWN)
125+
return set()
105126

106127
try:
107128
result = self.connector.post_json("/api/v2/ci/libraries/tests", request_data, telemetry=telemetry)
108129
result.on_error_raise_exception()
130+
131+
except Exception as e:
132+
log.exception("Error getting known tests from API: %s", e)
133+
return set()
134+
135+
try:
109136
tests_data = result.parsed_response["data"]["attributes"]["tests"]
110137
known_test_ids = set()
111138

@@ -116,13 +143,14 @@ def get_known_tests(self) -> t.Set[TestRef]:
116143
for test in tests:
117144
known_test_ids.add(TestRef(suite_ref, test))
118145

119-
self.telemetry_api.record_known_tests_count(len(known_test_ids))
120-
return known_test_ids
121-
122146
except Exception:
123147
log.exception("Error getting known tests from API")
148+
telemetry.record_error(ErrorType.BAD_JSON)
124149
return set()
125150

151+
self.telemetry_api.record_known_tests_count(len(known_test_ids))
152+
return known_test_ids
153+
126154
def get_test_management_properties(self) -> t.Dict[TestRef, TestProperties]:
127155
telemetry = self.telemetry_api.with_request_metric_names(
128156
count="test_management_tests.request",
@@ -131,23 +159,35 @@ def get_test_management_properties(self) -> t.Dict[TestRef, TestProperties]:
131159
error="test_management_tests.request_errors",
132160
)
133161

134-
request_data = {
135-
"data": {
136-
"id": str(uuid.uuid4()),
137-
"type": "ci_app_libraries_tests_request",
138-
"attributes": {
139-
"repository_url": self.env_tags[GitTag.REPOSITORY_URL],
140-
"commit_message": self.env_tags[GitTag.COMMIT_MESSAGE],
141-
"sha": self.env_tags[GitTag.COMMIT_SHA],
142-
},
162+
try:
163+
request_data = {
164+
"data": {
165+
"id": str(uuid.uuid4()),
166+
"type": "ci_app_libraries_tests_request",
167+
"attributes": {
168+
"repository_url": self.env_tags[GitTag.REPOSITORY_URL],
169+
"commit_message": self.env_tags[GitTag.COMMIT_MESSAGE],
170+
"sha": self.env_tags[GitTag.COMMIT_SHA],
171+
},
172+
}
143173
}
144-
}
174+
175+
except KeyError as e:
176+
log.error("Git info not available, cannot fetch Test Management properties (missing key: %s)", e)
177+
telemetry.record_error(ErrorType.UNKNOWN)
178+
return {}
145179

146180
try:
147181
result = self.connector.post_json(
148182
"/api/v2/test/libraries/test-management/tests", request_data, telemetry=telemetry
149183
)
150184
result.on_error_raise_exception()
185+
186+
except Exception as e:
187+
log.error("Error getting Test Management properties from API: %s", e)
188+
return {}
189+
190+
try:
151191
test_properties: t.Dict[TestRef, TestProperties] = {}
152192
modules = result.parsed_response["data"]["attributes"]["modules"]
153193

@@ -166,54 +206,103 @@ def get_test_management_properties(self) -> t.Dict[TestRef, TestProperties]:
166206
attempt_to_fix=properties.get("attempt_to_fix", False),
167207
)
168208

169-
self.telemetry_api.record_test_management_tests_count(len(test_properties))
170-
171-
return test_properties
172-
173209
except Exception:
174-
log.exception("Failed to parse Test Management tests data")
210+
log.exception("Failed to parse Test Management tests data from API")
211+
telemetry.record_error(ErrorType.BAD_JSON)
175212
return {}
176213

214+
self.telemetry_api.record_test_management_tests_count(len(test_properties))
215+
return test_properties
216+
177217
def get_known_commits(self, latest_commits: t.List[str]) -> t.List[str]:
178-
request_data = {
179-
"meta": {
180-
"repository_url": self.env_tags[GitTag.REPOSITORY_URL],
181-
},
182-
"data": [{"id": sha, "type": "commit"} for sha in latest_commits],
183-
}
218+
telemetry = self.telemetry_api.with_request_metric_names(
219+
count="git_requests.search_commits",
220+
duration="git_requests.search_commits_ms",
221+
response_bytes=None,
222+
error="git_requests.search_commits_errors",
223+
)
224+
225+
try:
226+
request_data = {
227+
"meta": {
228+
"repository_url": self.env_tags[GitTag.REPOSITORY_URL],
229+
},
230+
"data": [{"id": sha, "type": "commit"} for sha in latest_commits],
231+
}
232+
233+
except KeyError as e:
234+
log.error("Git info not available, cannot fetch known commits (missing key: %s)", e)
235+
telemetry.record_error(ErrorType.UNKNOWN)
236+
return []
184237

185238
try:
186239
result = self.connector.post_json("/api/v2/git/repository/search_commits", request_data)
187240
result.on_error_raise_exception()
188-
return [item["id"] for item in result.parsed_response["data"] if item["type"] == "commit"]
241+
242+
except Exception as e:
243+
log.error("Error getting known commits from API: %s", e)
244+
return []
245+
246+
try:
247+
known_commits = [item["id"] for item in result.parsed_response["data"] if item["type"] == "commit"]
189248

190249
except Exception:
191250
log.exception("Failed to parse search_commits data")
251+
telemetry.record_error(ErrorType.BAD_JSON)
192252
return []
193253

194-
def send_git_pack_file(self, packfile: Path) -> None:
195-
metadata = {
196-
"data": {"id": self.env_tags[GitTag.COMMIT_SHA], "type": "commit"},
197-
"meta": {"repository_url": self.env_tags[GitTag.REPOSITORY_URL]},
198-
}
199-
content = packfile.read_bytes()
200-
files = [
201-
FileAttachment(
202-
name="pushedSha",
203-
filename=None,
204-
content_type="application/json",
205-
data=json.dumps(metadata).encode("utf-8"),
206-
),
207-
FileAttachment(
208-
name="packfile", filename=packfile.name, content_type="application/octet-stream", data=content
209-
),
210-
]
254+
return known_commits
255+
256+
def send_git_pack_file(self, packfile: Path) -> t.Optional[int]:
257+
telemetry = self.telemetry_api.with_request_metric_names(
258+
count="git_requests.objects_pack",
259+
duration="git_requests.objects_pack_ms",
260+
response_bytes=None,
261+
error="git_requests.objects_pack_errors",
262+
)
263+
264+
try:
265+
metadata = {
266+
"data": {"id": self.env_tags[GitTag.COMMIT_SHA], "type": "commit"},
267+
"meta": {"repository_url": self.env_tags[GitTag.REPOSITORY_URL]},
268+
}
269+
270+
except KeyError as e:
271+
log.error("Git info not available, cannot send git packfile (missing key: %s)", e)
272+
telemetry.record_error(ErrorType.UNKNOWN)
273+
return None
274+
211275
try:
212-
result = self.connector.post_files("/api/v2/git/repository/packfile", files=files, send_gzip=False)
276+
content = packfile.read_bytes()
277+
278+
files = [
279+
FileAttachment(
280+
name="pushedSha",
281+
filename=None,
282+
content_type="application/json",
283+
data=json.dumps(metadata).encode("utf-8"),
284+
),
285+
FileAttachment(
286+
name="packfile", filename=packfile.name, content_type="application/octet-stream", data=content
287+
),
288+
]
289+
290+
except Exception:
291+
log.exception("Error sending Git pack data")
292+
telemetry.record_error(ErrorType.UNKNOWN)
293+
return None
294+
295+
try:
296+
result = self.connector.post_files(
297+
"/api/v2/git/repository/packfile", files=files, send_gzip=False, telemetry=telemetry
298+
)
213299
result.on_error_raise_exception()
214300

215301
except Exception:
216-
log.warning("Failed to upload git pack data")
302+
log.warning("Failed to upload Git pack data")
303+
return None
304+
305+
return len(content)
217306

218307
def get_skippable_tests(self) -> t.Tuple[t.Set[t.Union[SuiteRef, TestRef]], t.Optional[str]]:
219308
telemetry = self.telemetry_api.with_request_metric_names(
@@ -223,24 +312,36 @@ def get_skippable_tests(self) -> t.Tuple[t.Set[t.Union[SuiteRef, TestRef]], t.Op
223312
error="itr_skippable_tests.request_errors",
224313
)
225314

226-
request_data = {
227-
"data": {
228-
"id": str(uuid.uuid4()),
229-
"type": "test_params",
230-
"attributes": {
231-
"service": self.service,
232-
"env": self.env,
233-
"repository_url": self.env_tags[GitTag.REPOSITORY_URL],
234-
"sha": self.env_tags[GitTag.COMMIT_SHA],
235-
"configurations": self.configurations,
236-
"test_level": self.itr_skipping_level.value,
237-
},
315+
try:
316+
request_data = {
317+
"data": {
318+
"id": str(uuid.uuid4()),
319+
"type": "test_params",
320+
"attributes": {
321+
"service": self.service,
322+
"env": self.env,
323+
"repository_url": self.env_tags[GitTag.REPOSITORY_URL],
324+
"sha": self.env_tags[GitTag.COMMIT_SHA],
325+
"configurations": self.configurations,
326+
"test_level": self.itr_skipping_level.value,
327+
},
328+
}
238329
}
239-
}
330+
331+
except KeyError as e:
332+
log.error("Git info not available, cannot get skippable items (missing key: %s)", e)
333+
telemetry.record_error(ErrorType.UNKNOWN)
334+
return set(), None
335+
240336
try:
241337
result = self.connector.post_json("/api/v2/ci/tests/skippable", request_data, telemetry=telemetry)
242338
result.on_error_raise_exception()
243339

340+
except Exception as e:
341+
log.error("Error getting known commits from API: %s", e)
342+
return set(), None
343+
344+
try:
244345
skippable_items: t.Set[t.Union[SuiteRef, TestRef]] = set()
245346

246347
for item in result.parsed_response["data"]:
@@ -255,10 +356,11 @@ def get_skippable_tests(self) -> t.Tuple[t.Set[t.Union[SuiteRef, TestRef]], t.Op
255356

256357
correlation_id = result.parsed_response["meta"]["correlation_id"]
257358

258-
self.telemetry_api.record_skippable_count(count=len(skippable_items), level=self.itr_skipping_level)
259-
260-
return skippable_items, correlation_id
261-
262359
except Exception:
263360
log.exception("Error getting skippable tests from API")
361+
telemetry.record_error(ErrorType.BAD_JSON)
264362
return set(), None
363+
364+
self.telemetry_api.record_skippable_count(count=len(skippable_items), level=self.itr_skipping_level)
365+
366+
return skippable_items, correlation_id

0 commit comments

Comments
 (0)