17
17
from openstack .network .v2 .security_group import SecurityGroup as OpenstackSecurityGroup
18
18
from openstack .network .v2 .security_group_rule import SecurityGroupRule
19
19
20
- from github_runner_manager .errors import OpenStackError
20
+ from github_runner_manager .errors import OpenStackError , SSHError
21
21
from github_runner_manager .openstack_cloud .openstack_cloud import (
22
22
_MIN_KEYPAIR_AGE_IN_SECONDS_BEFORE_DELETION ,
23
+ _TEST_STRING ,
23
24
DEFAULT_SECURITY_RULES ,
24
25
OpenstackCloud ,
25
26
OpenStackCredentials ,
32
33
logger = logging .getLogger (__name__ )
33
34
34
35
36
+ @pytest .fixture (name = "openstack_cloud" , scope = "function" )
37
+ def openstack_cloud_fixture (monkeypatch ):
38
+ # Mock expanduser as this is used in OpenstackCloud constructor
39
+ monkeypatch .setattr (
40
+ "github_runner_manager.openstack_cloud.openstack_cloud.Path.expanduser" , MagicMock ()
41
+ )
42
+ creds = OpenStackCredentials (
43
+ username = FAKE_ARG ,
44
+ password = FAKE_ARG ,
45
+ project_name = FAKE_ARG ,
46
+ user_domain_name = FAKE_ARG ,
47
+ project_domain_name = FAKE_ARG ,
48
+ auth_url = FAKE_ARG ,
49
+ region_name = FAKE_ARG ,
50
+ )
51
+ return OpenstackCloud (creds , FAKE_PREFIX , FAKE_ARG )
52
+
53
+
35
54
@pytest .mark .parametrize (
36
55
"public_method, args" ,
37
56
[
51
70
],
52
71
)
53
72
def test_raises_openstack_error (
54
- public_method : str , args : dict [Any , Any ], monkeypatch : pytest .MonkeyPatch
73
+ openstack_cloud : OpenstackCloud ,
74
+ public_method : str ,
75
+ args : dict [Any , Any ],
76
+ monkeypatch : pytest .MonkeyPatch ,
55
77
):
56
78
"""
57
79
arrange: Mock OpenstackCloud and openstack.connect to raise an Openstack api exception.
58
80
act: Call a public method which connects to Openstack.
59
81
assert: OpenStackError is raised.
60
82
"""
61
- creds = OpenStackCredentials (
62
- username = FAKE_ARG ,
63
- password = FAKE_ARG ,
64
- project_name = FAKE_ARG ,
65
- user_domain_name = FAKE_ARG ,
66
- project_domain_name = FAKE_ARG ,
67
- auth_url = FAKE_ARG ,
68
- region_name = FAKE_ARG ,
69
- )
70
83
# Mock expanduser as this is used in OpenstackCloud constructor
71
84
monkeypatch .setattr (
72
85
"github_runner_manager.openstack_cloud.openstack_cloud.Path.expanduser" , MagicMock ()
73
86
)
74
87
75
- cloud = OpenstackCloud (creds , FAKE_ARG , FAKE_ARG )
76
88
openstack_connect_mock = MagicMock (spec = openstack .connect )
77
89
78
90
excs = (openstack .exceptions .SDKException , keystoneauth1 .exceptions .ClientException )
@@ -83,7 +95,7 @@ def test_raises_openstack_error(
83
95
openstack_connect_mock ,
84
96
)
85
97
with pytest .raises (OpenStackError ) as innerexc :
86
- getattr (cloud , public_method )(** args )
98
+ getattr (openstack_cloud , public_method )(** args )
87
99
assert "Failed OpenStack API call" in str (innerexc .value )
88
100
89
101
@@ -142,7 +154,9 @@ def test_missing_security_rules(security_rules, extra_ports, expected_missing_ru
142
154
assert missing == expected_missing_rules
143
155
144
156
145
- def test_keypair_cleanup_freshly_created_keypairs (monkeypatch : pytest .MonkeyPatch , tmp_path : Path ):
157
+ def test_keypair_cleanup_freshly_created_keypairs (
158
+ openstack_cloud : OpenstackCloud , monkeypatch : pytest .MonkeyPatch , tmp_path : Path
159
+ ):
146
160
"""
147
161
arrange: Keypairs with different creation time.
148
162
act: Call cleanup.
@@ -154,18 +168,8 @@ def test_keypair_cleanup_freshly_created_keypairs(monkeypatch: pytest.MonkeyPatc
154
168
"github_runner_manager.openstack_cloud.openstack_cloud.Path.expanduser" , MagicMock ()
155
169
)
156
170
157
- creds = OpenStackCredentials (
158
- username = FAKE_ARG ,
159
- password = FAKE_ARG ,
160
- project_name = FAKE_ARG ,
161
- user_domain_name = FAKE_ARG ,
162
- project_domain_name = FAKE_ARG ,
163
- auth_url = FAKE_ARG ,
164
- region_name = FAKE_ARG ,
165
- )
166
- cloud = OpenstackCloud (creds , FAKE_PREFIX , FAKE_ARG )
167
- cloud ._ssh_key_dir = tmp_path / "ssh_key_dir"
168
- cloud ._ssh_key_dir .mkdir ()
171
+ openstack_cloud ._ssh_key_dir = tmp_path / "ssh_key_dir"
172
+ openstack_cloud ._ssh_key_dir .mkdir ()
169
173
170
174
openstack_connect_mock = MagicMock (spec = openstack .connect )
171
175
monkeypatch .setattr (
@@ -176,7 +180,7 @@ def test_keypair_cleanup_freshly_created_keypairs(monkeypatch: pytest.MonkeyPatc
176
180
now = _mock_datetime_now (monkeypatch )
177
181
keypairs_older_or_same_min_age = (
178
182
(
179
- cloud ._ssh_key_dir / f"{ FAKE_PREFIX } -old-{ i } .key" ,
183
+ openstack_cloud ._ssh_key_dir / f"{ FAKE_PREFIX } -old-{ i } .key" ,
180
184
now - datetime .timedelta (seconds = seconds ),
181
185
)
182
186
for i , seconds in enumerate (
@@ -189,7 +193,7 @@ def test_keypair_cleanup_freshly_created_keypairs(monkeypatch: pytest.MonkeyPatc
189
193
)
190
194
keypairs_younger_than_min_age = (
191
195
(
192
- cloud ._ssh_key_dir / f"{ FAKE_PREFIX } -new-{ i } .key" ,
196
+ openstack_cloud ._ssh_key_dir / f"{ FAKE_PREFIX } -new-{ i } .key" ,
193
197
now - datetime .timedelta (seconds = seconds ),
194
198
)
195
199
for i , seconds in enumerate ((1 , _MIN_KEYPAIR_AGE_IN_SECONDS_BEFORE_DELETION - 1 ))
@@ -214,7 +218,7 @@ def test_keypair_cleanup_freshly_created_keypairs(monkeypatch: pytest.MonkeyPatc
214
218
openstack_connect_mock .return_value = openstack_connection_mock
215
219
216
220
# act #
217
- cloud .cleanup ()
221
+ openstack_cloud .cleanup ()
218
222
219
223
# assert #
220
224
# Check if only the old keypairs are deleted
@@ -241,3 +245,60 @@ def _mock_datetime_now(monkeypatch):
241
245
"github_runner_manager.openstack_cloud.openstack_cloud.datetime" , datetime_mock
242
246
)
243
247
return now
248
+
249
+
250
+ def test_get_ssh_connection_success (openstack_cloud , monkeypatch ):
251
+ """
252
+ arrange: Setup SSH connection to succeed.
253
+ act: Get SSH connection.
254
+ assert: No SSHError raised. No SSH connection errors.
255
+ """
256
+ mock_result = MagicMock (ok = True , stdout = _TEST_STRING )
257
+ mock_connection = MagicMock (run = MagicMock (return_value = mock_result ))
258
+
259
+ def mock_ssh_connection (* _args , ** _kwargs ) -> MagicMock :
260
+ """Mock get_ssh_connection function.
261
+
262
+ Returns:
263
+ The mocked connection.
264
+ """
265
+ return mock_connection
266
+
267
+ monkeypatch .setattr (
268
+ "github_runner_manager.openstack_cloud.openstack_cloud.SSHConnection" , mock_ssh_connection
269
+ )
270
+
271
+ mock_instance = MagicMock ()
272
+ mock_instance .addresses = ["mock_ip" ]
273
+ with openstack_cloud .get_ssh_connection (mock_instance ) as conn :
274
+ assert conn == mock_connection
275
+
276
+
277
+ def test_get_ssh_connection_failure (openstack_cloud , monkeypatch ):
278
+ """
279
+ arrange: Setup SSH connection to fail.
280
+ act: Get SSH connection.
281
+ assert: Error raised with no connectable SSH address found.
282
+ """
283
+ mock_result = MagicMock (ok = False , stdout = _TEST_STRING )
284
+ mock_connection = MagicMock (run = MagicMock (return_value = mock_result ))
285
+
286
+ def mock_ssh_connection (* _args , ** _kwargs ) -> MagicMock :
287
+ """Mock get_ssh_connection function.
288
+
289
+ Returns:
290
+ The mocked connection.
291
+ """
292
+ return mock_connection
293
+
294
+ monkeypatch .setattr (
295
+ "github_runner_manager.openstack_cloud.openstack_cloud.SSHConnection" , mock_ssh_connection
296
+ )
297
+
298
+ mock_instance = MagicMock ()
299
+ mock_instance .addresses = ["mock_ip" ]
300
+ with pytest .raises (SSHError ) as err :
301
+ with openstack_cloud .get_ssh_connection (mock_instance ):
302
+ pass
303
+
304
+ assert "No connectable SSH addresses found" in str (err .value )
0 commit comments