55
66from __future__ import annotations
77
8+ import subprocess
89import threading
910from unittest .mock import patch
1011
@@ -50,7 +51,7 @@ def provisioner():
5051 return OsLoginKeyProvisioner ()
5152
5253
53- @patch ("iris.cluster.providers.gcp.ssh.subprocess.run" )
54+ @patch ("iris.cluster.providers.gcp.ssh.subprocess.run" , return_value = subprocess . CompletedProcess ([], 0 ) )
5455@patch ("iris.cluster.providers.gcp.ssh.os.path.exists" , return_value = False )
5556@patch ("iris.cluster.providers.gcp.ssh.os.makedirs" )
5657def test_ensure_key_generates_and_registers (mock_makedirs , mock_exists , mock_run , provisioner ):
@@ -77,7 +78,7 @@ def test_ensure_key_skips_when_valid(mock_exists, mock_run, provisioner):
7778 mock_run .assert_not_called ()
7879
7980
80- @patch ("iris.cluster.providers.gcp.ssh.subprocess.run" )
81+ @patch ("iris.cluster.providers.gcp.ssh.subprocess.run" , return_value = subprocess . CompletedProcess ([], 0 ) )
8182@patch ("iris.cluster.providers.gcp.ssh.os.path.exists" , return_value = True )
8283@patch ("iris.cluster.providers.gcp.ssh.time.monotonic" , return_value = 100000.0 )
8384def test_ensure_key_reregisters_on_expiry (mock_monotonic , mock_exists , mock_run , provisioner ):
@@ -91,7 +92,7 @@ def test_ensure_key_reregisters_on_expiry(mock_monotonic, mock_exists, mock_run,
9192 assert "os-login" in mock_run .call_args .args [0 ]
9293
9394
94- @patch ("iris.cluster.providers.gcp.ssh.subprocess.run" )
95+ @patch ("iris.cluster.providers.gcp.ssh.subprocess.run" , return_value = subprocess . CompletedProcess ([], 0 ) )
9596@patch ("iris.cluster.providers.gcp.ssh.os.path.exists" , return_value = False )
9697@patch ("iris.cluster.providers.gcp.ssh.os.makedirs" )
9798def test_ensure_key_no_impersonate_sa (mock_makedirs , mock_exists , mock_run , provisioner ):
@@ -102,7 +103,7 @@ def test_ensure_key_no_impersonate_sa(mock_makedirs, mock_exists, mock_run, prov
102103 assert not any ("--impersonate-service-account" in arg for arg in cmd )
103104
104105
105- @patch ("iris.cluster.providers.gcp.ssh.subprocess.run" )
106+ @patch ("iris.cluster.providers.gcp.ssh.subprocess.run" , return_value = subprocess . CompletedProcess ([], 0 ) )
106107@patch ("iris.cluster.providers.gcp.ssh.os.path.exists" , return_value = False )
107108@patch ("iris.cluster.providers.gcp.ssh.os.makedirs" )
108109def test_ensure_key_thread_safety (mock_makedirs , mock_exists , mock_run , provisioner ):
@@ -155,6 +156,18 @@ def test_ssh_key_file_os_login_provisions(mock_provisioner):
155156 assert call_args .args [1 ] == "sa@test.iam.gserviceaccount.com"
156157
157158
159+ @patch ("iris.cluster.providers.gcp.ssh._os_login_key_provisioner" )
160+ def test_ssh_key_file_os_login_uses_config_sa_as_fallback (mock_provisioner ):
161+ """When no explicit SA is passed, ssh_key_file falls back to the config's impersonate_service_account."""
162+ cfg = _os_login_config ()
163+ cfg .impersonate_service_account = "sa-from-config@project.iam.gserviceaccount.com"
164+ result = ssh_key_file (cfg )
165+ assert result is not None
166+ mock_provisioner .ensure_key .assert_called_once ()
167+ call_args = mock_provisioner .ensure_key .call_args
168+ assert call_args .args [1 ] == "sa-from-config@project.iam.gserviceaccount.com"
169+
170+
158171@patch ("iris.cluster.providers.gcp.ssh._os_login_key_provisioner" )
159172def test_ssh_key_file_none_config (mock_provisioner ):
160173 result = ssh_key_file (None )
0 commit comments