File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change 1212
1313import pytest
1414
15+ from tests .integration_tests .util import retry
1516
1617USER_DATA = """\
1718 #cloud-config
2627class 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" )
Original file line number Diff line number Diff line change 1+ import functools
12import logging
23import multiprocessing
34import 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
You can’t perform that action at this time.
0 commit comments