mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-02 02:11:58 +00:00
* feat(s3_v2): add s3_partition_granularity option for hourly S3 folders Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * test(integration): cover s3 v2 partition granularity across surfaces, settings and chaos Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * test(integration): cover previous_response_id history rebuilt from an hourly cold storage object Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * fix(s3_v2): reuse the cold storage key only when s3_v2 owns cold storage Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * test(s3_v2): cover hour rollover, postgres outage, in-flight switches, key/team vars and real S3 layout Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * chore(liccheck): authorize libfaketime, the GPLv2 dev-only clock the s3 rollover integration test preloads Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * test(s3_v2): wait for the rejected-request cell's payloads by id, not by line count Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * test(s3_v2): declare the postgres outage cell's models in config and trip the relay on burst ids Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * test(s3_v2): drop the libfaketime hour rollover cell and its dev dependency Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * test(e2e): deselect the s3_v2 live e2e on the stage-mirror stack The stage-mirror config enables no s3_v2 callback, so every test in test_s3_log_e2e.py fails its readiness check there. The file keeps running in the Buildkite e2e lane, which configures s3_v2 Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * test(s3_v2): declare the sink outage burst models in config Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * refactor(s3_v2): read cold storage metadata without an empty dict default Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * test(integration): wait for the proxy to reconnect before the postgres outage recovery request Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> --------- Co-authored-by: mrinal <mrinal@berri.ai> Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Co-authored-by: yucheng <yucheng@berri.ai>
52 lines
2.1 KiB
Python
52 lines
2.1 KiB
Python
import re
|
|
import sys
|
|
from typing import Final
|
|
|
|
SELECTABLE: Final = re.compile(r"^tests/e2e/([A-Za-z0-9_.-]+/)*test_[A-Za-z0-9_.-]+\.py$")
|
|
UNSUPPORTED: Final = re.compile(
|
|
r"^tests/e2e/(ui|claude_code|load|migrations)/"
|
|
r"|^tests/e2e/mcp/test_mcp_oauth_happy_path_e2e\.py$"
|
|
r"|^tests/e2e/llm_translation/realtime/test_realtime_pipecat_audio_e2e\.py$"
|
|
r"|^tests/e2e/batches/test_managed_files_enforcement_e2e\.py$"
|
|
r"|^tests/e2e/guardrails/test_presidio_masking_e2e\.py$"
|
|
r"|^tests/e2e/logging/test_otel_v2_langfuse_generation_output_e2e\.py$"
|
|
r"|^tests/e2e/logging/test_langsmith_batch_serialization_e2e\.py$"
|
|
r"|^tests/e2e/logging/test_s3_log_e2e\.py$"
|
|
r"|^tests/e2e/secret_manager/"
|
|
)
|
|
HARNESS: Final = re.compile(
|
|
r"^tests/e2e/[A-Za-z0-9_.-]+\.(py|ini)$"
|
|
r"|^tests/e2e/idp_realm\.json$"
|
|
r"|^tests/e2e/management/(management_client|jwt_actors|conftest)\.py$"
|
|
r"|^tests/e2e/coverage_registry/management_cases\.py$"
|
|
r"|^tests/e2e/gateway/"
|
|
r"|^\.github/e2e-stack/"
|
|
r"|^\.github/workflows/test-e2e-changed\.yml$"
|
|
)
|
|
UNEXPANDED: Final = re.compile(r"[*?\[]")
|
|
|
|
|
|
def is_selectable(path: str) -> bool:
|
|
return SELECTABLE.match(path) is not None and UNSUPPORTED.match(path) is None
|
|
|
|
|
|
def select(changed: tuple[str, ...], canary: tuple[str, ...]) -> tuple[str, ...]:
|
|
direct: Final = frozenset(path for path in changed if is_selectable(path))
|
|
harness_changed: Final = any(HARNESS.match(path) for path in changed)
|
|
canary_tests: Final = frozenset(path for path in canary if harness_changed and is_selectable(path))
|
|
return tuple(sorted(direct | canary_tests))
|
|
|
|
|
|
def main() -> int:
|
|
canary: Final = tuple(sys.argv[1:])
|
|
unexpanded: Final = tuple(path for path in canary if UNEXPANDED.search(path))
|
|
if unexpanded:
|
|
_ = sys.stderr.write(f"the canary paths reached the selector unexpanded: {' '.join(unexpanded)}\n")
|
|
return 1
|
|
changed: Final = tuple(line.strip() for line in sys.stdin if line.strip())
|
|
_ = sys.stdout.write(" ".join(select(changed, canary)) + "\n")
|
|
return 0
|
|
|
|
|
|
if __name__ == "__main__":
|
|
sys.exit(main())
|