Files
crewAI/lib/crewai-core/tests/test_smoke.py
João Moura 8eaae40acf Track TUI button telemetry (#6346)
* feat(cli): track TUI button telemetry

* fix(cli): use feature usage telemetry for TUI buttons

---------

Co-authored-by: Lorenze Jay <63378463+lorenzejay@users.noreply.github.com>
2026-06-26 12:28:47 -07:00

236 lines
7.0 KiB
Python

"""Smoke tests for the crewai-core leaf modules."""
from __future__ import annotations
import os
from pathlib import Path
from unittest.mock import Mock
from crewai_core import (
constants,
lock_store,
paths,
printer,
project,
user_data,
version,
)
from opentelemetry.sdk.trace import TracerProvider
import pytest
def test_version_returns_string() -> None:
v = version.get_crewai_version()
assert isinstance(v, str) and v
def test_paths_creates_storage_dir(
tmp_path: Path, monkeypatch: pytest.MonkeyPatch
) -> None:
monkeypatch.setenv("CREWAI_STORAGE_DIR", str(tmp_path / "store"))
monkeypatch.setattr(
"crewai_core.paths.appdirs.user_data_dir",
lambda app, author: str(tmp_path / app),
)
out = paths.db_storage_path()
assert Path(out).exists()
def test_constants_exposes_env_keys() -> None:
assert constants.CREWAI_TRAINED_AGENTS_FILE_ENV == "CREWAI_TRAINED_AGENTS_FILE"
def test_printer_emits_when_not_suppressed(capsys: pytest.CaptureFixture[str]) -> None:
printer.PRINTER.print("hello", color="green")
out = capsys.readouterr().out
assert "hello" in out
def test_printer_respects_suppression(capsys: pytest.CaptureFixture[str]) -> None:
token = printer.set_suppress_console_output(True)
try:
printer.PRINTER.print("hidden")
finally:
printer._suppress_console_output.reset(token) # type: ignore[arg-type]
assert "hidden" not in capsys.readouterr().out
def test_lock_acquires_and_releases() -> None:
with lock_store.lock("crewai_core.tests.smoke", timeout=5):
pass
def test_user_data_round_trip(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> None:
monkeypatch.setenv("CREWAI_STORAGE_DIR", "crewai_core_test_user_data")
monkeypatch.setattr(
"crewai_core.paths.appdirs.user_data_dir",
lambda app, author: str(tmp_path / app),
)
user_data.update_user_data({"trace_consent": True, "first_execution_done": True})
data = user_data._load_user_data()
assert data == {"trace_consent": True, "first_execution_done": True}
assert user_data.has_user_declined_tracing() is False
monkeypatch.setenv("CREWAI_TRACING_ENABLED", "true")
assert user_data.is_tracing_enabled() is True
monkeypatch.delenv("CREWAI_TRACING_ENABLED", raising=False)
assert (
user_data.is_tracing_enabled() is True
) # consent alone enables (matches runtime)
def test_user_data_decline_blocks(
tmp_path: Path, monkeypatch: pytest.MonkeyPatch
) -> None:
monkeypatch.setenv("CREWAI_STORAGE_DIR", "crewai_core_test_decline")
monkeypatch.setattr(
"crewai_core.paths.appdirs.user_data_dir",
lambda app, author: str(tmp_path / app),
)
user_data.update_user_data({"trace_consent": False, "first_execution_done": True})
assert user_data.has_user_declined_tracing() is True
monkeypatch.delenv("CREWAI_TRACING_ENABLED", raising=False)
assert user_data.is_tracing_enabled() is False
monkeypatch.setenv("CREWAI_TRACING_ENABLED", "true")
assert user_data.is_tracing_enabled() is True # env-var override (matches runtime)
def test_unused_var_warning_silenced() -> None:
# Touch os to keep the import (used by env-var fixtures above)
assert os.environ is not None
def test_configured_project_definition_resolves_project_local_file(
tmp_path: Path,
) -> None:
definition = tmp_path / "crew.jsonc"
definition.write_text("{}\n")
resolved = project.configured_project_definition(
"crew",
pyproject_data={
"tool": {
"crewai": {
"type": "crew",
"definition": " crew.jsonc ",
}
}
},
project_root=tmp_path,
)
assert resolved == definition.resolve()
def test_configured_project_definition_rejects_project_escape(tmp_path: Path) -> None:
outside = tmp_path.parent / f"{tmp_path.name}-outside-crew.jsonc"
outside.write_text("{}\n")
with pytest.raises(project.ProjectDefinitionError):
project.configured_project_definition(
"crew",
pyproject_data={
"tool": {
"crewai": {
"type": "crew",
"definition": "../outside-crew.jsonc",
}
}
},
project_root=tmp_path,
)
def test_configured_project_definition_rejects_non_string_definition(
tmp_path: Path,
) -> None:
with pytest.raises(project.ProjectDefinitionError, match="must be a string"):
project.configured_project_definition(
"crew",
pyproject_data={
"tool": {
"crewai": {
"type": "crew",
"definition": ["crew.jsonc"],
}
}
},
project_root=tmp_path,
)
def test_configured_project_definition_rejects_empty_definition(
tmp_path: Path,
) -> None:
with pytest.raises(project.ProjectDefinitionError, match="non-empty"):
project.configured_project_definition(
"crew",
pyproject_data={
"tool": {
"crewai": {
"type": "crew",
"definition": " ",
}
}
},
project_root=tmp_path,
)
def test_core_telemetry_skips_duplicate_tracer_provider(
monkeypatch: pytest.MonkeyPatch,
) -> None:
from crewai_core.telemetry import Telemetry
Telemetry._instance = None
monkeypatch.delenv("OTEL_SDK_DISABLED", raising=False)
monkeypatch.delenv("CREWAI_DISABLE_TELEMETRY", raising=False)
monkeypatch.delenv("CREWAI_DISABLE_TRACKING", raising=False)
monkeypatch.setattr(
"crewai_core.telemetry.trace.get_tracer_provider",
lambda: TracerProvider(),
)
called = False
def fail_if_called(provider: object) -> None:
nonlocal called
called = True
monkeypatch.setattr(
"crewai_core.telemetry.trace.set_tracer_provider",
fail_if_called,
)
telemetry = Telemetry()
telemetry.set_tracer()
assert called is False
assert telemetry.trace_set is True
def test_core_telemetry_records_feature_usage(
monkeypatch: pytest.MonkeyPatch,
) -> None:
from crewai_core.telemetry import Telemetry
Telemetry._instance = None
monkeypatch.delenv("OTEL_SDK_DISABLED", raising=False)
monkeypatch.delenv("CREWAI_DISABLE_TELEMETRY", raising=False)
monkeypatch.delenv("CREWAI_DISABLE_TRACKING", raising=False)
tracer = Mock()
span = Mock()
tracer.start_span.return_value = span
monkeypatch.setattr(
"crewai_core.telemetry.trace.get_tracer",
lambda _name: tracer,
)
telemetry = Telemetry()
telemetry.feature_usage_span("cli_usage:view_traces")
tracer.start_span.assert_called_once_with("Feature Usage")
span.set_attribute.assert_any_call("feature", "cli_usage:view_traces")
span.end.assert_called_once()