langfun 0.1.2.dev202510300805__py3-none-any.whl → 0.1.2.dev202511010804__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.
Potentially problematic release.
This version of langfun might be problematic. Click here for more details.
- langfun/env/__init__.py +4 -2
- langfun/env/base_environment.py +12 -19
- langfun/env/base_environment_test.py +473 -0
- langfun/env/base_feature.py +52 -8
- langfun/env/base_sandbox.py +43 -121
- langfun/env/{base_test.py → base_sandbox_test.py} +21 -484
- langfun/env/event_handlers/__init__.py +1 -1
- langfun/env/event_handlers/chain.py +255 -0
- langfun/env/event_handlers/chain_test.py +281 -0
- langfun/env/event_handlers/event_logger.py +39 -39
- langfun/env/event_handlers/event_logger_test.py +1 -1
- langfun/env/event_handlers/metric_writer.py +38 -38
- langfun/env/event_handlers/metric_writer_test.py +1 -1
- langfun/env/interface.py +344 -8
- langfun/env/test_utils.py +1 -4
- {langfun-0.1.2.dev202510300805.dist-info → langfun-0.1.2.dev202511010804.dist-info}/METADATA +1 -1
- {langfun-0.1.2.dev202510300805.dist-info → langfun-0.1.2.dev202511010804.dist-info}/RECORD +20 -18
- langfun/env/event_handlers/base.py +0 -350
- {langfun-0.1.2.dev202510300805.dist-info → langfun-0.1.2.dev202511010804.dist-info}/WHEEL +0 -0
- {langfun-0.1.2.dev202510300805.dist-info → langfun-0.1.2.dev202511010804.dist-info}/licenses/LICENSE +0 -0
- {langfun-0.1.2.dev202510300805.dist-info → langfun-0.1.2.dev202511010804.dist-info}/top_level.txt +0 -0
|
@@ -17,8 +17,6 @@ import unittest
|
|
|
17
17
|
|
|
18
18
|
from langfun.env import interface
|
|
19
19
|
from langfun.env import test_utils
|
|
20
|
-
from langfun.env.event_handlers import base as event_handler_base
|
|
21
|
-
|
|
22
20
|
|
|
23
21
|
TestingEnvironment = test_utils.TestingEnvironment
|
|
24
22
|
TestingSandbox = test_utils.TestingSandbox
|
|
@@ -26,453 +24,7 @@ TestingFeature = test_utils.TestingFeature
|
|
|
26
24
|
TestingEventHandler = test_utils.TestingEventHandler
|
|
27
25
|
|
|
28
26
|
|
|
29
|
-
class
|
|
30
|
-
|
|
31
|
-
def test_basics(self):
|
|
32
|
-
env = TestingEnvironment(
|
|
33
|
-
image_ids=['test_image'],
|
|
34
|
-
root_dir='/tmp',
|
|
35
|
-
pool_size=0,
|
|
36
|
-
features={'test_feature': TestingFeature()},
|
|
37
|
-
outage_grace_period=1,
|
|
38
|
-
outage_retry_interval=0,
|
|
39
|
-
)
|
|
40
|
-
self.assertIsNone(interface.Environment.current())
|
|
41
|
-
self.assertEqual(env.image_ids, ['test_image'])
|
|
42
|
-
self.assertFalse(env.supports_dynamic_image_loading)
|
|
43
|
-
self.assertEqual(env.status, interface.Environment.Status.CREATED)
|
|
44
|
-
self.assertFalse(env.is_online)
|
|
45
|
-
self.assertEqual(env.min_pool_size('test_image'), 0)
|
|
46
|
-
self.assertEqual(env.max_pool_size('test_image'), 0)
|
|
47
|
-
self.assertEqual(env.sandbox_pool, {})
|
|
48
|
-
self.assertEqual(env.id, interface.Environment.Id('testing-env'))
|
|
49
|
-
self.assertEqual(env.outage_grace_period, 1)
|
|
50
|
-
self.assertEqual(env.features['test_feature'].name, 'test_feature')
|
|
51
|
-
|
|
52
|
-
self.assertIsNone(env.start_time)
|
|
53
|
-
|
|
54
|
-
with env:
|
|
55
|
-
self.assertEqual(env.status, interface.Environment.Status.ONLINE)
|
|
56
|
-
self.assertIs(interface.Environment.current(), env)
|
|
57
|
-
self.assertTrue(env.is_online)
|
|
58
|
-
self.assertIsNotNone(env.start_time)
|
|
59
|
-
self.assertEqual(env.offline_duration, 0.0)
|
|
60
|
-
self.assertEqual(env.sandbox_pool, {})
|
|
61
|
-
self.assertEqual(env.working_dir, '/tmp/testing-env')
|
|
62
|
-
|
|
63
|
-
with env.sandbox(session_id='session1') as sb:
|
|
64
|
-
self.assertEqual(
|
|
65
|
-
sb.id, interface.Sandbox.Id(
|
|
66
|
-
environment_id=env.id,
|
|
67
|
-
image_id=sb.image_id,
|
|
68
|
-
sandbox_id='0')
|
|
69
|
-
)
|
|
70
|
-
self.assertEqual(sb.session_id, 'session1')
|
|
71
|
-
self.assertEqual(sb.working_dir, '/tmp/testing-env/test_image/0')
|
|
72
|
-
self.assertTrue(sb.is_online)
|
|
73
|
-
self.assertIs(sb.test_feature, sb.features['test_feature'])
|
|
74
|
-
self.assertEqual(
|
|
75
|
-
sb.test_feature.working_dir,
|
|
76
|
-
'/tmp/testing-env/test_image/0/test_feature'
|
|
77
|
-
)
|
|
78
|
-
with self.assertRaises(AttributeError):
|
|
79
|
-
_ = sb.test_feature2
|
|
80
|
-
self.assertFalse(sb.is_online)
|
|
81
|
-
|
|
82
|
-
with self.assertRaisesRegex(
|
|
83
|
-
ValueError, 'Environment .* does not serve image ID .*'
|
|
84
|
-
):
|
|
85
|
-
env.sandbox('test_image2')
|
|
86
|
-
|
|
87
|
-
with env.test_feature() as feature:
|
|
88
|
-
self.assertIsInstance(feature, TestingFeature)
|
|
89
|
-
self.assertEqual(
|
|
90
|
-
feature.sandbox.status, interface.Sandbox.Status.IN_SESSION
|
|
91
|
-
)
|
|
92
|
-
self.assertTrue(
|
|
93
|
-
feature.sandbox.session_id.startswith('test_feature-session')
|
|
94
|
-
)
|
|
95
|
-
|
|
96
|
-
with self.assertRaises(AttributeError):
|
|
97
|
-
_ = env.test_feature2
|
|
98
|
-
|
|
99
|
-
def test_dynamic_image_loading(self):
|
|
100
|
-
env = TestingEnvironment(
|
|
101
|
-
image_ids=[],
|
|
102
|
-
supports_dynamic_image_loading=True,
|
|
103
|
-
pool_size=0,
|
|
104
|
-
features={'test_feature': TestingFeature()},
|
|
105
|
-
outage_grace_period=1,
|
|
106
|
-
outage_retry_interval=0,
|
|
107
|
-
)
|
|
108
|
-
with env:
|
|
109
|
-
with env.sandbox(image_id='test_image2') as sb:
|
|
110
|
-
self.assertEqual(sb.image_id, 'test_image2')
|
|
111
|
-
|
|
112
|
-
with self.assertRaisesRegex(
|
|
113
|
-
ValueError, 'Environment .* does not have a default image ID.'
|
|
114
|
-
):
|
|
115
|
-
env.sandbox()
|
|
116
|
-
|
|
117
|
-
def test_dynamic_image_loading_with_pooling(self):
|
|
118
|
-
env = TestingEnvironment(
|
|
119
|
-
image_ids=[],
|
|
120
|
-
supports_dynamic_image_loading=True,
|
|
121
|
-
pool_size=2,
|
|
122
|
-
features={'test_feature': TestingFeature()},
|
|
123
|
-
outage_grace_period=1,
|
|
124
|
-
outage_retry_interval=0,
|
|
125
|
-
)
|
|
126
|
-
with env:
|
|
127
|
-
with env.sandbox(image_id='test_image'):
|
|
128
|
-
self.assertEqual(len(env.sandbox_pool['test_image']), 1)
|
|
129
|
-
|
|
130
|
-
with env.sandbox(image_id='test_image'):
|
|
131
|
-
self.assertEqual(len(env.sandbox_pool['test_image']), 2)
|
|
132
|
-
|
|
133
|
-
with self.assertRaises(interface.EnvironmentOverloadError):
|
|
134
|
-
with env.sandbox(image_id='test_image'):
|
|
135
|
-
pass
|
|
136
|
-
self.assertEqual(len(env.sandbox_pool['test_image']), 2)
|
|
137
|
-
|
|
138
|
-
with env.sandbox(image_id='test_image'):
|
|
139
|
-
self.assertEqual(len(env.sandbox_pool['test_image']), 2)
|
|
140
|
-
|
|
141
|
-
def test_image_feature_mappings(self):
|
|
142
|
-
env = TestingEnvironment(
|
|
143
|
-
image_ids=[
|
|
144
|
-
'test_image1',
|
|
145
|
-
'test_image2',
|
|
146
|
-
],
|
|
147
|
-
features={
|
|
148
|
-
'test_feature': TestingFeature(
|
|
149
|
-
applicable_images=['test_image1.*']
|
|
150
|
-
),
|
|
151
|
-
'test_feature2': TestingFeature(
|
|
152
|
-
applicable_images=['test_image2.*']
|
|
153
|
-
),
|
|
154
|
-
'test_feature3': TestingFeature(
|
|
155
|
-
applicable_images=['test_image.*']
|
|
156
|
-
),
|
|
157
|
-
},
|
|
158
|
-
pool_size=0,
|
|
159
|
-
outage_grace_period=1,
|
|
160
|
-
outage_retry_interval=0,
|
|
161
|
-
sandbox_keepalive_interval=0,
|
|
162
|
-
)
|
|
163
|
-
with env:
|
|
164
|
-
with env.sandbox(image_id='test_image1') as sb:
|
|
165
|
-
self.assertIn('test_feature', sb.features)
|
|
166
|
-
self.assertNotIn('test_feature2', sb.features)
|
|
167
|
-
self.assertIn('test_feature3', sb.features)
|
|
168
|
-
|
|
169
|
-
with env.sandbox(image_id='test_image2') as sb:
|
|
170
|
-
self.assertNotIn('test_feature', sb.features)
|
|
171
|
-
self.assertIn('test_feature2', sb.features)
|
|
172
|
-
self.assertIn('test_feature3', sb.features)
|
|
173
|
-
|
|
174
|
-
with env.test_feature() as feature:
|
|
175
|
-
self.assertEqual(feature.sandbox.image_id, 'test_image1')
|
|
176
|
-
|
|
177
|
-
with self.assertRaisesRegex(
|
|
178
|
-
ValueError, 'Feature .* is not applicable to .*'
|
|
179
|
-
):
|
|
180
|
-
with env.test_feature('test_image2'):
|
|
181
|
-
pass
|
|
182
|
-
|
|
183
|
-
with env.test_feature2() as feature:
|
|
184
|
-
self.assertEqual(feature.sandbox.image_id, 'test_image2')
|
|
185
|
-
|
|
186
|
-
with env.test_feature3() as feature:
|
|
187
|
-
self.assertEqual(feature.sandbox.image_id, 'test_image1')
|
|
188
|
-
|
|
189
|
-
with env.test_feature3('test_image2') as feature:
|
|
190
|
-
self.assertEqual(feature.sandbox.image_id, 'test_image2')
|
|
191
|
-
|
|
192
|
-
def test_feature_applicability_check(self):
|
|
193
|
-
with self.assertRaisesRegex(
|
|
194
|
-
ValueError, 'Feature .* is not applicable to .*'
|
|
195
|
-
):
|
|
196
|
-
TestingEnvironment(
|
|
197
|
-
image_ids=[
|
|
198
|
-
'test_image1',
|
|
199
|
-
],
|
|
200
|
-
features={
|
|
201
|
-
'test_feature2': TestingFeature(
|
|
202
|
-
applicable_images=['test_image2.*']
|
|
203
|
-
),
|
|
204
|
-
},
|
|
205
|
-
)
|
|
206
|
-
env = TestingEnvironment(
|
|
207
|
-
image_ids=[],
|
|
208
|
-
supports_dynamic_image_loading=True,
|
|
209
|
-
features={
|
|
210
|
-
'test_feature2': TestingFeature(
|
|
211
|
-
applicable_images=['test_image2.*']
|
|
212
|
-
),
|
|
213
|
-
},
|
|
214
|
-
pool_size=0
|
|
215
|
-
)
|
|
216
|
-
with env:
|
|
217
|
-
with self.assertRaisesRegex(
|
|
218
|
-
ValueError, 'No image ID found for feature .*'
|
|
219
|
-
):
|
|
220
|
-
with env.test_feature2():
|
|
221
|
-
pass
|
|
222
|
-
|
|
223
|
-
# Dynamically loaded IDs.
|
|
224
|
-
with env.test_feature2('test_image2') as feature:
|
|
225
|
-
self.assertEqual(feature.sandbox.image_id, 'test_image2')
|
|
226
|
-
|
|
227
|
-
def test_pool_size(self):
|
|
228
|
-
env = TestingEnvironment(
|
|
229
|
-
image_ids=['test_image'],
|
|
230
|
-
pool_size=1,
|
|
231
|
-
outage_grace_period=1,
|
|
232
|
-
outage_retry_interval=0,
|
|
233
|
-
)
|
|
234
|
-
self.assertEqual(env.min_pool_size('test_image'), 1)
|
|
235
|
-
self.assertEqual(env.max_pool_size('test_image'), 1)
|
|
236
|
-
|
|
237
|
-
env = TestingEnvironment(
|
|
238
|
-
image_ids=['test_image'],
|
|
239
|
-
pool_size=(0, 256),
|
|
240
|
-
outage_grace_period=1,
|
|
241
|
-
outage_retry_interval=0,
|
|
242
|
-
)
|
|
243
|
-
self.assertEqual(env.min_pool_size('test_image'), 0)
|
|
244
|
-
self.assertEqual(env.max_pool_size('test_image'), 256)
|
|
245
|
-
|
|
246
|
-
env = TestingEnvironment(
|
|
247
|
-
image_ids=['test_image'],
|
|
248
|
-
pool_size={
|
|
249
|
-
'test_.*': (0, 128),
|
|
250
|
-
'my.*': (5, 64),
|
|
251
|
-
'exact_image_name': 10,
|
|
252
|
-
},
|
|
253
|
-
outage_grace_period=1,
|
|
254
|
-
outage_retry_interval=0,
|
|
255
|
-
)
|
|
256
|
-
self.assertEqual(env.min_pool_size('test_image'), 0)
|
|
257
|
-
self.assertEqual(env.max_pool_size('test_image'), 128)
|
|
258
|
-
self.assertEqual(env.min_pool_size('my_image'), 5)
|
|
259
|
-
self.assertEqual(env.max_pool_size('my_image'), 64)
|
|
260
|
-
self.assertEqual(env.min_pool_size('exact_image_name'), 10)
|
|
261
|
-
self.assertEqual(env.max_pool_size('exact_image_name'), 10)
|
|
262
|
-
self.assertEqual(env.min_pool_size('some_image'), 0) # default
|
|
263
|
-
self.assertEqual(env.max_pool_size('some_image'), 256) # default
|
|
264
|
-
|
|
265
|
-
def test_del(self):
|
|
266
|
-
env = TestingEnvironment(
|
|
267
|
-
features={'test_feature': TestingFeature()},
|
|
268
|
-
pool_size=0,
|
|
269
|
-
outage_grace_period=1,
|
|
270
|
-
outage_retry_interval=0,
|
|
271
|
-
sandbox_keepalive_interval=0,
|
|
272
|
-
)
|
|
273
|
-
env.start()
|
|
274
|
-
sb = env.acquire()
|
|
275
|
-
del sb
|
|
276
|
-
del env
|
|
277
|
-
|
|
278
|
-
def test_acquire_env_offline(self):
|
|
279
|
-
env = TestingEnvironment(
|
|
280
|
-
features={'test_feature': TestingFeature()},
|
|
281
|
-
pool_size=0,
|
|
282
|
-
outage_grace_period=1,
|
|
283
|
-
outage_retry_interval=0,
|
|
284
|
-
sandbox_keepalive_interval=0,
|
|
285
|
-
)
|
|
286
|
-
with self.assertRaises(interface.EnvironmentOutageError):
|
|
287
|
-
env.acquire()
|
|
288
|
-
|
|
289
|
-
def test_acquire_no_pooling(self):
|
|
290
|
-
env = TestingEnvironment(
|
|
291
|
-
features={'test_feature': TestingFeature()},
|
|
292
|
-
pool_size=0,
|
|
293
|
-
outage_grace_period=1,
|
|
294
|
-
outage_retry_interval=0,
|
|
295
|
-
sandbox_keepalive_interval=0,
|
|
296
|
-
)
|
|
297
|
-
with env:
|
|
298
|
-
sb = env.acquire()
|
|
299
|
-
self.assertEqual(sb.status, interface.Sandbox.Status.ACQUIRED)
|
|
300
|
-
self.assertIsNone(env.working_dir)
|
|
301
|
-
self.assertIsNone(sb.working_dir)
|
|
302
|
-
self.assertIsNone(sb.test_feature.working_dir)
|
|
303
|
-
|
|
304
|
-
def test_acquire_no_pooling_with_error(self):
|
|
305
|
-
env = TestingEnvironment(
|
|
306
|
-
features={
|
|
307
|
-
'test_feature': TestingFeature(
|
|
308
|
-
simulate_setup_error=interface.SandboxStateError
|
|
309
|
-
)
|
|
310
|
-
},
|
|
311
|
-
pool_size=0,
|
|
312
|
-
outage_grace_period=1,
|
|
313
|
-
outage_retry_interval=0,
|
|
314
|
-
sandbox_keepalive_interval=0,
|
|
315
|
-
)
|
|
316
|
-
with env:
|
|
317
|
-
with self.assertRaises(interface.EnvironmentOutageError):
|
|
318
|
-
env.acquire()
|
|
319
|
-
|
|
320
|
-
def test_acquire_with_pooling(self):
|
|
321
|
-
env = TestingEnvironment(
|
|
322
|
-
features={'test_feature': TestingFeature()},
|
|
323
|
-
pool_size=1,
|
|
324
|
-
outage_grace_period=1,
|
|
325
|
-
outage_retry_interval=0,
|
|
326
|
-
sandbox_keepalive_interval=0,
|
|
327
|
-
)
|
|
328
|
-
with env:
|
|
329
|
-
sb = env.acquire()
|
|
330
|
-
self.assertEqual(sb.status, interface.Sandbox.Status.ACQUIRED)
|
|
331
|
-
|
|
332
|
-
def test_acquire_with_pooling_overload(self):
|
|
333
|
-
env = TestingEnvironment(
|
|
334
|
-
features={'test_feature': TestingFeature()},
|
|
335
|
-
pool_size=1,
|
|
336
|
-
outage_grace_period=1,
|
|
337
|
-
outage_retry_interval=0,
|
|
338
|
-
sandbox_keepalive_interval=0,
|
|
339
|
-
)
|
|
340
|
-
with env:
|
|
341
|
-
sb = env.acquire()
|
|
342
|
-
self.assertEqual(sb.status, interface.Sandbox.Status.ACQUIRED)
|
|
343
|
-
with self.assertRaises(interface.EnvironmentOverloadError):
|
|
344
|
-
env.acquire()
|
|
345
|
-
|
|
346
|
-
def test_acquire_with_growing_pool(self):
|
|
347
|
-
env = TestingEnvironment(
|
|
348
|
-
features={'test_feature': TestingFeature()},
|
|
349
|
-
pool_size=(1, 3),
|
|
350
|
-
outage_grace_period=1,
|
|
351
|
-
outage_retry_interval=0,
|
|
352
|
-
sandbox_keepalive_interval=0,
|
|
353
|
-
)
|
|
354
|
-
with env:
|
|
355
|
-
self.assertEqual(len(env.sandbox_pool['test_image']), 1)
|
|
356
|
-
self.assertEqual(
|
|
357
|
-
env.stats(),
|
|
358
|
-
{
|
|
359
|
-
'sandbox': {
|
|
360
|
-
'test_image': {
|
|
361
|
-
'created': 0,
|
|
362
|
-
'setting_up': 0,
|
|
363
|
-
'ready': 1,
|
|
364
|
-
'acquired': 0,
|
|
365
|
-
'in_session': 0,
|
|
366
|
-
'exiting_session': 0,
|
|
367
|
-
'shutting_down': 0,
|
|
368
|
-
'offline': 0,
|
|
369
|
-
}
|
|
370
|
-
}
|
|
371
|
-
}
|
|
372
|
-
)
|
|
373
|
-
sb = env.acquire()
|
|
374
|
-
self.assertEqual(sb.status, interface.Sandbox.Status.ACQUIRED)
|
|
375
|
-
self.assertEqual(
|
|
376
|
-
env.stats(),
|
|
377
|
-
{
|
|
378
|
-
'sandbox': {
|
|
379
|
-
'test_image': {
|
|
380
|
-
'created': 0,
|
|
381
|
-
'setting_up': 0,
|
|
382
|
-
'ready': 0,
|
|
383
|
-
'acquired': 1,
|
|
384
|
-
'in_session': 0,
|
|
385
|
-
'exiting_session': 0,
|
|
386
|
-
'shutting_down': 0,
|
|
387
|
-
'offline': 0,
|
|
388
|
-
}
|
|
389
|
-
}
|
|
390
|
-
}
|
|
391
|
-
)
|
|
392
|
-
self.assertEqual(len(env.sandbox_pool['test_image']), 1)
|
|
393
|
-
sb2 = env.acquire()
|
|
394
|
-
self.assertEqual(sb2.status, interface.Sandbox.Status.ACQUIRED)
|
|
395
|
-
self.assertEqual(len(env.sandbox_pool['test_image']), 2)
|
|
396
|
-
self.assertEqual(
|
|
397
|
-
env.stats(),
|
|
398
|
-
{
|
|
399
|
-
'sandbox': {
|
|
400
|
-
'test_image': {
|
|
401
|
-
'created': 0,
|
|
402
|
-
'setting_up': 0,
|
|
403
|
-
'ready': 0,
|
|
404
|
-
'acquired': 2,
|
|
405
|
-
'in_session': 0,
|
|
406
|
-
'exiting_session': 0,
|
|
407
|
-
'shutting_down': 0,
|
|
408
|
-
'offline': 0,
|
|
409
|
-
}
|
|
410
|
-
}
|
|
411
|
-
}
|
|
412
|
-
)
|
|
413
|
-
self.assertEqual(
|
|
414
|
-
env.stats(),
|
|
415
|
-
{
|
|
416
|
-
'sandbox': {}
|
|
417
|
-
}
|
|
418
|
-
)
|
|
419
|
-
|
|
420
|
-
def test_acquire_with_growing_pool_failure(self):
|
|
421
|
-
env = TestingEnvironment(
|
|
422
|
-
features={'test_feature': TestingFeature()},
|
|
423
|
-
pool_size=(1, 3),
|
|
424
|
-
outage_grace_period=1,
|
|
425
|
-
outage_retry_interval=0,
|
|
426
|
-
sandbox_keepalive_interval=0,
|
|
427
|
-
)
|
|
428
|
-
with env:
|
|
429
|
-
self.assertEqual(len(env.sandbox_pool), 1)
|
|
430
|
-
sb = env.acquire()
|
|
431
|
-
self.assertEqual(sb.status, interface.Sandbox.Status.ACQUIRED)
|
|
432
|
-
|
|
433
|
-
# Make future sandbox setup to fail.
|
|
434
|
-
env.features.test_feature.rebind(
|
|
435
|
-
simulate_setup_error=interface.SandboxStateError,
|
|
436
|
-
skip_notification=True
|
|
437
|
-
)
|
|
438
|
-
with self.assertRaises(interface.EnvironmentOutageError):
|
|
439
|
-
env.acquire()
|
|
440
|
-
|
|
441
|
-
def test_housekeep_error(self):
|
|
442
|
-
env = TestingEnvironment(
|
|
443
|
-
features={'test_feature': TestingFeature()},
|
|
444
|
-
pool_size=1,
|
|
445
|
-
proactive_session_setup=True,
|
|
446
|
-
outage_grace_period=1,
|
|
447
|
-
outage_retry_interval=0,
|
|
448
|
-
sandbox_keepalive_interval=0,
|
|
449
|
-
)
|
|
450
|
-
with env:
|
|
451
|
-
self.assertEqual(len(env.sandbox_pool), 1)
|
|
452
|
-
self.assertIn('test_image', env.sandbox_pool)
|
|
453
|
-
self.assertEqual(
|
|
454
|
-
env.sandbox_pool['test_image'][0].status,
|
|
455
|
-
interface.Sandbox.Status.READY
|
|
456
|
-
)
|
|
457
|
-
# Make future sandbox setup to fail.
|
|
458
|
-
env.features.test_feature.rebind(
|
|
459
|
-
simulate_setup_error=interface.SandboxStateError,
|
|
460
|
-
skip_notification=True
|
|
461
|
-
)
|
|
462
|
-
with self.assertRaises(interface.SandboxStateError):
|
|
463
|
-
with env.sandbox() as sb:
|
|
464
|
-
sb.shell('bad command', raise_error=interface.SandboxStateError)
|
|
465
|
-
self.assertEqual(sb.status, interface.Sandbox.Status.OFFLINE)
|
|
466
|
-
self.assertEqual(len(sb.state_errors), 1)
|
|
467
|
-
sb_offline_time = time.time()
|
|
468
|
-
while time.time() - sb_offline_time < 10:
|
|
469
|
-
if not env.is_online:
|
|
470
|
-
break
|
|
471
|
-
time.sleep(0.5)
|
|
472
|
-
self.assertFalse(env.is_online)
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
class SandboxStatusTests(unittest.TestCase):
|
|
27
|
+
class BaseSandboxTests(unittest.TestCase):
|
|
476
28
|
|
|
477
29
|
def setUp(self):
|
|
478
30
|
super().setUp()
|
|
@@ -494,7 +46,7 @@ class SandboxStatusTests(unittest.TestCase):
|
|
|
494
46
|
pool_size=pool_size,
|
|
495
47
|
features=features,
|
|
496
48
|
outage_grace_period=0,
|
|
497
|
-
|
|
49
|
+
event_handler=self.event_handler,
|
|
498
50
|
outage_retry_interval=0,
|
|
499
51
|
**kwargs
|
|
500
52
|
)
|
|
@@ -604,19 +156,14 @@ class SandboxStatusTests(unittest.TestCase):
|
|
|
604
156
|
]
|
|
605
157
|
)
|
|
606
158
|
|
|
607
|
-
def
|
|
159
|
+
def test_proactive_session_setup_with_setup_session_error(self):
|
|
608
160
|
env = self._create_env(
|
|
609
161
|
features={'test_feature': TestingFeature(setup_session_delay=0.5)},
|
|
610
162
|
pool_size=1,
|
|
611
|
-
|
|
612
|
-
event_handler = TestingEventHandler(
|
|
613
|
-
log_sandbox_status=True,
|
|
614
|
-
log_feature_setup=True,
|
|
615
|
-
log_session_setup=True,
|
|
163
|
+
housekeep_interval=10.0,
|
|
616
164
|
)
|
|
617
165
|
with env:
|
|
618
166
|
with env.sandbox(session_id='session1') as sb:
|
|
619
|
-
sb.add_event_handler(event_handler)
|
|
620
167
|
sb.test_feature.rebind(
|
|
621
168
|
simulate_setup_session_error=interface.SandboxStateError,
|
|
622
169
|
skip_notification=True
|
|
@@ -630,15 +177,26 @@ class SandboxStatusTests(unittest.TestCase):
|
|
|
630
177
|
self.assertEqual(len(sb.state_errors), 1)
|
|
631
178
|
self.assertEqual(sb.status, interface.Sandbox.Status.OFFLINE)
|
|
632
179
|
self.assertEqual(
|
|
633
|
-
event_handler.logs,
|
|
180
|
+
self.event_handler.logs,
|
|
634
181
|
[
|
|
635
182
|
# pylint: disable=line-too-long
|
|
183
|
+
'[testing-env/test_image:0:0] shell: "test_feature" setup',
|
|
184
|
+
'[testing-env/test_image:0:0/test_feature] feature setup',
|
|
185
|
+
'[testing-env/test_image:0:0] shell: "test_feature" setup session',
|
|
186
|
+
'[testing-env/test_image:0:0/test_feature] 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",
|
|
636
194
|
'[testing-env/test_image:0:0] in_session -> exiting_session',
|
|
637
195
|
'[testing-env/test_image:0:0/session1] shell: "test_feature" teardown session',
|
|
638
196
|
'[testing-env/test_image:0:0/test_feature] feature teardown session',
|
|
639
197
|
"[testing-env/test_image:0:0] session 'session1' ended",
|
|
640
198
|
'[testing-env/test_image:0:0] exiting_session -> setting_up',
|
|
641
|
-
'[testing-env/test_image:0:0/test_feature] feature setup session with SandboxStateError',
|
|
199
|
+
'[testing-env/test_image:0:0/test_feature] feature setup session with SandboxStateError',
|
|
642
200
|
'[testing-env/test_image:0:0] setting_up -> shutting_down',
|
|
643
201
|
'[testing-env/test_image:0:0] shell: "test_feature" teardown',
|
|
644
202
|
'[testing-env/test_image:0:0/test_feature] feature teardown',
|
|
@@ -1328,7 +886,7 @@ class SandboxActivityTests(unittest.TestCase):
|
|
|
1328
886
|
outage_grace_period=0,
|
|
1329
887
|
outage_retry_interval=0.1,
|
|
1330
888
|
sandbox_keepalive_interval=0,
|
|
1331
|
-
|
|
889
|
+
event_handler=event_handler,
|
|
1332
890
|
)
|
|
1333
891
|
with env:
|
|
1334
892
|
with env.sandbox(session_id='session1') as sb:
|
|
@@ -1374,27 +932,6 @@ class SandboxActivityTests(unittest.TestCase):
|
|
|
1374
932
|
]
|
|
1375
933
|
)
|
|
1376
934
|
|
|
1377
|
-
def test_remove_event_handler(self):
|
|
1378
|
-
env = TestingEnvironment(
|
|
1379
|
-
features={'test_feature': TestingFeature(housekeep_interval=0)},
|
|
1380
|
-
pool_size=1,
|
|
1381
|
-
outage_grace_period=0,
|
|
1382
|
-
outage_retry_interval=0,
|
|
1383
|
-
sandbox_keepalive_interval=0,
|
|
1384
|
-
)
|
|
1385
|
-
event_handler = TestingEventHandler()
|
|
1386
|
-
with env:
|
|
1387
|
-
with env.sandbox(session_id='session1') as sb:
|
|
1388
|
-
sb.add_event_handler(event_handler)
|
|
1389
|
-
sb.shell('test_feature')
|
|
1390
|
-
sb.remove_event_handler(event_handler)
|
|
1391
|
-
events = list(event_handler.logs)
|
|
1392
|
-
sb.wait_until_not(interface.Sandbox.Status.SETTING_UP)
|
|
1393
|
-
self.assertGreater(len(events), 0)
|
|
1394
|
-
with env.sandbox(session_id='session2') as sb:
|
|
1395
|
-
sb.shell('test_feature')
|
|
1396
|
-
self.assertEqual(len(events), len(event_handler.logs))
|
|
1397
|
-
|
|
1398
935
|
|
|
1399
936
|
class SandboxServiceTests(unittest.TestCase):
|
|
1400
937
|
|
|
@@ -1408,13 +945,13 @@ class SandboxServiceTests(unittest.TestCase):
|
|
|
1408
945
|
outage_grace_period=0,
|
|
1409
946
|
outage_retry_interval=0,
|
|
1410
947
|
sandbox_keepalive_interval=0,
|
|
1411
|
-
|
|
948
|
+
event_handler=self.event_handler,
|
|
1412
949
|
random_seed=1,
|
|
1413
950
|
)
|
|
1414
951
|
|
|
1415
952
|
def test_service_call_activity_log(self):
|
|
1416
953
|
|
|
1417
|
-
class CustomEventHandler(
|
|
954
|
+
class CustomEventHandler(interface.EventHandler):
|
|
1418
955
|
|
|
1419
956
|
def __init__(self):
|
|
1420
957
|
self.calls = []
|
|
@@ -1435,7 +972,7 @@ class SandboxServiceTests(unittest.TestCase):
|
|
|
1435
972
|
env = TestingEnvironment(
|
|
1436
973
|
features={'test_feature': TestingFeature()},
|
|
1437
974
|
pool_size=0,
|
|
1438
|
-
|
|
975
|
+
event_handler=event_handler,
|
|
1439
976
|
)
|
|
1440
977
|
with env:
|
|
1441
978
|
with env.test_feature(session_id='session1') as test_feature:
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
# pylint: disable=g-importing-member
|
|
4
4
|
# pylint: disable=g-bad-import-order
|
|
5
5
|
|
|
6
|
-
from langfun.env.event_handlers.
|
|
6
|
+
from langfun.env.event_handlers.chain import EventHandlerChain
|
|
7
7
|
|
|
8
8
|
from langfun.env.event_handlers.event_logger import EventLogger
|
|
9
9
|
from langfun.env.event_handlers.event_logger import ConsoleEventLogger
|