Skip to content

Commit f1cfa5e

Browse files
refactor(ci_visibility): remove core usage (#13654)
Co-authored-by: Vítor De Araújo <[email protected]>
1 parent 5cb7719 commit f1cfa5e

30 files changed

+727
-1573
lines changed

ddtrace/contrib/internal/pytest/_plugin_v1.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -472,7 +472,7 @@ def pytest_sessionstart(session):
472472
global _global_skipped_elements
473473
_global_skipped_elements = 0
474474

475-
workspace_path = _CIVisibility.get_workspace_path()
475+
workspace_path = _CIVisibility._instance.get_workspace_path()
476476
if workspace_path is None:
477477
workspace_path = session.config.rootdir
478478

@@ -492,7 +492,7 @@ def pytest_sessionstart(session):
492492
test_session_span.set_tag_str(test.COMMAND, test_command)
493493
test_session_span.set_tag_str(_SESSION_ID, str(test_session_span.span_id))
494494

495-
_CIVisibility.set_test_session_name(test_command=test_command)
495+
_CIVisibility._instance.set_test_session_name(test_command=test_command)
496496

497497
if _CIVisibility.test_skipping_enabled():
498498
test_session_span.set_tag_str(test.ITR_TEST_SKIPPING_ENABLED, "true")

ddtrace/contrib/internal/pytest/_plugin_v2.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -441,7 +441,7 @@ def _pytest_runtest_protocol_pre_yield(item) -> t.Optional[ModuleCodeCollector.C
441441
_handle_test_management(item, test_id)
442442
_handle_itr_should_skip(item, test_id)
443443

444-
item_will_skip = _pytest_marked_to_skip(item) or InternalTest.was_skipped_by_itr(test_id)
444+
item_will_skip = _pytest_marked_to_skip(item) or InternalTest.was_itr_skipped(test_id)
445445

446446
collect_test_coverage = InternalTestSession.should_collect_coverage() and not item_will_skip
447447

@@ -470,7 +470,7 @@ def _pytest_runtest_protocol_post_yield(item, nextitem, coverage_collector):
470470
# - we trust that the next item is in the same module if it is in the same suite
471471
next_test_id = _get_test_id_from_item(nextitem) if nextitem else None
472472
if next_test_id is None or next_test_id.parent_id != suite_id:
473-
if InternalTestSuite.is_itr_skippable(suite_id) and not InternalTestSuite.was_forced_run(suite_id):
473+
if InternalTestSuite.is_itr_skippable(suite_id) and not InternalTestSuite.was_itr_forced_run(suite_id):
474474
InternalTestSuite.mark_itr_skipped(suite_id)
475475
else:
476476
_handle_coverage_dependencies(suite_id)
@@ -611,7 +611,7 @@ def _process_result(item, result) -> _TestOutcome:
611611
# If run with --runxfail flag, tests behave as if they were not marked with xfail,
612612
# that's why no XFAIL_REASON or test.RESULT tags will be added.
613613
if result.skipped:
614-
if InternalTest.was_skipped_by_itr(test_id):
614+
if InternalTest.was_itr_skipped(test_id):
615615
# Items that were skipped by ITR already have their status and reason set
616616
return _TestOutcome()
617617

@@ -794,7 +794,7 @@ def _pytest_sessionfinish(session: pytest.Session, exitstatus: int) -> None:
794794
if skipped_count > 0:
795795
# Update the session's internal _itr_skipped_count so that when _set_itr_tags() is called
796796
# during session finishing, it will use the correct worker-aggregated count
797-
InternalTestSession.set_itr_tags(skipped_count)
797+
InternalTestSession.set_itr_skipped_count(skipped_count)
798798

799799
InternalTestSession.finish(
800800
force_finish_children=True,

ddtrace/contrib/internal/pytest/_report_links.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
from urllib.parse import quote
44

55
from ddtrace.ext import ci
6-
from ddtrace.internal.ci_visibility import CIVisibility
6+
from ddtrace.internal.ci_visibility.service_registry import require_ci_visibility_service
77

88

99
DEFAULT_DATADOG_SITE = "datadoghq.com"
@@ -16,10 +16,11 @@ def print_test_report_links(terminalreporter):
1616
base_url = _get_base_url(
1717
dd_site=os.getenv("DD_SITE", DEFAULT_DATADOG_SITE), dd_subdomain=os.getenv("DD_SUBDOMAIN", "")
1818
)
19-
ci_tags = CIVisibility.get_ci_tags()
20-
settings = CIVisibility.get_session_settings()
19+
ci_visibility_instance = require_ci_visibility_service()
20+
ci_tags = ci_visibility_instance.get_ci_tags()
21+
settings = ci_visibility_instance.get_session_settings()
2122
service = settings.test_service
22-
env = CIVisibility.get_dd_env()
23+
env = ci_visibility_instance.get_dd_env()
2324

2425
redirect_test_commit_url = _build_test_commit_redirect_url(base_url, ci_tags, service, env)
2526
test_runs_url = _build_test_runs_url(base_url, ci_tags)

ddtrace/contrib/internal/unittest/patch.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -659,7 +659,7 @@ def _start_test_session_span(instance) -> ddtrace.trace.Span:
659659
"true" if _CIVisibility._instance._collect_coverage_enabled else "false",
660660
)
661661

662-
_CIVisibility.set_test_session_name(test_command=test_command)
662+
_CIVisibility._instance.set_test_session_name(test_command=test_command)
663663

664664
if _CIVisibility.test_skipping_enabled():
665665
_set_test_skipping_tags_to_span(test_session_span)

ddtrace/ext/test_visibility/_item_ids.py

Lines changed: 0 additions & 38 deletions
This file was deleted.

ddtrace/ext/test_visibility/_test_visibility_base.py

Lines changed: 34 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,7 @@
22
import dataclasses
33
from enum import Enum
44
from pathlib import Path
5-
from typing import Any
6-
from typing import Dict
75
from typing import Generic
8-
from typing import List
9-
from typing import NamedTuple
106
from typing import Optional
117
from typing import TypeVar
128
from typing import Union
@@ -61,46 +57,57 @@ def get_parent_id(self) -> PT:
6157
return self.parent_id
6258

6359

64-
TestVisibilityItemId = TypeVar(
65-
"TestVisibilityItemId", bound=Union[_TestVisibilityChildItemIdBase, _TestVisibilityRootItemIdBase, TestSessionId]
66-
)
60+
@dataclasses.dataclass(frozen=True)
61+
class TestModuleId(_TestVisibilityRootItemIdBase):
62+
name: str
6763

64+
def __repr__(self):
65+
return "TestModuleId(module={})".format(
66+
self.name,
67+
)
6868

69-
class _TestVisibilityAPIBase(abc.ABC):
70-
__test__ = False
7169

72-
class GetTagArgs(NamedTuple):
73-
item_id: Union[_TestVisibilityChildItemIdBase, _TestVisibilityRootItemIdBase, TestSessionId]
74-
name: str
70+
@dataclasses.dataclass(frozen=True)
71+
class TestSuiteId(_TestVisibilityChildItemIdBase[TestModuleId]):
72+
def __repr__(self):
73+
return "TestSuiteId(module={}, suite={})".format(self.parent_id.name, self.name)
7574

76-
class SetTagArgs(NamedTuple):
77-
item_id: Union[_TestVisibilityChildItemIdBase, _TestVisibilityRootItemIdBase, TestSessionId]
78-
name: str
79-
value: Any
8075

81-
class DeleteTagArgs(NamedTuple):
82-
item_id: Union[_TestVisibilityChildItemIdBase, _TestVisibilityRootItemIdBase, TestSessionId]
83-
name: str
76+
@dataclasses.dataclass(frozen=True)
77+
class TestId(_TestVisibilityChildItemIdBase[TestSuiteId]):
78+
parameters: Optional[str] = None # For hashability, a JSON string of a dictionary of parameters
8479

85-
class SetTagsArgs(NamedTuple):
86-
item_id: Union[_TestVisibilityChildItemIdBase, _TestVisibilityRootItemIdBase, TestSessionId]
87-
tags: Dict[str, Any]
80+
def __repr__(self):
81+
return "TestId(module={}, suite={}, test={}, parameters={})".format(
82+
self.parent_id.parent_id.name,
83+
self.parent_id.name,
84+
self.name,
85+
self.parameters,
86+
)
8887

89-
class DeleteTagsArgs(NamedTuple):
90-
item_id: Union[_TestVisibilityChildItemIdBase, _TestVisibilityRootItemIdBase, TestSessionId]
91-
names: List[str]
88+
89+
TestVisibilityItemId = TypeVar(
90+
"TestVisibilityItemId",
91+
bound=Union[
92+
_TestVisibilityChildItemIdBase, _TestVisibilityRootItemIdBase, TestSessionId, TestModuleId, TestSuiteId, TestId
93+
],
94+
)
95+
96+
97+
class _TestVisibilityAPIBase(abc.ABC):
98+
__test__ = False
9299

93100
def __init__(self):
94101
raise NotImplementedError("This class is not meant to be instantiated")
95102

96103
@staticmethod
97104
@abc.abstractmethod
98-
def discover(item_id: TestVisibilityItemId, *args, **kwargs):
105+
def discover(*args, **kwargs):
99106
pass
100107

101108
@staticmethod
102109
@abc.abstractmethod
103-
def start(item_id: TestVisibilityItemId, *args, **kwargs):
110+
def start(*args, **kwargs):
104111
pass
105112

106113
@staticmethod

ddtrace/ext/test_visibility/_utils.py

Lines changed: 7 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,19 @@
11
from functools import wraps
2-
from typing import Any
3-
from typing import Dict
4-
from typing import List
52

6-
from ddtrace.ext.test_visibility._test_visibility_base import TestVisibilityItemId
7-
from ddtrace.ext.test_visibility._test_visibility_base import _TestVisibilityAPIBase
8-
from ddtrace.internal import core
3+
from ddtrace import config as ddconfig
94
from ddtrace.internal.logger import get_logger
105

116

127
log = get_logger(__name__)
138

149

10+
def _noop_decorator(func):
11+
return func
12+
13+
1514
def _catch_and_log_exceptions(func):
1615
"""This decorator is meant to be used around all methods of the Test Visibility classes.
17-
1816
It accepts an optional parameter to allow it to be used on functions and methods.
19-
2017
No uncaught errors should ever reach the integration-side, and potentially cause crashes.
2118
"""
2219

@@ -30,36 +27,5 @@ def wrapper(*args, **kwargs):
3027
return wrapper
3128

3229

33-
def _get_item_tag(item_id: TestVisibilityItemId, tag_name: str) -> Any:
34-
log.debug("Getting tag for item %s: %s", item_id, tag_name)
35-
tag_value = core.dispatch_with_results(
36-
"test_visibility.item.get_tag", (_TestVisibilityAPIBase.GetTagArgs(item_id, tag_name),)
37-
).tag_value.value
38-
return tag_value
39-
40-
41-
def _set_item_tag(item_id: TestVisibilityItemId, tag_name: str, tag_value: Any, recurse: bool = False):
42-
log.debug("Setting tag for item %s: %s=%s", item_id, tag_name, tag_value)
43-
core.dispatch("test_visibility.item.set_tag", (_TestVisibilityAPIBase.SetTagArgs(item_id, tag_name, tag_value),))
44-
45-
46-
def _set_item_tags(item_id: TestVisibilityItemId, tags: Dict[str, Any], recurse: bool = False):
47-
log.debug("Setting tags for item %s: %s", item_id, tags)
48-
core.dispatch("test_visibility.item.set_tags", (_TestVisibilityAPIBase.SetTagsArgs(item_id, tags),))
49-
50-
51-
def _delete_item_tag(item_id: TestVisibilityItemId, tag_name: str, recurse: bool = False):
52-
log.debug("Deleting tag for item %s: %s", item_id, tag_name)
53-
core.dispatch("test_visibility.item.delete_tag", (_TestVisibilityAPIBase.DeleteTagArgs(item_id, tag_name),))
54-
55-
56-
def _delete_item_tags(item_id: TestVisibilityItemId, tag_names: List[str], recurse: bool = False):
57-
log.debug("Deleting tags for item %s: %s", item_id, tag_names)
58-
core.dispatch("test_visibility.item.delete_tags", (_TestVisibilityAPIBase.DeleteTagsArgs(item_id, tag_names),))
59-
60-
61-
def _is_item_finished(item_id: TestVisibilityItemId) -> bool:
62-
log.debug("Checking if item %s is finished", item_id)
63-
_is_finished = bool(core.dispatch_with_results("test_visibility.item.is_finished", (item_id,)).is_finished.value)
64-
log.debug("Item %s is finished: %s", item_id, _is_finished)
65-
return _is_finished
30+
if ddconfig._raise:
31+
_catch_and_log_decorator = _noop_decorator

0 commit comments

Comments
 (0)