From 3f5a7c57bfe9ef5d46b972df9a68d888bfdd71b1 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 1 Aug 2024 17:46:34 -0400 Subject: [PATCH 1/4] chore: update release note wording for #9610 [backport 2.8] (#10046) Backport 64586b9de4dc15279e8ed72149e5abf6a91d28e0 from #10043 to 2.8. ## Checklist - [x] PR author has checked that all the criteria below are met - The PR description includes an overview of the change - The PR description articulates the motivation for the change - The change includes tests OR the PR description describes a testing strategy - The PR description notes risks associated with the change, if any - Newly-added code is easy to change - The change follows the [library release note guidelines](https://ddtrace.readthedocs.io/en/stable/releasenotes.html) - The change includes or references documentation updates if necessary - Backport labels are set (if [applicable](https://ddtrace.readthedocs.io/en/latest/contributing.html#backporting)) ## Reviewer Checklist - [x] Reviewer has checked that all the criteria below are met - Title is accurate - All changes are related to the pull request's stated goal - Avoids breaking [API](https://ddtrace.readthedocs.io/en/stable/versioning.html#interfaces) changes - Testing strategy adequately addresses listed risks - Newly-added code is easy to change - Release note makes sense to a user of the library - If necessary, author has acknowledged and discussed the performance implications of this PR as reported in the benchmarks PR comment - Backport labels are set in a manner that is consistent with the [release branch maintenance policy](https://ddtrace.readthedocs.io/en/latest/contributing.html#backporting) Co-authored-by: Taegyun Kim --- .../notes/profiling-add-lock-with-f75908e35a70ab71.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/releasenotes/notes/profiling-add-lock-with-f75908e35a70ab71.yaml b/releasenotes/notes/profiling-add-lock-with-f75908e35a70ab71.yaml index 422be5a041c..3969cd6f88c 100644 --- a/releasenotes/notes/profiling-add-lock-with-f75908e35a70ab71.yaml +++ b/releasenotes/notes/profiling-add-lock-with-f75908e35a70ab71.yaml @@ -1,3 +1,3 @@ -features: +fixes: - | profiling: captures lock usages with ``with`` context managers, e.g. ``with lock:`` From 93416f2784b68819f04882b2ed4a72a8fc6e255b Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 2 Aug 2024 08:48:57 +0100 Subject: [PATCH 2/4] fix(ci): add workaround for `importlib-resources` name discrepancies [backport 2.8] (#10033) Backport d4b8e9dfcc8e90e20b51b2e89b0e0495e356713c from #9871 to 2.8. Currently we have some `internal` test failures like [this](https://app.circleci.com/pipelines/github/DataDog/dd-trace-py/66174/workflows/c90a65a7-ba6a-4fa2-b834-73c5bfe51d80/jobs/4070901) on `importlib-resources` due to naming discrepancies. Seems like they started happening on main after https://github.com/DataDog/dd-trace-py/pull/9866 was merged into main. This should fix these failures. ## Checklist - [x] PR author has checked that all the criteria below are met - The PR description includes an overview of the change - The PR description articulates the motivation for the change - The change includes tests OR the PR description describes a testing strategy - The PR description notes risks associated with the change, if any - Newly-added code is easy to change - The change follows the [library release note guidelines](https://ddtrace.readthedocs.io/en/stable/releasenotes.html) - The change includes or references documentation updates if necessary - Backport labels are set (if [applicable](https://ddtrace.readthedocs.io/en/latest/contributing.html#backporting)) ## Reviewer Checklist - [x] Reviewer has checked that all the criteria below are met - Title is accurate - All changes are related to the pull request's stated goal - Avoids breaking [API](https://ddtrace.readthedocs.io/en/stable/versioning.html#interfaces) changes - Testing strategy adequately addresses listed risks - Newly-added code is easy to change - Release note makes sense to a user of the library - If necessary, author has acknowledged and discussed the performance implications of this PR as reported in the benchmarks PR comment - Backport labels are set in a manner that is consistent with the [release branch maintenance policy](https://ddtrace.readthedocs.io/en/latest/contributing.html#backporting) Co-authored-by: erikayasuda <153395705+erikayasuda@users.noreply.github.com> Co-authored-by: Romain Komorn <136473744+romainkomorndatadog@users.noreply.github.com> --- tests/internal/test_packages.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/internal/test_packages.py b/tests/internal/test_packages.py index 4f689d69c06..bd00c70f333 100644 --- a/tests/internal/test_packages.py +++ b/tests/internal/test_packages.py @@ -55,6 +55,10 @@ def test_get_distributions(): importlib_pkgs.add("importlib-metadata") elif pkg.name == "importlib-metadata" and "importlib_metadata" in pkg_resources_ws: importlib_pkgs.add("importlib_metadata") + elif pkg.name == "importlib-resources" and "importlib_resources" in pkg_resources_ws: + importlib_pkgs.add("importlib_resources") + elif pkg.name == "importlib_resources" and "importlib-resources" in pkg_resources_ws: + importlib_pkgs.add("importlib-resources") else: importlib_pkgs.add(pkg.name) From 1c2e737dd43a1164c36134959caeb893f9f6bf4a Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 2 Aug 2024 08:04:45 +0000 Subject: [PATCH 3/4] ci(opentelemetry): pin opentelemetry-api version to unblock tests [backport 2.8] (#9936) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Backport 27cd94cf93611bbae3b8e11b41f8ec167f53dc59 from #9932 to 2.8. Resolves the following failures: [https://app.circleci.com/pipelines/github/DataDog/dd-trace-py/66676/workflows/fa3470d[…]2a-d3447f3f431a/jobs/4095885/parallel-runs/2?filterBy=FAILED](https://app.circleci.com/pipelines/github/DataDog/dd-trace-py/66676/workflows/fa3470d1-e065-43a1-9a2a-d3447f3f431a/jobs/4095885/parallel-runs/2?filterBy=FAILED) in ci. The `opentelemetry-api` broke compatibility with ddtrace in v1.25.0 and then introduced another breaking change in 1.26.0. This PR ensures the telemetry test suite uses a stable version of the `opentelemetry-api`. ## Checklist - [x] PR author has checked that all the criteria below are met - The PR description includes an overview of the change - The PR description articulates the motivation for the change - The change includes tests OR the PR description describes a testing strategy - The PR description notes risks associated with the change, if any - Newly-added code is easy to change - The change follows the [library release note guidelines](https://ddtrace.readthedocs.io/en/stable/releasenotes.html) - The change includes or references documentation updates if necessary - Backport labels are set (if [applicable](https://ddtrace.readthedocs.io/en/latest/contributing.html#backporting)) ## Reviewer Checklist - [x] Reviewer has checked that all the criteria below are met - Title is accurate - All changes are related to the pull request's stated goal - Avoids breaking [API](https://ddtrace.readthedocs.io/en/stable/versioning.html#interfaces) changes - Testing strategy adequately addresses listed risks - Newly-added code is easy to change - Release note makes sense to a user of the library - If necessary, author has acknowledged and discussed the performance implications of this PR as reported in the benchmarks PR comment - Backport labels are set in a manner that is consistent with the [release branch maintenance policy](https://ddtrace.readthedocs.io/en/latest/contributing.html#backporting) Co-authored-by: Munir Abdinur --- .../requirements/{15235b0.txt => 12974a3.txt} | 33 ++++++++++--------- .../requirements/{1153ad9.txt => 1677649.txt} | 29 +++++++++------- .../requirements/{427c22a.txt => 17c4377.txt} | 15 +++++---- .../requirements/{135aac0.txt => 18589ec.txt} | 33 ++++++++++--------- .../requirements/{118cb50.txt => 1a14242.txt} | 31 +++++++++-------- .../requirements/{17a929f.txt => 5c0475c.txt} | 29 +++++++++------- riotfile.py | 2 ++ 7 files changed, 99 insertions(+), 73 deletions(-) rename .riot/requirements/{15235b0.txt => 12974a3.txt} (50%) rename .riot/requirements/{1153ad9.txt => 1677649.txt} (51%) rename .riot/requirements/{427c22a.txt => 17c4377.txt} (68%) rename .riot/requirements/{135aac0.txt => 18589ec.txt} (50%) rename .riot/requirements/{118cb50.txt => 1a14242.txt} (50%) rename .riot/requirements/{17a929f.txt => 5c0475c.txt} (51%) diff --git a/.riot/requirements/15235b0.txt b/.riot/requirements/12974a3.txt similarity index 50% rename from .riot/requirements/15235b0.txt rename to .riot/requirements/12974a3.txt index 7380eee24f9..db272e2f553 100644 --- a/.riot/requirements/15235b0.txt +++ b/.riot/requirements/12974a3.txt @@ -2,35 +2,38 @@ # This file is autogenerated by pip-compile with Python 3.8 # by the following command: # -# pip-compile --no-annotate --resolver=backtracking .riot/requirements/15235b0.in +# pip-compile --no-annotate .riot/requirements/12974a3.in # attrs==23.2.0 -certifi==2023.11.17 +certifi==2024.7.4 charset-normalizer==3.3.2 click==7.1.2 -coverage[toml]==7.4.0 -exceptiongroup==1.2.0 +coverage[toml]==7.6.0 +deprecated==1.2.14 +exceptiongroup==1.2.2 flask==1.1.4 -gunicorn==21.2.0 +gunicorn==22.0.0 httpretty==1.0.5 hypothesis==6.45.0 -idna==3.6 -importlib-metadata==7.0.1 +idna==3.7 +importlib-metadata==7.0.0 iniconfig==2.0.0 itsdangerous==1.1.0 jinja2==2.11.3 markupsafe==1.1.1 mock==5.1.0 +opentelemetry-api==1.24.0 opentracing==2.4.0 -packaging==23.2 -pluggy==1.3.0 -pytest==7.4.4 -pytest-cov==4.1.0 -pytest-mock==3.12.0 +packaging==24.1 +pluggy==1.5.0 +pytest==8.3.2 +pytest-cov==5.0.0 +pytest-mock==3.14.0 pytest-randomly==3.15.0 -requests==2.31.0 +requests==2.32.3 sortedcontainers==2.4.0 tomli==2.0.1 -urllib3==2.1.0 +urllib3==2.2.2 werkzeug==1.0.1 -zipp==3.17.0 +wrapt==1.16.0 +zipp==3.19.2 diff --git a/.riot/requirements/1153ad9.txt b/.riot/requirements/1677649.txt similarity index 51% rename from .riot/requirements/1153ad9.txt rename to .riot/requirements/1677649.txt index 3816405de28..e4862279695 100644 --- a/.riot/requirements/1153ad9.txt +++ b/.riot/requirements/1677649.txt @@ -2,31 +2,36 @@ # This file is autogenerated by pip-compile with Python 3.11 # by the following command: # -# pip-compile --no-annotate --resolver=backtracking .riot/requirements/1153ad9.in +# pip-compile --no-annotate .riot/requirements/1677649.in # attrs==23.2.0 -certifi==2023.11.17 +certifi==2024.7.4 charset-normalizer==3.3.2 click==7.1.2 -coverage[toml]==7.4.0 +coverage[toml]==7.6.0 +deprecated==1.2.14 flask==1.1.4 -gunicorn==21.2.0 +gunicorn==22.0.0 httpretty==1.0.5 hypothesis==6.45.0 -idna==3.6 +idna==3.7 +importlib-metadata==7.0.0 iniconfig==2.0.0 itsdangerous==1.1.0 jinja2==2.11.3 markupsafe==1.1.1 mock==5.1.0 +opentelemetry-api==1.24.0 opentracing==2.4.0 -packaging==23.2 -pluggy==1.3.0 -pytest==7.4.4 -pytest-cov==4.1.0 -pytest-mock==3.12.0 +packaging==24.1 +pluggy==1.5.0 +pytest==8.3.2 +pytest-cov==5.0.0 +pytest-mock==3.14.0 pytest-randomly==3.15.0 -requests==2.31.0 +requests==2.32.3 sortedcontainers==2.4.0 -urllib3==2.1.0 +urllib3==2.2.2 werkzeug==1.0.1 +wrapt==1.16.0 +zipp==3.19.2 diff --git a/.riot/requirements/427c22a.txt b/.riot/requirements/17c4377.txt similarity index 68% rename from .riot/requirements/427c22a.txt rename to .riot/requirements/17c4377.txt index 10859c1323e..7ad55b82d7b 100644 --- a/.riot/requirements/427c22a.txt +++ b/.riot/requirements/17c4377.txt @@ -2,27 +2,29 @@ # This file is autogenerated by pip-compile with Python 3.7 # by the following command: # -# pip-compile --no-annotate --resolver=backtracking .riot/requirements/427c22a.in +# pip-compile --config=pyproject.toml --no-annotate --resolver=backtracking .riot/requirements/17c4377.in # attrs==23.2.0 -certifi==2023.11.17 +certifi==2024.7.4 charset-normalizer==3.3.2 click==7.1.2 coverage[toml]==7.2.7 -exceptiongroup==1.2.0 +deprecated==1.2.14 +exceptiongroup==1.2.2 flask==1.1.4 -gunicorn==21.2.0 +gunicorn==22.0.0 httpretty==1.0.5 hypothesis==6.45.0 -idna==3.6 +idna==3.7 importlib-metadata==6.7.0 iniconfig==2.0.0 itsdangerous==1.1.0 jinja2==2.11.3 markupsafe==1.1.1 mock==5.1.0 +opentelemetry-api==1.22.0 opentracing==2.4.0 -packaging==23.2 +packaging==24.0 pluggy==1.2.0 pytest==7.4.4 pytest-cov==4.1.0 @@ -34,4 +36,5 @@ tomli==2.0.1 typing-extensions==4.7.1 urllib3==2.0.7 werkzeug==1.0.1 +wrapt==1.16.0 zipp==3.15.0 diff --git a/.riot/requirements/135aac0.txt b/.riot/requirements/18589ec.txt similarity index 50% rename from .riot/requirements/135aac0.txt rename to .riot/requirements/18589ec.txt index 34447792a37..b57924b80f4 100644 --- a/.riot/requirements/135aac0.txt +++ b/.riot/requirements/18589ec.txt @@ -2,35 +2,38 @@ # This file is autogenerated by pip-compile with Python 3.9 # by the following command: # -# pip-compile --no-annotate --resolver=backtracking .riot/requirements/135aac0.in +# pip-compile --no-annotate .riot/requirements/18589ec.in # attrs==23.2.0 -certifi==2023.11.17 +certifi==2024.7.4 charset-normalizer==3.3.2 click==7.1.2 -coverage[toml]==7.4.0 -exceptiongroup==1.2.0 +coverage[toml]==7.6.0 +deprecated==1.2.14 +exceptiongroup==1.2.2 flask==1.1.4 -gunicorn==21.2.0 +gunicorn==22.0.0 httpretty==1.0.5 hypothesis==6.45.0 -idna==3.6 -importlib-metadata==7.0.1 +idna==3.7 +importlib-metadata==7.0.0 iniconfig==2.0.0 itsdangerous==1.1.0 jinja2==2.11.3 markupsafe==1.1.1 mock==5.1.0 +opentelemetry-api==1.24.0 opentracing==2.4.0 -packaging==23.2 -pluggy==1.3.0 -pytest==7.4.4 -pytest-cov==4.1.0 -pytest-mock==3.12.0 +packaging==24.1 +pluggy==1.5.0 +pytest==8.3.2 +pytest-cov==5.0.0 +pytest-mock==3.14.0 pytest-randomly==3.15.0 -requests==2.31.0 +requests==2.32.3 sortedcontainers==2.4.0 tomli==2.0.1 -urllib3==2.1.0 +urllib3==2.2.2 werkzeug==1.0.1 -zipp==3.17.0 +wrapt==1.16.0 +zipp==3.19.2 diff --git a/.riot/requirements/118cb50.txt b/.riot/requirements/1a14242.txt similarity index 50% rename from .riot/requirements/118cb50.txt rename to .riot/requirements/1a14242.txt index ecb387eea6c..024e32a631f 100644 --- a/.riot/requirements/118cb50.txt +++ b/.riot/requirements/1a14242.txt @@ -2,33 +2,38 @@ # This file is autogenerated by pip-compile with Python 3.10 # by the following command: # -# pip-compile --no-annotate .riot/requirements/118cb50.in +# pip-compile --no-annotate .riot/requirements/1a14242.in # attrs==23.2.0 -certifi==2023.11.17 +certifi==2024.7.4 charset-normalizer==3.3.2 click==7.1.2 -coverage[toml]==7.4.0 -exceptiongroup==1.2.0 +coverage[toml]==7.6.0 +deprecated==1.2.14 +exceptiongroup==1.2.2 flask==1.1.4 -gunicorn==21.2.0 +gunicorn==22.0.0 httpretty==1.0.5 hypothesis==6.45.0 -idna==3.6 +idna==3.7 +importlib-metadata==7.0.0 iniconfig==2.0.0 itsdangerous==1.1.0 jinja2==2.11.3 markupsafe==1.1.1 mock==5.1.0 +opentelemetry-api==1.24.0 opentracing==2.4.0 -packaging==23.2 -pluggy==1.3.0 -pytest==7.4.4 -pytest-cov==4.1.0 -pytest-mock==3.12.0 +packaging==24.1 +pluggy==1.5.0 +pytest==8.3.2 +pytest-cov==5.0.0 +pytest-mock==3.14.0 pytest-randomly==3.15.0 -requests==2.31.0 +requests==2.32.3 sortedcontainers==2.4.0 tomli==2.0.1 -urllib3==2.1.0 +urllib3==2.2.2 werkzeug==1.0.1 +wrapt==1.16.0 +zipp==3.19.2 diff --git a/.riot/requirements/17a929f.txt b/.riot/requirements/5c0475c.txt similarity index 51% rename from .riot/requirements/17a929f.txt rename to .riot/requirements/5c0475c.txt index d37acc78410..e57d30b0c6c 100644 --- a/.riot/requirements/17a929f.txt +++ b/.riot/requirements/5c0475c.txt @@ -2,31 +2,36 @@ # This file is autogenerated by pip-compile with Python 3.12 # by the following command: # -# pip-compile --no-annotate .riot/requirements/17a929f.in +# pip-compile --no-annotate .riot/requirements/5c0475c.in # attrs==23.2.0 -certifi==2023.11.17 +certifi==2024.7.4 charset-normalizer==3.3.2 click==7.1.2 -coverage[toml]==7.4.0 +coverage[toml]==7.6.0 +deprecated==1.2.14 flask==1.1.4 -gunicorn==21.2.0 +gunicorn==22.0.0 httpretty==1.0.5 hypothesis==6.45.0 -idna==3.6 +idna==3.7 +importlib-metadata==7.0.0 iniconfig==2.0.0 itsdangerous==1.1.0 jinja2==2.11.3 markupsafe==1.1.1 mock==5.1.0 +opentelemetry-api==1.24.0 opentracing==2.4.0 -packaging==23.2 -pluggy==1.3.0 -pytest==7.4.4 -pytest-cov==4.1.0 -pytest-mock==3.12.0 +packaging==24.1 +pluggy==1.5.0 +pytest==8.3.2 +pytest-cov==5.0.0 +pytest-mock==3.14.0 pytest-randomly==3.15.0 -requests==2.31.0 +requests==2.32.3 sortedcontainers==2.4.0 -urllib3==2.1.0 +urllib3==2.2.2 werkzeug==1.0.1 +wrapt==1.16.0 +zipp==3.19.2 diff --git a/riotfile.py b/riotfile.py index d2d1f65b845..049c78ee1b2 100644 --- a/riotfile.py +++ b/riotfile.py @@ -320,6 +320,8 @@ def select_pys(min_version=MIN_PYTHON_VERSION, max_version=MAX_PYTHON_VERSION): "flask": "<=2.2.3", "httpretty": "<1.1", "werkzeug": "<2.0", + # FIXME: ddtrace does not support the latest versions of opentelemetry-api + "opentelemetry-api": "<1.25.0", "pytest-randomly": latest, "markupsafe": "<2.0", }, From edc6cac49ccf262bf0d0f16787271ecc75f7e388 Mon Sep 17 00:00:00 2001 From: Romain Komorn <136473744+romainkomorndatadog@users.noreply.github.com> Date: Fri, 2 Aug 2024 09:27:30 +0100 Subject: [PATCH 4/4] fix(ci_visibility): don't rely on git in pytest plugin [backport 2.8] (#10024) Backport c460441c0c43d40b5d12e647ce60086b2f8f493f from #9989 to 2.8. Fixes an issue introduced by #9586 and reported in #9981 where the pytest plugin would crash if the `git` binary was absent. The workspace is instead grabbed from the `CIVisibility` service's tags (via a new getter classmethod). In order for the variable to persist through to the `pytest_terminal_summary` hook, it is moved from being stashed on the pytest `session` object to the nested `config` object (which itself is passed to `pytest_terminal_summary`). For improved testability, a function to get the location of the `git` binary's passed, using `@cached()` to avoid re-fetching the path each time we call `git`. ## Checklist - [x] PR author has checked that all the criteria below are met - The PR description includes an overview of the change - The PR description articulates the motivation for the change - The change includes tests OR the PR description describes a testing strategy - The PR description notes risks associated with the change, if any - Newly-added code is easy to change - The change follows the [library release note guidelines](https://ddtrace.readthedocs.io/en/stable/releasenotes.html) - The change includes or references documentation updates if necessary - Backport labels are set (if [applicable](https://ddtrace.readthedocs.io/en/latest/contributing.html#backporting)) ## Reviewer Checklist - [x] Reviewer has checked that all the criteria below are met - Title is accurate - All changes are related to the pull request's stated goal - Avoids breaking [API](https://ddtrace.readthedocs.io/en/stable/versioning.html#interfaces) changes - Testing strategy adequately addresses listed risks - Newly-added code is easy to change - Release note makes sense to a user of the library - If necessary, author has acknowledged and discussed the performance implications of this PR as reported in the benchmarks PR comment - Backport labels are set in a manner that is consistent with the [release branch maintenance policy](https://ddtrace.readthedocs.io/en/latest/contributing.html#backporting) --- ddtrace/contrib/pytest/plugin.py | 8 +-- ddtrace/ext/git.py | 17 +++++- ddtrace/internal/ci_visibility/recorder.py | 11 ++++ ...ontrib_depend_on_git-d922e9326c981f38.yaml | 4 ++ tests/contrib/pytest/test_pytest.py | 56 +++++++++++++++++++ 5 files changed, 89 insertions(+), 7 deletions(-) create mode 100644 releasenotes/notes/ci_visibility-fix-dont_make_pytest_contrib_depend_on_git-d922e9326c981f38.yaml diff --git a/ddtrace/contrib/pytest/plugin.py b/ddtrace/contrib/pytest/plugin.py index 48b710ce6bd..820c2d94965 100644 --- a/ddtrace/contrib/pytest/plugin.py +++ b/ddtrace/contrib/pytest/plugin.py @@ -37,7 +37,6 @@ from ddtrace.contrib.unittest import unpatch as unpatch_unittest from ddtrace.ext import SpanTypes from ddtrace.ext import test -from ddtrace.ext.git import extract_workspace_path from ddtrace.internal.ci_visibility import CIVisibility as _CIVisibility from ddtrace.internal.ci_visibility.constants import EVENT_TYPE as _EVENT_TYPE from ddtrace.internal.ci_visibility.constants import ITR_CORRELATION_ID_TAG_NAME @@ -462,11 +461,8 @@ def pytest_sessionstart(session): log.debug("CI Visibility enabled - starting test session") global _global_skipped_elements _global_skipped_elements = 0 - try: - workspace_path = extract_workspace_path() - except ValueError: - log.debug("Couldn't extract workspace path from git, reverting to config rootdir") - workspace_path = session.config.rootdir + + workspace_path = _CIVisibility.get_workspace_path() or session.config.rootdir session._dd_workspace_path = workspace_path diff --git a/ddtrace/ext/git.py b/ddtrace/ext/git.py index 277d510e7a7..bf1a1323ab6 100644 --- a/ddtrace/ext/git.py +++ b/ddtrace/ext/git.py @@ -6,6 +6,7 @@ import os import random import re +from shutil import which import subprocess from typing import Dict # noqa:F401 from typing import Generator # noqa:F401 @@ -18,6 +19,7 @@ from ddtrace.internal import compat from ddtrace.internal.logger import get_logger +from ddtrace.internal.utils.cache import cached from ddtrace.internal.utils.time import StopWatch @@ -80,6 +82,16 @@ def is_ref_a_tag(ref): return "tags/" in ref if ref else False +@cached() +def _get_executable_path(executable_name: str) -> Optional[str]: + """Return the path to an executable. + + NOTE: cached() requires an argument which is why executable_name is passed in, even though it's really only ever + used to find the git executable at this point. + """ + return which(executable_name, mode=os.X_OK) + + def _git_subprocess_cmd_with_details(*cmd, cwd=None, std_in=None): # type: (str, Optional[str], Optional[bytes]) -> _GitSubprocessDetails """Helper for invoking the git CLI binary @@ -90,7 +102,10 @@ def _git_subprocess_cmd_with_details(*cmd, cwd=None, std_in=None): - the time it took to execute the command, in milliseconds - the exit code """ - git_cmd = ["git"] + git_cmd = _get_executable_path("git") + if git_cmd is None: + raise FileNotFoundError("Git executable not found") + git_cmd = [git_cmd] git_cmd.extend(cmd) log.debug("Executing git command: %s", git_cmd) diff --git a/ddtrace/internal/ci_visibility/recorder.py b/ddtrace/internal/ci_visibility/recorder.py index 53e6a5a98f2..75411ee092a 100644 --- a/ddtrace/internal/ci_visibility/recorder.py +++ b/ddtrace/internal/ci_visibility/recorder.py @@ -750,6 +750,17 @@ def get_service(cls) -> Optional[str]: return None return instance._service + @classmethod + def get_workspace_path(cls) -> Optional[str]: + if not cls.enabled: + error_msg = "CI Visibility is not enabled" + log.warning(error_msg) + raise CIVisibilityError(error_msg) + instance = cls.get_instance() + if instance is None: + return None + return instance._tags.get(ci.WORKSPACE_PATH) + def _requires_civisibility_enabled(func): def wrapper(*args, **kwargs): diff --git a/releasenotes/notes/ci_visibility-fix-dont_make_pytest_contrib_depend_on_git-d922e9326c981f38.yaml b/releasenotes/notes/ci_visibility-fix-dont_make_pytest_contrib_depend_on_git-d922e9326c981f38.yaml new file mode 100644 index 00000000000..3594a995298 --- /dev/null +++ b/releasenotes/notes/ci_visibility-fix-dont_make_pytest_contrib_depend_on_git-d922e9326c981f38.yaml @@ -0,0 +1,4 @@ +--- +fixes: + - | + CI Visibility: Fixes an issue where the pytest plugin would crash if the git binary was absent diff --git a/tests/contrib/pytest/test_pytest.py b/tests/contrib/pytest/test_pytest.py index c653beececb..6c56b622377 100644 --- a/tests/contrib/pytest/test_pytest.py +++ b/tests/contrib/pytest/test_pytest.py @@ -3774,3 +3774,59 @@ def test_grand_slam(): } assert expected_source_info == test_names_to_source_info + + def test_pytest_without_git_does_not_crash(self): + with open("tools.py", "w+") as fd: + fd.write( + textwrap.dedent( + ( + """ + def add_two_number_list(list_1, list_2): + output_list = [] + for number_a, number_b in zip(list_1, list_2): + output_list.append(number_a + number_b) + return output_list + + def multiply_two_number_list(list_1, list_2): + output_list = [] + for number_a, number_b in zip(list_1, list_2): + output_list.append(number_a * number_b) + return output_list + """ + ) + ) + ) + + with open("test_tools.py", "w+") as fd: + fd.write( + textwrap.dedent( + ( + """ + from tools import add_two_number_list + + def test_add_two_number_list(): + a_list = [1,2,3,4,5,6,7,8] + b_list = [2,3,4,5,6,7,8,9] + actual_output = add_two_number_list(a_list, b_list) + + assert actual_output == [3,5,7,9,11,13,15,17] + """ + ) + ) + ) + + self.testdir.chdir() + with mock.patch("ddtrace.ext.git._get_executable_path", return_value=None): + self.inline_run("--ddtrace") + + spans = self.pop_spans() + assert len(spans) == 4 + test_span = spans[0] + test_session_span = spans[1] + test_module_span = spans[2] + test_suite_span = spans[3] + + assert test_session_span.get_metric("test.code_coverage.lines_pct") is None + assert test_module_span.get_metric("test.code_coverage.lines_pct") is None + assert test_suite_span.get_metric("test.code_coverage.lines_pct") is None + assert test_span.get_metric("test.code_coverage.lines_pct") is None