langfun 0.1.2.dev202511010804__tar.gz → 0.1.2.dev202511020804__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of langfun might be problematic. Click here for more details.
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/PKG-INFO +1 -1
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/eval/v2/runners_test.py +3 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/env/__init__.py +1 -1
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/env/base_environment.py +62 -5
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/env/base_environment_test.py +5 -5
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/env/base_feature.py +38 -20
- langfun-0.1.2.dev202511020804/langfun/env/base_feature_test.py +228 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/env/base_sandbox.py +27 -33
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/env/base_sandbox_test.py +258 -251
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/env/event_handlers/chain.py +58 -80
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/env/event_handlers/chain_test.py +83 -111
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/env/event_handlers/event_logger.py +77 -80
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/env/event_handlers/event_logger_test.py +18 -18
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/env/event_handlers/metric_writer.py +176 -140
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/env/interface.py +493 -199
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/env/interface_test.py +30 -1
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/env/test_utils.py +110 -78
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun.egg-info/PKG-INFO +1 -1
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun.egg-info/SOURCES.txt +1 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/LICENSE +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/README.md +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/__init__.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/assistant/capabilities/gui/__init__.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/assistant/capabilities/gui/bounding_box_parser.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/assistant/capabilities/gui/bounding_box_parser_test.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/assistant/capabilities/gui/drawing.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/assistant/capabilities/gui/drawing_test.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/assistant/capabilities/gui/location.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/assistant/capabilities/gui/location_test.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/__init__.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/agentic/__init__.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/agentic/action.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/agentic/action_eval.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/agentic/action_eval_test.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/agentic/action_test.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/async_support.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/async_support_test.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/coding/__init__.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/coding/python/__init__.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/coding/python/correction.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/coding/python/correction_test.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/coding/python/execution.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/coding/python/execution_test.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/coding/python/generation.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/coding/python/generation_test.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/coding/python/parsing.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/coding/python/parsing_test.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/coding/python/sandboxing.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/coding/python/sandboxing_test.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/component.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/component_test.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/concurrent.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/concurrent_test.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/console.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/console_test.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/data/__init__.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/data/conversion/__init__.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/data/conversion/anthropic.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/data/conversion/anthropic_test.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/data/conversion/gemini.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/data/conversion/gemini_test.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/data/conversion/openai.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/data/conversion/openai_test.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/eval/__init__.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/eval/base.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/eval/base_test.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/eval/matching.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/eval/matching_test.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/eval/patching.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/eval/patching_test.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/eval/scoring.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/eval/scoring_test.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/eval/v2/__init__.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/eval/v2/checkpointing.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/eval/v2/checkpointing_test.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/eval/v2/eval_test_helper.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/eval/v2/evaluation.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/eval/v2/evaluation_test.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/eval/v2/example.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/eval/v2/example_test.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/eval/v2/experiment.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/eval/v2/experiment_test.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/eval/v2/metric_values.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/eval/v2/metric_values_test.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/eval/v2/metrics.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/eval/v2/metrics_test.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/eval/v2/progress.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/eval/v2/progress_test.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/eval/v2/progress_tracking.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/eval/v2/progress_tracking_test.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/eval/v2/reporting.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/eval/v2/reporting_test.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/eval/v2/runners.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/langfunc.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/langfunc_test.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/language_model.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/language_model_test.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/llms/__init__.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/llms/anthropic.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/llms/anthropic_test.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/llms/azure_openai.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/llms/azure_openai_test.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/llms/cache/__init__.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/llms/cache/base.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/llms/cache/in_memory.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/llms/cache/in_memory_test.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/llms/compositional.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/llms/compositional_test.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/llms/deepseek.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/llms/deepseek_test.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/llms/fake.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/llms/fake_test.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/llms/gemini.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/llms/gemini_test.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/llms/google_genai.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/llms/google_genai_test.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/llms/groq.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/llms/groq_test.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/llms/llama_cpp.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/llms/llama_cpp_test.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/llms/openai.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/llms/openai_compatible.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/llms/openai_compatible_test.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/llms/openai_test.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/llms/rest.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/llms/rest_test.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/llms/vertexai.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/llms/vertexai_test.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/logging.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/logging_test.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/mcp/__init__.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/mcp/client.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/mcp/client_test.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/mcp/session.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/mcp/session_test.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/mcp/testing/simple_mcp_client.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/mcp/testing/simple_mcp_server.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/mcp/tool.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/mcp/tool_test.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/memories/__init__.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/memories/conversation_history.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/memories/conversation_history_test.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/memory.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/message.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/message_test.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/modalities/__init__.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/modalities/audio.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/modalities/audio_test.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/modalities/image.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/modalities/image_test.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/modalities/mime.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/modalities/mime_test.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/modalities/pdf.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/modalities/pdf_test.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/modalities/video.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/modalities/video_test.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/modality.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/modality_test.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/natural_language.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/natural_language_test.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/sampling.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/sampling_test.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/structured/__init__.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/structured/completion.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/structured/completion_test.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/structured/description.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/structured/description_test.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/structured/function_generation.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/structured/function_generation_test.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/structured/mapping.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/structured/mapping_test.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/structured/parsing.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/structured/parsing_test.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/structured/querying.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/structured/querying_test.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/structured/schema.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/structured/schema_generation.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/structured/schema_generation_test.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/structured/schema_test.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/structured/scoring.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/structured/scoring_test.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/structured/tokenization.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/structured/tokenization_test.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/subscription.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/subscription_test.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/template.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/template_test.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/templates/__init__.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/templates/completion.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/templates/completion_test.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/templates/conversation.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/templates/conversation_test.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/templates/demonstration.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/templates/demonstration_test.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/templates/selfplay.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/core/templates/selfplay_test.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/env/event_handlers/__init__.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/env/event_handlers/metric_writer_test.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/env/load_balancers.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/env/load_balancers_test.py +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun.egg-info/dependency_links.txt +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun.egg-info/requires.txt +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun.egg-info/top_level.txt +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/setup.cfg +0 -0
- {langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/setup.py +0 -0
|
@@ -28,7 +28,7 @@ from langfun.env.interface import EventHandler
|
|
|
28
28
|
|
|
29
29
|
# Decorators for sandbox/feature methods.
|
|
30
30
|
from langfun.env.interface import treat_as_sandbox_state_error
|
|
31
|
-
from langfun.env.interface import
|
|
31
|
+
from langfun.env.interface import log_activity
|
|
32
32
|
|
|
33
33
|
from langfun.env.base_environment import BaseEnvironment
|
|
34
34
|
from langfun.env.base_sandbox import BaseSandbox
|
{langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/env/base_environment.py
RENAMED
|
@@ -179,6 +179,7 @@ class BaseEnvironment(interface.Environment):
|
|
|
179
179
|
)
|
|
180
180
|
self._housekeep_thread = None
|
|
181
181
|
self._offline_start_time = None
|
|
182
|
+
self._non_sandbox_based_features_with_setup_called = set()
|
|
182
183
|
|
|
183
184
|
# Check image IDs and feature requirements.
|
|
184
185
|
self._check_image_ids()
|
|
@@ -192,7 +193,9 @@ class BaseEnvironment(interface.Environment):
|
|
|
192
193
|
if self.supports_dynamic_image_loading:
|
|
193
194
|
return
|
|
194
195
|
for name, feature in self.features.items():
|
|
195
|
-
if
|
|
196
|
+
if not feature.is_sandbox_based or any(
|
|
197
|
+
feature.is_applicable(image_id) for image_id in self.image_ids
|
|
198
|
+
):
|
|
196
199
|
continue
|
|
197
200
|
raise ValueError(
|
|
198
201
|
f'Feature {name!r} is not applicable to all available images: '
|
|
@@ -267,6 +270,13 @@ class BaseEnvironment(interface.Environment):
|
|
|
267
270
|
def _start(self) -> None:
|
|
268
271
|
"""Implementation of starting the environment."""
|
|
269
272
|
sandbox_startup_infos = []
|
|
273
|
+
self._non_sandbox_based_features_with_setup_called.clear()
|
|
274
|
+
# Setup all non-sandbox-based features.
|
|
275
|
+
for feature in self.non_sandbox_based_features():
|
|
276
|
+
self._non_sandbox_based_features_with_setup_called.add(feature.name)
|
|
277
|
+
feature.setup(sandbox=None)
|
|
278
|
+
|
|
279
|
+
# Setup sandbox pools.
|
|
270
280
|
for image_id in self.image_ids:
|
|
271
281
|
next_sandbox_id = 0
|
|
272
282
|
if self.enable_pooling(image_id):
|
|
@@ -312,10 +322,15 @@ class BaseEnvironment(interface.Environment):
|
|
|
312
322
|
self._housekeep_thread.join()
|
|
313
323
|
self._housekeep_thread = None
|
|
314
324
|
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
325
|
+
# Teardown all non-sandbox-based features.
|
|
326
|
+
for feature in self.non_sandbox_based_features():
|
|
327
|
+
if feature.name in self._non_sandbox_based_features_with_setup_called:
|
|
328
|
+
try:
|
|
329
|
+
feature.teardown()
|
|
330
|
+
except BaseException: # pylint: disable=broad-except
|
|
331
|
+
pass
|
|
318
332
|
|
|
333
|
+
# Shutdown sandbox pools.
|
|
319
334
|
if self._sandbox_pool:
|
|
320
335
|
sandboxes = []
|
|
321
336
|
for sandbox in self._sandbox_pool.values():
|
|
@@ -323,6 +338,10 @@ class BaseEnvironment(interface.Environment):
|
|
|
323
338
|
self._sandbox_pool = {}
|
|
324
339
|
|
|
325
340
|
if sandboxes:
|
|
341
|
+
def _shutdown_sandbox(sandbox: base_sandbox.BaseSandbox) -> None:
|
|
342
|
+
if sandbox is not None:
|
|
343
|
+
sandbox.shutdown()
|
|
344
|
+
|
|
326
345
|
_ = list(
|
|
327
346
|
lf.concurrent_map(
|
|
328
347
|
_shutdown_sandbox,
|
|
@@ -635,9 +654,45 @@ class BaseEnvironment(interface.Environment):
|
|
|
635
654
|
indices_by_image_id[image_id].append(i)
|
|
636
655
|
return indices_by_image_id
|
|
637
656
|
|
|
657
|
+
last_housekeep_time = {
|
|
658
|
+
f.name: time.time() for f in self.non_sandbox_based_features()
|
|
659
|
+
}
|
|
660
|
+
|
|
638
661
|
while self._status not in (self.Status.SHUTTING_DOWN, self.Status.OFFLINE):
|
|
639
662
|
housekeep_start_time = time.time()
|
|
663
|
+
feature_housekeep_successes = []
|
|
664
|
+
feature_housekeep_failures = []
|
|
665
|
+
|
|
666
|
+
# Housekeeping non-sandbox-based features.
|
|
667
|
+
for feature in self.non_sandbox_based_features():
|
|
668
|
+
if feature.housekeep_interval is None:
|
|
669
|
+
continue
|
|
670
|
+
if (last_housekeep_time[feature.name]
|
|
671
|
+
+ feature.housekeep_interval < time.time()):
|
|
672
|
+
try:
|
|
673
|
+
feature.housekeep()
|
|
674
|
+
last_housekeep_time[feature.name] = time.time()
|
|
675
|
+
feature_housekeep_successes.append(feature.name)
|
|
676
|
+
except BaseException as e: # pylint: disable=broad-except
|
|
677
|
+
pg.logging.error(
|
|
678
|
+
'[%s/%s]: Feature housekeeping failed with error: %s.'
|
|
679
|
+
'Shutting down environment...',
|
|
680
|
+
self.id,
|
|
681
|
+
feature.name,
|
|
682
|
+
e,
|
|
683
|
+
)
|
|
684
|
+
feature_housekeep_failures.append(feature.name)
|
|
685
|
+
self._housekeep_counter += 1
|
|
686
|
+
self.on_housekeep(
|
|
687
|
+
duration=time.time() - housekeep_start_time,
|
|
688
|
+
error=e,
|
|
689
|
+
feature_housekeep_successes=feature_housekeep_successes,
|
|
690
|
+
feature_housekeep_failures=feature_housekeep_failures,
|
|
691
|
+
)
|
|
692
|
+
self.shutdown()
|
|
693
|
+
return
|
|
640
694
|
|
|
695
|
+
# Replace dead sandboxes.
|
|
641
696
|
is_online = True
|
|
642
697
|
dead_sandbox_entries = []
|
|
643
698
|
for image_id, sandboxes in self._sandbox_pool.items():
|
|
@@ -658,6 +713,8 @@ class BaseEnvironment(interface.Environment):
|
|
|
658
713
|
duration = time.time() - housekeep_start_time
|
|
659
714
|
|
|
660
715
|
kwargs = dict(
|
|
716
|
+
feature_housekeep_successes=feature_housekeep_successes,
|
|
717
|
+
feature_housekeep_failures=feature_housekeep_failures,
|
|
661
718
|
dead_sandboxes=_indices_by_image_id(dead_sandbox_entries),
|
|
662
719
|
replaced_sandboxes=replaced_indices_by_image_id,
|
|
663
720
|
offline_duration=self.offline_duration,
|
|
@@ -666,7 +723,6 @@ class BaseEnvironment(interface.Environment):
|
|
|
666
723
|
self.on_housekeep(duration, **kwargs)
|
|
667
724
|
time.sleep(self.housekeep_interval)
|
|
668
725
|
else:
|
|
669
|
-
self.shutdown()
|
|
670
726
|
self.on_housekeep(
|
|
671
727
|
duration,
|
|
672
728
|
interface.EnvironmentOutageError(
|
|
@@ -674,6 +730,7 @@ class BaseEnvironment(interface.Environment):
|
|
|
674
730
|
),
|
|
675
731
|
**kwargs
|
|
676
732
|
)
|
|
733
|
+
self.shutdown()
|
|
677
734
|
|
|
678
735
|
def _replace_dead_sandboxes(
|
|
679
736
|
self,
|
{langfun-0.1.2.dev202511010804 → langfun-0.1.2.dev202511020804}/langfun/env/base_environment_test.py
RENAMED
|
@@ -57,7 +57,7 @@ class BaseEnvironmentTests(unittest.TestCase):
|
|
|
57
57
|
self.assertEqual(env.sandbox_pool, {})
|
|
58
58
|
self.assertEqual(env.working_dir, '/tmp/testing-env')
|
|
59
59
|
|
|
60
|
-
with env.sandbox(
|
|
60
|
+
with env.sandbox('session1') as sb:
|
|
61
61
|
self.assertEqual(
|
|
62
62
|
sb.id, interface.Sandbox.Id(
|
|
63
63
|
environment_id=env.id,
|
|
@@ -79,7 +79,7 @@ class BaseEnvironmentTests(unittest.TestCase):
|
|
|
79
79
|
with self.assertRaisesRegex(
|
|
80
80
|
ValueError, 'Environment .* does not serve image ID .*'
|
|
81
81
|
):
|
|
82
|
-
env.sandbox('test_image2')
|
|
82
|
+
env.sandbox(image_id='test_image2')
|
|
83
83
|
|
|
84
84
|
with env.test_feature() as feature:
|
|
85
85
|
self.assertIsInstance(feature, TestingFeature)
|
|
@@ -174,7 +174,7 @@ class BaseEnvironmentTests(unittest.TestCase):
|
|
|
174
174
|
with self.assertRaisesRegex(
|
|
175
175
|
ValueError, 'Feature .* is not applicable to .*'
|
|
176
176
|
):
|
|
177
|
-
with env.test_feature('test_image2'):
|
|
177
|
+
with env.test_feature(image_id='test_image2'):
|
|
178
178
|
pass
|
|
179
179
|
|
|
180
180
|
with env.test_feature2() as feature:
|
|
@@ -183,7 +183,7 @@ class BaseEnvironmentTests(unittest.TestCase):
|
|
|
183
183
|
with env.test_feature3() as feature:
|
|
184
184
|
self.assertEqual(feature.sandbox.image_id, 'test_image1')
|
|
185
185
|
|
|
186
|
-
with env.test_feature3('test_image2') as feature:
|
|
186
|
+
with env.test_feature3(image_id='test_image2') as feature:
|
|
187
187
|
self.assertEqual(feature.sandbox.image_id, 'test_image2')
|
|
188
188
|
|
|
189
189
|
def test_feature_applicability_check(self):
|
|
@@ -218,7 +218,7 @@ class BaseEnvironmentTests(unittest.TestCase):
|
|
|
218
218
|
pass
|
|
219
219
|
|
|
220
220
|
# Dynamically loaded IDs.
|
|
221
|
-
with env.test_feature2('test_image2') as feature:
|
|
221
|
+
with env.test_feature2(image_id='test_image2') as feature:
|
|
222
222
|
self.assertEqual(feature.sandbox.image_id, 'test_image2')
|
|
223
223
|
|
|
224
224
|
def test_pool_size(self):
|
|
@@ -11,9 +11,9 @@
|
|
|
11
11
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
12
|
# See the License for the specific language governing permissions and
|
|
13
13
|
# limitations under the License.
|
|
14
|
-
"""Common base class for
|
|
14
|
+
"""Common base class for environment features.
|
|
15
15
|
|
|
16
|
-
This module provides an base class `BaseFeature` for
|
|
16
|
+
This module provides an base class `BaseFeature` for environment features,
|
|
17
17
|
which provides event handlers for the feature lifecycle events, which can be
|
|
18
18
|
overridden by subclasses to provide custom behaviors. Please note that this base
|
|
19
19
|
class is intended to provide a convenient way to implement features, and not
|
|
@@ -22,18 +22,24 @@ coupled with `BaseEnvironment` and `BaseSandbox`, and is expected to work with
|
|
|
22
22
|
the `Environment` and `Sandbox` interfaces directly.
|
|
23
23
|
"""
|
|
24
24
|
|
|
25
|
+
import contextlib
|
|
25
26
|
import functools
|
|
26
27
|
import os
|
|
27
28
|
import re
|
|
28
29
|
import time
|
|
29
|
-
from typing import Annotated, Callable
|
|
30
|
+
from typing import Annotated, Any, Callable, Iterator
|
|
30
31
|
|
|
31
32
|
from langfun.env import interface
|
|
32
33
|
import pyglove as pg
|
|
33
34
|
|
|
34
35
|
|
|
35
36
|
class BaseFeature(interface.Feature):
|
|
36
|
-
"""Common base class for
|
|
37
|
+
"""Common base class for environment features."""
|
|
38
|
+
|
|
39
|
+
is_sandbox_based: Annotated[
|
|
40
|
+
bool,
|
|
41
|
+
'Whether the feature is sandbox-based.'
|
|
42
|
+
] = True
|
|
37
43
|
|
|
38
44
|
applicable_images: Annotated[
|
|
39
45
|
list[str],
|
|
@@ -120,9 +126,11 @@ class BaseFeature(interface.Feature):
|
|
|
120
126
|
return env
|
|
121
127
|
|
|
122
128
|
@property
|
|
123
|
-
def sandbox(self) -> interface.Sandbox:
|
|
129
|
+
def sandbox(self) -> interface.Sandbox | None:
|
|
124
130
|
"""Returns the sandbox that the feature is running in."""
|
|
125
|
-
assert self._sandbox is not None
|
|
131
|
+
assert self._sandbox is not None or not self.is_sandbox_based, (
|
|
132
|
+
'Feature has not been set up yet.'
|
|
133
|
+
)
|
|
126
134
|
return self._sandbox
|
|
127
135
|
|
|
128
136
|
@property
|
|
@@ -159,7 +167,7 @@ class BaseFeature(interface.Feature):
|
|
|
159
167
|
finally:
|
|
160
168
|
event_handler(duration=time.time() - start_time, error=error)
|
|
161
169
|
|
|
162
|
-
def setup(self, sandbox: interface.Sandbox) -> None:
|
|
170
|
+
def setup(self, sandbox: interface.Sandbox | None = None) -> None:
|
|
163
171
|
"""Sets up the feature."""
|
|
164
172
|
self._sandbox = sandbox
|
|
165
173
|
self._do(self._setup, self.on_setup)
|
|
@@ -198,8 +206,6 @@ class BaseFeature(interface.Feature):
|
|
|
198
206
|
) -> None:
|
|
199
207
|
"""Called when the feature is setup."""
|
|
200
208
|
self.environment.event_handler.on_feature_setup(
|
|
201
|
-
environment=self.environment,
|
|
202
|
-
sandbox=self.sandbox,
|
|
203
209
|
feature=self,
|
|
204
210
|
duration=duration,
|
|
205
211
|
error=error
|
|
@@ -212,8 +218,6 @@ class BaseFeature(interface.Feature):
|
|
|
212
218
|
) -> None:
|
|
213
219
|
"""Called when the feature is teardown."""
|
|
214
220
|
self.environment.event_handler.on_feature_teardown(
|
|
215
|
-
environment=self.environment,
|
|
216
|
-
sandbox=self.sandbox,
|
|
217
221
|
feature=self,
|
|
218
222
|
duration=duration,
|
|
219
223
|
error=error
|
|
@@ -227,8 +231,6 @@ class BaseFeature(interface.Feature):
|
|
|
227
231
|
) -> None:
|
|
228
232
|
"""Called when the feature has done housekeeping."""
|
|
229
233
|
self.environment.event_handler.on_feature_housekeep(
|
|
230
|
-
environment=self.environment,
|
|
231
|
-
sandbox=self.sandbox,
|
|
232
234
|
feature=self,
|
|
233
235
|
counter=self._housekeep_counter,
|
|
234
236
|
duration=duration,
|
|
@@ -243,8 +245,6 @@ class BaseFeature(interface.Feature):
|
|
|
243
245
|
) -> None:
|
|
244
246
|
"""Called when the feature is setup for a user session."""
|
|
245
247
|
self.environment.event_handler.on_feature_setup_session(
|
|
246
|
-
environment=self.environment,
|
|
247
|
-
sandbox=self.sandbox,
|
|
248
248
|
feature=self,
|
|
249
249
|
session_id=self.session_id,
|
|
250
250
|
duration=duration,
|
|
@@ -258,8 +258,6 @@ class BaseFeature(interface.Feature):
|
|
|
258
258
|
) -> None:
|
|
259
259
|
"""Called when the feature is teardown for a user session."""
|
|
260
260
|
self.environment.event_handler.on_feature_teardown_session(
|
|
261
|
-
environment=self.environment,
|
|
262
|
-
sandbox=self.sandbox,
|
|
263
261
|
feature=self,
|
|
264
262
|
session_id=self.session_id,
|
|
265
263
|
duration=duration,
|
|
@@ -274,13 +272,33 @@ class BaseFeature(interface.Feature):
|
|
|
274
272
|
**kwargs
|
|
275
273
|
) -> None:
|
|
276
274
|
"""Called when a sandbox activity is performed."""
|
|
277
|
-
self.environment.event_handler.
|
|
275
|
+
self.environment.event_handler.on_feature_activity(
|
|
278
276
|
name=f'{self.name}.{name}',
|
|
279
|
-
environment=self.environment,
|
|
280
|
-
sandbox=self.sandbox,
|
|
281
277
|
feature=self,
|
|
282
278
|
session_id=self.session_id,
|
|
283
279
|
duration=duration,
|
|
284
280
|
error=error,
|
|
285
281
|
**kwargs
|
|
286
282
|
)
|
|
283
|
+
|
|
284
|
+
@contextlib.contextmanager
|
|
285
|
+
def track_activity(
|
|
286
|
+
self,
|
|
287
|
+
name: str,
|
|
288
|
+
**kwargs: Any
|
|
289
|
+
) -> Iterator[None]:
|
|
290
|
+
"""Context manager that tracks a feature activity."""
|
|
291
|
+
start_time = time.time()
|
|
292
|
+
error = None
|
|
293
|
+
try:
|
|
294
|
+
yield None
|
|
295
|
+
except BaseException as e: # pylint: disable=broad-except
|
|
296
|
+
error = e
|
|
297
|
+
raise
|
|
298
|
+
finally:
|
|
299
|
+
self.on_activity(
|
|
300
|
+
name=name,
|
|
301
|
+
duration=time.time() - start_time,
|
|
302
|
+
error=error,
|
|
303
|
+
**kwargs
|
|
304
|
+
)
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
# Copyright 2025 The Langfun Authors
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
import unittest
|
|
15
|
+
|
|
16
|
+
from langfun.env import test_utils
|
|
17
|
+
|
|
18
|
+
TestingEnvironment = test_utils.TestingEnvironment
|
|
19
|
+
TestingNonSandboxBasedFeature = test_utils.TestingNonSandboxBasedFeature
|
|
20
|
+
TestingEventHandler = test_utils.TestingEventHandler
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class NonSandboxBasedFeatureTests(unittest.TestCase):
|
|
24
|
+
|
|
25
|
+
def test_basics(self):
|
|
26
|
+
feature = TestingNonSandboxBasedFeature()
|
|
27
|
+
event_handler = TestingEventHandler(
|
|
28
|
+
log_session_setup=True,
|
|
29
|
+
log_feature_setup=True,
|
|
30
|
+
log_sandbox_status=True
|
|
31
|
+
)
|
|
32
|
+
env = TestingEnvironment(
|
|
33
|
+
image_ids=[],
|
|
34
|
+
features={'test_feature': feature},
|
|
35
|
+
event_handler=event_handler,
|
|
36
|
+
)
|
|
37
|
+
self.assertFalse(env.is_online)
|
|
38
|
+
self.assertEqual(len(list(env.non_sandbox_based_features())), 1)
|
|
39
|
+
with env:
|
|
40
|
+
self.assertTrue(env.is_online)
|
|
41
|
+
with env.test_feature('session1') as feature:
|
|
42
|
+
self.assertIsNone(feature.sandbox)
|
|
43
|
+
self.assertEqual(feature.session_id, 'session1')
|
|
44
|
+
|
|
45
|
+
self.assertEqual(
|
|
46
|
+
event_handler.logs,
|
|
47
|
+
[
|
|
48
|
+
'[testing-env/test_feature] feature setup',
|
|
49
|
+
'[testing-env] environment started',
|
|
50
|
+
'[testing-env/test_feature@session1] feature setup session',
|
|
51
|
+
'[testing-env/test_feature@session1] feature teardown session',
|
|
52
|
+
'[testing-env/test_feature] feature teardown',
|
|
53
|
+
'[testing-env] environment shutdown'
|
|
54
|
+
]
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
def test_feature_setup_error(self):
|
|
58
|
+
event_handler = TestingEventHandler(
|
|
59
|
+
log_session_setup=True,
|
|
60
|
+
log_feature_setup=True,
|
|
61
|
+
log_sandbox_status=True
|
|
62
|
+
)
|
|
63
|
+
env = TestingEnvironment(
|
|
64
|
+
image_ids=[],
|
|
65
|
+
features={
|
|
66
|
+
'test_feature': TestingNonSandboxBasedFeature(
|
|
67
|
+
simulate_setup_error=ValueError
|
|
68
|
+
)
|
|
69
|
+
},
|
|
70
|
+
event_handler=event_handler,
|
|
71
|
+
)
|
|
72
|
+
with self.assertRaises(ValueError):
|
|
73
|
+
with env:
|
|
74
|
+
pass
|
|
75
|
+
self.assertEqual(
|
|
76
|
+
event_handler.logs,
|
|
77
|
+
[
|
|
78
|
+
'[testing-env/test_feature] feature setup with ValueError',
|
|
79
|
+
'[testing-env] environment started with ValueError',
|
|
80
|
+
'[testing-env/test_feature] feature teardown',
|
|
81
|
+
'[testing-env] environment shutdown'
|
|
82
|
+
]
|
|
83
|
+
)
|
|
84
|
+
|
|
85
|
+
def test_feature_teardown_error(self):
|
|
86
|
+
event_handler = TestingEventHandler(
|
|
87
|
+
log_session_setup=True,
|
|
88
|
+
log_feature_setup=True,
|
|
89
|
+
log_sandbox_status=True
|
|
90
|
+
)
|
|
91
|
+
env = TestingEnvironment(
|
|
92
|
+
image_ids=[],
|
|
93
|
+
features={
|
|
94
|
+
'test_feature': TestingNonSandboxBasedFeature(
|
|
95
|
+
simulate_teardown_error=ValueError
|
|
96
|
+
)
|
|
97
|
+
},
|
|
98
|
+
event_handler=event_handler,
|
|
99
|
+
)
|
|
100
|
+
with env:
|
|
101
|
+
pass
|
|
102
|
+
self.assertEqual(
|
|
103
|
+
event_handler.logs,
|
|
104
|
+
[
|
|
105
|
+
'[testing-env/test_feature] feature setup',
|
|
106
|
+
'[testing-env] environment started',
|
|
107
|
+
'[testing-env/test_feature] feature teardown with ValueError',
|
|
108
|
+
'[testing-env] environment shutdown'
|
|
109
|
+
]
|
|
110
|
+
)
|
|
111
|
+
|
|
112
|
+
def test_feature_setup_session_error(self):
|
|
113
|
+
event_handler = TestingEventHandler(
|
|
114
|
+
log_session_setup=True,
|
|
115
|
+
log_feature_setup=True,
|
|
116
|
+
log_sandbox_status=True
|
|
117
|
+
)
|
|
118
|
+
env = TestingEnvironment(
|
|
119
|
+
image_ids=[],
|
|
120
|
+
features={
|
|
121
|
+
'test_feature': TestingNonSandboxBasedFeature(
|
|
122
|
+
simulate_setup_session_error=ValueError
|
|
123
|
+
)
|
|
124
|
+
},
|
|
125
|
+
event_handler=event_handler,
|
|
126
|
+
)
|
|
127
|
+
with env:
|
|
128
|
+
with self.assertRaises(ValueError):
|
|
129
|
+
with env.test_feature('session1'):
|
|
130
|
+
pass
|
|
131
|
+
self.assertEqual(
|
|
132
|
+
event_handler.logs,
|
|
133
|
+
[
|
|
134
|
+
# pylint: disable=line-too-long
|
|
135
|
+
'[testing-env/test_feature] feature setup',
|
|
136
|
+
'[testing-env] environment started',
|
|
137
|
+
'[testing-env/test_feature@session1] feature setup session with ValueError',
|
|
138
|
+
'[testing-env/test_feature@session1] feature teardown session',
|
|
139
|
+
'[testing-env/test_feature] feature teardown',
|
|
140
|
+
'[testing-env] environment shutdown',
|
|
141
|
+
# pylint: enable=line-too-long
|
|
142
|
+
]
|
|
143
|
+
)
|
|
144
|
+
|
|
145
|
+
def test_feature_teardown_session_error(self):
|
|
146
|
+
event_handler = TestingEventHandler(
|
|
147
|
+
log_session_setup=True,
|
|
148
|
+
log_feature_setup=True,
|
|
149
|
+
log_sandbox_status=True
|
|
150
|
+
)
|
|
151
|
+
env = TestingEnvironment(
|
|
152
|
+
image_ids=[],
|
|
153
|
+
features={
|
|
154
|
+
'test_feature': TestingNonSandboxBasedFeature(
|
|
155
|
+
simulate_teardown_session_error=ValueError
|
|
156
|
+
)
|
|
157
|
+
},
|
|
158
|
+
event_handler=event_handler,
|
|
159
|
+
)
|
|
160
|
+
with env:
|
|
161
|
+
with env.test_feature('session1'):
|
|
162
|
+
pass
|
|
163
|
+
self.assertEqual(
|
|
164
|
+
event_handler.logs,
|
|
165
|
+
[
|
|
166
|
+
# pylint: disable=line-too-long
|
|
167
|
+
'[testing-env/test_feature] feature setup',
|
|
168
|
+
'[testing-env] environment started',
|
|
169
|
+
'[testing-env/test_feature@session1] feature setup session',
|
|
170
|
+
'[testing-env/test_feature@session1] feature teardown session with ValueError',
|
|
171
|
+
'[testing-env/test_feature] feature teardown',
|
|
172
|
+
'[testing-env] environment shutdown',
|
|
173
|
+
# pylint: enable=line-too-long
|
|
174
|
+
]
|
|
175
|
+
)
|
|
176
|
+
|
|
177
|
+
def test_feature_housekeeping(self):
|
|
178
|
+
event_handler = TestingEventHandler(
|
|
179
|
+
log_sandbox_status=False,
|
|
180
|
+
log_feature_setup=False,
|
|
181
|
+
log_housekeep=True
|
|
182
|
+
)
|
|
183
|
+
env = TestingEnvironment(
|
|
184
|
+
image_ids=[],
|
|
185
|
+
features={
|
|
186
|
+
'test_feature': TestingNonSandboxBasedFeature(
|
|
187
|
+
housekeep_interval=0.1
|
|
188
|
+
)
|
|
189
|
+
},
|
|
190
|
+
event_handler=event_handler,
|
|
191
|
+
housekeep_interval=0.2
|
|
192
|
+
)
|
|
193
|
+
with env:
|
|
194
|
+
env.wait_for_housekeeping()
|
|
195
|
+
self.assertIn(
|
|
196
|
+
'[testing-env/test_feature] feature housekeeping 0',
|
|
197
|
+
event_handler.logs
|
|
198
|
+
)
|
|
199
|
+
|
|
200
|
+
def test_feature_housekeeping_error(self):
|
|
201
|
+
event_handler = TestingEventHandler(
|
|
202
|
+
log_sandbox_status=False,
|
|
203
|
+
log_feature_setup=False,
|
|
204
|
+
log_housekeep=True
|
|
205
|
+
)
|
|
206
|
+
env = TestingEnvironment(
|
|
207
|
+
image_ids=[],
|
|
208
|
+
features={
|
|
209
|
+
'test_feature': TestingNonSandboxBasedFeature(
|
|
210
|
+
simulate_housekeep_error=ValueError,
|
|
211
|
+
housekeep_interval=0.1
|
|
212
|
+
)
|
|
213
|
+
},
|
|
214
|
+
event_handler=event_handler,
|
|
215
|
+
housekeep_interval=0.2
|
|
216
|
+
)
|
|
217
|
+
with env:
|
|
218
|
+
env.wait_for_housekeeping()
|
|
219
|
+
self.assertFalse(env.is_online)
|
|
220
|
+
self.assertIn(
|
|
221
|
+
'[testing-env/test_feature] feature housekeeping 0 with ValueError',
|
|
222
|
+
event_handler.logs
|
|
223
|
+
)
|
|
224
|
+
|
|
225
|
+
|
|
226
|
+
if __name__ == '__main__':
|
|
227
|
+
unittest.main()
|
|
228
|
+
|