langfun 0.1.2.dev202509120804__py3-none-any.whl → 0.1.2.dev202512150805__py3-none-any.whl
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.
- langfun/__init__.py +1 -1
- langfun/core/__init__.py +7 -1
- langfun/core/agentic/__init__.py +8 -1
- langfun/core/agentic/action.py +740 -112
- langfun/core/agentic/action_eval.py +9 -2
- langfun/core/agentic/action_test.py +189 -24
- langfun/core/async_support.py +104 -5
- langfun/core/async_support_test.py +23 -0
- langfun/core/coding/python/correction.py +19 -9
- langfun/core/coding/python/execution.py +14 -12
- langfun/core/coding/python/generation.py +21 -16
- langfun/core/coding/python/sandboxing.py +23 -3
- langfun/core/component.py +42 -3
- langfun/core/concurrent.py +70 -6
- langfun/core/concurrent_test.py +9 -2
- langfun/core/console.py +1 -1
- langfun/core/data/conversion/anthropic.py +12 -3
- langfun/core/data/conversion/anthropic_test.py +8 -6
- langfun/core/data/conversion/gemini.py +11 -2
- langfun/core/data/conversion/gemini_test.py +48 -9
- langfun/core/data/conversion/openai.py +145 -31
- langfun/core/data/conversion/openai_test.py +161 -17
- langfun/core/eval/base.py +48 -44
- langfun/core/eval/base_test.py +5 -5
- langfun/core/eval/matching.py +5 -2
- langfun/core/eval/patching.py +3 -3
- langfun/core/eval/scoring.py +4 -3
- langfun/core/eval/v2/__init__.py +3 -0
- langfun/core/eval/v2/checkpointing.py +148 -46
- langfun/core/eval/v2/checkpointing_test.py +9 -2
- langfun/core/eval/v2/config_saver.py +37 -0
- langfun/core/eval/v2/config_saver_test.py +36 -0
- langfun/core/eval/v2/eval_test_helper.py +104 -3
- langfun/core/eval/v2/evaluation.py +102 -19
- langfun/core/eval/v2/evaluation_test.py +9 -3
- langfun/core/eval/v2/example.py +50 -40
- langfun/core/eval/v2/example_test.py +16 -8
- langfun/core/eval/v2/experiment.py +95 -20
- langfun/core/eval/v2/experiment_test.py +19 -0
- langfun/core/eval/v2/metric_values.py +31 -3
- langfun/core/eval/v2/metric_values_test.py +32 -0
- langfun/core/eval/v2/metrics.py +157 -44
- langfun/core/eval/v2/metrics_test.py +39 -18
- langfun/core/eval/v2/progress.py +31 -1
- langfun/core/eval/v2/progress_test.py +27 -0
- langfun/core/eval/v2/progress_tracking.py +13 -5
- langfun/core/eval/v2/progress_tracking_test.py +9 -1
- langfun/core/eval/v2/reporting.py +88 -71
- langfun/core/eval/v2/reporting_test.py +24 -6
- langfun/core/eval/v2/runners/__init__.py +30 -0
- langfun/core/eval/v2/{runners.py → runners/base.py} +73 -180
- langfun/core/eval/v2/runners/beam.py +354 -0
- langfun/core/eval/v2/runners/beam_test.py +153 -0
- langfun/core/eval/v2/runners/ckpt_monitor.py +350 -0
- langfun/core/eval/v2/runners/ckpt_monitor_test.py +213 -0
- langfun/core/eval/v2/runners/debug.py +40 -0
- langfun/core/eval/v2/runners/debug_test.py +76 -0
- langfun/core/eval/v2/runners/parallel.py +243 -0
- langfun/core/eval/v2/runners/parallel_test.py +182 -0
- langfun/core/eval/v2/runners/sequential.py +47 -0
- langfun/core/eval/v2/runners/sequential_test.py +169 -0
- langfun/core/langfunc.py +45 -130
- langfun/core/langfunc_test.py +7 -5
- langfun/core/language_model.py +189 -36
- langfun/core/language_model_test.py +54 -3
- langfun/core/llms/__init__.py +14 -1
- langfun/core/llms/anthropic.py +157 -2
- langfun/core/llms/azure_openai.py +29 -17
- langfun/core/llms/cache/base.py +25 -3
- langfun/core/llms/cache/in_memory.py +48 -7
- langfun/core/llms/cache/in_memory_test.py +14 -4
- langfun/core/llms/compositional.py +25 -1
- langfun/core/llms/deepseek.py +30 -2
- langfun/core/llms/fake.py +32 -1
- langfun/core/llms/gemini.py +90 -12
- langfun/core/llms/gemini_test.py +110 -0
- langfun/core/llms/google_genai.py +52 -1
- langfun/core/llms/groq.py +28 -3
- langfun/core/llms/llama_cpp.py +23 -4
- langfun/core/llms/openai.py +120 -3
- langfun/core/llms/openai_compatible.py +148 -27
- langfun/core/llms/openai_compatible_test.py +207 -20
- langfun/core/llms/openai_test.py +0 -2
- langfun/core/llms/rest.py +16 -1
- langfun/core/llms/vertexai.py +78 -8
- langfun/core/logging.py +1 -1
- langfun/core/mcp/__init__.py +10 -0
- langfun/core/mcp/client.py +177 -0
- langfun/core/mcp/client_test.py +71 -0
- langfun/core/mcp/session.py +241 -0
- langfun/core/mcp/session_test.py +54 -0
- langfun/core/mcp/testing/simple_mcp_client.py +33 -0
- langfun/core/mcp/testing/simple_mcp_server.py +33 -0
- langfun/core/mcp/tool.py +254 -0
- langfun/core/mcp/tool_test.py +197 -0
- langfun/core/memory.py +1 -0
- langfun/core/message.py +160 -55
- langfun/core/message_test.py +65 -81
- langfun/core/modalities/__init__.py +8 -0
- langfun/core/modalities/audio.py +21 -1
- langfun/core/modalities/image.py +73 -3
- langfun/core/modalities/image_test.py +116 -0
- langfun/core/modalities/mime.py +78 -4
- langfun/core/modalities/mime_test.py +59 -0
- langfun/core/modalities/pdf.py +19 -1
- langfun/core/modalities/video.py +21 -1
- langfun/core/modality.py +167 -29
- langfun/core/modality_test.py +42 -12
- langfun/core/natural_language.py +1 -1
- langfun/core/sampling.py +4 -4
- langfun/core/sampling_test.py +20 -4
- langfun/core/structured/__init__.py +2 -24
- langfun/core/structured/completion.py +34 -44
- langfun/core/structured/completion_test.py +23 -43
- langfun/core/structured/description.py +54 -50
- langfun/core/structured/function_generation.py +29 -12
- langfun/core/structured/mapping.py +81 -37
- langfun/core/structured/parsing.py +95 -79
- langfun/core/structured/parsing_test.py +0 -3
- langfun/core/structured/querying.py +230 -154
- langfun/core/structured/querying_test.py +69 -33
- langfun/core/structured/schema/__init__.py +49 -0
- langfun/core/structured/schema/base.py +664 -0
- langfun/core/structured/schema/base_test.py +531 -0
- langfun/core/structured/schema/json.py +174 -0
- langfun/core/structured/schema/json_test.py +121 -0
- langfun/core/structured/schema/python.py +316 -0
- langfun/core/structured/schema/python_test.py +410 -0
- langfun/core/structured/schema_generation.py +33 -14
- langfun/core/structured/scoring.py +47 -36
- langfun/core/structured/tokenization.py +26 -11
- langfun/core/subscription.py +2 -2
- langfun/core/template.py +175 -50
- langfun/core/template_test.py +123 -17
- langfun/env/__init__.py +43 -0
- langfun/env/base_environment.py +827 -0
- langfun/env/base_environment_test.py +473 -0
- langfun/env/base_feature.py +304 -0
- langfun/env/base_feature_test.py +228 -0
- langfun/env/base_sandbox.py +842 -0
- langfun/env/base_sandbox_test.py +1235 -0
- langfun/env/event_handlers/__init__.py +14 -0
- langfun/env/event_handlers/chain.py +233 -0
- langfun/env/event_handlers/chain_test.py +253 -0
- langfun/env/event_handlers/event_logger.py +472 -0
- langfun/env/event_handlers/event_logger_test.py +304 -0
- langfun/env/event_handlers/metric_writer.py +726 -0
- langfun/env/event_handlers/metric_writer_test.py +214 -0
- langfun/env/interface.py +1640 -0
- langfun/env/interface_test.py +153 -0
- langfun/env/load_balancers.py +59 -0
- langfun/env/load_balancers_test.py +141 -0
- langfun/env/test_utils.py +507 -0
- {langfun-0.1.2.dev202509120804.dist-info → langfun-0.1.2.dev202512150805.dist-info}/METADATA +7 -3
- langfun-0.1.2.dev202512150805.dist-info/RECORD +217 -0
- langfun/core/eval/v2/runners_test.py +0 -343
- langfun/core/structured/schema.py +0 -987
- langfun/core/structured/schema_test.py +0 -982
- langfun-0.1.2.dev202509120804.dist-info/RECORD +0 -172
- {langfun-0.1.2.dev202509120804.dist-info → langfun-0.1.2.dev202512150805.dist-info}/WHEEL +0 -0
- {langfun-0.1.2.dev202509120804.dist-info → langfun-0.1.2.dev202512150805.dist-info}/licenses/LICENSE +0 -0
- {langfun-0.1.2.dev202509120804.dist-info → langfun-0.1.2.dev202512150805.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,1235 @@
|
|
|
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 time
|
|
15
|
+
from typing import Any
|
|
16
|
+
import unittest
|
|
17
|
+
|
|
18
|
+
from langfun.env import interface
|
|
19
|
+
from langfun.env import test_utils
|
|
20
|
+
|
|
21
|
+
TestingEnvironment = test_utils.TestingEnvironment
|
|
22
|
+
TestingSandbox = test_utils.TestingSandbox
|
|
23
|
+
TestingFeature = test_utils.TestingFeature
|
|
24
|
+
TestingEventHandler = test_utils.TestingEventHandler
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class SandboxStateTests(unittest.TestCase):
|
|
28
|
+
|
|
29
|
+
def setUp(self):
|
|
30
|
+
super().setUp()
|
|
31
|
+
self.event_handler = TestingEventHandler(
|
|
32
|
+
log_sandbox_status=True,
|
|
33
|
+
log_feature_setup=True,
|
|
34
|
+
log_session_setup=True,
|
|
35
|
+
)
|
|
36
|
+
self.maxDiff = None
|
|
37
|
+
|
|
38
|
+
def _create_env(
|
|
39
|
+
self,
|
|
40
|
+
features,
|
|
41
|
+
*,
|
|
42
|
+
pool_size=0,
|
|
43
|
+
**kwargs
|
|
44
|
+
) -> TestingEnvironment:
|
|
45
|
+
return TestingEnvironment(
|
|
46
|
+
pool_size=pool_size,
|
|
47
|
+
features=features,
|
|
48
|
+
outage_grace_period=0,
|
|
49
|
+
event_handler=self.event_handler,
|
|
50
|
+
outage_retry_interval=0,
|
|
51
|
+
**kwargs
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
def test_passive_session_setup(self):
|
|
55
|
+
env = self._create_env(
|
|
56
|
+
features={
|
|
57
|
+
'feature1': TestingFeature(),
|
|
58
|
+
'feature2': TestingFeature(),
|
|
59
|
+
},
|
|
60
|
+
)
|
|
61
|
+
self.assertFalse(env.enable_pooling('test_image'))
|
|
62
|
+
with env:
|
|
63
|
+
with env.sandbox('session1') as sb:
|
|
64
|
+
sb.shell('echo "hello"')
|
|
65
|
+
self.assertEqual(
|
|
66
|
+
self.event_handler.logs,
|
|
67
|
+
[
|
|
68
|
+
# pylint: disable=line-too-long
|
|
69
|
+
'[testing-env] environment started',
|
|
70
|
+
'[testing-env/test_image:0@<idle>] shell: "feature1" setup',
|
|
71
|
+
'[testing-env/test_image:0/feature1] feature setup',
|
|
72
|
+
'[testing-env/test_image:0@<idle>] shell: "feature2" setup',
|
|
73
|
+
'[testing-env/test_image:0/feature2] feature setup',
|
|
74
|
+
'[testing-env/test_image:0] created -> ready',
|
|
75
|
+
'[testing-env/test_image:0] sandbox started',
|
|
76
|
+
'[testing-env/test_image:0] ready -> acquired',
|
|
77
|
+
'[testing-env/test_image:0] acquired -> setting_up',
|
|
78
|
+
'[testing-env/test_image:0@session1] shell: "feature1" setup session',
|
|
79
|
+
'[testing-env/test_image:0/feature1@session1] feature setup session',
|
|
80
|
+
'[testing-env/test_image:0@session1] shell: "feature2" setup session',
|
|
81
|
+
'[testing-env/test_image:0/feature2@session1] feature setup session',
|
|
82
|
+
'[testing-env/test_image:0] setting_up -> in_session',
|
|
83
|
+
"[testing-env/test_image:0] session 'session1' started",
|
|
84
|
+
'[testing-env/test_image:0@session1] shell: echo "hello"',
|
|
85
|
+
'[testing-env/test_image:0] in_session -> exiting_session',
|
|
86
|
+
'[testing-env/test_image:0@session1] shell: "feature1" teardown session',
|
|
87
|
+
'[testing-env/test_image:0/feature1@session1] feature teardown session',
|
|
88
|
+
'[testing-env/test_image:0@session1] shell: "feature2" teardown session',
|
|
89
|
+
'[testing-env/test_image:0/feature2@session1] feature teardown session',
|
|
90
|
+
"[testing-env/test_image:0] session 'session1' ended",
|
|
91
|
+
'[testing-env/test_image:0] exiting_session -> acquired',
|
|
92
|
+
'[testing-env/test_image:0] acquired -> shutting_down',
|
|
93
|
+
'[testing-env/test_image:0@<idle>] shell: "feature1" teardown',
|
|
94
|
+
'[testing-env/test_image:0/feature1] feature teardown',
|
|
95
|
+
'[testing-env/test_image:0@<idle>] shell: "feature2" teardown',
|
|
96
|
+
'[testing-env/test_image:0/feature2] feature teardown',
|
|
97
|
+
'[testing-env/test_image:0] shutting_down -> offline',
|
|
98
|
+
'[testing-env/test_image:0] sandbox shutdown'
|
|
99
|
+
# pylint: enable=line-too-long
|
|
100
|
+
]
|
|
101
|
+
)
|
|
102
|
+
|
|
103
|
+
def test_proactive_session_setup(self):
|
|
104
|
+
env = self._create_env(
|
|
105
|
+
features={
|
|
106
|
+
'feature1': TestingFeature(setup_session_delay=0.1),
|
|
107
|
+
'feature2': TestingFeature(),
|
|
108
|
+
},
|
|
109
|
+
pool_size=1,
|
|
110
|
+
proactive_session_setup=True,
|
|
111
|
+
)
|
|
112
|
+
self.assertTrue(env.enable_pooling('test_image'))
|
|
113
|
+
with env:
|
|
114
|
+
with env.sandbox('session1') as sb:
|
|
115
|
+
sb.shell('echo "hello"')
|
|
116
|
+
sb.wait_until_not(
|
|
117
|
+
(
|
|
118
|
+
interface.Sandbox.Status.IN_SESSION,
|
|
119
|
+
interface.Sandbox.Status.SETTING_UP
|
|
120
|
+
)
|
|
121
|
+
)
|
|
122
|
+
self.assertEqual(sb.status, interface.Sandbox.Status.READY)
|
|
123
|
+
self.assertEqual(
|
|
124
|
+
self.event_handler.logs,
|
|
125
|
+
[
|
|
126
|
+
# pylint: disable=line-too-long
|
|
127
|
+
'[testing-env/test_image:0:0@<idle>] shell: "feature1" setup',
|
|
128
|
+
'[testing-env/test_image:0:0/feature1] feature setup',
|
|
129
|
+
'[testing-env/test_image:0:0@<idle>] shell: "feature2" setup',
|
|
130
|
+
'[testing-env/test_image:0:0/feature2] feature setup',
|
|
131
|
+
'[testing-env/test_image:0:0@<idle>] shell: "feature1" setup session',
|
|
132
|
+
'[testing-env/test_image:0:0/feature1@<idle>] feature setup session',
|
|
133
|
+
'[testing-env/test_image:0:0@<idle>] shell: "feature2" setup session',
|
|
134
|
+
'[testing-env/test_image:0:0/feature2@<idle>] feature setup session',
|
|
135
|
+
'[testing-env/test_image:0:0] created -> ready',
|
|
136
|
+
'[testing-env/test_image:0:0] sandbox started',
|
|
137
|
+
'[testing-env] environment started',
|
|
138
|
+
'[testing-env/test_image:0:0] ready -> acquired',
|
|
139
|
+
'[testing-env/test_image:0:0] acquired -> setting_up',
|
|
140
|
+
'[testing-env/test_image:0:0] setting_up -> in_session',
|
|
141
|
+
"[testing-env/test_image:0:0] session 'session1' started",
|
|
142
|
+
'[testing-env/test_image:0:0@session1] shell: echo "hello"',
|
|
143
|
+
'[testing-env/test_image:0:0] in_session -> exiting_session',
|
|
144
|
+
'[testing-env/test_image:0:0@session1] shell: "feature1" teardown session',
|
|
145
|
+
'[testing-env/test_image:0:0/feature1@session1] feature teardown session',
|
|
146
|
+
'[testing-env/test_image:0:0@session1] shell: "feature2" teardown session',
|
|
147
|
+
'[testing-env/test_image:0:0/feature2@session1] feature teardown session',
|
|
148
|
+
"[testing-env/test_image:0:0] session 'session1' ended",
|
|
149
|
+
'[testing-env/test_image:0:0] exiting_session -> setting_up',
|
|
150
|
+
'[testing-env/test_image:0:0@<idle>] shell: "feature1" setup session',
|
|
151
|
+
'[testing-env/test_image:0:0/feature1@<idle>] feature setup session',
|
|
152
|
+
'[testing-env/test_image:0:0@<idle>] shell: "feature2" setup session',
|
|
153
|
+
'[testing-env/test_image:0:0/feature2@<idle>] feature setup session',
|
|
154
|
+
'[testing-env/test_image:0:0] setting_up -> ready'
|
|
155
|
+
# pylint: enable=line-too-long
|
|
156
|
+
]
|
|
157
|
+
)
|
|
158
|
+
|
|
159
|
+
def test_proactive_session_setup_with_setup_session_error(self):
|
|
160
|
+
env = self._create_env(
|
|
161
|
+
features={'test_feature': TestingFeature(setup_session_delay=0.5)},
|
|
162
|
+
pool_size=1,
|
|
163
|
+
housekeep_interval=10.0,
|
|
164
|
+
)
|
|
165
|
+
with env:
|
|
166
|
+
with env.sandbox('session1') as sb:
|
|
167
|
+
sb.test_feature.rebind(
|
|
168
|
+
simulate_setup_session_error=interface.SandboxStateError,
|
|
169
|
+
skip_notification=True
|
|
170
|
+
)
|
|
171
|
+
sb.wait_until_not(
|
|
172
|
+
(
|
|
173
|
+
interface.Sandbox.Status.SETTING_UP,
|
|
174
|
+
interface.Sandbox.Status.SHUTTING_DOWN
|
|
175
|
+
)
|
|
176
|
+
)
|
|
177
|
+
self.assertEqual(len(sb.state_errors), 1)
|
|
178
|
+
self.assertEqual(sb.status, interface.Sandbox.Status.OFFLINE)
|
|
179
|
+
self.assertEqual(
|
|
180
|
+
self.event_handler.logs,
|
|
181
|
+
[
|
|
182
|
+
# pylint: disable=line-too-long
|
|
183
|
+
'[testing-env/test_image:0:0@<idle>] shell: "test_feature" setup',
|
|
184
|
+
'[testing-env/test_image:0:0/test_feature] feature setup',
|
|
185
|
+
'[testing-env/test_image:0:0@<idle>] shell: "test_feature" setup session',
|
|
186
|
+
'[testing-env/test_image:0:0/test_feature@<idle>] feature setup session',
|
|
187
|
+
'[testing-env/test_image:0:0] created -> ready',
|
|
188
|
+
'[testing-env/test_image:0:0] sandbox started',
|
|
189
|
+
'[testing-env] environment started',
|
|
190
|
+
'[testing-env/test_image:0:0] ready -> acquired',
|
|
191
|
+
'[testing-env/test_image:0:0] acquired -> setting_up',
|
|
192
|
+
'[testing-env/test_image:0:0] setting_up -> in_session',
|
|
193
|
+
"[testing-env/test_image:0:0] session 'session1' started",
|
|
194
|
+
'[testing-env/test_image:0:0] in_session -> exiting_session',
|
|
195
|
+
'[testing-env/test_image:0:0@session1] shell: "test_feature" teardown session',
|
|
196
|
+
'[testing-env/test_image:0:0/test_feature@session1] feature teardown session',
|
|
197
|
+
"[testing-env/test_image:0:0] session 'session1' ended",
|
|
198
|
+
'[testing-env/test_image:0:0] exiting_session -> setting_up',
|
|
199
|
+
'[testing-env/test_image:0:0/test_feature@<idle>] feature setup session with SandboxStateError',
|
|
200
|
+
'[testing-env/test_image:0:0] setting_up -> shutting_down',
|
|
201
|
+
'[testing-env/test_image:0:0@<idle>] shell: "test_feature" teardown',
|
|
202
|
+
'[testing-env/test_image:0:0/test_feature] feature teardown',
|
|
203
|
+
'[testing-env/test_image:0:0] shutting_down -> offline',
|
|
204
|
+
'[testing-env/test_image:0:0] sandbox shutdown'
|
|
205
|
+
# pylint: enable=line-too-long
|
|
206
|
+
]
|
|
207
|
+
)
|
|
208
|
+
|
|
209
|
+
def test_sandbox_start_non_state_error(self):
|
|
210
|
+
env = self._create_env(
|
|
211
|
+
features={
|
|
212
|
+
'feature1': TestingFeature(),
|
|
213
|
+
'feature2': TestingFeature(),
|
|
214
|
+
},
|
|
215
|
+
simulate_start_error=ValueError,
|
|
216
|
+
)
|
|
217
|
+
with env:
|
|
218
|
+
with self.assertRaises(ValueError):
|
|
219
|
+
with env.sandbox('session1'):
|
|
220
|
+
pass
|
|
221
|
+
self.assertTrue(env.is_online)
|
|
222
|
+
self.assertEqual(
|
|
223
|
+
self.event_handler.logs,
|
|
224
|
+
[
|
|
225
|
+
'[testing-env] environment started',
|
|
226
|
+
'[testing-env/test_image:0] sandbox started with ValueError',
|
|
227
|
+
'[testing-env/test_image:0] created -> shutting_down',
|
|
228
|
+
'[testing-env/test_image:0] shutting_down -> offline',
|
|
229
|
+
'[testing-env/test_image:0] sandbox shutdown'
|
|
230
|
+
]
|
|
231
|
+
)
|
|
232
|
+
|
|
233
|
+
def test_sandbox_start_state_error(self):
|
|
234
|
+
env = self._create_env(
|
|
235
|
+
features={
|
|
236
|
+
'feature1': TestingFeature(),
|
|
237
|
+
'feature2': TestingFeature(),
|
|
238
|
+
},
|
|
239
|
+
pool_size=1,
|
|
240
|
+
simulate_start_error=interface.SandboxStateError,
|
|
241
|
+
)
|
|
242
|
+
with self.assertRaises(interface.EnvironmentOutageError):
|
|
243
|
+
with env:
|
|
244
|
+
pass
|
|
245
|
+
self.assertEqual(
|
|
246
|
+
self.event_handler.logs,
|
|
247
|
+
[
|
|
248
|
+
# pylint: disable=line-too-long
|
|
249
|
+
'[testing-env/test_image:0:0] sandbox started with SandboxStateError',
|
|
250
|
+
'[testing-env/test_image:0:0] created -> shutting_down',
|
|
251
|
+
'[testing-env/test_image:0:0] shutting_down -> offline',
|
|
252
|
+
'[testing-env/test_image:0:0] sandbox shutdown',
|
|
253
|
+
'[testing-env] environment started with EnvironmentOutageError',
|
|
254
|
+
'[testing-env] environment shutdown'
|
|
255
|
+
# pylint: enable=line-too-long
|
|
256
|
+
]
|
|
257
|
+
)
|
|
258
|
+
|
|
259
|
+
def test_sandbox_shutdown_non_state_error(self):
|
|
260
|
+
env = self._create_env(
|
|
261
|
+
features={
|
|
262
|
+
'feature1': TestingFeature(),
|
|
263
|
+
'feature2': TestingFeature(),
|
|
264
|
+
},
|
|
265
|
+
simulate_shutdown_error=ValueError,
|
|
266
|
+
)
|
|
267
|
+
with env:
|
|
268
|
+
with self.assertRaises(ValueError):
|
|
269
|
+
with env.sandbox('session1') as sb:
|
|
270
|
+
sb.shell('echo "hello"')
|
|
271
|
+
self.assertEqual(len(sb.state_errors), 0)
|
|
272
|
+
self.assertEqual(
|
|
273
|
+
self.event_handler.logs,
|
|
274
|
+
[
|
|
275
|
+
# pylint: disable=line-too-long
|
|
276
|
+
'[testing-env] environment started',
|
|
277
|
+
'[testing-env/test_image:0@<idle>] shell: "feature1" setup',
|
|
278
|
+
'[testing-env/test_image:0/feature1] feature setup',
|
|
279
|
+
'[testing-env/test_image:0@<idle>] shell: "feature2" setup',
|
|
280
|
+
'[testing-env/test_image:0/feature2] feature setup',
|
|
281
|
+
'[testing-env/test_image:0] created -> ready',
|
|
282
|
+
'[testing-env/test_image:0] sandbox started',
|
|
283
|
+
'[testing-env/test_image:0] ready -> acquired',
|
|
284
|
+
'[testing-env/test_image:0] acquired -> setting_up',
|
|
285
|
+
'[testing-env/test_image:0@session1] shell: "feature1" setup session',
|
|
286
|
+
'[testing-env/test_image:0/feature1@session1] feature setup session',
|
|
287
|
+
'[testing-env/test_image:0@session1] shell: "feature2" setup session',
|
|
288
|
+
'[testing-env/test_image:0/feature2@session1] feature setup session',
|
|
289
|
+
'[testing-env/test_image:0] setting_up -> in_session',
|
|
290
|
+
"[testing-env/test_image:0] session 'session1' started",
|
|
291
|
+
'[testing-env/test_image:0@session1] shell: echo "hello"',
|
|
292
|
+
'[testing-env/test_image:0] in_session -> exiting_session',
|
|
293
|
+
'[testing-env/test_image:0@session1] shell: "feature1" teardown session',
|
|
294
|
+
'[testing-env/test_image:0/feature1@session1] feature teardown session',
|
|
295
|
+
'[testing-env/test_image:0@session1] shell: "feature2" teardown session',
|
|
296
|
+
'[testing-env/test_image:0/feature2@session1] feature teardown session',
|
|
297
|
+
"[testing-env/test_image:0] session 'session1' ended",
|
|
298
|
+
'[testing-env/test_image:0] exiting_session -> acquired',
|
|
299
|
+
'[testing-env/test_image:0] acquired -> shutting_down',
|
|
300
|
+
'[testing-env/test_image:0@<idle>] shell: "feature1" teardown',
|
|
301
|
+
'[testing-env/test_image:0/feature1] feature teardown',
|
|
302
|
+
'[testing-env/test_image:0@<idle>] shell: "feature2" teardown',
|
|
303
|
+
'[testing-env/test_image:0/feature2] feature teardown',
|
|
304
|
+
'[testing-env/test_image:0] shutting_down -> offline',
|
|
305
|
+
'[testing-env/test_image:0] sandbox shutdown with ValueError',
|
|
306
|
+
'[testing-env] environment shutdown',
|
|
307
|
+
# pylint: enable=line-too-long
|
|
308
|
+
]
|
|
309
|
+
)
|
|
310
|
+
|
|
311
|
+
def test_env_shutdown_non_state_error(self):
|
|
312
|
+
env = self._create_env(
|
|
313
|
+
pool_size=1,
|
|
314
|
+
features={
|
|
315
|
+
'feature1': TestingFeature(),
|
|
316
|
+
'feature2': TestingFeature(),
|
|
317
|
+
},
|
|
318
|
+
simulate_shutdown_error=ValueError,
|
|
319
|
+
)
|
|
320
|
+
with self.assertRaises(ValueError):
|
|
321
|
+
with env:
|
|
322
|
+
pass
|
|
323
|
+
|
|
324
|
+
self.assertEqual(
|
|
325
|
+
self.event_handler.logs,
|
|
326
|
+
[
|
|
327
|
+
# pylint: disable=line-too-long
|
|
328
|
+
'[testing-env/test_image:0:0@<idle>] shell: "feature1" setup',
|
|
329
|
+
'[testing-env/test_image:0:0/feature1] feature setup',
|
|
330
|
+
'[testing-env/test_image:0:0@<idle>] shell: "feature2" setup',
|
|
331
|
+
'[testing-env/test_image:0:0/feature2] feature setup',
|
|
332
|
+
'[testing-env/test_image:0:0@<idle>] shell: "feature1" setup session',
|
|
333
|
+
'[testing-env/test_image:0:0/feature1@<idle>] feature setup session',
|
|
334
|
+
'[testing-env/test_image:0:0@<idle>] shell: "feature2" setup session',
|
|
335
|
+
'[testing-env/test_image:0:0/feature2@<idle>] feature setup session',
|
|
336
|
+
'[testing-env/test_image:0:0] created -> ready',
|
|
337
|
+
'[testing-env/test_image:0:0] sandbox started',
|
|
338
|
+
'[testing-env] environment started',
|
|
339
|
+
'[testing-env/test_image:0:0] ready -> shutting_down',
|
|
340
|
+
'[testing-env/test_image:0:0@<idle>] shell: "feature1" teardown',
|
|
341
|
+
'[testing-env/test_image:0:0/feature1] feature teardown',
|
|
342
|
+
'[testing-env/test_image:0:0@<idle>] shell: "feature2" teardown',
|
|
343
|
+
'[testing-env/test_image:0:0/feature2] feature teardown',
|
|
344
|
+
'[testing-env/test_image:0:0] shutting_down -> offline',
|
|
345
|
+
'[testing-env/test_image:0:0] sandbox shutdown with ValueError',
|
|
346
|
+
'[testing-env] environment shutdown with ValueError'
|
|
347
|
+
# pylint: enable=line-too-long
|
|
348
|
+
]
|
|
349
|
+
)
|
|
350
|
+
|
|
351
|
+
def test_sandbox_shutdown_state_error(self):
|
|
352
|
+
env = self._create_env(
|
|
353
|
+
features={
|
|
354
|
+
'feature1': TestingFeature(),
|
|
355
|
+
'feature2': TestingFeature(),
|
|
356
|
+
},
|
|
357
|
+
simulate_shutdown_error=interface.SandboxStateError,
|
|
358
|
+
)
|
|
359
|
+
with env:
|
|
360
|
+
with env.sandbox('session1') as sb:
|
|
361
|
+
sb.shell('echo "hello"')
|
|
362
|
+
self.assertEqual(len(sb.state_errors), 1)
|
|
363
|
+
|
|
364
|
+
self.assertEqual(
|
|
365
|
+
self.event_handler.logs,
|
|
366
|
+
[
|
|
367
|
+
# pylint: disable=line-too-long
|
|
368
|
+
'[testing-env] environment started',
|
|
369
|
+
'[testing-env/test_image:0@<idle>] shell: "feature1" setup',
|
|
370
|
+
'[testing-env/test_image:0/feature1] feature setup',
|
|
371
|
+
'[testing-env/test_image:0@<idle>] shell: "feature2" setup',
|
|
372
|
+
'[testing-env/test_image:0/feature2] feature setup',
|
|
373
|
+
'[testing-env/test_image:0] created -> ready',
|
|
374
|
+
'[testing-env/test_image:0] sandbox started',
|
|
375
|
+
'[testing-env/test_image:0] ready -> acquired',
|
|
376
|
+
'[testing-env/test_image:0] acquired -> setting_up',
|
|
377
|
+
'[testing-env/test_image:0@session1] shell: "feature1" setup session',
|
|
378
|
+
'[testing-env/test_image:0/feature1@session1] feature setup session',
|
|
379
|
+
'[testing-env/test_image:0@session1] shell: "feature2" setup session',
|
|
380
|
+
'[testing-env/test_image:0/feature2@session1] feature setup session',
|
|
381
|
+
'[testing-env/test_image:0] setting_up -> in_session',
|
|
382
|
+
"[testing-env/test_image:0] session 'session1' started",
|
|
383
|
+
'[testing-env/test_image:0@session1] shell: echo "hello"',
|
|
384
|
+
'[testing-env/test_image:0] in_session -> exiting_session',
|
|
385
|
+
'[testing-env/test_image:0@session1] shell: "feature1" teardown session',
|
|
386
|
+
'[testing-env/test_image:0/feature1@session1] feature teardown session',
|
|
387
|
+
'[testing-env/test_image:0@session1] shell: "feature2" teardown session',
|
|
388
|
+
'[testing-env/test_image:0/feature2@session1] feature teardown session',
|
|
389
|
+
"[testing-env/test_image:0] session 'session1' ended",
|
|
390
|
+
'[testing-env/test_image:0] exiting_session -> acquired',
|
|
391
|
+
'[testing-env/test_image:0] acquired -> shutting_down',
|
|
392
|
+
'[testing-env/test_image:0@<idle>] shell: "feature1" teardown',
|
|
393
|
+
'[testing-env/test_image:0/feature1] feature teardown',
|
|
394
|
+
'[testing-env/test_image:0@<idle>] shell: "feature2" teardown',
|
|
395
|
+
'[testing-env/test_image:0/feature2] feature teardown',
|
|
396
|
+
'[testing-env/test_image:0] shutting_down -> offline',
|
|
397
|
+
'[testing-env/test_image:0] sandbox shutdown with SandboxStateError',
|
|
398
|
+
'[testing-env] environment shutdown',
|
|
399
|
+
# pylint: enable=line-too-long
|
|
400
|
+
]
|
|
401
|
+
)
|
|
402
|
+
|
|
403
|
+
def test_feature_setup_non_state_error(self):
|
|
404
|
+
env = self._create_env(
|
|
405
|
+
features={
|
|
406
|
+
'feature1': TestingFeature(),
|
|
407
|
+
'feature2': TestingFeature(
|
|
408
|
+
simulate_setup_error=ValueError
|
|
409
|
+
),
|
|
410
|
+
},
|
|
411
|
+
)
|
|
412
|
+
with env:
|
|
413
|
+
with self.assertRaises(ValueError):
|
|
414
|
+
with env.sandbox('session1'):
|
|
415
|
+
pass
|
|
416
|
+
self.assertEqual(
|
|
417
|
+
self.event_handler.logs,
|
|
418
|
+
[
|
|
419
|
+
# pylint: disable=line-too-long
|
|
420
|
+
'[testing-env] environment started',
|
|
421
|
+
'[testing-env/test_image:0@<idle>] shell: "feature1" setup',
|
|
422
|
+
'[testing-env/test_image:0/feature1] feature setup',
|
|
423
|
+
'[testing-env/test_image:0/feature2] feature setup with ValueError',
|
|
424
|
+
'[testing-env/test_image:0] sandbox started with ValueError',
|
|
425
|
+
'[testing-env/test_image:0] created -> shutting_down',
|
|
426
|
+
'[testing-env/test_image:0@<idle>] shell: "feature1" teardown',
|
|
427
|
+
'[testing-env/test_image:0/feature1] feature teardown',
|
|
428
|
+
'[testing-env/test_image:0@<idle>] shell: "feature2" teardown',
|
|
429
|
+
'[testing-env/test_image:0/feature2] feature teardown',
|
|
430
|
+
'[testing-env/test_image:0] shutting_down -> offline',
|
|
431
|
+
'[testing-env/test_image:0] sandbox shutdown'
|
|
432
|
+
# pylint: enable=line-too-long
|
|
433
|
+
]
|
|
434
|
+
)
|
|
435
|
+
|
|
436
|
+
def test_feature_setup_state_error(self):
|
|
437
|
+
env = self._create_env(
|
|
438
|
+
features={
|
|
439
|
+
'feature1': TestingFeature(
|
|
440
|
+
simulate_setup_error=interface.SandboxStateError
|
|
441
|
+
),
|
|
442
|
+
'feature2': TestingFeature(),
|
|
443
|
+
},
|
|
444
|
+
)
|
|
445
|
+
with env:
|
|
446
|
+
with self.assertRaises(interface.EnvironmentOutageError):
|
|
447
|
+
with env.sandbox('session1'):
|
|
448
|
+
pass
|
|
449
|
+
self.assertEqual(
|
|
450
|
+
self.event_handler.logs,
|
|
451
|
+
[
|
|
452
|
+
# pylint: disable=line-too-long
|
|
453
|
+
'[testing-env] environment started',
|
|
454
|
+
'[testing-env/test_image:0/feature1] feature setup with SandboxStateError',
|
|
455
|
+
'[testing-env/test_image:0] sandbox started with SandboxStateError',
|
|
456
|
+
'[testing-env/test_image:0] created -> shutting_down',
|
|
457
|
+
'[testing-env/test_image:0@<idle>] shell: "feature1" teardown',
|
|
458
|
+
'[testing-env/test_image:0/feature1] feature teardown',
|
|
459
|
+
'[testing-env/test_image:0] shutting_down -> offline',
|
|
460
|
+
'[testing-env/test_image:0] sandbox shutdown',
|
|
461
|
+
'[testing-env] environment shutdown',
|
|
462
|
+
# pylint: enable=line-too-long
|
|
463
|
+
]
|
|
464
|
+
)
|
|
465
|
+
|
|
466
|
+
def test_feature_teardown_non_state_error(self):
|
|
467
|
+
env = self._create_env(
|
|
468
|
+
features={
|
|
469
|
+
'feature1': TestingFeature(),
|
|
470
|
+
'feature2': TestingFeature(
|
|
471
|
+
simulate_teardown_error=ValueError
|
|
472
|
+
),
|
|
473
|
+
},
|
|
474
|
+
)
|
|
475
|
+
with env:
|
|
476
|
+
with self.assertRaises(interface.FeatureTeardownError):
|
|
477
|
+
with env.sandbox('session1'):
|
|
478
|
+
pass
|
|
479
|
+
self.assertEqual(
|
|
480
|
+
self.event_handler.logs,
|
|
481
|
+
[
|
|
482
|
+
# pylint: disable=line-too-long
|
|
483
|
+
'[testing-env] environment started',
|
|
484
|
+
'[testing-env/test_image:0@<idle>] shell: "feature1" setup',
|
|
485
|
+
'[testing-env/test_image:0/feature1] feature setup',
|
|
486
|
+
'[testing-env/test_image:0@<idle>] shell: "feature2" setup',
|
|
487
|
+
'[testing-env/test_image:0/feature2] feature setup',
|
|
488
|
+
'[testing-env/test_image:0] created -> ready',
|
|
489
|
+
'[testing-env/test_image:0] sandbox started',
|
|
490
|
+
'[testing-env/test_image:0] ready -> acquired',
|
|
491
|
+
'[testing-env/test_image:0] acquired -> setting_up',
|
|
492
|
+
'[testing-env/test_image:0@session1] shell: "feature1" setup session',
|
|
493
|
+
'[testing-env/test_image:0/feature1@session1] feature setup session',
|
|
494
|
+
'[testing-env/test_image:0@session1] shell: "feature2" setup session',
|
|
495
|
+
'[testing-env/test_image:0/feature2@session1] feature setup session',
|
|
496
|
+
'[testing-env/test_image:0] setting_up -> in_session',
|
|
497
|
+
"[testing-env/test_image:0] session 'session1' started",
|
|
498
|
+
'[testing-env/test_image:0] in_session -> exiting_session',
|
|
499
|
+
'[testing-env/test_image:0@session1] shell: "feature1" teardown session',
|
|
500
|
+
'[testing-env/test_image:0/feature1@session1] feature teardown session',
|
|
501
|
+
'[testing-env/test_image:0@session1] shell: "feature2" teardown session',
|
|
502
|
+
'[testing-env/test_image:0/feature2@session1] feature teardown session',
|
|
503
|
+
"[testing-env/test_image:0] session 'session1' ended",
|
|
504
|
+
'[testing-env/test_image:0] exiting_session -> acquired',
|
|
505
|
+
'[testing-env/test_image:0] acquired -> shutting_down',
|
|
506
|
+
'[testing-env/test_image:0@<idle>] shell: "feature1" teardown',
|
|
507
|
+
'[testing-env/test_image:0/feature1] feature teardown',
|
|
508
|
+
'[testing-env/test_image:0/feature2] feature teardown with ValueError',
|
|
509
|
+
'[testing-env/test_image:0] shutting_down -> offline',
|
|
510
|
+
'[testing-env/test_image:0] sandbox shutdown with FeatureTeardownError',
|
|
511
|
+
# pylint: enable=line-too-long
|
|
512
|
+
]
|
|
513
|
+
)
|
|
514
|
+
|
|
515
|
+
def test_feature_teardown_state_error(self):
|
|
516
|
+
env = self._create_env(
|
|
517
|
+
features={
|
|
518
|
+
'feature1': TestingFeature(
|
|
519
|
+
simulate_teardown_error=interface.SandboxStateError
|
|
520
|
+
),
|
|
521
|
+
'feature2': TestingFeature(
|
|
522
|
+
),
|
|
523
|
+
},
|
|
524
|
+
)
|
|
525
|
+
with env:
|
|
526
|
+
with env.sandbox('session1') as sb:
|
|
527
|
+
pass
|
|
528
|
+
self.assertEqual(len(sb.state_errors), 1)
|
|
529
|
+
self.assertEqual(
|
|
530
|
+
self.event_handler.logs,
|
|
531
|
+
[
|
|
532
|
+
# pylint: disable=line-too-long
|
|
533
|
+
'[testing-env] environment started',
|
|
534
|
+
'[testing-env/test_image:0@<idle>] shell: "feature1" setup',
|
|
535
|
+
'[testing-env/test_image:0/feature1] feature setup',
|
|
536
|
+
'[testing-env/test_image:0@<idle>] shell: "feature2" setup',
|
|
537
|
+
'[testing-env/test_image:0/feature2] feature setup',
|
|
538
|
+
'[testing-env/test_image:0] created -> ready',
|
|
539
|
+
'[testing-env/test_image:0] sandbox started',
|
|
540
|
+
'[testing-env/test_image:0] ready -> acquired',
|
|
541
|
+
'[testing-env/test_image:0] acquired -> setting_up',
|
|
542
|
+
'[testing-env/test_image:0@session1] shell: "feature1" setup session',
|
|
543
|
+
'[testing-env/test_image:0/feature1@session1] feature setup session',
|
|
544
|
+
'[testing-env/test_image:0@session1] shell: "feature2" setup session',
|
|
545
|
+
'[testing-env/test_image:0/feature2@session1] feature setup session',
|
|
546
|
+
'[testing-env/test_image:0] setting_up -> in_session',
|
|
547
|
+
"[testing-env/test_image:0] session 'session1' started",
|
|
548
|
+
'[testing-env/test_image:0] in_session -> exiting_session',
|
|
549
|
+
'[testing-env/test_image:0@session1] shell: "feature1" teardown session',
|
|
550
|
+
'[testing-env/test_image:0/feature1@session1] feature teardown session',
|
|
551
|
+
'[testing-env/test_image:0@session1] shell: "feature2" teardown session',
|
|
552
|
+
'[testing-env/test_image:0/feature2@session1] feature teardown session',
|
|
553
|
+
"[testing-env/test_image:0] session 'session1' ended",
|
|
554
|
+
'[testing-env/test_image:0] exiting_session -> acquired',
|
|
555
|
+
'[testing-env/test_image:0] acquired -> shutting_down',
|
|
556
|
+
'[testing-env/test_image:0/feature1] feature teardown with SandboxStateError',
|
|
557
|
+
'[testing-env/test_image:0@<idle>] shell: "feature2" teardown',
|
|
558
|
+
'[testing-env/test_image:0/feature2] feature teardown',
|
|
559
|
+
'[testing-env/test_image:0] shutting_down -> offline',
|
|
560
|
+
'[testing-env/test_image:0] sandbox shutdown with FeatureTeardownError',
|
|
561
|
+
# pylint: enable=line-too-long
|
|
562
|
+
]
|
|
563
|
+
)
|
|
564
|
+
|
|
565
|
+
def test_feature_setup_session_non_state_error(self):
|
|
566
|
+
env = self._create_env(
|
|
567
|
+
features={
|
|
568
|
+
'feature1': TestingFeature(),
|
|
569
|
+
'feature2': TestingFeature(
|
|
570
|
+
simulate_setup_session_error=ValueError
|
|
571
|
+
),
|
|
572
|
+
},
|
|
573
|
+
)
|
|
574
|
+
with env:
|
|
575
|
+
with self.assertRaises(ValueError):
|
|
576
|
+
with env.sandbox('session1') as sb:
|
|
577
|
+
sb.shell('echo "hello"')
|
|
578
|
+
self.assertEqual(
|
|
579
|
+
self.event_handler.logs,
|
|
580
|
+
[
|
|
581
|
+
# pylint: disable=line-too-long
|
|
582
|
+
'[testing-env] environment started',
|
|
583
|
+
'[testing-env/test_image:0@<idle>] shell: "feature1" setup',
|
|
584
|
+
'[testing-env/test_image:0/feature1] feature setup',
|
|
585
|
+
'[testing-env/test_image:0@<idle>] shell: "feature2" setup',
|
|
586
|
+
'[testing-env/test_image:0/feature2] feature setup',
|
|
587
|
+
'[testing-env/test_image:0] created -> ready',
|
|
588
|
+
'[testing-env/test_image:0] sandbox started',
|
|
589
|
+
'[testing-env/test_image:0] ready -> acquired',
|
|
590
|
+
'[testing-env/test_image:0] acquired -> setting_up',
|
|
591
|
+
'[testing-env/test_image:0@session1] shell: "feature1" setup session',
|
|
592
|
+
'[testing-env/test_image:0/feature1@session1] feature setup session',
|
|
593
|
+
'[testing-env/test_image:0/feature2@session1] feature setup session with ValueError',
|
|
594
|
+
"[testing-env/test_image:0] session 'session1' started with ValueError",
|
|
595
|
+
'[testing-env/test_image:0] setting_up -> shutting_down',
|
|
596
|
+
'[testing-env/test_image:0@session1] shell: "feature1" teardown',
|
|
597
|
+
'[testing-env/test_image:0/feature1] feature teardown',
|
|
598
|
+
'[testing-env/test_image:0@session1] shell: "feature2" teardown',
|
|
599
|
+
'[testing-env/test_image:0/feature2] feature teardown',
|
|
600
|
+
'[testing-env/test_image:0] shutting_down -> offline',
|
|
601
|
+
'[testing-env/test_image:0] sandbox shutdown'
|
|
602
|
+
# pylint: enable=line-too-long
|
|
603
|
+
]
|
|
604
|
+
)
|
|
605
|
+
|
|
606
|
+
def test_feature_teardown_session_non_state_error(self):
|
|
607
|
+
env = self._create_env(
|
|
608
|
+
features={
|
|
609
|
+
'feature1': TestingFeature(
|
|
610
|
+
simulate_teardown_session_error=ValueError
|
|
611
|
+
),
|
|
612
|
+
'feature2': TestingFeature(),
|
|
613
|
+
},
|
|
614
|
+
)
|
|
615
|
+
with env:
|
|
616
|
+
with self.assertRaises(interface.SessionTeardownError):
|
|
617
|
+
with env.sandbox('session1') as sb:
|
|
618
|
+
sb.shell('echo "hello"')
|
|
619
|
+
self.assertEqual(sb.status, interface.Sandbox.Status.OFFLINE)
|
|
620
|
+
self.assertEqual(
|
|
621
|
+
self.event_handler.logs,
|
|
622
|
+
[
|
|
623
|
+
# pylint: disable=line-too-long
|
|
624
|
+
'[testing-env] environment started',
|
|
625
|
+
'[testing-env/test_image:0@<idle>] shell: "feature1" setup',
|
|
626
|
+
'[testing-env/test_image:0/feature1] feature setup',
|
|
627
|
+
'[testing-env/test_image:0@<idle>] shell: "feature2" setup',
|
|
628
|
+
'[testing-env/test_image:0/feature2] feature setup',
|
|
629
|
+
'[testing-env/test_image:0] created -> ready',
|
|
630
|
+
'[testing-env/test_image:0] sandbox started',
|
|
631
|
+
'[testing-env/test_image:0] ready -> acquired',
|
|
632
|
+
'[testing-env/test_image:0] acquired -> setting_up',
|
|
633
|
+
'[testing-env/test_image:0@session1] shell: "feature1" setup session',
|
|
634
|
+
'[testing-env/test_image:0/feature1@session1] feature setup session',
|
|
635
|
+
'[testing-env/test_image:0@session1] shell: "feature2" setup session',
|
|
636
|
+
'[testing-env/test_image:0/feature2@session1] feature setup session',
|
|
637
|
+
'[testing-env/test_image:0] setting_up -> in_session',
|
|
638
|
+
"[testing-env/test_image:0] session 'session1' started",
|
|
639
|
+
'[testing-env/test_image:0@session1] shell: echo "hello"',
|
|
640
|
+
'[testing-env/test_image:0] in_session -> exiting_session',
|
|
641
|
+
'[testing-env/test_image:0/feature1@session1] feature teardown session with ValueError',
|
|
642
|
+
'[testing-env/test_image:0@session1] shell: "feature2" teardown session',
|
|
643
|
+
'[testing-env/test_image:0/feature2@session1] feature teardown session',
|
|
644
|
+
"[testing-env/test_image:0] session 'session1' ended",
|
|
645
|
+
'[testing-env/test_image:0] exiting_session -> acquired',
|
|
646
|
+
'[testing-env/test_image:0] acquired -> shutting_down',
|
|
647
|
+
'[testing-env/test_image:0@<idle>] shell: "feature1" teardown',
|
|
648
|
+
'[testing-env/test_image:0/feature1] feature teardown',
|
|
649
|
+
'[testing-env/test_image:0@<idle>] shell: "feature2" teardown',
|
|
650
|
+
'[testing-env/test_image:0/feature2] feature teardown',
|
|
651
|
+
'[testing-env/test_image:0] shutting_down -> offline',
|
|
652
|
+
'[testing-env/test_image:0] sandbox shutdown',
|
|
653
|
+
# pylint: enable=line-too-long
|
|
654
|
+
]
|
|
655
|
+
)
|
|
656
|
+
|
|
657
|
+
def test_feature_teardown_session_state_error(self):
|
|
658
|
+
env = self._create_env(
|
|
659
|
+
features={
|
|
660
|
+
'feature1': TestingFeature(
|
|
661
|
+
simulate_teardown_session_error=interface.SandboxStateError
|
|
662
|
+
),
|
|
663
|
+
'feature2': TestingFeature(),
|
|
664
|
+
},
|
|
665
|
+
)
|
|
666
|
+
with env:
|
|
667
|
+
with env.sandbox('session1') as sb:
|
|
668
|
+
sb.shell('echo "hello"')
|
|
669
|
+
self.assertEqual(len(sb.state_errors), 1)
|
|
670
|
+
self.assertEqual(sb.status, interface.Sandbox.Status.OFFLINE)
|
|
671
|
+
self.assertEqual(
|
|
672
|
+
self.event_handler.logs,
|
|
673
|
+
[
|
|
674
|
+
# pylint: disable=line-too-long
|
|
675
|
+
'[testing-env] environment started',
|
|
676
|
+
'[testing-env/test_image:0@<idle>] shell: "feature1" setup',
|
|
677
|
+
'[testing-env/test_image:0/feature1] feature setup',
|
|
678
|
+
'[testing-env/test_image:0@<idle>] shell: "feature2" setup',
|
|
679
|
+
'[testing-env/test_image:0/feature2] feature setup',
|
|
680
|
+
'[testing-env/test_image:0] created -> ready',
|
|
681
|
+
'[testing-env/test_image:0] sandbox started',
|
|
682
|
+
'[testing-env/test_image:0] ready -> acquired',
|
|
683
|
+
'[testing-env/test_image:0] acquired -> setting_up',
|
|
684
|
+
'[testing-env/test_image:0@session1] shell: "feature1" setup session',
|
|
685
|
+
'[testing-env/test_image:0/feature1@session1] feature setup session',
|
|
686
|
+
'[testing-env/test_image:0@session1] shell: "feature2" setup session',
|
|
687
|
+
'[testing-env/test_image:0/feature2@session1] feature setup session',
|
|
688
|
+
'[testing-env/test_image:0] setting_up -> in_session',
|
|
689
|
+
"[testing-env/test_image:0] session 'session1' started",
|
|
690
|
+
'[testing-env/test_image:0@session1] shell: echo "hello"',
|
|
691
|
+
'[testing-env/test_image:0] in_session -> exiting_session',
|
|
692
|
+
'[testing-env/test_image:0/feature1@session1] feature teardown session with SandboxStateError',
|
|
693
|
+
'[testing-env/test_image:0@session1] shell: "feature2" teardown session',
|
|
694
|
+
'[testing-env/test_image:0/feature2@session1] feature teardown session',
|
|
695
|
+
"[testing-env/test_image:0] session 'session1' ended with SandboxStateError",
|
|
696
|
+
'[testing-env/test_image:0] exiting_session -> acquired',
|
|
697
|
+
'[testing-env/test_image:0] acquired -> shutting_down',
|
|
698
|
+
'[testing-env/test_image:0@<idle>] shell: "feature1" teardown',
|
|
699
|
+
'[testing-env/test_image:0/feature1] feature teardown',
|
|
700
|
+
'[testing-env/test_image:0@<idle>] shell: "feature2" teardown',
|
|
701
|
+
'[testing-env/test_image:0/feature2] feature teardown',
|
|
702
|
+
'[testing-env/test_image:0] shutting_down -> offline',
|
|
703
|
+
'[testing-env/test_image:0] sandbox shutdown',
|
|
704
|
+
# pylint: enable=line-too-long
|
|
705
|
+
]
|
|
706
|
+
)
|
|
707
|
+
|
|
708
|
+
def test_feature_teardown_session_calling_end_session(self):
|
|
709
|
+
env = self._create_env(
|
|
710
|
+
features={
|
|
711
|
+
'feature1': TestingFeature(
|
|
712
|
+
call_end_session_on_teardown_session=True
|
|
713
|
+
),
|
|
714
|
+
'feature2': TestingFeature(),
|
|
715
|
+
},
|
|
716
|
+
)
|
|
717
|
+
with env:
|
|
718
|
+
with env.sandbox('session1') as sb:
|
|
719
|
+
sb.shell('echo "hello"')
|
|
720
|
+
self.assertEqual(
|
|
721
|
+
self.event_handler.logs,
|
|
722
|
+
[
|
|
723
|
+
# pylint: disable=line-too-long
|
|
724
|
+
'[testing-env] environment started',
|
|
725
|
+
'[testing-env/test_image:0@<idle>] shell: "feature1" setup',
|
|
726
|
+
'[testing-env/test_image:0/feature1] feature setup',
|
|
727
|
+
'[testing-env/test_image:0@<idle>] shell: "feature2" setup',
|
|
728
|
+
'[testing-env/test_image:0/feature2] feature setup',
|
|
729
|
+
'[testing-env/test_image:0] created -> ready',
|
|
730
|
+
'[testing-env/test_image:0] sandbox started',
|
|
731
|
+
'[testing-env/test_image:0] ready -> acquired',
|
|
732
|
+
'[testing-env/test_image:0] acquired -> setting_up',
|
|
733
|
+
'[testing-env/test_image:0@session1] shell: "feature1" setup session',
|
|
734
|
+
'[testing-env/test_image:0/feature1@session1] feature setup session',
|
|
735
|
+
'[testing-env/test_image:0@session1] shell: "feature2" setup session',
|
|
736
|
+
'[testing-env/test_image:0/feature2@session1] feature setup session',
|
|
737
|
+
'[testing-env/test_image:0] setting_up -> in_session',
|
|
738
|
+
"[testing-env/test_image:0] session 'session1' started",
|
|
739
|
+
'[testing-env/test_image:0@session1] shell: echo "hello"',
|
|
740
|
+
'[testing-env/test_image:0] in_session -> exiting_session',
|
|
741
|
+
'[testing-env/test_image:0@session1] shell: "feature1" teardown session',
|
|
742
|
+
'[testing-env/test_image:0/feature1@session1] feature teardown session',
|
|
743
|
+
'[testing-env/test_image:0@session1] shell: "feature2" teardown session',
|
|
744
|
+
'[testing-env/test_image:0/feature2@session1] feature teardown session',
|
|
745
|
+
"[testing-env/test_image:0] session 'session1' ended",
|
|
746
|
+
'[testing-env/test_image:0] exiting_session -> acquired',
|
|
747
|
+
'[testing-env/test_image:0] acquired -> shutting_down',
|
|
748
|
+
'[testing-env/test_image:0@<idle>] shell: "feature1" teardown',
|
|
749
|
+
'[testing-env/test_image:0/feature1] feature teardown',
|
|
750
|
+
'[testing-env/test_image:0@<idle>] shell: "feature2" teardown',
|
|
751
|
+
'[testing-env/test_image:0/feature2] feature teardown',
|
|
752
|
+
'[testing-env/test_image:0] shutting_down -> offline',
|
|
753
|
+
'[testing-env/test_image:0] sandbox shutdown'
|
|
754
|
+
# pylint: enable=line-too-long
|
|
755
|
+
]
|
|
756
|
+
)
|
|
757
|
+
|
|
758
|
+
def test_session_activity_non_state_error(self):
|
|
759
|
+
env = self._create_env(
|
|
760
|
+
pool_size=1,
|
|
761
|
+
features={
|
|
762
|
+
'feature1': TestingFeature(),
|
|
763
|
+
},
|
|
764
|
+
)
|
|
765
|
+
with env:
|
|
766
|
+
with env.sandbox('session1') as sb:
|
|
767
|
+
with self.assertRaises(ValueError):
|
|
768
|
+
sb.shell('echo foo', raise_error=ValueError)
|
|
769
|
+
self.assertEqual(len(sb.state_errors), 0)
|
|
770
|
+
sb.shell('echo bar')
|
|
771
|
+
self.assertEqual(sb.status, interface.Sandbox.Status.IN_SESSION)
|
|
772
|
+
sb.wait_until_not(interface.Sandbox.Status.SETTING_UP)
|
|
773
|
+
self.assertEqual(sb.status, interface.Sandbox.Status.READY)
|
|
774
|
+
self.assertEqual(
|
|
775
|
+
self.event_handler.logs,
|
|
776
|
+
[
|
|
777
|
+
# pylint: disable=line-too-long
|
|
778
|
+
'[testing-env/test_image:0:0@<idle>] shell: "feature1" setup',
|
|
779
|
+
'[testing-env/test_image:0:0/feature1] feature setup',
|
|
780
|
+
'[testing-env/test_image:0:0@<idle>] shell: "feature1" setup session',
|
|
781
|
+
'[testing-env/test_image:0:0/feature1@<idle>] feature setup session',
|
|
782
|
+
'[testing-env/test_image:0:0] created -> ready',
|
|
783
|
+
'[testing-env/test_image:0:0] sandbox started',
|
|
784
|
+
'[testing-env] environment started',
|
|
785
|
+
'[testing-env/test_image:0:0] ready -> acquired',
|
|
786
|
+
'[testing-env/test_image:0:0] acquired -> setting_up',
|
|
787
|
+
'[testing-env/test_image:0:0] setting_up -> in_session',
|
|
788
|
+
"[testing-env/test_image:0:0] session 'session1' started",
|
|
789
|
+
'[testing-env/test_image:0:0@session1] shell: echo foo with ValueError',
|
|
790
|
+
'[testing-env/test_image:0:0@session1] shell: echo bar',
|
|
791
|
+
'[testing-env/test_image:0:0] in_session -> exiting_session',
|
|
792
|
+
'[testing-env/test_image:0:0@session1] shell: "feature1" teardown session',
|
|
793
|
+
'[testing-env/test_image:0:0/feature1@session1] feature teardown session',
|
|
794
|
+
"[testing-env/test_image:0:0] session 'session1' ended",
|
|
795
|
+
'[testing-env/test_image:0:0] exiting_session -> setting_up',
|
|
796
|
+
'[testing-env/test_image:0:0@<idle>] shell: "feature1" setup session',
|
|
797
|
+
'[testing-env/test_image:0:0/feature1@<idle>] feature setup session',
|
|
798
|
+
'[testing-env/test_image:0:0] setting_up -> ready',
|
|
799
|
+
# pylint: enable=line-too-long
|
|
800
|
+
]
|
|
801
|
+
)
|
|
802
|
+
|
|
803
|
+
def test_session_activity_state_error(self):
|
|
804
|
+
env = self._create_env(
|
|
805
|
+
pool_size=1,
|
|
806
|
+
features={
|
|
807
|
+
'feature1': TestingFeature(),
|
|
808
|
+
},
|
|
809
|
+
)
|
|
810
|
+
with env:
|
|
811
|
+
with self.assertRaises(interface.SandboxStateError):
|
|
812
|
+
with env.sandbox('session1') as sb:
|
|
813
|
+
sb.shell('echo foo', raise_error=RuntimeError)
|
|
814
|
+
self.assertEqual(len(sb.state_errors), 1)
|
|
815
|
+
self.assertEqual(sb.status, interface.Sandbox.Status.OFFLINE)
|
|
816
|
+
self.assertEqual(
|
|
817
|
+
self.event_handler.logs,
|
|
818
|
+
[
|
|
819
|
+
# pylint: disable=line-too-long
|
|
820
|
+
'[testing-env/test_image:0:0@<idle>] shell: "feature1" setup',
|
|
821
|
+
'[testing-env/test_image:0:0/feature1] feature setup',
|
|
822
|
+
'[testing-env/test_image:0:0@<idle>] shell: "feature1" setup session',
|
|
823
|
+
'[testing-env/test_image:0:0/feature1@<idle>] feature setup session',
|
|
824
|
+
'[testing-env/test_image:0:0] created -> ready',
|
|
825
|
+
'[testing-env/test_image:0:0] sandbox started',
|
|
826
|
+
'[testing-env] environment started',
|
|
827
|
+
'[testing-env/test_image:0:0] ready -> acquired',
|
|
828
|
+
'[testing-env/test_image:0:0] acquired -> setting_up',
|
|
829
|
+
'[testing-env/test_image:0:0] setting_up -> in_session',
|
|
830
|
+
"[testing-env/test_image:0:0] session 'session1' started",
|
|
831
|
+
'[testing-env/test_image:0:0@session1] shell: echo foo with RuntimeError',
|
|
832
|
+
'[testing-env/test_image:0:0] in_session -> exiting_session',
|
|
833
|
+
'[testing-env/test_image:0:0@session1] shell: "feature1" teardown session',
|
|
834
|
+
'[testing-env/test_image:0:0/feature1@session1] feature teardown session',
|
|
835
|
+
"[testing-env/test_image:0:0] session 'session1' ended with SandboxStateError",
|
|
836
|
+
'[testing-env/test_image:0:0] exiting_session -> acquired',
|
|
837
|
+
'[testing-env/test_image:0:0] acquired -> shutting_down',
|
|
838
|
+
'[testing-env/test_image:0:0@<idle>] shell: "feature1" teardown',
|
|
839
|
+
'[testing-env/test_image:0:0/feature1] feature teardown',
|
|
840
|
+
'[testing-env/test_image:0:0] shutting_down -> offline',
|
|
841
|
+
'[testing-env/test_image:0:0] sandbox shutdown',
|
|
842
|
+
# pylint: enable=line-too-long
|
|
843
|
+
]
|
|
844
|
+
)
|
|
845
|
+
|
|
846
|
+
|
|
847
|
+
class SandboxActivityTests(unittest.TestCase):
|
|
848
|
+
|
|
849
|
+
def test_session_id(self):
|
|
850
|
+
env = TestingEnvironment(
|
|
851
|
+
features={'test_feature': TestingFeature()},
|
|
852
|
+
pool_size=0
|
|
853
|
+
)
|
|
854
|
+
with env:
|
|
855
|
+
with env.sandbox() as sb:
|
|
856
|
+
self.assertRegex(sb.session_id, r'session-[0-9a-f]{7}')
|
|
857
|
+
|
|
858
|
+
with env.test_feature() as test_feature:
|
|
859
|
+
self.assertIsInstance(test_feature, TestingFeature)
|
|
860
|
+
self.assertRegex(
|
|
861
|
+
test_feature.session_id,
|
|
862
|
+
r'test_feature-session-[0-9a-f]{7}'
|
|
863
|
+
)
|
|
864
|
+
|
|
865
|
+
def test_ping_error(self):
|
|
866
|
+
env = TestingEnvironment(
|
|
867
|
+
features={'test_feature': TestingFeature(housekeep_interval=0)},
|
|
868
|
+
pool_size=1,
|
|
869
|
+
sandbox_keepalive_interval=0,
|
|
870
|
+
)
|
|
871
|
+
with env:
|
|
872
|
+
with env.sandbox('session1') as sb:
|
|
873
|
+
sb.rebind(
|
|
874
|
+
simulate_ping_error=interface.SandboxStateError,
|
|
875
|
+
skip_notification=True
|
|
876
|
+
)
|
|
877
|
+
sb.wait_until_next_housekeep()
|
|
878
|
+
self.assertIn(sb.status, (sb.Status.SHUTTING_DOWN, sb.Status.OFFLINE))
|
|
879
|
+
|
|
880
|
+
def test_housekeep_error(self):
|
|
881
|
+
event_handler = TestingEventHandler(log_housekeep=False)
|
|
882
|
+
env = TestingEnvironment(
|
|
883
|
+
features={'test_feature': TestingFeature(housekeep_interval=0)},
|
|
884
|
+
pool_size=1,
|
|
885
|
+
housekeep_interval=1.0,
|
|
886
|
+
outage_grace_period=0,
|
|
887
|
+
outage_retry_interval=0.1,
|
|
888
|
+
sandbox_keepalive_interval=0,
|
|
889
|
+
event_handler=event_handler,
|
|
890
|
+
)
|
|
891
|
+
with env:
|
|
892
|
+
with env.sandbox('session1') as sb:
|
|
893
|
+
self.assertEqual(len(env.sandbox_pool), 1)
|
|
894
|
+
self.assertEqual(sb.status, interface.Sandbox.Status.IN_SESSION)
|
|
895
|
+
self.assertEqual(sb.session_id, 'session1')
|
|
896
|
+
housekeep_count = sb.housekeep_counter
|
|
897
|
+
sb.test_feature.rebind(
|
|
898
|
+
simulate_housekeep_error=interface.SandboxStateError,
|
|
899
|
+
skip_notification=True
|
|
900
|
+
)
|
|
901
|
+
while sb.housekeep_counter == housekeep_count or (
|
|
902
|
+
sb.status == interface.Sandbox.Status.IN_SESSION
|
|
903
|
+
):
|
|
904
|
+
time.sleep(0.01)
|
|
905
|
+
time.sleep(1.0)
|
|
906
|
+
self.assertEqual(sb.status, interface.Sandbox.Status.OFFLINE)
|
|
907
|
+
env.wait_for_housekeeping()
|
|
908
|
+
self.assertEqual(
|
|
909
|
+
event_handler.logs,
|
|
910
|
+
[
|
|
911
|
+
# pylint: disable=line-too-long
|
|
912
|
+
'[testing-env/test_image:0:0@<idle>] shell: "test_feature" setup',
|
|
913
|
+
'[testing-env/test_image:0:0/test_feature] feature setup',
|
|
914
|
+
'[testing-env/test_image:0:0@<idle>] shell: "test_feature" setup session',
|
|
915
|
+
'[testing-env/test_image:0:0] sandbox started',
|
|
916
|
+
'[testing-env] environment started',
|
|
917
|
+
"[testing-env/test_image:0:0] session 'session1' started",
|
|
918
|
+
'[testing-env/test_image:0:0@session1] shell: "test_feature" teardown session',
|
|
919
|
+
"[testing-env/test_image:0:0] session 'session1' ended with SandboxStateError",
|
|
920
|
+
'[testing-env/test_image:0:0@<idle>] shell: "test_feature" teardown',
|
|
921
|
+
'[testing-env/test_image:0:0/test_feature] feature teardown',
|
|
922
|
+
'[testing-env/test_image:0:0] sandbox shutdown',
|
|
923
|
+
'[testing-env/test_image:0:1@<idle>] shell: "test_feature" setup',
|
|
924
|
+
'[testing-env/test_image:0:1/test_feature] feature setup',
|
|
925
|
+
'[testing-env/test_image:0:1@<idle>] shell: "test_feature" setup session',
|
|
926
|
+
'[testing-env/test_image:0:1] sandbox started',
|
|
927
|
+
'[testing-env/test_image:0:1@<idle>] shell: "test_feature" teardown',
|
|
928
|
+
'[testing-env/test_image:0:1/test_feature] feature teardown',
|
|
929
|
+
'[testing-env/test_image:0:1] sandbox shutdown',
|
|
930
|
+
'[testing-env] environment shutdown'
|
|
931
|
+
# pylint: enable=line-too-long
|
|
932
|
+
]
|
|
933
|
+
)
|
|
934
|
+
|
|
935
|
+
|
|
936
|
+
class SandboxServiceTests(unittest.TestCase):
|
|
937
|
+
|
|
938
|
+
def setUp(self):
|
|
939
|
+
super().setUp()
|
|
940
|
+
self.maxDiff = None
|
|
941
|
+
self.event_handler = TestingEventHandler()
|
|
942
|
+
self.env = TestingEnvironment(
|
|
943
|
+
features={'test_feature': TestingFeature()},
|
|
944
|
+
pool_size=0,
|
|
945
|
+
outage_grace_period=0,
|
|
946
|
+
outage_retry_interval=0,
|
|
947
|
+
sandbox_keepalive_interval=0,
|
|
948
|
+
event_handler=self.event_handler,
|
|
949
|
+
random_seed=1,
|
|
950
|
+
)
|
|
951
|
+
|
|
952
|
+
def test_service_call_activity_log(self):
|
|
953
|
+
|
|
954
|
+
class CustomEventHandler(interface.EventHandler):
|
|
955
|
+
|
|
956
|
+
def __init__(self):
|
|
957
|
+
self.calls = []
|
|
958
|
+
|
|
959
|
+
def on_sandbox_activity(
|
|
960
|
+
self,
|
|
961
|
+
name: str,
|
|
962
|
+
sandbox: interface.Sandbox,
|
|
963
|
+
session_id: str | None,
|
|
964
|
+
duration: float,
|
|
965
|
+
error: BaseException | None,
|
|
966
|
+
**kwargs: Any):
|
|
967
|
+
self.calls.append((session_id, name, kwargs))
|
|
968
|
+
|
|
969
|
+
def on_feature_activity(
|
|
970
|
+
self,
|
|
971
|
+
name: str,
|
|
972
|
+
feature: interface.Feature,
|
|
973
|
+
session_id: str | None,
|
|
974
|
+
duration: float,
|
|
975
|
+
error: BaseException | None,
|
|
976
|
+
**kwargs: Any):
|
|
977
|
+
self.calls.append((session_id, name, kwargs))
|
|
978
|
+
|
|
979
|
+
event_handler = CustomEventHandler()
|
|
980
|
+
env = TestingEnvironment(
|
|
981
|
+
features={'test_feature': TestingFeature()},
|
|
982
|
+
pool_size=0,
|
|
983
|
+
event_handler=event_handler,
|
|
984
|
+
)
|
|
985
|
+
with env:
|
|
986
|
+
with env.test_feature(session_id='session1') as test_feature:
|
|
987
|
+
test_feature.call_with_varargs('sum', 1, 2, debug=True)
|
|
988
|
+
self.assertEqual(
|
|
989
|
+
event_handler.calls,
|
|
990
|
+
[
|
|
991
|
+
(None, 'shell', {'code': '"test_feature" setup'}),
|
|
992
|
+
('session1', 'shell', {'code': '"test_feature" setup session'}),
|
|
993
|
+
('session1', 'test_feature.call_with_varargs', {'args': (1, 2), 'code': 'sum', 'debug': True}), # pylint: disable=line-too-long
|
|
994
|
+
('session1', 'shell', {'code': '"test_feature" teardown session'}),
|
|
995
|
+
(None, 'shell', {'code': '"test_feature" teardown'}),
|
|
996
|
+
]
|
|
997
|
+
)
|
|
998
|
+
|
|
999
|
+
def test_service_call_from_feature(self):
|
|
1000
|
+
with self.env:
|
|
1001
|
+
with self.env.sandbox('session1') as sb:
|
|
1002
|
+
self.assertEqual(sb.test_feature.num_shell_calls(), 2)
|
|
1003
|
+
self.assertEqual(sb.test_feature.num_shell_calls(), 2)
|
|
1004
|
+
self.assertEqual(
|
|
1005
|
+
self.event_handler.logs,
|
|
1006
|
+
[
|
|
1007
|
+
# pylint: disable=line-too-long
|
|
1008
|
+
'[testing-env] environment started',
|
|
1009
|
+
'[testing-env/test_image:0@<idle>] shell: "test_feature" setup',
|
|
1010
|
+
'[testing-env/test_image:0/test_feature] feature setup',
|
|
1011
|
+
'[testing-env/test_image:0] sandbox started',
|
|
1012
|
+
'[testing-env/test_image:0@session1] shell: "test_feature" setup session',
|
|
1013
|
+
"[testing-env/test_image:0] session 'session1' started",
|
|
1014
|
+
'[testing-env/test_image:0/test_feature@session1] test_feature.num_shell_calls: None',
|
|
1015
|
+
'[testing-env/test_image:0/test_feature@session1] test_feature.num_shell_calls: None',
|
|
1016
|
+
'[testing-env/test_image:0@session1] shell: "test_feature" teardown session',
|
|
1017
|
+
"[testing-env/test_image:0] session 'session1' ended",
|
|
1018
|
+
'[testing-env/test_image:0@<idle>] shell: "test_feature" teardown',
|
|
1019
|
+
'[testing-env/test_image:0/test_feature] feature teardown',
|
|
1020
|
+
'[testing-env/test_image:0] sandbox shutdown',
|
|
1021
|
+
'[testing-env] environment shutdown',
|
|
1022
|
+
# pylint: enable=line-too-long
|
|
1023
|
+
]
|
|
1024
|
+
)
|
|
1025
|
+
|
|
1026
|
+
def test_service_call_from_feature_with_error(self):
|
|
1027
|
+
with self.env:
|
|
1028
|
+
with self.assertRaises(interface.SandboxStateError):
|
|
1029
|
+
with self.env.sandbox('session1') as sb:
|
|
1030
|
+
sb.test_feature.bad_shell_call()
|
|
1031
|
+
self.assertEqual(sb.status, interface.Sandbox.Status.OFFLINE)
|
|
1032
|
+
self.assertEqual(len(sb.state_errors), 1)
|
|
1033
|
+
self.assertEqual(
|
|
1034
|
+
self.event_handler.logs,
|
|
1035
|
+
[
|
|
1036
|
+
# pylint: disable=line-too-long
|
|
1037
|
+
'[testing-env] environment started',
|
|
1038
|
+
'[testing-env/test_image:0@<idle>] shell: "test_feature" setup',
|
|
1039
|
+
'[testing-env/test_image:0/test_feature] feature setup',
|
|
1040
|
+
'[testing-env/test_image:0] sandbox started',
|
|
1041
|
+
'[testing-env/test_image:0@session1] shell: "test_feature" setup session',
|
|
1042
|
+
"[testing-env/test_image:0] session 'session1' started",
|
|
1043
|
+
'[testing-env/test_image:0@session1] shell: bad command with RuntimeError',
|
|
1044
|
+
'[testing-env/test_image:0/test_feature@session1] test_feature.bad_shell_call: None with SandboxStateError',
|
|
1045
|
+
'[testing-env/test_image:0@session1] shell: "test_feature" teardown session',
|
|
1046
|
+
"[testing-env/test_image:0] session 'session1' ended with SandboxStateError",
|
|
1047
|
+
'[testing-env/test_image:0@<idle>] shell: "test_feature" teardown',
|
|
1048
|
+
'[testing-env/test_image:0/test_feature] feature teardown',
|
|
1049
|
+
'[testing-env/test_image:0] sandbox shutdown',
|
|
1050
|
+
'[testing-env] environment shutdown'
|
|
1051
|
+
# pylint: enable=line-too-long
|
|
1052
|
+
]
|
|
1053
|
+
)
|
|
1054
|
+
|
|
1055
|
+
def test_service_call_from_environment(self):
|
|
1056
|
+
with self.env:
|
|
1057
|
+
with self.env.test_feature() as test_feature:
|
|
1058
|
+
self.assertEqual(test_feature.num_shell_calls(), 2)
|
|
1059
|
+
self.assertEqual(
|
|
1060
|
+
self.event_handler.logs,
|
|
1061
|
+
[
|
|
1062
|
+
# pylint: disable=line-too-long
|
|
1063
|
+
'[testing-env] environment started',
|
|
1064
|
+
'[testing-env/test_image:0@<idle>] shell: "test_feature" setup',
|
|
1065
|
+
'[testing-env/test_image:0/test_feature] feature setup',
|
|
1066
|
+
'[testing-env/test_image:0] sandbox started',
|
|
1067
|
+
'[testing-env/test_image:0@test_feature-session-2291d8c] shell: "test_feature" setup session',
|
|
1068
|
+
"[testing-env/test_image:0] session 'test_feature-session-2291d8c' started",
|
|
1069
|
+
'[testing-env/test_image:0/test_feature@test_feature-session-2291d8c] test_feature.num_shell_calls: None',
|
|
1070
|
+
'[testing-env/test_image:0@test_feature-session-2291d8c] shell: "test_feature" teardown session',
|
|
1071
|
+
"[testing-env/test_image:0] session 'test_feature-session-2291d8c' ended",
|
|
1072
|
+
'[testing-env/test_image:0@<idle>] shell: "test_feature" teardown',
|
|
1073
|
+
'[testing-env/test_image:0/test_feature] feature teardown',
|
|
1074
|
+
'[testing-env/test_image:0] sandbox shutdown',
|
|
1075
|
+
'[testing-env] environment shutdown'
|
|
1076
|
+
# pylint: enable=line-too-long
|
|
1077
|
+
]
|
|
1078
|
+
)
|
|
1079
|
+
|
|
1080
|
+
def test_service_call_from_environment_with_error(self):
|
|
1081
|
+
with self.env:
|
|
1082
|
+
with self.assertRaises(interface.SandboxStateError):
|
|
1083
|
+
with self.env.test_feature(session_id='session1') as test_feature:
|
|
1084
|
+
test_feature.bad_shell_call()
|
|
1085
|
+
self.assertEqual(
|
|
1086
|
+
self.event_handler.logs,
|
|
1087
|
+
[
|
|
1088
|
+
# pylint: disable=line-too-long
|
|
1089
|
+
'[testing-env] environment started',
|
|
1090
|
+
'[testing-env/test_image:0@<idle>] shell: "test_feature" setup',
|
|
1091
|
+
'[testing-env/test_image:0/test_feature] feature setup',
|
|
1092
|
+
'[testing-env/test_image:0] sandbox started',
|
|
1093
|
+
'[testing-env/test_image:0@session1] shell: "test_feature" setup session',
|
|
1094
|
+
"[testing-env/test_image:0] session 'session1' started",
|
|
1095
|
+
'[testing-env/test_image:0@session1] shell: bad command with RuntimeError',
|
|
1096
|
+
'[testing-env/test_image:0/test_feature@session1] test_feature.bad_shell_call: None with SandboxStateError',
|
|
1097
|
+
'[testing-env/test_image:0@session1] shell: "test_feature" teardown session',
|
|
1098
|
+
"[testing-env/test_image:0] session 'session1' ended with SandboxStateError",
|
|
1099
|
+
'[testing-env/test_image:0@<idle>] shell: "test_feature" teardown',
|
|
1100
|
+
'[testing-env/test_image:0/test_feature] feature teardown',
|
|
1101
|
+
'[testing-env/test_image:0] sandbox shutdown',
|
|
1102
|
+
'[testing-env] environment shutdown',
|
|
1103
|
+
# pylint: enable=line-too-long
|
|
1104
|
+
]
|
|
1105
|
+
)
|
|
1106
|
+
|
|
1107
|
+
def test_service_context_manager_from_feature(self):
|
|
1108
|
+
with self.env:
|
|
1109
|
+
with self.env.sandbox('session1') as sb:
|
|
1110
|
+
with sb.test_feature.my_service() as service:
|
|
1111
|
+
service.do('hello')
|
|
1112
|
+
sb.shell('foo')
|
|
1113
|
+
self.assertEqual(sb.status, interface.Sandbox.Status.IN_SESSION)
|
|
1114
|
+
self.assertEqual(
|
|
1115
|
+
self.event_handler.logs,
|
|
1116
|
+
[
|
|
1117
|
+
# pylint: disable=line-too-long
|
|
1118
|
+
'[testing-env] environment started',
|
|
1119
|
+
'[testing-env/test_image:0@<idle>] shell: "test_feature" setup',
|
|
1120
|
+
'[testing-env/test_image:0/test_feature] feature setup',
|
|
1121
|
+
'[testing-env/test_image:0] sandbox started',
|
|
1122
|
+
'[testing-env/test_image:0@session1] shell: "test_feature" setup session',
|
|
1123
|
+
"[testing-env/test_image:0] session 'session1' started",
|
|
1124
|
+
'[testing-env/test_image:0@session1] shell: hello',
|
|
1125
|
+
'[testing-env/test_image:0@session1] shell: foo',
|
|
1126
|
+
'[testing-env/test_image:0@session1] shell: "test_feature" teardown session',
|
|
1127
|
+
"[testing-env/test_image:0] session 'session1' ended",
|
|
1128
|
+
'[testing-env/test_image:0@<idle>] shell: "test_feature" teardown',
|
|
1129
|
+
'[testing-env/test_image:0/test_feature] feature teardown',
|
|
1130
|
+
'[testing-env/test_image:0] sandbox shutdown',
|
|
1131
|
+
'[testing-env] environment shutdown',
|
|
1132
|
+
# pylint: enable=line-too-long
|
|
1133
|
+
]
|
|
1134
|
+
)
|
|
1135
|
+
|
|
1136
|
+
def test_service_context_manager_from_feature_with_error(self):
|
|
1137
|
+
with self.env:
|
|
1138
|
+
with self.assertRaises(interface.SandboxStateError):
|
|
1139
|
+
with self.env.sandbox('session1') as sb:
|
|
1140
|
+
with sb.test_feature.my_service() as service:
|
|
1141
|
+
service.do('hello', raise_error=interface.SandboxStateError)
|
|
1142
|
+
self.assertEqual(sb.status, interface.Sandbox.Status.OFFLINE)
|
|
1143
|
+
self.assertEqual(len(sb.state_errors), 1)
|
|
1144
|
+
self.assertEqual(
|
|
1145
|
+
self.event_handler.logs,
|
|
1146
|
+
[
|
|
1147
|
+
# pylint: disable=line-too-long
|
|
1148
|
+
'[testing-env] environment started',
|
|
1149
|
+
'[testing-env/test_image:0@<idle>] shell: "test_feature" setup',
|
|
1150
|
+
'[testing-env/test_image:0/test_feature] feature setup',
|
|
1151
|
+
'[testing-env/test_image:0] sandbox started',
|
|
1152
|
+
'[testing-env/test_image:0@session1] shell: "test_feature" setup session',
|
|
1153
|
+
"[testing-env/test_image:0] session 'session1' started",
|
|
1154
|
+
'[testing-env/test_image:0@session1] shell: hello with SandboxStateError',
|
|
1155
|
+
'[testing-env/test_image:0@session1] shell: "test_feature" teardown session',
|
|
1156
|
+
"[testing-env/test_image:0] session 'session1' ended with SandboxStateError",
|
|
1157
|
+
'[testing-env/test_image:0@<idle>] shell: "test_feature" teardown',
|
|
1158
|
+
'[testing-env/test_image:0/test_feature] feature teardown',
|
|
1159
|
+
'[testing-env/test_image:0] sandbox shutdown',
|
|
1160
|
+
'[testing-env] environment shutdown',
|
|
1161
|
+
# pylint: enable=line-too-long
|
|
1162
|
+
]
|
|
1163
|
+
)
|
|
1164
|
+
|
|
1165
|
+
def test_service_context_manager_from_environment(self):
|
|
1166
|
+
with self.env:
|
|
1167
|
+
with self.env.test_feature(session_id='session1') as test_feature:
|
|
1168
|
+
with test_feature.my_service() as service:
|
|
1169
|
+
service.do('foo')
|
|
1170
|
+
|
|
1171
|
+
with self.env.test_feature() as test_feature:
|
|
1172
|
+
with test_feature.my_service() as service:
|
|
1173
|
+
service.do('bar')
|
|
1174
|
+
self.assertEqual(
|
|
1175
|
+
self.event_handler.logs,
|
|
1176
|
+
[
|
|
1177
|
+
# pylint: disable=line-too-long
|
|
1178
|
+
'[testing-env] environment started',
|
|
1179
|
+
'[testing-env/test_image:0@<idle>] shell: "test_feature" setup',
|
|
1180
|
+
'[testing-env/test_image:0/test_feature] feature setup',
|
|
1181
|
+
'[testing-env/test_image:0] sandbox started',
|
|
1182
|
+
'[testing-env/test_image:0@session1] shell: "test_feature" setup session',
|
|
1183
|
+
"[testing-env/test_image:0] session 'session1' started",
|
|
1184
|
+
'[testing-env/test_image:0@session1] shell: foo',
|
|
1185
|
+
'[testing-env/test_image:0@session1] shell: "test_feature" teardown session',
|
|
1186
|
+
"[testing-env/test_image:0] session 'session1' ended",
|
|
1187
|
+
'[testing-env/test_image:0@<idle>] shell: "test_feature" teardown',
|
|
1188
|
+
'[testing-env/test_image:0/test_feature] feature teardown',
|
|
1189
|
+
'[testing-env/test_image:0] sandbox shutdown',
|
|
1190
|
+
'[testing-env/test_image:1@<idle>] shell: "test_feature" setup',
|
|
1191
|
+
'[testing-env/test_image:1/test_feature] feature setup',
|
|
1192
|
+
'[testing-env/test_image:1] sandbox started',
|
|
1193
|
+
'[testing-env/test_image:1@test_feature-session-2291d8c] shell: "test_feature" setup session',
|
|
1194
|
+
"[testing-env/test_image:1] session 'test_feature-session-2291d8c' started",
|
|
1195
|
+
'[testing-env/test_image:1@test_feature-session-2291d8c] shell: bar',
|
|
1196
|
+
'[testing-env/test_image:1@test_feature-session-2291d8c] shell: "test_feature" teardown session',
|
|
1197
|
+
"[testing-env/test_image:1] session 'test_feature-session-2291d8c' ended",
|
|
1198
|
+
'[testing-env/test_image:1@<idle>] shell: "test_feature" teardown',
|
|
1199
|
+
'[testing-env/test_image:1/test_feature] feature teardown',
|
|
1200
|
+
'[testing-env/test_image:1] sandbox shutdown',
|
|
1201
|
+
'[testing-env] environment shutdown',
|
|
1202
|
+
# pylint: enable=line-too-long
|
|
1203
|
+
]
|
|
1204
|
+
)
|
|
1205
|
+
|
|
1206
|
+
def test_service_context_manager_from_environment_with_error(self):
|
|
1207
|
+
with self.env:
|
|
1208
|
+
with self.assertRaises(interface.SandboxStateError):
|
|
1209
|
+
with self.env.test_feature() as test_feature:
|
|
1210
|
+
with test_feature.my_service() as service:
|
|
1211
|
+
service.do('hello', raise_error=interface.SandboxStateError)
|
|
1212
|
+
self.assertEqual(
|
|
1213
|
+
self.event_handler.logs,
|
|
1214
|
+
[
|
|
1215
|
+
# pylint: disable=line-too-long
|
|
1216
|
+
'[testing-env] environment started',
|
|
1217
|
+
'[testing-env/test_image:0@<idle>] shell: "test_feature" setup',
|
|
1218
|
+
'[testing-env/test_image:0/test_feature] feature setup',
|
|
1219
|
+
'[testing-env/test_image:0] sandbox started',
|
|
1220
|
+
'[testing-env/test_image:0@test_feature-session-2291d8c] shell: "test_feature" setup session',
|
|
1221
|
+
"[testing-env/test_image:0] session 'test_feature-session-2291d8c' started",
|
|
1222
|
+
'[testing-env/test_image:0@test_feature-session-2291d8c] shell: hello with SandboxStateError',
|
|
1223
|
+
'[testing-env/test_image:0@test_feature-session-2291d8c] shell: "test_feature" teardown session',
|
|
1224
|
+
"[testing-env/test_image:0] session 'test_feature-session-2291d8c' ended with SandboxStateError",
|
|
1225
|
+
'[testing-env/test_image:0@<idle>] shell: "test_feature" teardown',
|
|
1226
|
+
'[testing-env/test_image:0/test_feature] feature teardown',
|
|
1227
|
+
'[testing-env/test_image:0] sandbox shutdown',
|
|
1228
|
+
'[testing-env] environment shutdown',
|
|
1229
|
+
# pylint: enable=line-too-long
|
|
1230
|
+
]
|
|
1231
|
+
)
|
|
1232
|
+
|
|
1233
|
+
|
|
1234
|
+
if __name__ == '__main__':
|
|
1235
|
+
unittest.main()
|