Skip to content
Closed
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
37 changes: 37 additions & 0 deletions .github/scripts/detect_loongsuite_changes.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@
TOX_LOONGSUITE_INI_PATH = "tox-loongsuite.ini"
UTIL_GENAI_PREFIX = "util/opentelemetry-util-genai/"
LOONGSUITE_INSTRUMENTATION_PREFIX = "instrumentation-loongsuite/"
BOOTSTRAP_REGISTRY_PREFIX = (
"loongsuite-distro/src/loongsuite/distro/bootstrap_registry/"
)
DOC_ONLY_SUFFIXES = (".md", ".rst")
REPO_ROOT = Path.cwd()
TOX_LOONGSUITE_INI = REPO_ROOT / TOX_LOONGSUITE_INI_PATH
Expand Down Expand Up @@ -150,6 +153,30 @@ def _loongsuite_package_from_path(path: str) -> str | None:
return None


def _loongsuite_package_from_bootstrap_registry_path(path: str) -> str | None:
normalized = path.strip("/")
if not normalized.startswith(BOOTSTRAP_REGISTRY_PREFIX):
return None

relative_path = normalized.removeprefix(BOOTSTRAP_REGISTRY_PREFIX)
if "/" in relative_path:
return None

registry_path = PurePosixPath(relative_path)
if registry_path.suffix != ".py":
return None

module_name = registry_path.stem
if module_name == "__init__" or module_name.startswith("_"):
return None

package = module_name.replace("_", "-")
if package.startswith("loongsuite-instrumentation-"):
return package

return None


def _known_loongsuite_packages() -> set[str]:
text = TOX_LOONGSUITE_INI.read_text(encoding="utf-8")
packages = set()
Expand Down Expand Up @@ -339,6 +366,16 @@ def _detect_outputs() -> dict[str, str]:
tox_changed = True
continue

registry_package = _loongsuite_package_from_bootstrap_registry_path(
changed_file
)
if registry_package:
if registry_package not in known_packages:
unknown_packages.add(registry_package)
else:
packages.add(registry_package)
continue

if _requires_full_run(changed_file):
return _full_outputs(
f"shared LoongSuite file changed: {changed_file}"
Expand Down
60 changes: 60 additions & 0 deletions .github/scripts/tests/test_detect_loongsuite_changes.py
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,66 @@ def test_generated_workflow_only_change_skips_jobs(monkeypatch, tmp_path):
assert outputs["packages"] == "||"


def test_bootstrap_registry_fragment_scopes_package_change(
monkeypatch,
tmp_path,
):
outputs = _run_detector(
monkeypatch,
tmp_path,
[
"loongsuite-distro/src/loongsuite/distro/bootstrap_registry/"
"loongsuite_instrumentation_crewai.py"
],
known_packages={"loongsuite-instrumentation-crewai"},
)

assert outputs["full"] == "false"
assert outputs["packages"] == "|loongsuite-instrumentation-crewai|"


def test_bootstrap_registry_loader_change_runs_full_suite(
monkeypatch,
tmp_path,
):
outputs = _run_detector(
monkeypatch,
tmp_path,
[
"loongsuite-distro/src/loongsuite/distro/bootstrap_registry/"
"__init__.py"
],
)

assert outputs["full"] == "true"
assert outputs["reason"] == (
"shared LoongSuite file changed: "
"loongsuite-distro/src/loongsuite/distro/bootstrap_registry/"
"__init__.py"
)


def test_upstream_bootstrap_registry_fragment_runs_full_suite(
monkeypatch,
tmp_path,
):
outputs = _run_detector(
monkeypatch,
tmp_path,
[
"loongsuite-distro/src/loongsuite/distro/bootstrap_registry/"
"opentelemetry_instrumentation_aiohttp_client.py"
],
)

assert outputs["full"] == "true"
assert outputs["reason"] == (
"shared LoongSuite file changed: "
"loongsuite-distro/src/loongsuite/distro/bootstrap_registry/"
"opentelemetry_instrumentation_aiohttp_client.py"
)


def test_release_workflow_change_runs_full_suite(monkeypatch, tmp_path):
outputs = _run_detector(
monkeypatch,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## Unreleased

### Fixed

- Keep the authentication-failure test deterministic by using fake provider
keys instead of empty keys, avoiding fallback live OpenAI calls in CI.
([#232](https://github.com/alibaba/loongsuite-python/pull/232))

## Version 0.6.0 (2026-06-03)

### Breaking
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,23 +103,23 @@ def tearDown(self):

def test_api_key_missing(self):
"""
Test execution with missing API key.
Test execution with authentication failure.

Business Demo:
- Creates a Crew with 1 Agent
- API key is empty/missing
- API key is rejected by the LLM service
- Executes 1 Task that fails due to authentication

Verification:
- Affected spans (e.g., Agent/Task) have ERROR status
- Span records authentication exception in events
- Input messages are still captured for context
"""
# Temporarily remove API keys
# Use non-empty fake keys so provider validation reaches kickoff.
original_dashscope_key = os.environ.get("DASHSCOPE_API_KEY")
original_openai_key = os.environ.get("OPENAI_API_KEY")
os.environ["DASHSCOPE_API_KEY"] = ""
os.environ["OPENAI_API_KEY"] = ""
os.environ["DASHSCOPE_API_KEY"] = "fake-key"
os.environ["OPENAI_API_KEY"] = "fake-key"

try:
agent = Agent(
Expand Down Expand Up @@ -150,9 +150,13 @@ def test_api_key_missing(self):

finally:
# Restore API keys
if original_dashscope_key:
if original_dashscope_key is None:
os.environ.pop("DASHSCOPE_API_KEY", None)
else:
os.environ["DASHSCOPE_API_KEY"] = original_dashscope_key
if original_openai_key:
if original_openai_key is None:
os.environ.pop("OPENAI_API_KEY", None)
else:
os.environ["OPENAI_API_KEY"] = original_openai_key

# Verify spans
Expand Down
Loading
Loading