Split the "test key loading" fixture function
Marco Ricci

Marco Ricci commited on 2025-12-27 15:09:33
Zeige 1 geänderte Dateien mit 56 Einfügungen und 50 Löschungen.


Extract the `_prepare_payload` and the `_load_keys_optimistically`
helper functions from the `ssh_agent_client_with_test_keys_loaded`
fixture function.

The `_load_keys_optimistically` helper function needs further
refactoring into a per-key function, not a per-keyset function; to be
added in a following commit.
... ...
@@ -835,54 +835,6 @@ def spawn_ssh_agent(
835 835
         return
836 836
 
837 837
 
838
-@pytest.fixture
839
-def ssh_agent_client_with_test_keys_loaded(  # noqa: C901
840
-    spawn_ssh_agent: data.SpawnedSSHAgentInfo,
841
-) -> Iterator[ssh_agent.SSHAgentClient]:
842
-    """Provide an SSH agent with loaded test keys, as a pytest fixture.
843
-
844
-    Use the `spawn_ssh_agent` fixture to acquire a usable SSH agent,
845
-    upload the known test keys into the agent, and return a connected
846
-    client.
847
-
848
-    The agent may reject several of the test keys due to unsupported or
849
-    obsolete key types.  Rejected keys will be silently ignored, unless
850
-    all keys are rejected; then the test will be skipped.  You must not
851
-    automatically assume any particular key is present in the agent.
852
-
853
-    Yields:
854
-        A [named tuple][collections.namedtuple] containing
855
-        information about the spawned agent, e.g. the software
856
-        product, a client connected to the agent, and whether the
857
-        agent is isolated from other clients.
858
-
859
-    Raises:
860
-        OSError:
861
-            There was a communication or a socket setup error with the
862
-            agent.
863
-        pytest.skip.Exception:
864
-            If the agent is unusable or if it rejected all test keys,
865
-            skip this test.
866
-
867
-    Warning:
868
-        It is the fixture's responsibility to clean up the SSH agent
869
-        client after the test.  Closing the client's socket connection
870
-        beforehand (e.g. by using the client as a context manager) may
871
-        lead to exceptions being thrown upon fixture teardown.
872
-
873
-    """
874
-    agent_type, client, isolated = spawn_ssh_agent
875
-    successfully_loaded_keys: set[str] = set()
876
-
877
-    # This fixture relies on `spawn_ssh_agent`, which in turn uses
878
-    # `spawn_named_agent` to, well, spawn agents.  `spawn_named_agent`
879
-    # runs sanity tests on the agents it spawns, via
880
-    # `SSHAgentClient.list_keys`.  There is thus little point in
881
-    # repeating the very same sanity test here, on an agent that was
882
-    # already sanity-tested.
883
-    #
884
-    # (But see below, too.)
885
-
886 838
 def _prepare_payload(
887 839
         payload: bytes | bytearray,
888 840
         *,
... ...
@@ -901,8 +853,9 @@ def ssh_agent_client_with_test_keys_loaded(  # noqa: C901
901 853
         )
902 854
         return (return_code, bytes(payload) + lifetime_constraint)
903 855
 
904
-    spawned_agent_info = spawn_ssh_agent
905
-    try:
856
+
857
+def _load_keys_optimistically(spawned_agent_info: data.SpawnedSSHAgentInfo) -> set[str]:
858
+        successfully_loaded_keys: set[str] = set()
906 859
         for key_type, key_struct in data.ALL_KEYS.items():
907 860
             agent_type, client, isolated = spawned_agent_info
908 861
             private_key_data = key_struct.private_key_blob
... ...
@@ -961,6 +914,59 @@ def ssh_agent_client_with_test_keys_loaded(  # noqa: C901
961 914
                 pass
962 915
             else:  # pragma: no cover [external]
963 916
                 successfully_loaded_keys.add(key_type)
917
+        return successfully_loaded_keys
918
+
919
+
920
+@pytest.fixture
921
+def ssh_agent_client_with_test_keys_loaded(
922
+    spawn_ssh_agent: data.SpawnedSSHAgentInfo,
923
+) -> Iterator[ssh_agent.SSHAgentClient]:
924
+    """Provide an SSH agent with loaded test keys, as a pytest fixture.
925
+
926
+    Use the `spawn_ssh_agent` fixture to acquire a usable SSH agent,
927
+    upload the known test keys into the agent, and return a connected
928
+    client.
929
+
930
+    The agent may reject several of the test keys due to unsupported or
931
+    obsolete key types.  Rejected keys will be silently ignored, unless
932
+    all keys are rejected; then the test will be skipped.  You must not
933
+    automatically assume any particular key is present in the agent.
934
+
935
+    Yields:
936
+        A [named tuple][collections.namedtuple] containing
937
+        information about the spawned agent, e.g. the software
938
+        product, a client connected to the agent, and whether the
939
+        agent is isolated from other clients.
940
+
941
+    Raises:
942
+        OSError:
943
+            There was a communication or a socket setup error with the
944
+            agent.
945
+        pytest.skip.Exception:
946
+            If the agent is unusable or if it rejected all test keys,
947
+            skip this test.
948
+
949
+    Warning:
950
+        It is the fixture's responsibility to clean up the SSH agent
951
+        client after the test.  Closing the client's socket connection
952
+        beforehand (e.g. by using the client as a context manager) may
953
+        lead to exceptions being thrown upon fixture teardown.
954
+
955
+    """
956
+    agent_type, client, isolated = spawn_ssh_agent
957
+    successfully_loaded_keys: set[str] = set()
958
+
959
+    # This fixture relies on `spawn_ssh_agent`, which in turn uses
960
+    # `spawn_named_agent` to, well, spawn agents.  `spawn_named_agent`
961
+    # runs sanity tests on the agents it spawns, via
962
+    # `SSHAgentClient.list_keys`.  There is thus little point in
963
+    # repeating the very same sanity test here, on an agent that was
964
+    # already sanity-tested.
965
+    #
966
+    # (But see below, too.)
967
+
968
+    try:
969
+        successfully_loaded_keys = _load_keys_optimistically(spawn_ssh_agent)
964 970
         if (
965 971
             agent_type != data.KnownSSHAgent.StubbedSSHAgent
966 972
             and not successfully_loaded_keys
967 973