Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .cursor/rules/code-format-standards.mdc
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,9 @@ alwaysApply: true

* All shell/bash scripts must be compatible with shellcheck. All shell/bash scripts you create or modify must pass shellcheck without errors or warnings.
* Follow Python type annotation best practices that are compatible with mypy strict checking, using Python 3.12 standards as defined in pyproject.toml. Always provide explicit type annotations for all function arguments and return values. For collections, use precise types (e.g., list[str], dict[str, int]). If a value can be None, always use Optional[...] explicitly. Do not rely on implicit Optional types (e.g., avoid using x: int = None—instead, use x: Optional[int] = None). Do not omit type annotations, and do not use untyped or partially typed collections.
* Test modules must access pytest through the approved facade: `from utils import pytest`. Never use `import pytest` or `from pytest import ...` under `tests/`.
* If a pytest API is missing, first decide whether it belongs in the facade. Add only the narrow, reviewed API to `utils/pytest.py`; do not bypass the facade.
* Do not expose `pytest.mark.skip_if_xfail`. Use the semantic `slow` or `scenario_crash` decorators from `utils`, together with a manifest declaration, as described in the test activation rules.
* Run `lint-imports` (also included in `./format.sh`) to verify this policy.
* Always run [format](mdc:format.sh) before committing changes to ensure code follows the project's style guidelines, including proper Path usage instead of os.path, no unused variables, complete type annotations, and efficient code patterns that satisfy mypy and ruff checks. if the format.sh script fails, try to fix the format mistakes.
* All YAML files you create or modify must pass both yamllint and yamlfmt checks before being committed.
8 changes: 7 additions & 1 deletion .cursor/rules/pr-review.mdc
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,13 @@ When adding a new weblog, verify the name is unique across all languages. Search

- Ref: [build.md](mdc:docs/execute/build.md)

## 10. Manifest YAML Syntax
## 10. No Cross-Test-File Imports

A `test_*.py` file must never import from another `test_*.py` file. If logic is shared between test files, it must be moved to a non-test utility module instead. Flag any PR that adds a cross-test import or a new exception to `.importlinter`.

- Ref: [repository-structure.mdc](mdc:.cursor/rules/repository-structure.mdc), enforced by the `Test files do not import other test files` Import Linter contract

## 11. Manifest YAML Syntax

