Skip to content

Commit 824977b

Browse files
testing: fix test_ssh_import_id.py (canonical#954)
test_ssh_import_id.py occassionally fails because cloud-init finishes before the keys have been fully imported. A retry has been added to the test.
1 parent 6e7066e commit 824977b

2 files changed

Lines changed: 36 additions & 0 deletions

File tree

tests/integration_tests/modules/test_ssh_import_id.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
import pytest
1414

15+
from tests.integration_tests.util import retry
1516

1617
USER_DATA = """\
1718
#cloud-config
@@ -26,6 +27,11 @@
2627
class TestSshImportId:
2728

2829
@pytest.mark.user_data(USER_DATA)
30+
# Retry is needed here because ssh import id is one of the last modules
31+
# run, and it fires off a web request, then continues with the rest of
32+
# cloud-init. It is possible cloud-init's status is "done" before the
33+
# id's have been fully imported.
34+
@retry(tries=30, delay=1)
2935
def test_ssh_import_id(self, client):
3036
ssh_output = client.read_from_file(
3137
"/home/ubuntu/.ssh/authorized_keys")

tests/integration_tests/util.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import functools
12
import logging
23
import multiprocessing
34
import os
@@ -64,3 +65,32 @@ def get_test_rsa_keypair(key_name: str = 'test1') -> key_pair:
6465
with private_key_path.open() as private_file:
6566
private_key = private_file.read()
6667
return key_pair(public_key, private_key)
68+
69+
70+
def retry(*, tries: int = 30, delay: int = 1):
71+
"""Decorator for retries.
72+
73+
Retry a function until code no longer raises an exception or
74+
max tries is reached.
75+
76+
Example:
77+
@retry(tries=5, delay=1)
78+
def try_something_that_may_not_be_ready():
79+
...
80+
"""
81+
def _retry(func):
82+
@functools.wraps(func)
83+
def wrapper(*args, **kwargs):
84+
last_error = None
85+
for _ in range(tries):
86+
try:
87+
func(*args, **kwargs)
88+
break
89+
except Exception as e:
90+
last_error = e
91+
time.sleep(delay)
92+
else:
93+
if last_error:
94+
raise last_error
95+
return wrapper
96+
return _retry

0 commit comments

Comments
 (0)