userver
C++ Async Framework
Toggle main menu visibility
Loading...
Searching...
No Matches
control.py
1
import
dataclasses
2
import
getpass
3
import
pathlib
4
import
typing
5
6
from
testsuite.utils
import
yaml_util
7
8
from
.
import
service, utils
9
10
CONFIG_PATH = pathlib.Path(
'~/.config/yasuite/env.yaml'
)
11
DEFAULT_WORKER_ID =
'master'
12
13
14
class
BaseError
(Exception):
15
"""Base class for exceptions of this module."""
16
17
18
class
AlreadyStarted
(
BaseError
):
19
pass
20
21
22
class
ServiceUnknown
(
BaseError
):
23
pass
24
25
26
@dataclasses.dataclass(frozen=
True
)
27
class
Config
:
28
env_dir: pathlib.Path
29
worker_id: str
30
reuse_services: bool
31
verbose: int
32
33
34
class
Environment
:
35
config: Config
36
_services: dict[str,
service.ScriptService
]
37
_services_start_order: list[str]
38
_env: dict[str, str] |
None
39
_service_factories: dict[str, typing.Callable]
40
41
def
__init__(
42
self,
43
config: Config,
44
env: dict[str, str] |
None
=
None
,
45
) ->
None
:
46
self.
config
= config
47
self.
_services
= {}
48
self.
_services_start_order
= []
49
self.
_env
= env
50
self.
_service_factories
= {}
51
52
def
register_service(self, name: str, factory) ->
None
:
53
self.
_service_factories
[name] = factory
54
55
def
ensure_started(self, service_name: str, **kwargs) ->
None
:
56
if
service_name
not
in
self.
_services
:
57
self.
start_service
(service_name, **kwargs)
58
59
def
start_service(self, service_name: str, **kwargs) ->
None
:
60
if
service_name
in
self.
_services
:
61
raise
AlreadyStarted
(f
'Service {service_name} is already started'
)
62
script_service = self.
_create_service
(service_name, **kwargs)
63
if
not
(self.
config
.reuse_services
and
script_service.is_running()):
64
script_service.ensure_started(verbose=self.
config
.verbose)
65
self.
_services_start_order
.append(service_name)
66
self.
_services
[service_name] = script_service
67
68
def
stop_service(self, service_name: str) ->
None
:
69
if
service_name
not
in
self.
_services
:
70
self.
_services
[service_name] = self.
_create_service
(service_name)
71
if
not
self.
config
.reuse_services:
72
self.
_services
[service_name].stop(verbose=self.
config
.verbose)
73
74
def
close(self) -> None:
75
while
self.
_services_start_order
:
76
service_name = self.
_services_start_order
.pop()
77
self.
stop_service
(service_name)
78
self.
_services
.pop(service_name)
79
80
def
_create_service(
81
self,
82
service_name: str,
83
**kwargs,
84
) ->
service.ScriptService
:
85
if
service_name
not
in
self.
_service_factories
:
86
raise
ServiceUnknown
(f
'Unknown service {service_name} requested'
)
87
service_class = self.
_service_factories
[service_name]
88
return
service_class(
89
service_name=service_name,
90
working_dir=self.
_get_working_dir_for
(service_name),
91
env=self.
_env
,
92
**kwargs,
93
)
94
95
def
_get_working_dir_for(self, service_name: str) -> pathlib.Path:
96
working_dir = self.
config
.env_dir.joinpath(
97
'services'
,
98
utils.DOCKERTEST_WORKER,
99
service_name,
100
)
101
if
self.
config
.worker_id !=
'master'
:
102
return
working_dir.joinpath(
'_'
+ self.
config
.worker_id)
103
return
working_dir
104
105
106
class
TestsuiteEnvironment
(
Environment
):
107
def
__init__(self, config: Config) ->
None
:
108
if
config.worker_id == DEFAULT_WORKER_ID:
109
worker_suffix =
'_'
+ config.worker_id
110
else
:
111
worker_suffix =
''
112
super().__init__(
113
config=config,
114
env={
'WORKER_SUFFIX'
: worker_suffix},
115
)
116
117
118
def
load_environment_config(
119
*,
120
env_dir: pathlib.Path |
None
=
None
,
121
worker_id: str = DEFAULT_WORKER_ID,
122
reuse_services: bool =
False
,
123
verbose: int = 0,
124
) -> Config:
125
base_config = _load_config()
126
if
env_dir
is
None
:
127
if
'direcotry'
in
base_config:
128
env_dir = pathlib.Path(base_config[
'direcotry'
])
129
else
:
130
env_dir = pathlib.Path(f
'/tmp/.yasuite-{getpass.getuser()}'
)
131
return
Config
(
132
env_dir=env_dir.expanduser().resolve(),
133
worker_id=worker_id,
134
reuse_services=reuse_services,
135
verbose=verbose,
136
)
137
138
139
def
_load_config():
140
config_path = CONFIG_PATH.expanduser()
141
if
config_path.exists():
142
return
yaml_util.load_file(config_path)
143
return
{}
en
testsuite
environment
control.py
Generated on
for userver by
Doxygen
1.17.0