tests/appium: refactor conftest.py to be more readable

Signed-off-by: Jakub Sokołowski <jakub@status.im>
This commit is contained in:
Jakub Sokołowski 2023-11-15 13:42:03 +01:00
parent 7153e4da48
commit 2043e9353b
No known key found for this signature in database
GPG Key ID: FE65CD384D5BF7B4
1 changed files with 69 additions and 59 deletions

View File

@ -161,6 +161,40 @@ def is_uploaded():
return True return True
@contextmanager
def _upload_time_limit(seconds):
def signal_handler(signum, frame):
raise TimeoutError("Apk upload took more than %s seconds" % seconds)
signal.signal(signal.SIGALRM, signal_handler)
signal.alarm(seconds)
try:
yield
finally:
signal.alarm(0)
class UploadApkException(Exception):
pass
def _upload_and_check_response(apk_file_path):
with _upload_time_limit(600):
with open(apk_file_path, 'rb') as f:
resp = sauce.storage._session.request('post', '/v1/storage/upload', files={'payload': f})
try:
if resp['item']['name'] != test_suite_data.apk_name:
raise UploadApkException("Incorrect apk was uploaded to Sauce storage, response:\n%s" % resp)
except KeyError:
raise UploadApkException("Error when uploading apk to Sauce storage, response:\n%s" % resp)
def _upload_and_check_response_with_retries(apk_file_path, retries=3):
for _ in range(retries):
try:
_upload_and_check_response(apk_file_path)
break
except (ConnectionError, RemoteDisconnected):
sleep(10)
def pytest_configure(config): def pytest_configure(config):
global option global option
option = config.option option = config.option
@ -180,75 +214,51 @@ def pytest_configure(config):
apibase = 'eu-central-1.saucelabs.com' apibase = 'eu-central-1.saucelabs.com'
else: else:
raise NotImplementedError("Unknown SauceLabs datacenter") raise NotImplementedError("Unknown SauceLabs datacenter")
global sauce global sauce
sauce = SauceLab('https://api.' + apibase + '/', sauce_username, sauce_access_key) sauce = SauceLab('https://api.' + apibase + '/', sauce_username, sauce_access_key)
if config.getoption('log_steps'): if config.getoption('log_steps'):
import logging import logging
logging.basicConfig(level=logging.INFO) logging.basicConfig(level=logging.INFO)
if config.getoption('env') != 'api': if config.getoption('env') == 'api':
test_suite_data.apk_name = ([i for i in [i for i in config.getoption('apk').split('/') return
if '.apk' in i]])[0]
if is_master(config):
pr_number = config.getoption('pr_number')
if config.getoption('testrail_report'):
if pr_number:
run_number = len(testrail_report.get_runs(pr_number)) + 1
run_name = 'PR-%s run #%s' % (pr_number, run_number)
else:
run_name = test_suite_data.apk_name
testrail_report.add_run(run_name)
if pr_number:
from github import Github
repo = Github(github_token).get_user('status-im').get_repo('status-mobile')
pull = repo.get_pull(int(pr_number))
pull.get_commits()[0].create_status(state='pending', context='Mobile e2e tests',
description='e2e tests are running')
if config.getoption('env') == 'sauce':
if not is_uploaded():
def _upload_and_check_response(apk_file_path):
@contextmanager
def _upload_time_limit(seconds):
def signal_handler(signum, frame):
raise TimeoutError("Apk upload took more than %s seconds" % seconds)
signal.signal(signal.SIGALRM, signal_handler) test_suite_data.apk_name = ([i for i in [i for i in config.getoption('apk').split('/')
signal.alarm(seconds) if '.apk' in i]])[0]
try: if not is_master(config):
yield return
finally:
signal.alarm(0)
with _upload_time_limit(600): pr_number = config.getoption('pr_number')
class UploadApkException(Exception): if config.getoption('testrail_report'):
pass if pr_number:
run_number = len(testrail_report.get_runs(pr_number)) + 1
run_name = 'PR-%s run #%s' % (pr_number, run_number)
else:
run_name = test_suite_data.apk_name
testrail_report.add_run(run_name)
with open(apk_file_path, 'rb') as f: if pr_number:
resp = sauce.storage._session.request('post', '/v1/storage/upload', from github import Github
files={'payload': f}) repo = Github(github_token).get_user('status-im').get_repo('status-mobile')
try: pull = repo.get_pull(int(pr_number))
if resp['item']['name'] != test_suite_data.apk_name: pull.get_commits()[0].create_status(
raise UploadApkException( state='pending',
"Incorrect apk was uploaded to Sauce storage, response:\n%s" % resp) context='Mobile e2e tests',
except KeyError: description='e2e tests are running'
raise UploadApkException( )
"Error when uploading apk to Sauce storage, response:\n%s" % resp)
if 'http' in config.getoption('apk'): if config.getoption('env') == 'sauce' and not is_uploaded():
# it works with just a file_name, but I've added full path because not sure how it'll behave on the remote run (Jenkins) apk_src = config.getoption('apk')
file_path, to_remove = os.path.join(os.path.dirname(__file__), test_suite_data.apk_name), True if apk_src.startsWith('http'):
urllib.request.urlretrieve(config.getoption('apk'), # Absolute path adde to handle CI runs.
filename=file_path) # if url is not valid it raises an error apk_path = os.path.join(os.path.dirname(__file__), test_suite_data.apk_name)
else: urllib.request.urlretrieve(apk_src, filename=apk_path)
file_path, to_remove = config.getoption('apk'), False else:
apk_path = apk_src
for _ in range(3): _upload_and_check_response_with_retries(apk_path)
try: if apk_src.startsWith('http'):
_upload_and_check_response(apk_file_path=file_path) os.remove(apk_path)
break
except (ConnectionError, RemoteDisconnected):
sleep(10)
if to_remove:
os.remove(file_path)
def pytest_unconfigure(config): def pytest_unconfigure(config):