- `bug` and `flaky` markers must include a JIRA ticket (e.g., `bug (JIRA-123)`)
- Values with special YAML characters (`>`, `<`, `:`, `#`) must be quoted
Expand Down
9 changes: 8 additions & 1 deletion .cursor/rules/repository-structure.mdc
Original file line number Diff line number Diff line change
Expand Up @@ -119,4 +119,11 @@ system-tests/
def test_XYZ(self):
...
```
- Never define a setup method without a matching test method.
- Never define a setup method without a matching test method.

## 6. No Cross-Test-File Imports

- A test file (`test_*.py`) must never import anything from another test file, whether through an absolute import such as `from tests.xxx.test_yyy import ...` or a relative import such as `from .test_yyy import ...`.
- If logic needs to be shared between test files, move it into a non-test utility module and have both test files import from there.
- Existing exceptions are explicitly listed in `.importlinter`. Do not add a new exception; refactor the shared logic instead.
- This is enforced by the `Test files do not import other test files` Import Linter contract run by `./format.sh`.
14 changes: 14 additions & 0 deletions .cursor/rules/test-activation.mdc
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,20 @@ which version contains the change.

## Decorator Rules

### Pytest Facade

Test modules must import pytest with `from utils import pytest`. Direct imports of
the external `pytest` package are forbidden by Import Linter.

`pytest.mark.skip_if_xfail` is an internal implementation detail and is
intentionally absent from the facade. Never recreate an alias for it. If an
expected failure must not execute:

1. Keep its declaration in the appropriate manifest.
2. Add `@slow` when running the test would consume excessive CI time.
3. Add `@scenario_crash` only when running the test could crash the scenario or
disrupt other tests.

### Version Format

**CRITICAL**: Always use `library@version` format:
Expand Down
29 changes: 29 additions & 0 deletions .importlinter
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
[importlinter]
root_packages =
tests
utils
include_external_packages = True
contract_types =
no-cross-test-imports: utils.format.import_linter_contracts.NoCrossTestImportsContract

[importlinter:contract:pytest-facade]
name = Tests use the approved pytest facade
type = forbidden
source_modules =
tests
forbidden_modules =
pytest
allow_indirect_imports = True

[importlinter:contract:no-cross-test-imports]
name = Test files do not import other test files
type = no-cross-test-imports
ignore_imports =
tests.appsec.api_security.test_apisecurity_telemetry -> tests.appsec.api_security.test_schemas
tests.appsec.waf.test_blocking -> tests.appsec.waf.test_blocking_security_response_id
tests.docker_ssi.test_docker_ssi -> tests.parametric.test_telemetry
tests.docker_ssi.test_docker_ssi_appsec -> tests.parametric.test_telemetry
tests.parametric.test_ffe.test_configuration_sources -> tests.parametric.test_ffe.test_dynamic_evaluation
tests.parametric.test_parametric_endpoints -> tests.parametric.test_dynamic_configuration
tests.test_telemetry -> tests.test_telemetry_heartbeat_utils
tests.test_the_test.test_telemetry_heartbeat -> tests.test_telemetry_heartbeat_utils
6 changes: 6 additions & 0 deletions format.sh
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,12 @@ if ! mypy --config pyproject.toml; then
exit 1
fi

echo "Running import policy checks..."
if ! lint-imports; then
echo "Import policy checks failed. Please fix the errors above. 💥 💔 💥"
exit 1
fi

echo "Running ruff formatter..."
if [ "$COMMAND" == "fix" ]; then
ruff format
Expand Down
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ ddapm-test-agent==1.18.0
dictdiffer==0.9.0 # for parametric tests
docker==7.1.0
filelock==3.12.2 # for parametric tests
import-linter==2.13
jsonschema==4.16.0
kubernetes==29.0.0 #lib-injection kubernetes
mitmproxy==9.0.1
Expand Down
2 changes: 1 addition & 1 deletion tests/ai_guard/conftest.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from collections.abc import Generator
from typing import Any
import pytest
from utils import pytest


@pytest.hookimpl(hookwrapper=True)
Expand Down
2 changes: 1 addition & 1 deletion tests/appsec/waf/test_addresses.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
# Copyright 2021 Datadog, Inc.
import json

import pytest
from utils import pytest
from utils import weblog, interfaces, rfc, scenarios, features, logger
from utils.dd_types import DataDogLibrarySpan

Expand Down
1 change: 0 additions & 1 deletion tests/ffe/test_flag_eval_evp.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
from concurrent.futures import ThreadPoolExecutor
from typing import cast


from tests.ffe.utils.fixtures import JSON, make_ufc_fixture
from utils import HttpResponse
from utils import features
Expand Down
2 changes: 1 addition & 1 deletion tests/integration_frameworks/conftest.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from collections.abc import Generator
from typing import Any
import pytest
from utils import pytest

from utils.docker_fixtures import (
FrameworkTestClientApi,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
/create request and its tool_use blocks. After-model needs the stream path: not yet cross-language.
"""

import pytest
from utils import pytest

from utils import features, scenarios
from utils.docker_fixtures import FrameworkTestClientApi, TestAgentAPI
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from utils import context, scenarios, features
from utils.docker_fixtures import FrameworkTestClientApi, TestAgentAPI

import pytest
from utils import pytest

from .utils import BaseAnthropicTest

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

from .utils import TOOLS, BaseAnthropicTest

import pytest
from utils import pytest
from unittest import mock
import json

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from utils import features, scenarios
from utils.docker_fixtures import FrameworkTestClientApi, TestAgentAPI

import pytest
from utils import pytest

from .utils import BaseGoogleGenaiTest

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from utils import features, scenarios
from utils.docker_fixtures import FrameworkTestClientApi, TestAgentAPI

import pytest
from utils import pytest
from unittest import mock
from typing import Any

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
/chat/completions request and its tool calls. After-model needs the stream path: not yet cross-language.
"""

import pytest
from utils import pytest

from utils import features, scenarios
from utils.docker_fixtures import FrameworkTestClientApi, TestAgentAPI
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from utils import features, scenarios
from .utils import TOOLS, BaseOpenaiTest

import pytest
from utils import pytest

from utils.docker_fixtures import FrameworkTestClientApi, TestAgentAPI

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import json
from utils import features, scenarios

import pytest
from utils import pytest
from unittest import mock

from utils.docker_fixtures import FrameworkTestClientApi, TestAgentAPI
Expand Down
2 changes: 1 addition & 1 deletion tests/parametric/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import shutil
import subprocess

import pytest
from utils import pytest
import yaml

from utils import scenarios, logger
Expand Down
2 changes: 1 addition & 1 deletion tests/parametric/otel_env_vars/test_otel_sdk_disabled.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import pytest
from utils import pytest

from tests.parametric.conftest import APMLibrary, nodejs_telemetry_value
from utils import features, scenarios
Expand Down
2 changes: 1 addition & 1 deletion tests/parametric/otel_env_vars/test_otel_service_name.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import pytest
from utils import pytest

from tests.parametric.conftest import APMLibrary
from utils import features, scenarios
Expand Down
2 changes: 1 addition & 1 deletion tests/parametric/test_128_bit_traceids.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import pytest
from utils import pytest

from utils.docker_fixtures.spec.trace import find_first_span_in_trace_payload, find_trace, find_only_span
from utils import scenarios, features
Expand Down
2 changes: 1 addition & 1 deletion tests/parametric/test_config_consistency.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

from urllib.parse import urlparse

import pytest
from utils import pytest
import yaml
from utils import (
scenarios,
Expand Down
2 changes: 1 addition & 1 deletion tests/parametric/test_crashtracking.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import base64
import json
import pytest
from utils import pytest

from utils import features, scenarios, logger
from utils.docker_fixtures import TestAgentAPI, ParametricTestClientApi as APMLibrary
Expand Down
2 changes: 1 addition & 1 deletion tests/parametric/test_dynamic_configuration.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from pathlib import Path
from typing import Any

import pytest
from utils import pytest
import yaml

from utils import (
Expand Down
2 changes: 1 addition & 1 deletion tests/parametric/test_extract_behavior.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import pytest
from utils import pytest

from utils import features, scenarios
from utils.docker_fixtures import TestAgentAPI
Expand Down
2 changes: 1 addition & 1 deletion tests/parametric/test_ffe/test_configuration_sources.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
import time
from typing import Any

import pytest
from utils import pytest

from tests.parametric.conftest import APMLibrary
from tests.parametric.test_ffe.test_dynamic_evaluation import _set_and_wait_ffe_rc, _ffe_evaluate_with_rc_retry
Expand Down
2 changes: 1 addition & 1 deletion tests/parametric/test_ffe/test_dynamic_evaluation.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
"""Test FFE (Feature Flags & Experimentation) functionality via parametric tests."""

import json
import pytest
from utils import pytest
import time
from pathlib import Path
from typing import Any
Expand Down
2 changes: 1 addition & 1 deletion tests/parametric/test_ffe/test_span_enrichment.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
"""

import json
import pytest
from utils import pytest
from pathlib import Path
from typing import Any

Expand Down
2 changes: 1 addition & 1 deletion tests/parametric/test_headers_b3.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import pytest
from utils import pytest

from utils.docker_fixtures.spec.trace import SAMPLING_PRIORITY_KEY, ORIGIN
from utils.docker_fixtures.spec.trace import span_has_no_parent
Expand Down
2 changes: 1 addition & 1 deletion tests/parametric/test_headers_b3multi.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import pytest
from utils import pytest

from utils.docker_fixtures.spec.trace import SAMPLING_PRIORITY_KEY, ORIGIN
from utils.docker_fixtures.spec.trace import span_has_no_parent
Expand Down
2 changes: 1 addition & 1 deletion tests/parametric/test_headers_baggage.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from utils import features, scenarios
from utils.docker_fixtures import TestAgentAPI

import pytest
from utils import pytest

from .conftest import APMLibrary

Expand Down
2 changes: 1 addition & 1 deletion tests/parametric/test_headers_none.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import pytest
from utils import pytest

from utils.docker_fixtures.spec.trace import SAMPLING_PRIORITY_KEY, ORIGIN
from utils.docker_fixtures.spec.trace import find_only_span
Expand Down
2 changes: 1 addition & 1 deletion tests/parametric/test_headers_opm.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
RFC: https://docs.google.com/document/d/1SzZWivVWT79lJe80ZulEra6AARszjEYVEwWJ7IhJ6Xo/edit?tab=t.0
"""

import pytest
from utils import pytest

from utils import features, scenarios, rfc
from utils.docker_fixtures import TestAgentAPI
Expand Down
2 changes: 1 addition & 1 deletion tests/parametric/test_headers_precedence.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import pytest
from utils import pytest

from utils.docker_fixtures.spec.tracecontext import get_tracecontext
from utils import scenarios, features
Expand Down
2 changes: 1 addition & 1 deletion tests/parametric/test_headers_tracecontext.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.


import pytest
from utils import pytest

from utils.docker_fixtures.spec.tracecontext import get_tracecontext
from utils.docker_fixtures.spec.trace import find_span_in_traces, find_only_span
Expand Down
2 changes: 1 addition & 1 deletion tests/parametric/test_headers_tracestate_dd.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import pytest
from utils import pytest

from utils.docker_fixtures.spec.tracecontext import get_tracecontext
from utils import scenarios, features
Expand Down
2 changes: 1 addition & 1 deletion tests/parametric/test_library_tracestats.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import base64

import msgpack
import pytest
from utils import pytest


from utils.docker_fixtures.spec.trace import SPAN_MEASURED_KEY
Expand Down
2 changes: 1 addition & 1 deletion tests/parametric/test_llm_observability/conftest.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from collections.abc import Generator
from typing import Any
import pytest
from utils import pytest


@pytest.hookimpl(hookwrapper=True)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import pytest
from utils import pytest

from utils import scenarios, features
from utils.docker_fixtures import TestAgentAPI
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from typing import TYPE_CHECKING
import pytest
from utils import pytest

from tests.parametric.test_llm_observability.utils import check_and_get_api_key
from utils import features, scenarios
Expand Down
2 changes: 1 addition & 1 deletion tests/parametric/test_llm_observability/utils.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import os
import pytest
from utils import pytest


def check_and_get_api_key(api_key_name: str, *, generate_cassettes: bool = False) -> str | None:
Expand Down
Loading
Loading