"""Module for declaring decorators used throughout integration tests."""
import time
from framework.defs import MAX_API_CALL_DURATION_MS
def timed_request(method):
"""Decorate functions to monitor their duration."""
class ApiTimeoutException(Exception):
"""A custom exception containing the details of the failed API call."""
def __init__(self, duration, method, resource, payload):
"""Compose the error message from the API call components."""
super().__init__(
'API call exceeded maximum duration: {:.2f} ms.\n'
'Call: {} {} {}'.format(duration, method, resource, payload)
)
def timed(*args, **kwargs):
"""Raise an exception if method's duration exceeds the max value."""
start = time.time()
result = method(*args, **kwargs)
duration_ms = (time.time() - start) * 1000
if duration_ms > MAX_API_CALL_DURATION_MS:
try:
resource = args[1][(args[1].rfind("/")):]
except IndexError:
resource = ''
payload = kwargs['json'] if 'json' in kwargs else ''
raise ApiTimeoutException(
duration_ms,
method.__name__.upper(),
resource,
payload
)
return result
return timed
def test_context(cap, count=1):
"""Set the image capability and vm count attribute for individual tests."""
def wrap(func):
setattr(func, '_capability', cap)
setattr(func, '_pool_size', count)
return func
return wrap