arena-pytest 5.2.0__py3-none-win_amd64.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.
- arena_pytest/__init__.py +178 -0
- arena_pytest/arena.py +195 -0
- arena_pytest/arena_ffi_shared.dll +0 -0
- arena_pytest/closed_arena.py +101 -0
- arena_pytest/dep/__init__.py +0 -0
- arena_pytest/dep/http.py +549 -0
- arena_pytest/dep/kafka.py +73 -0
- arena_pytest/dep/localstack.py +254 -0
- arena_pytest/dep/mssql.py +125 -0
- arena_pytest/dep/postgres.py +112 -0
- arena_pytest/dep/smtp.py +72 -0
- arena_pytest/dep/temporal.py +64 -0
- arena_pytest/exec/__init__.py +0 -0
- arena_pytest/exec/containerized_component.py +100 -0
- arena_pytest/exec/executable_component.py +105 -0
- arena_pytest/ffi/__init__.py +1 -0
- arena_pytest/ffi/_ffi.py +682 -0
- arena_pytest/ffi/_ffi_children.py +7 -0
- arena_pytest/ffi/_ffi_readiness.py +30 -0
- arena_pytest/match/__init__.py +3 -0
- arena_pytest/match/matches.py +112 -0
- arena_pytest/oauth/__init__.py +103 -0
- arena_pytest/playbook/__init__.py +331 -0
- arena_pytest/readiness/__init__.py +16 -0
- arena_pytest/support/__init__.py +0 -0
- arena_pytest/support/_identifier.py +64 -0
- arena_pytest-5.2.0.dist-info/METADATA +817 -0
- arena_pytest-5.2.0.dist-info/RECORD +30 -0
- arena_pytest-5.2.0.dist-info/WHEEL +4 -0
- arena_pytest-5.2.0.dist-info/entry_points.txt +2 -0
arena_pytest/__init__.py
ADDED
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
from arena_pytest.ffi._ffi import (
|
|
2
|
+
ArenaBindingError,
|
|
3
|
+
ArenaLogLevel,
|
|
4
|
+
ArenaNativeLib,
|
|
5
|
+
register_dispatcher_logging_target_for_logger,
|
|
6
|
+
unregister_dispatcher_logging_target,
|
|
7
|
+
)
|
|
8
|
+
from arena_pytest.arena import (
|
|
9
|
+
OpenArena,
|
|
10
|
+
arena,
|
|
11
|
+
arena_ffi,
|
|
12
|
+
closed_arena,
|
|
13
|
+
)
|
|
14
|
+
from arena_pytest.closed_arena import ClosedArena
|
|
15
|
+
from arena_pytest.match import Match, MatchBuilder
|
|
16
|
+
from arena_pytest.exec.containerized_component import (
|
|
17
|
+
ContainerizedComponent,
|
|
18
|
+
ContainerizedComponentBuilder,
|
|
19
|
+
)
|
|
20
|
+
from arena_pytest.exec.executable_component import (
|
|
21
|
+
BuildTool,
|
|
22
|
+
ExecutableComponent,
|
|
23
|
+
ExecutableComponentBuilder,
|
|
24
|
+
)
|
|
25
|
+
from arena_pytest.playbook import (
|
|
26
|
+
ActiveHttpPlaybook,
|
|
27
|
+
ActiveLocalstackPlaybook,
|
|
28
|
+
ActiveMssqlPlaybook,
|
|
29
|
+
ActivePlaybook,
|
|
30
|
+
ManagedPlaybook,
|
|
31
|
+
Playbook,
|
|
32
|
+
UnmanagedPlaybook,
|
|
33
|
+
playbook,
|
|
34
|
+
)
|
|
35
|
+
from arena_pytest.dep.http import (
|
|
36
|
+
ActiveHttpPlaybookBuilder,
|
|
37
|
+
HttpDependency,
|
|
38
|
+
HttpDependencyBuilder,
|
|
39
|
+
HttpHeaderPattern,
|
|
40
|
+
HttpMappingBuilder,
|
|
41
|
+
HttpMappingExpect,
|
|
42
|
+
HttpPlaybookBuilder,
|
|
43
|
+
HttpResponse,
|
|
44
|
+
HttpSequenceBuilder,
|
|
45
|
+
ManagedHttpPlaybook,
|
|
46
|
+
created,
|
|
47
|
+
no_content,
|
|
48
|
+
ok,
|
|
49
|
+
ok_json,
|
|
50
|
+
server_error,
|
|
51
|
+
status,
|
|
52
|
+
)
|
|
53
|
+
from arena_pytest.dep.kafka import (
|
|
54
|
+
KAFKA_INTERNAL_DOCKER_PORT,
|
|
55
|
+
KafkaDependency,
|
|
56
|
+
KafkaDependencyBuilder,
|
|
57
|
+
KafkaFlavor,
|
|
58
|
+
)
|
|
59
|
+
from arena_pytest.dep.localstack import (
|
|
60
|
+
LOCALSTACK_DEFAULT_ACCOUNT_ID,
|
|
61
|
+
LOCALSTACK_DEFAULT_REGION,
|
|
62
|
+
LOCALSTACK_INTERNAL_DOCKER_PORT,
|
|
63
|
+
EventBusSpec,
|
|
64
|
+
EventRuleSpec,
|
|
65
|
+
EventRuleTarget,
|
|
66
|
+
EventTargetKind,
|
|
67
|
+
LambdaSpec,
|
|
68
|
+
LambdaTarget,
|
|
69
|
+
LocalstackDependency,
|
|
70
|
+
LocalstackDependencyBuilder,
|
|
71
|
+
ManagedLocalstackPlaybook,
|
|
72
|
+
QueueSpec,
|
|
73
|
+
SqsQueueTarget,
|
|
74
|
+
)
|
|
75
|
+
from arena_pytest.dep.mssql import (
|
|
76
|
+
ManagedMssqlPlaybook,
|
|
77
|
+
MssqlDependency,
|
|
78
|
+
MssqlDependencyBuilder,
|
|
79
|
+
MssqlEncryption,
|
|
80
|
+
)
|
|
81
|
+
from arena_pytest.oauth import (
|
|
82
|
+
DEFAULT_OAUTH_PORT,
|
|
83
|
+
OAUTH_ISSUER,
|
|
84
|
+
OauthDependency,
|
|
85
|
+
OauthDependencyBuilder,
|
|
86
|
+
oauth_issuer_host_is_non_loopback,
|
|
87
|
+
oauth_loopback_tls_pem_pair,
|
|
88
|
+
)
|
|
89
|
+
from arena_pytest.dep.postgres import (
|
|
90
|
+
ManagedPostgresPlaybook,
|
|
91
|
+
PostgresDependency,
|
|
92
|
+
PostgresDependencyBuilder,
|
|
93
|
+
)
|
|
94
|
+
from arena_pytest.dep.smtp import SmtpDependency, SmtpDependencyBuilder
|
|
95
|
+
from arena_pytest.dep.temporal import TemporalDependency, TemporalDependencyBuilder
|
|
96
|
+
from arena_pytest.readiness import HttpReadinessCheck, ReadinessCheck, TcpReadinessCheck
|
|
97
|
+
|
|
98
|
+
__all__ = [
|
|
99
|
+
"ArenaBindingError",
|
|
100
|
+
"ArenaLogLevel",
|
|
101
|
+
"ArenaNativeLib",
|
|
102
|
+
"ClosedArena",
|
|
103
|
+
"register_dispatcher_logging_target_for_logger",
|
|
104
|
+
"unregister_dispatcher_logging_target",
|
|
105
|
+
"ContainerizedComponent",
|
|
106
|
+
"ContainerizedComponentBuilder",
|
|
107
|
+
"Match",
|
|
108
|
+
"MatchBuilder",
|
|
109
|
+
"BuildTool",
|
|
110
|
+
"ExecutableComponent",
|
|
111
|
+
"ExecutableComponentBuilder",
|
|
112
|
+
"HttpDependency",
|
|
113
|
+
"HttpDependencyBuilder",
|
|
114
|
+
"HttpMappingExpect",
|
|
115
|
+
"HttpHeaderPattern",
|
|
116
|
+
"HttpMappingBuilder",
|
|
117
|
+
"HttpResponse",
|
|
118
|
+
"HttpSequenceBuilder",
|
|
119
|
+
"ActiveHttpPlaybookBuilder",
|
|
120
|
+
"HttpPlaybookBuilder",
|
|
121
|
+
"ok",
|
|
122
|
+
"ok_json",
|
|
123
|
+
"status",
|
|
124
|
+
"server_error",
|
|
125
|
+
"created",
|
|
126
|
+
"no_content",
|
|
127
|
+
"ActiveHttpPlaybook",
|
|
128
|
+
"ActiveLocalstackPlaybook",
|
|
129
|
+
"ActiveMssqlPlaybook",
|
|
130
|
+
"ActivePlaybook",
|
|
131
|
+
"ManagedHttpPlaybook",
|
|
132
|
+
"ManagedMssqlPlaybook",
|
|
133
|
+
"ManagedPlaybook",
|
|
134
|
+
"Playbook",
|
|
135
|
+
"UnmanagedPlaybook",
|
|
136
|
+
"KAFKA_INTERNAL_DOCKER_PORT",
|
|
137
|
+
"KafkaDependency",
|
|
138
|
+
"KafkaDependencyBuilder",
|
|
139
|
+
"KafkaFlavor",
|
|
140
|
+
"LOCALSTACK_DEFAULT_ACCOUNT_ID",
|
|
141
|
+
"LOCALSTACK_DEFAULT_REGION",
|
|
142
|
+
"LOCALSTACK_INTERNAL_DOCKER_PORT",
|
|
143
|
+
"EventBusSpec",
|
|
144
|
+
"EventRuleSpec",
|
|
145
|
+
"EventRuleTarget",
|
|
146
|
+
"EventTargetKind",
|
|
147
|
+
"LambdaSpec",
|
|
148
|
+
"LambdaTarget",
|
|
149
|
+
"LocalstackDependency",
|
|
150
|
+
"LocalstackDependencyBuilder",
|
|
151
|
+
"ManagedLocalstackPlaybook",
|
|
152
|
+
"QueueSpec",
|
|
153
|
+
"SqsQueueTarget",
|
|
154
|
+
"MssqlDependency",
|
|
155
|
+
"MssqlDependencyBuilder",
|
|
156
|
+
"MssqlEncryption",
|
|
157
|
+
"DEFAULT_OAUTH_PORT",
|
|
158
|
+
"OAUTH_ISSUER",
|
|
159
|
+
"OauthDependency",
|
|
160
|
+
"OauthDependencyBuilder",
|
|
161
|
+
"oauth_issuer_host_is_non_loopback",
|
|
162
|
+
"oauth_loopback_tls_pem_pair",
|
|
163
|
+
"ManagedPostgresPlaybook",
|
|
164
|
+
"PostgresDependency",
|
|
165
|
+
"PostgresDependencyBuilder",
|
|
166
|
+
"TemporalDependency",
|
|
167
|
+
"TemporalDependencyBuilder",
|
|
168
|
+
"SmtpDependency",
|
|
169
|
+
"SmtpDependencyBuilder",
|
|
170
|
+
"HttpReadinessCheck",
|
|
171
|
+
"TcpReadinessCheck",
|
|
172
|
+
"ReadinessCheck",
|
|
173
|
+
"arena",
|
|
174
|
+
"arena_ffi",
|
|
175
|
+
"playbook",
|
|
176
|
+
"closed_arena",
|
|
177
|
+
"OpenArena",
|
|
178
|
+
]
|
arena_pytest/arena.py
ADDED
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import asyncio
|
|
4
|
+
from typing import Any, List, Optional, Type
|
|
5
|
+
|
|
6
|
+
import pytest
|
|
7
|
+
import pytest_asyncio
|
|
8
|
+
|
|
9
|
+
from arena_pytest.ffi._ffi import (
|
|
10
|
+
ArenaBindingError,
|
|
11
|
+
ArenaNativeLib,
|
|
12
|
+
close_arena,
|
|
13
|
+
hard_reset as ffi_hard_reset,
|
|
14
|
+
load_ffi,
|
|
15
|
+
soft_reset as ffi_soft_reset,
|
|
16
|
+
)
|
|
17
|
+
from arena_pytest.playbook import (
|
|
18
|
+
PLAYBOOK_MARKER,
|
|
19
|
+
ActivePlaybook,
|
|
20
|
+
Playbook,
|
|
21
|
+
_activate_classes,
|
|
22
|
+
_class_marker_classes,
|
|
23
|
+
_drop_actives,
|
|
24
|
+
_finish_playbook_scope,
|
|
25
|
+
_matches_from_closed_arena,
|
|
26
|
+
_module_marker_classes,
|
|
27
|
+
_own_marker_classes,
|
|
28
|
+
_partition_classes,
|
|
29
|
+
_run_managed_classes,
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
class OpenArena:
|
|
34
|
+
def __init__(
|
|
35
|
+
self,
|
|
36
|
+
ffi: ArenaNativeLib,
|
|
37
|
+
handle: int,
|
|
38
|
+
dispatcher_logging_target_token: int = 0,
|
|
39
|
+
):
|
|
40
|
+
self._ffi = ffi
|
|
41
|
+
self._handle = handle
|
|
42
|
+
self._dispatcher_logging_target_token = dispatcher_logging_target_token
|
|
43
|
+
|
|
44
|
+
def handle(self) -> int:
|
|
45
|
+
return self._handle
|
|
46
|
+
|
|
47
|
+
async def close(self) -> None:
|
|
48
|
+
if self._handle:
|
|
49
|
+
await asyncio.to_thread(
|
|
50
|
+
close_arena,
|
|
51
|
+
self._ffi,
|
|
52
|
+
self._handle,
|
|
53
|
+
dispatcher_logging_target_token=self._dispatcher_logging_target_token,
|
|
54
|
+
)
|
|
55
|
+
self._handle = 0
|
|
56
|
+
self._dispatcher_logging_target_token = 0
|
|
57
|
+
|
|
58
|
+
async def soft_reset(self, dependency_identifier: str) -> None:
|
|
59
|
+
await asyncio.to_thread(
|
|
60
|
+
ffi_soft_reset, self._ffi, self._handle, dependency_identifier
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
async def hard_reset(self, dependency_identifier: str) -> None:
|
|
64
|
+
await asyncio.to_thread(
|
|
65
|
+
ffi_hard_reset, self._ffi, self._handle, dependency_identifier
|
|
66
|
+
)
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
@pytest.fixture(scope="session")
|
|
70
|
+
def arena_ffi() -> ArenaNativeLib:
|
|
71
|
+
ffi = load_ffi()
|
|
72
|
+
if ffi is None:
|
|
73
|
+
pytest.skip(
|
|
74
|
+
"arena shared library not found (set ARENA_FFI_LIB or use Bazel runfiles)"
|
|
75
|
+
)
|
|
76
|
+
return ffi
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
@pytest.fixture(scope="session")
|
|
80
|
+
def closed_arena() -> Optional[Any]:
|
|
81
|
+
return None
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
@pytest_asyncio.fixture(scope="session")
|
|
85
|
+
async def arena(closed_arena) -> OpenArena:
|
|
86
|
+
if closed_arena is None:
|
|
87
|
+
pytest.skip("closed_arena fixture not overridden (no arena to open)")
|
|
88
|
+
try:
|
|
89
|
+
open_arena_obj = await closed_arena.open()
|
|
90
|
+
except ArenaBindingError as e:
|
|
91
|
+
pytest.fail(f"arena_open failed: {e}", pytrace=False)
|
|
92
|
+
yield open_arena_obj
|
|
93
|
+
await open_arena_obj.close()
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
def pytest_configure(config: pytest.Config) -> None:
|
|
97
|
+
config.addinivalue_line(
|
|
98
|
+
"markers",
|
|
99
|
+
f"{PLAYBOOK_MARKER}(klass): open one playbook identified by its Playbook "
|
|
100
|
+
"subclass for the test, class, or module scope; stack multiple "
|
|
101
|
+
"@playbook(...) decorators for more than one.",
|
|
102
|
+
)
|
|
103
|
+
if config.getini("asyncio_mode") in (None, "strict", "STRICT"):
|
|
104
|
+
config._inicache["asyncio_mode"] = "auto"
|
|
105
|
+
if not config.getini("asyncio_default_fixture_loop_scope"):
|
|
106
|
+
config._inicache["asyncio_default_fixture_loop_scope"] = "session"
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
_FUNCTION_ACTIVES_ATTR = "_arena_pytest_function_actives"
|
|
110
|
+
_FUNCTION_MANAGED_ATTR = "_arena_pytest_function_managed_classes"
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
def active_playbooks_for_item(item: pytest.Item) -> List[ActivePlaybook]:
|
|
114
|
+
actives: Optional[List[ActivePlaybook]] = getattr(item, _FUNCTION_ACTIVES_ATTR, None)
|
|
115
|
+
return list(actives) if actives else []
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
def _item_request(item: pytest.Item) -> pytest.FixtureRequest:
|
|
119
|
+
request = getattr(item, "_request", None)
|
|
120
|
+
if request is None:
|
|
121
|
+
raise pytest.UsageError(
|
|
122
|
+
"@pytest.mark.playbook requires a pytest test function with the "
|
|
123
|
+
"'arena' fixture available"
|
|
124
|
+
)
|
|
125
|
+
return request
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
@pytest.hookimpl(trylast=True)
|
|
129
|
+
def pytest_runtest_setup(item: pytest.Item) -> None:
|
|
130
|
+
classes = _own_marker_classes(item)
|
|
131
|
+
if not classes:
|
|
132
|
+
return
|
|
133
|
+
unmanaged_classes, managed_classes = _partition_classes(classes)
|
|
134
|
+
setattr(item, _FUNCTION_MANAGED_ATTR, managed_classes)
|
|
135
|
+
if not unmanaged_classes:
|
|
136
|
+
return
|
|
137
|
+
request = _item_request(item)
|
|
138
|
+
arena_obj = request.getfixturevalue("arena")
|
|
139
|
+
matches = _matches_from_closed_arena(request.getfixturevalue("closed_arena"))
|
|
140
|
+
actives = _activate_classes(arena_obj, matches, unmanaged_classes)
|
|
141
|
+
setattr(item, _FUNCTION_ACTIVES_ATTR, actives)
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
@pytest.hookimpl(tryfirst=True)
|
|
145
|
+
def pytest_runtest_teardown(item: pytest.Item, nextitem: Optional[pytest.Item]) -> None:
|
|
146
|
+
actives: Optional[List[ActivePlaybook]] = getattr(item, _FUNCTION_ACTIVES_ATTR, None)
|
|
147
|
+
if actives:
|
|
148
|
+
setattr(item, _FUNCTION_ACTIVES_ATTR, None)
|
|
149
|
+
_drop_actives(actives)
|
|
150
|
+
|
|
151
|
+
managed_classes: Optional[List[Type[Playbook]]] = getattr(
|
|
152
|
+
item, _FUNCTION_MANAGED_ATTR, None
|
|
153
|
+
)
|
|
154
|
+
if managed_classes:
|
|
155
|
+
setattr(item, _FUNCTION_MANAGED_ATTR, None)
|
|
156
|
+
request = _item_request(item)
|
|
157
|
+
arena_obj = request.getfixturevalue("arena")
|
|
158
|
+
matches = _matches_from_closed_arena(request.getfixturevalue("closed_arena"))
|
|
159
|
+
_run_managed_classes(arena_obj, matches, managed_classes)
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
@pytest.fixture(scope="class", autouse=True)
|
|
163
|
+
def _playbook_class_scope(request: pytest.FixtureRequest):
|
|
164
|
+
cls = getattr(request, "cls", None)
|
|
165
|
+
classes = _class_marker_classes(cls)
|
|
166
|
+
if not classes:
|
|
167
|
+
yield
|
|
168
|
+
return
|
|
169
|
+
unmanaged_classes, managed_classes = _partition_classes(classes)
|
|
170
|
+
arena_obj = request.getfixturevalue("arena")
|
|
171
|
+
closed = request.getfixturevalue("closed_arena")
|
|
172
|
+
matches = _matches_from_closed_arena(closed)
|
|
173
|
+
actives = _activate_classes(arena_obj, matches, unmanaged_classes)
|
|
174
|
+
try:
|
|
175
|
+
yield
|
|
176
|
+
finally:
|
|
177
|
+
_finish_playbook_scope(arena_obj, matches, actives, managed_classes)
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
@pytest.fixture(scope="module", autouse=True)
|
|
181
|
+
def _playbook_module_scope(request: pytest.FixtureRequest):
|
|
182
|
+
module = getattr(request, "module", None)
|
|
183
|
+
classes = _module_marker_classes(module)
|
|
184
|
+
if not classes:
|
|
185
|
+
yield
|
|
186
|
+
return
|
|
187
|
+
unmanaged_classes, managed_classes = _partition_classes(classes)
|
|
188
|
+
arena_obj = request.getfixturevalue("arena")
|
|
189
|
+
closed = request.getfixturevalue("closed_arena")
|
|
190
|
+
matches = _matches_from_closed_arena(closed)
|
|
191
|
+
actives = _activate_classes(arena_obj, matches, unmanaged_classes)
|
|
192
|
+
try:
|
|
193
|
+
yield
|
|
194
|
+
finally:
|
|
195
|
+
_finish_playbook_scope(arena_obj, matches, actives, managed_classes)
|
|
Binary file
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import asyncio
|
|
4
|
+
import json
|
|
5
|
+
import logging
|
|
6
|
+
from typing import List, Optional, Sequence
|
|
7
|
+
|
|
8
|
+
from arena_pytest.arena import OpenArena
|
|
9
|
+
from arena_pytest.ffi._ffi import (
|
|
10
|
+
ArenaBindingError,
|
|
11
|
+
ArenaLogLevel,
|
|
12
|
+
close_arena,
|
|
13
|
+
load_ffi,
|
|
14
|
+
open_arena as ffi_open_arena,
|
|
15
|
+
register_default_dispatcher_logging_target,
|
|
16
|
+
register_dispatcher_logging_target_for_logger,
|
|
17
|
+
set_dispatcher_component_allow_json,
|
|
18
|
+
set_dispatcher_dependency_allow_json,
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def _normalize_optional_id_seq(
|
|
23
|
+
seq: Optional[Sequence[str]],
|
|
24
|
+
) -> tuple[str, ...]:
|
|
25
|
+
if not seq:
|
|
26
|
+
return ()
|
|
27
|
+
return tuple(str(x).strip() for x in seq if str(x).strip())
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class ClosedArena:
|
|
31
|
+
def __init__(
|
|
32
|
+
self,
|
|
33
|
+
name: str,
|
|
34
|
+
matches: List,
|
|
35
|
+
*,
|
|
36
|
+
log_level: ArenaLogLevel = ArenaLogLevel.INFO,
|
|
37
|
+
logger: Optional[logging.Logger] = None,
|
|
38
|
+
log_component_ids: Optional[Sequence[str]] = None,
|
|
39
|
+
log_dependency_ids: Optional[Sequence[str]] = None,
|
|
40
|
+
):
|
|
41
|
+
self.name = name
|
|
42
|
+
self._matches = matches
|
|
43
|
+
self._log_level = log_level
|
|
44
|
+
self._logger = logger
|
|
45
|
+
self._log_dependency_ids = _normalize_optional_id_seq(log_dependency_ids)
|
|
46
|
+
self._log_component_ids = _normalize_optional_id_seq(log_component_ids)
|
|
47
|
+
|
|
48
|
+
def _config(self) -> str:
|
|
49
|
+
if not self._matches:
|
|
50
|
+
return "{}"
|
|
51
|
+
a_match = self._matches[0]
|
|
52
|
+
config = a_match._for_ffi() if hasattr(a_match, "_for_ffi") else a_match
|
|
53
|
+
return json.dumps(config)
|
|
54
|
+
|
|
55
|
+
async def open(self) -> OpenArena:
|
|
56
|
+
ffi = load_ffi()
|
|
57
|
+
if ffi is None:
|
|
58
|
+
raise ArenaBindingError(
|
|
59
|
+
"arena shared library not found (set ARENA_FFI_LIB or use Bazel runfiles)"
|
|
60
|
+
)
|
|
61
|
+
config = self._config()
|
|
62
|
+
dep_json = (
|
|
63
|
+
json.dumps(list(self._log_dependency_ids))
|
|
64
|
+
if self._log_dependency_ids
|
|
65
|
+
else None
|
|
66
|
+
)
|
|
67
|
+
comp_json = (
|
|
68
|
+
json.dumps(list(self._log_component_ids))
|
|
69
|
+
if self._log_component_ids
|
|
70
|
+
else None
|
|
71
|
+
)
|
|
72
|
+
await asyncio.to_thread(set_dispatcher_dependency_allow_json, ffi, dep_json)
|
|
73
|
+
await asyncio.to_thread(set_dispatcher_component_allow_json, ffi, comp_json)
|
|
74
|
+
if self._logger is not None:
|
|
75
|
+
log_tok = await asyncio.to_thread(
|
|
76
|
+
register_dispatcher_logging_target_for_logger,
|
|
77
|
+
ffi,
|
|
78
|
+
self._logger,
|
|
79
|
+
arena_log_level=self._log_level,
|
|
80
|
+
)
|
|
81
|
+
else:
|
|
82
|
+
log_tok = await asyncio.to_thread(
|
|
83
|
+
register_default_dispatcher_logging_target,
|
|
84
|
+
ffi,
|
|
85
|
+
arena_log_level=self._log_level,
|
|
86
|
+
)
|
|
87
|
+
try:
|
|
88
|
+
handle = await asyncio.to_thread(
|
|
89
|
+
ffi_open_arena,
|
|
90
|
+
ffi,
|
|
91
|
+
self.name.encode("utf-8"),
|
|
92
|
+
config,
|
|
93
|
+
log_level=self._log_level,
|
|
94
|
+
)
|
|
95
|
+
except ArenaBindingError as e:
|
|
96
|
+
await asyncio.to_thread(
|
|
97
|
+
close_arena, ffi, 0, dispatcher_logging_target_token=log_tok
|
|
98
|
+
)
|
|
99
|
+
raise ArenaBindingError(f"arena_open failed: {e}") from e
|
|
100
|
+
|
|
101
|
+
return OpenArena(ffi, handle, log_tok)
|
|
File without changes
|