langfun 0.1.2.dev202509240805__py3-none-any.whl → 0.1.2.dev202509260805__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 -5
- langfun/env/base_environment.py +104 -66
- langfun/env/base_feature.py +35 -13
- langfun/env/base_sandbox.py +230 -99
- langfun/env/base_test.py +271 -431
- langfun/env/event_handlers/__init__.py +12 -0
- langfun/env/event_handlers/base.py +271 -0
- langfun/env/event_handlers/event_logger.py +415 -0
- langfun/env/event_handlers/event_logger_test.py +289 -0
- langfun/env/interface.py +117 -262
- langfun/env/interface_test.py +3 -3
- langfun/env/load_balancers_test.py +3 -15
- langfun/env/test_utils.py +459 -0
- {langfun-0.1.2.dev202509240805.dist-info → langfun-0.1.2.dev202509260805.dist-info}/METADATA +1 -1
- {langfun-0.1.2.dev202509240805.dist-info → langfun-0.1.2.dev202509260805.dist-info}/RECORD +18 -13
- {langfun-0.1.2.dev202509240805.dist-info → langfun-0.1.2.dev202509260805.dist-info}/WHEEL +0 -0
- {langfun-0.1.2.dev202509240805.dist-info → langfun-0.1.2.dev202509260805.dist-info}/licenses/LICENSE +0 -0
- {langfun-0.1.2.dev202509240805.dist-info → langfun-0.1.2.dev202509260805.dist-info}/top_level.txt +0 -0
langfun/env/interface.py
CHANGED
|
@@ -22,60 +22,6 @@ from typing import Annotated, Any, ContextManager, ClassVar, Iterator, Optional
|
|
|
22
22
|
|
|
23
23
|
import pyglove as pg
|
|
24
24
|
|
|
25
|
-
#
|
|
26
|
-
# Environemnt identifiers.
|
|
27
|
-
#
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
@dataclasses.dataclass(frozen=True)
|
|
31
|
-
class EnvironmentId:
|
|
32
|
-
"""Identifier for an environment."""
|
|
33
|
-
environment_id: str
|
|
34
|
-
|
|
35
|
-
def __str__(self) -> str:
|
|
36
|
-
return self.environment_id
|
|
37
|
-
|
|
38
|
-
def working_dir(self, root_dir: str | None) -> str | None:
|
|
39
|
-
"""Returns the download directory for the service."""
|
|
40
|
-
if root_dir is None:
|
|
41
|
-
return None
|
|
42
|
-
return os.path.join(root_dir, _make_path_compatible(self.environment_id))
|
|
43
|
-
|
|
44
|
-
# Enable automatic conversion from str to EnvironmentId.
|
|
45
|
-
pg.typing.register_converter(str, EnvironmentId, EnvironmentId)
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
@dataclasses.dataclass(frozen=True)
|
|
49
|
-
class SandboxId:
|
|
50
|
-
"""Identifier for a sandbox."""
|
|
51
|
-
environment_id: EnvironmentId
|
|
52
|
-
sandbox_id: str
|
|
53
|
-
|
|
54
|
-
def __str__(self) -> str:
|
|
55
|
-
return f'{self.environment_id}/{self.sandbox_id}'
|
|
56
|
-
|
|
57
|
-
def working_dir(self, root_dir: str | None) -> str | None:
|
|
58
|
-
"""Returns the download directory for the sandbox."""
|
|
59
|
-
if root_dir is None:
|
|
60
|
-
return None
|
|
61
|
-
return os.path.join(
|
|
62
|
-
self.environment_id.working_dir(root_dir),
|
|
63
|
-
_make_path_compatible(self.sandbox_id)
|
|
64
|
-
)
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
def _make_path_compatible(id_str: str) -> str:
|
|
68
|
-
"""Makes a path compatible with CNS."""
|
|
69
|
-
return id_str.translate(
|
|
70
|
-
str.maketrans({
|
|
71
|
-
'@': '_',
|
|
72
|
-
':': '_',
|
|
73
|
-
'#': '_',
|
|
74
|
-
' ': '',
|
|
75
|
-
})
|
|
76
|
-
)
|
|
77
|
-
|
|
78
|
-
|
|
79
25
|
#
|
|
80
26
|
# Environment errors.
|
|
81
27
|
#
|
|
@@ -216,144 +162,6 @@ class SessionTeardownError(SandboxError):
|
|
|
216
162
|
not isinstance(e, SandboxStateError) for e in self.errors.values()
|
|
217
163
|
)
|
|
218
164
|
|
|
219
|
-
|
|
220
|
-
#
|
|
221
|
-
# Event handler.
|
|
222
|
-
#
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
class SessionEventHandler:
|
|
226
|
-
"""Base class for session event handlers."""
|
|
227
|
-
|
|
228
|
-
def on_session_start(
|
|
229
|
-
self,
|
|
230
|
-
environment: 'Environment',
|
|
231
|
-
sandbox: 'Sandbox',
|
|
232
|
-
session_id: str,
|
|
233
|
-
error: BaseException | None
|
|
234
|
-
) -> None:
|
|
235
|
-
"""Called when a sandbox session starts."""
|
|
236
|
-
|
|
237
|
-
def on_session_activity(
|
|
238
|
-
self,
|
|
239
|
-
session_id: str,
|
|
240
|
-
name: str,
|
|
241
|
-
environment: 'Environment',
|
|
242
|
-
sandbox: 'Sandbox',
|
|
243
|
-
feature: Optional['Feature'],
|
|
244
|
-
error: BaseException | None,
|
|
245
|
-
**kwargs
|
|
246
|
-
) -> None:
|
|
247
|
-
"""Called when a sandbox activity is performed."""
|
|
248
|
-
|
|
249
|
-
def on_session_end(
|
|
250
|
-
self,
|
|
251
|
-
environment: 'Environment',
|
|
252
|
-
sandbox: 'Sandbox',
|
|
253
|
-
session_id: str,
|
|
254
|
-
error: BaseException | None
|
|
255
|
-
) -> None:
|
|
256
|
-
"""Called when a sandbox session ends."""
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
class FeatureEventHandler:
|
|
260
|
-
"""Base class for feature event handlers."""
|
|
261
|
-
|
|
262
|
-
def on_feature_setup(
|
|
263
|
-
self,
|
|
264
|
-
environment: 'Environment',
|
|
265
|
-
sandbox: 'Sandbox',
|
|
266
|
-
feature: 'Feature',
|
|
267
|
-
error: BaseException | None
|
|
268
|
-
) -> None:
|
|
269
|
-
"""Called when a sandbox feature is setup."""
|
|
270
|
-
|
|
271
|
-
def on_feature_teardown(
|
|
272
|
-
self,
|
|
273
|
-
environment: 'Environment',
|
|
274
|
-
sandbox: 'Sandbox',
|
|
275
|
-
feature: 'Feature',
|
|
276
|
-
error: BaseException | None
|
|
277
|
-
) -> None:
|
|
278
|
-
"""Called when a sandbox feature is teardown."""
|
|
279
|
-
|
|
280
|
-
def on_feature_teardown_session(
|
|
281
|
-
self,
|
|
282
|
-
environment: 'Environment',
|
|
283
|
-
sandbox: 'Sandbox',
|
|
284
|
-
feature: 'Feature',
|
|
285
|
-
session_id: str,
|
|
286
|
-
error: BaseException | None
|
|
287
|
-
) -> None:
|
|
288
|
-
"""Called when a feature is teardown with a session."""
|
|
289
|
-
|
|
290
|
-
def on_feature_setup_session(
|
|
291
|
-
self,
|
|
292
|
-
environment: 'Environment',
|
|
293
|
-
sandbox: 'Sandbox',
|
|
294
|
-
feature: 'Feature',
|
|
295
|
-
session_id: str | None,
|
|
296
|
-
error: BaseException | None
|
|
297
|
-
) -> None:
|
|
298
|
-
"""Called when a feature is setup with a session."""
|
|
299
|
-
|
|
300
|
-
def on_feature_housekeep(
|
|
301
|
-
self,
|
|
302
|
-
environment: 'Environment',
|
|
303
|
-
sandbox: 'Sandbox',
|
|
304
|
-
feature: 'Feature',
|
|
305
|
-
error: BaseException | None
|
|
306
|
-
) -> None:
|
|
307
|
-
"""Called when a sandbox feature is housekeeping."""
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
class SandboxEventHandler(FeatureEventHandler, SessionEventHandler):
|
|
311
|
-
"""Base class for sandbox event handlers."""
|
|
312
|
-
|
|
313
|
-
def on_sandbox_start(
|
|
314
|
-
self,
|
|
315
|
-
environment: 'Environment',
|
|
316
|
-
sandbox: 'Sandbox',
|
|
317
|
-
error: BaseException | None
|
|
318
|
-
) -> None:
|
|
319
|
-
"""Called when a sandbox is started."""
|
|
320
|
-
|
|
321
|
-
def on_sandbox_status_change(
|
|
322
|
-
self,
|
|
323
|
-
environment: 'Environment',
|
|
324
|
-
sandbox: 'Sandbox',
|
|
325
|
-
old_status: 'Sandbox.Status',
|
|
326
|
-
new_status: 'Sandbox.Status',
|
|
327
|
-
) -> None:
|
|
328
|
-
"""Called when a sandbox status changes."""
|
|
329
|
-
|
|
330
|
-
def on_sandbox_shutdown(
|
|
331
|
-
self,
|
|
332
|
-
environment: 'Environment',
|
|
333
|
-
sandbox: 'Sandbox',
|
|
334
|
-
error: BaseException | None
|
|
335
|
-
) -> None:
|
|
336
|
-
"""Called when a sandbox is shutdown."""
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
class EnvironmentEventHandler(SandboxEventHandler):
|
|
340
|
-
"""Base class for environment event handlers."""
|
|
341
|
-
|
|
342
|
-
def on_environment_start(
|
|
343
|
-
self,
|
|
344
|
-
environment: 'Environment',
|
|
345
|
-
error: BaseException | None
|
|
346
|
-
) -> None:
|
|
347
|
-
"""Called when the environment is started."""
|
|
348
|
-
|
|
349
|
-
def on_environment_shutdown(
|
|
350
|
-
self,
|
|
351
|
-
environment: 'Environment',
|
|
352
|
-
error: BaseException | None
|
|
353
|
-
) -> None:
|
|
354
|
-
"""Called when the environment is shutdown."""
|
|
355
|
-
|
|
356
|
-
|
|
357
165
|
#
|
|
358
166
|
# Interface for sandbox-based environment.
|
|
359
167
|
#
|
|
@@ -362,6 +170,20 @@ class EnvironmentEventHandler(SandboxEventHandler):
|
|
|
362
170
|
class Environment(pg.Object):
|
|
363
171
|
"""Base class for an environment."""
|
|
364
172
|
|
|
173
|
+
@dataclasses.dataclass(frozen=True)
|
|
174
|
+
class Id:
|
|
175
|
+
"""Identifier for an environment."""
|
|
176
|
+
environment_id: str
|
|
177
|
+
|
|
178
|
+
def __str__(self) -> str:
|
|
179
|
+
return self.environment_id
|
|
180
|
+
|
|
181
|
+
def working_dir(self, root_dir: str | None) -> str | None:
|
|
182
|
+
"""Returns the download directory for the service."""
|
|
183
|
+
if root_dir is None:
|
|
184
|
+
return None
|
|
185
|
+
return os.path.join(root_dir, _make_path_compatible(self.environment_id))
|
|
186
|
+
|
|
365
187
|
class Status(enum.Enum):
|
|
366
188
|
"""Environment state.
|
|
367
189
|
|
|
@@ -384,13 +206,6 @@ class Environment(pg.Object):
|
|
|
384
206
|
'Features to be exposed by the environment.'
|
|
385
207
|
] = {}
|
|
386
208
|
|
|
387
|
-
event_handlers: Annotated[
|
|
388
|
-
list[EnvironmentEventHandler],
|
|
389
|
-
(
|
|
390
|
-
'User handler for the environment events.'
|
|
391
|
-
)
|
|
392
|
-
] = []
|
|
393
|
-
|
|
394
209
|
_ENV_STACK: Annotated[
|
|
395
210
|
ClassVar[list['Environment']],
|
|
396
211
|
'Recording the environments stacked through context managers.'
|
|
@@ -402,7 +217,7 @@ class Environment(pg.Object):
|
|
|
402
217
|
|
|
403
218
|
@property
|
|
404
219
|
@abc.abstractmethod
|
|
405
|
-
def id(self) ->
|
|
220
|
+
def id(self) -> Id:
|
|
406
221
|
"""Returns the identifier for the environment."""
|
|
407
222
|
|
|
408
223
|
@property
|
|
@@ -466,6 +281,10 @@ class Environment(pg.Object):
|
|
|
466
281
|
Environment._ENV_STACK.pop()
|
|
467
282
|
self.shutdown()
|
|
468
283
|
|
|
284
|
+
def __del__(self):
|
|
285
|
+
"""Deletes the environment."""
|
|
286
|
+
self.shutdown()
|
|
287
|
+
|
|
469
288
|
@classmethod
|
|
470
289
|
def current(cls) -> Optional['Environment']:
|
|
471
290
|
"""Returns the current environment."""
|
|
@@ -506,49 +325,78 @@ class Environment(pg.Object):
|
|
|
506
325
|
raise AttributeError(name)
|
|
507
326
|
|
|
508
327
|
|
|
328
|
+
# Enable automatic conversion from str to Environment.Id.
|
|
329
|
+
pg.typing.register_converter(str, Environment.Id, Environment.Id)
|
|
330
|
+
|
|
331
|
+
|
|
509
332
|
class Sandbox(pg.Object):
|
|
510
333
|
"""Interface for sandboxes."""
|
|
511
334
|
|
|
335
|
+
@dataclasses.dataclass(frozen=True, slots=True)
|
|
336
|
+
class Id:
|
|
337
|
+
"""Identifier for a sandbox."""
|
|
338
|
+
environment_id: Environment.Id
|
|
339
|
+
sandbox_id: str
|
|
340
|
+
|
|
341
|
+
def __str__(self) -> str:
|
|
342
|
+
return f'{self.environment_id}/{self.sandbox_id}'
|
|
343
|
+
|
|
344
|
+
def working_dir(self, root_dir: str | None) -> str | None:
|
|
345
|
+
"""Returns the download directory for the sandbox."""
|
|
346
|
+
if root_dir is None:
|
|
347
|
+
return None
|
|
348
|
+
return os.path.join(
|
|
349
|
+
self.environment_id.working_dir(root_dir),
|
|
350
|
+
_make_path_compatible(self.sandbox_id)
|
|
351
|
+
)
|
|
352
|
+
|
|
512
353
|
class Status(enum.Enum):
|
|
513
|
-
"""Sandbox state.
|
|
354
|
+
r"""Sandbox state.
|
|
514
355
|
|
|
515
356
|
State transitions:
|
|
516
357
|
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
358
|
+
(sandbox / feature
|
|
359
|
+
+------------+ teardown) +---------------+
|
|
360
|
+
| <OFFLINE> | <--------------------- | SHUTTING_DOWN |
|
|
361
|
+
+------------+ +---------------+
|
|
362
|
+
^ ^
|
|
363
|
+
/ \
|
|
364
|
+
(setup failed) / \
|
|
365
|
+
/ \
|
|
366
|
+
+-----------+ (start) +------------+ \
|
|
367
|
+
| <CREATED> | --------> | SETTING_UP | \
|
|
368
|
+
+-----------+ ^ +------------+ \
|
|
369
|
+
/ | \
|
|
370
|
+
/ | (sandbox / \
|
|
371
|
+
/ | feature /session \
|
|
372
|
+
/ v setup succeeded) \
|
|
373
|
+
/ +---------+ \
|
|
374
|
+
/ | READY | \
|
|
375
|
+
/ +---------+ \
|
|
376
|
+
/ | \
|
|
377
|
+
/ | (acquire) \
|
|
378
|
+
/ v \
|
|
379
|
+
/ +----------+ \
|
|
380
|
+
| | ACQUIRED | \
|
|
381
|
+
| +----------+ |
|
|
382
|
+
| | |
|
|
383
|
+
| | (start_session) |
|
|
384
|
+
| +------------+ |
|
|
385
|
+
| | SETTING_UP |-- (setup failed) ------>+
|
|
386
|
+
| +------------+ |
|
|
387
|
+
| | |
|
|
388
|
+
| v (succeeded) |
|
|
389
|
+
| +--------------+ |
|
|
390
|
+
| | IN_SESSION |- (op failed) -------->+
|
|
391
|
+
| +--------------+ |
|
|
392
|
+
| | |
|
|
393
|
+
| | (end_session) |
|
|
394
|
+
| | |
|
|
395
|
+
| v (session teardown |
|
|
396
|
+
(setup next +-----------------+ failed OR |
|
|
397
|
+
session for <---------| EXITING_SESSION |- non-reusable -----+
|
|
398
|
+
reusable sandbox) +-----------------+ sandbox)
|
|
399
|
+
|
|
552
400
|
"""
|
|
553
401
|
|
|
554
402
|
# The sandbox is created, but not yet started.
|
|
@@ -566,6 +414,9 @@ class Sandbox(pg.Object):
|
|
|
566
414
|
# The sandbox is in a user session.
|
|
567
415
|
IN_SESSION = 'in_session'
|
|
568
416
|
|
|
417
|
+
# The sandbox is exiting a user session.
|
|
418
|
+
EXITING_SESSION = 'exiting_session'
|
|
419
|
+
|
|
569
420
|
# The sandbox is being shut down.
|
|
570
421
|
SHUTTING_DOWN = 'shutting_down'
|
|
571
422
|
|
|
@@ -584,7 +435,7 @@ class Sandbox(pg.Object):
|
|
|
584
435
|
|
|
585
436
|
@property
|
|
586
437
|
@abc.abstractmethod
|
|
587
|
-
def id(self) ->
|
|
438
|
+
def id(self) -> Id:
|
|
588
439
|
"""Returns the identifier for the sandbox."""
|
|
589
440
|
|
|
590
441
|
@property
|
|
@@ -607,24 +458,6 @@ class Sandbox(pg.Object):
|
|
|
607
458
|
"""Returns True if the sandbox is online."""
|
|
608
459
|
return self.status.is_online
|
|
609
460
|
|
|
610
|
-
@abc.abstractmethod
|
|
611
|
-
def set_acquired(self) -> None:
|
|
612
|
-
"""Marks the sandbox as acquired."""
|
|
613
|
-
|
|
614
|
-
@abc.abstractmethod
|
|
615
|
-
def add_event_handler(
|
|
616
|
-
self,
|
|
617
|
-
event_handler: EnvironmentEventHandler
|
|
618
|
-
) -> None:
|
|
619
|
-
"""Sets the status of the sandbox."""
|
|
620
|
-
|
|
621
|
-
@abc.abstractmethod
|
|
622
|
-
def remove_event_handler(
|
|
623
|
-
self,
|
|
624
|
-
event_handler: EnvironmentEventHandler
|
|
625
|
-
) -> None:
|
|
626
|
-
"""Removes the status of the sandbox."""
|
|
627
|
-
|
|
628
461
|
@property
|
|
629
462
|
@abc.abstractmethod
|
|
630
463
|
def state_errors(self) -> list[SandboxStateError]:
|
|
@@ -742,14 +575,18 @@ class Sandbox(pg.Object):
|
|
|
742
575
|
"""Ends the user session with the sandbox.
|
|
743
576
|
|
|
744
577
|
State transitions:
|
|
745
|
-
IN_SESSION -> READY: When user session exits normally,
|
|
746
|
-
to reuse.
|
|
747
|
-
IN_SESSION -> SHUTTING_DOWN -> OFFLINE: When user
|
|
578
|
+
IN_SESSION -> EXITING_SESSION -> READY: When user session exits normally,
|
|
579
|
+
and sandbox is set to reuse.
|
|
580
|
+
IN_SESSION -> EXITING_SESSION -> SHUTTING_DOWN -> OFFLINE: When user
|
|
581
|
+
session exits while
|
|
748
582
|
sandbox is set not to reuse, or session teardown fails.
|
|
749
|
-
IN_SESSION -> SETTING_UP -> READY: When user session
|
|
750
|
-
sandbox is set to reuse, and proactive session setup
|
|
751
|
-
|
|
752
|
-
|
|
583
|
+
IN_SESSION -> EXITING_SESSION -> SETTING_UP -> READY: When user session
|
|
584
|
+
exits normally, and sandbox is set to reuse, and proactive session setup
|
|
585
|
+
is enabled.
|
|
586
|
+
IN_SESSION -> EXITING_SESSION -> SETTING_UP -> SHUTTING_DOWN -> OFFLINE:
|
|
587
|
+
When user session exits normally, and proactive session setup is enabled
|
|
588
|
+
but fails.
|
|
589
|
+
EXITING_SESSION -> EXITING_SESSION: No operation.
|
|
753
590
|
not IN_SESSION -> same state: No operation
|
|
754
591
|
|
|
755
592
|
`end_session` should always be called for each `start_session` call, even
|
|
@@ -838,6 +675,10 @@ class Sandbox(pg.Object):
|
|
|
838
675
|
return self.features[name]
|
|
839
676
|
raise AttributeError(name)
|
|
840
677
|
|
|
678
|
+
def __del__(self):
|
|
679
|
+
"""Deletes the sandbox."""
|
|
680
|
+
self.shutdown()
|
|
681
|
+
|
|
841
682
|
|
|
842
683
|
class Feature(pg.Object):
|
|
843
684
|
"""Interface for sandbox features."""
|
|
@@ -969,3 +810,17 @@ class Feature(pg.Object):
|
|
|
969
810
|
"""Returns the current user session identifier."""
|
|
970
811
|
assert self.sandbox is not None
|
|
971
812
|
return self.sandbox.session_id
|
|
813
|
+
|
|
814
|
+
|
|
815
|
+
def _make_path_compatible(id_str: str) -> str:
|
|
816
|
+
"""Makes a path compatible with CNS."""
|
|
817
|
+
return id_str.translate(
|
|
818
|
+
str.maketrans({
|
|
819
|
+
'@': '_',
|
|
820
|
+
':': '_',
|
|
821
|
+
'#': '_',
|
|
822
|
+
' ': '',
|
|
823
|
+
'<': '',
|
|
824
|
+
'>': '',
|
|
825
|
+
})
|
|
826
|
+
)
|
langfun/env/interface_test.py
CHANGED
|
@@ -18,7 +18,7 @@ from langfun.env import interface
|
|
|
18
18
|
class IdTest(unittest.TestCase):
|
|
19
19
|
|
|
20
20
|
def test_environment_id(self):
|
|
21
|
-
env_id = interface.
|
|
21
|
+
env_id = interface.Environment.Id('env@1/a b:c#def')
|
|
22
22
|
self.assertEqual(str(env_id), 'env@1/a b:c#def')
|
|
23
23
|
self.assertEqual(
|
|
24
24
|
env_id.working_dir(root_dir='/tmp'),
|
|
@@ -27,8 +27,8 @@ class IdTest(unittest.TestCase):
|
|
|
27
27
|
self.assertIsNone(env_id.working_dir(root_dir=None))
|
|
28
28
|
|
|
29
29
|
def test_sandbox_id(self):
|
|
30
|
-
sandbox_id = interface.
|
|
31
|
-
environment_id=interface.
|
|
30
|
+
sandbox_id = interface.Sandbox.Id(
|
|
31
|
+
environment_id=interface.Environment.Id('env'),
|
|
32
32
|
sandbox_id='sandbox'
|
|
33
33
|
)
|
|
34
34
|
self.assertEqual(str(sandbox_id), 'env/sandbox')
|
|
@@ -28,9 +28,9 @@ class TestingSandbox(interface.Sandbox):
|
|
|
28
28
|
self._session_id = None
|
|
29
29
|
|
|
30
30
|
@property
|
|
31
|
-
def id(self) -> interface.
|
|
32
|
-
return interface.
|
|
33
|
-
environment_id=interface.
|
|
31
|
+
def id(self) -> interface.Sandbox.Id:
|
|
32
|
+
return interface.Sandbox.Id(
|
|
33
|
+
environment_id=interface.Environment.Id('testing-env'),
|
|
34
34
|
sandbox_id=self.sandbox_id
|
|
35
35
|
)
|
|
36
36
|
|
|
@@ -52,18 +52,6 @@ class TestingSandbox(interface.Sandbox):
|
|
|
52
52
|
def set_acquired(self) -> None:
|
|
53
53
|
self.set_status(self.Status.ACQUIRED)
|
|
54
54
|
|
|
55
|
-
def add_event_handler(
|
|
56
|
-
self,
|
|
57
|
-
event_handler: interface.EnvironmentEventHandler
|
|
58
|
-
) -> None:
|
|
59
|
-
pass
|
|
60
|
-
|
|
61
|
-
def remove_event_handler(
|
|
62
|
-
self,
|
|
63
|
-
event_handler: interface.EnvironmentEventHandler
|
|
64
|
-
) -> None:
|
|
65
|
-
pass
|
|
66
|
-
|
|
67
55
|
def start(self) -> None:
|
|
68
56
|
self.set_alive()
|
|
69
57
|
|