Marco Ricci commited on 2024-11-26 14:26:21
Zeige 4 geänderte Dateien mit 33 Einfügungen und 22 Löschungen.
In the current test scenario, where multiple SSH agents are spawned if possible, it is highly unhelpful to know *that* a running SSH agent failed, but not *which* agent did. For debugging purposes, it is better if the `running_ssh_agent` test fixture reports not only the agent's socket, but also its type. It is sufficient to have the type passed as a fixture output/test function input, because `pytest` will then pretty-print it when a test function fails.
... | ... |
@@ -462,6 +462,11 @@ class SpawnedSSHAgentInfo(NamedTuple): |
462 | 462 |
isolated: bool |
463 | 463 |
|
464 | 464 |
|
465 |
+class RunningSSHAgentInfo(NamedTuple): |
|
466 |
+ socket: str |
|
467 |
+ agent_type: KnownSSHAgent |
|
468 |
+ |
|
469 |
+ |
|
465 | 470 |
SUPPORTED_KEYS: Mapping[str, SSHTestKey] = { |
466 | 471 |
'ed25519': { |
467 | 472 |
'private_key': rb"""-----BEGIN OPENSSH PRIVATE KEY----- |
... | ... |
@@ -234,7 +234,7 @@ _spawn_handlers = [ |
234 | 234 |
@pytest.fixture |
235 | 235 |
def running_ssh_agent( # pragma: no cover |
236 | 236 |
skip_if_no_af_unix_support: None, |
237 |
-) -> Iterator[str]: |
|
237 |
+) -> Iterator[tests.RunningSSHAgentInfo]: |
|
238 | 238 |
"""Ensure a running SSH agent, if possible, as a pytest fixture. |
239 | 239 |
|
240 | 240 |
Check for a running SSH agent, or spawn a new one if possible. We |
... | ... |
@@ -245,9 +245,11 @@ def running_ssh_agent( # pragma: no cover |
245 | 245 |
can it guarantee a particular set of loaded keys. |
246 | 246 |
|
247 | 247 |
Yields: |
248 |
- str: |
|
249 |
- The value of the SSH_AUTH_SOCK environment variable, to be |
|
250 |
- used to connect to the running agent. |
|
248 |
+ : |
|
249 |
+ A 2-tuple `(ssh_auth_sock, agent_type)`, where |
|
250 |
+ `ssh_auth_sock` is the value of the `SSH_AUTH_SOCK` |
|
251 |
+ environment variable, to be used to connect to the running |
|
252 |
+ agent, and `agent_type` is the agent type. |
|
251 | 253 |
|
252 | 254 |
Raises: |
253 | 255 |
pytest.skip.Exception: |
... | ... |
@@ -279,7 +281,7 @@ def running_ssh_agent( # pragma: no cover |
279 | 281 |
monkeypatch.setenv('SSH_AUTH_SOCK', startup_ssh_auth_sock) |
280 | 282 |
else: # pragma: no cover |
281 | 283 |
monkeypatch.delenv('SSH_AUTH_SOCK', raising=False) |
282 |
- for exec_name, spawn_func, _ in _spawn_handlers: |
|
284 |
+ for exec_name, spawn_func, agent_type in _spawn_handlers: |
|
283 | 285 |
# Use match/case here once Python 3.9 becomes unsupported. |
284 | 286 |
if exec_name == '(system)': |
285 | 287 |
assert ( |
... | ... |
@@ -291,7 +293,9 @@ def running_ssh_agent( # pragma: no cover |
291 | 293 |
client.list_keys() |
292 | 294 |
except (KeyError, OSError): |
293 | 295 |
continue |
294 |
- yield os.environ['SSH_AUTH_SOCK'] |
|
296 |
+ yield tests.RunningSSHAgentInfo( |
|
297 |
+ os.environ['SSH_AUTH_SOCK'], agent_type |
|
298 |
+ ) |
|
295 | 299 |
assert ( |
296 | 300 |
os.environ.get('SSH_AUTH_SOCK', None) |
297 | 301 |
== startup_ssh_auth_sock |
... | ... |
@@ -342,7 +346,7 @@ def running_ssh_agent( # pragma: no cover |
342 | 346 |
pytest.MonkeyPatch.context() |
343 | 347 |
) |
344 | 348 |
monkeypatch2.setenv('SSH_AUTH_SOCK', ssh_auth_sock) |
345 |
- yield ssh_auth_sock |
|
349 |
+ yield tests.RunningSSHAgentInfo(ssh_auth_sock, agent_type) |
|
346 | 350 |
assert ( |
347 | 351 |
os.environ.get('SSH_AUTH_SOCK', None) |
348 | 352 |
== startup_ssh_auth_sock |
... | ... |
@@ -403,12 +403,12 @@ class TestCLI: |
403 | 403 |
def test_204c_key_override_on_command_line( |
404 | 404 |
self, |
405 | 405 |
monkeypatch: pytest.MonkeyPatch, |
406 |
- running_ssh_agent: str, |
|
406 |
+ running_ssh_agent: tests.RunningSSHAgentInfo, |
|
407 | 407 |
config: dict[str, Any], |
408 | 408 |
key_index: int, |
409 | 409 |
) -> None: |
410 | 410 |
with monkeypatch.context(): |
411 |
- monkeypatch.setenv('SSH_AUTH_SOCK', running_ssh_agent) |
|
411 |
+ monkeypatch.setenv('SSH_AUTH_SOCK', running_ssh_agent.socket) |
|
412 | 412 |
monkeypatch.setattr( |
413 | 413 |
ssh_agent.SSHAgentClient, 'list_keys', tests.list_keys |
414 | 414 |
) |
... | ... |
@@ -433,10 +433,10 @@ class TestCLI: |
433 | 433 |
def test_205_service_phrase_if_key_in_global_config( |
434 | 434 |
self, |
435 | 435 |
monkeypatch: pytest.MonkeyPatch, |
436 |
- running_ssh_agent: str, |
|
436 |
+ running_ssh_agent: tests.RunningSSHAgentInfo, |
|
437 | 437 |
) -> None: |
438 | 438 |
with monkeypatch.context(): |
439 |
- monkeypatch.setenv('SSH_AUTH_SOCK', running_ssh_agent) |
|
439 |
+ monkeypatch.setenv('SSH_AUTH_SOCK', running_ssh_agent.socket) |
|
440 | 440 |
monkeypatch.setattr( |
441 | 441 |
ssh_agent.SSHAgentClient, 'list_keys', tests.list_keys |
442 | 442 |
) |
... | ... |
@@ -491,11 +491,11 @@ class TestCLI: |
491 | 491 |
def test_206_setting_service_phrase_thus_overriding_key_in_config( |
492 | 492 |
self, |
493 | 493 |
monkeypatch: pytest.MonkeyPatch, |
494 |
- running_ssh_agent: str, |
|
494 |
+ running_ssh_agent: tests.RunningSSHAgentInfo, |
|
495 | 495 |
config: _types.VaultConfig, |
496 | 496 |
) -> None: |
497 | 497 |
with monkeypatch.context(): |
498 |
- monkeypatch.setenv('SSH_AUTH_SOCK', running_ssh_agent) |
|
498 |
+ monkeypatch.setenv('SSH_AUTH_SOCK', running_ssh_agent.socket) |
|
499 | 499 |
monkeypatch.setattr( |
500 | 500 |
ssh_agent.SSHAgentClient, 'list_keys', tests.list_keys |
501 | 501 |
) |
... | ... |
@@ -1789,11 +1789,11 @@ Boo. |
1789 | 1789 |
def test_227_get_suitable_ssh_keys( |
1790 | 1790 |
self, |
1791 | 1791 |
monkeypatch: pytest.MonkeyPatch, |
1792 |
- running_ssh_agent: str, |
|
1792 |
+ running_ssh_agent: tests.RunningSSHAgentInfo, |
|
1793 | 1793 |
conn_hint: str, |
1794 | 1794 |
) -> None: |
1795 | 1795 |
with monkeypatch.context(): |
1796 |
- monkeypatch.setenv('SSH_AUTH_SOCK', running_ssh_agent) |
|
1796 |
+ monkeypatch.setenv('SSH_AUTH_SOCK', running_ssh_agent.socket) |
|
1797 | 1797 |
monkeypatch.setattr( |
1798 | 1798 |
ssh_agent.SSHAgentClient, 'list_keys', tests.list_keys |
1799 | 1799 |
) |
... | ... |
@@ -1803,7 +1803,7 @@ Boo. |
1803 | 1803 |
hint = ssh_agent.SSHAgentClient() |
1804 | 1804 |
elif conn_hint == 'socket': |
1805 | 1805 |
hint = socket.socket(family=socket.AF_UNIX) |
1806 |
- hint.connect(running_ssh_agent) |
|
1806 |
+ hint.connect(running_ssh_agent.socket) |
|
1807 | 1807 |
else: |
1808 | 1808 |
assert conn_hint == 'none' |
1809 | 1809 |
hint = None |
... | ... |
@@ -348,10 +348,12 @@ class TestAgentInteraction: |
348 | 348 |
def test_300_constructor_bad_running_agent( |
349 | 349 |
self, |
350 | 350 |
monkeypatch: pytest.MonkeyPatch, |
351 |
- running_ssh_agent: str, |
|
351 |
+ running_ssh_agent: tests.RunningSSHAgentInfo, |
|
352 | 352 |
) -> None: |
353 | 353 |
with monkeypatch.context() as monkeypatch2: |
354 |
- monkeypatch2.setenv('SSH_AUTH_SOCK', running_ssh_agent + '~') |
|
354 |
+ monkeypatch2.setenv( |
|
355 |
+ 'SSH_AUTH_SOCK', running_ssh_agent.socket + '~' |
|
356 |
+ ) |
|
355 | 357 |
sock = socket.socket(family=socket.AF_UNIX) |
356 | 358 |
with pytest.raises(OSError): # noqa: PT011 |
357 | 359 |
ssh_agent.SSHAgentClient(socket=sock) |
... | ... |
@@ -379,7 +381,7 @@ class TestAgentInteraction: |
379 | 381 |
def test_310_truncated_server_response( |
380 | 382 |
self, |
381 | 383 |
monkeypatch: pytest.MonkeyPatch, |
382 |
- running_ssh_agent: str, |
|
384 |
+ running_ssh_agent: tests.RunningSSHAgentInfo, |
|
383 | 385 |
response: bytes, |
384 | 386 |
) -> None: |
385 | 387 |
del running_ssh_agent |
... | ... |
@@ -424,7 +426,7 @@ class TestAgentInteraction: |
424 | 426 |
def test_320_list_keys_error_responses( |
425 | 427 |
self, |
426 | 428 |
monkeypatch: pytest.MonkeyPatch, |
427 |
- running_ssh_agent: str, |
|
429 |
+ running_ssh_agent: tests.RunningSSHAgentInfo, |
|
428 | 430 |
response_code: _types.SSH_AGENT, |
429 | 431 |
response: bytes | bytearray, |
430 | 432 |
exc_type: type[Exception], |
... | ... |
@@ -500,7 +502,7 @@ class TestAgentInteraction: |
500 | 502 |
def test_330_sign_error_responses( |
501 | 503 |
self, |
502 | 504 |
monkeypatch: pytest.MonkeyPatch, |
503 |
- running_ssh_agent: str, |
|
505 |
+ running_ssh_agent: tests.RunningSSHAgentInfo, |
|
504 | 506 |
key: bytes | bytearray, |
505 | 507 |
check: bool, |
506 | 508 |
response_code: _types.SSH_AGENT, |
... | ... |
@@ -567,7 +569,7 @@ class TestAgentInteraction: |
567 | 569 |
) |
568 | 570 |
def test_340_request_error_responses( |
569 | 571 |
self, |
570 |
- running_ssh_agent: str, |
|
572 |
+ running_ssh_agent: tests.RunningSSHAgentInfo, |
|
571 | 573 |
request_code: _types.SSH_AGENTC, |
572 | 574 |
response_code: _types.SSH_AGENT, |
573 | 575 |
exc_type: type[Exception], |
574 | 576 |