blob: 9f458270c117efd6a118e324f99adb9d8383cd36 [file] [log] [blame]
from inspect import stack
from os.path import basename
from sys import version_info
from unittest import main as unittest_main, TestCase
from unittest.mock import call
from ittapi_native_mock import patch as ittapi_native_patch
import ittapi
class EventCreationTests(TestCase):
@ittapi_native_patch('Event')
@ittapi_native_patch('StringHandle')
def test_event_creation_with_default_constructor(self, event_mock, string_handle_mock):
string_handle_mock.side_effect = lambda x: x
event = ittapi.event()
caller = stack()[0]
expected_name = f'{basename(caller.filename)}:{caller.lineno-1}'
event_mock.assert_not_called()
event.begin()
event_mock.assert_called_once_with(expected_name)
self.assertEqual(event.name(), expected_name)
@ittapi_native_patch('Event')
@ittapi_native_patch('StringHandle')
def test_event_creation_as_decorator_for_function(self, event_mock, string_handle_mock):
string_handle_mock.side_effect = lambda x: x
@ittapi.event
def my_function():
pass # pragma: no cover
event_mock.assert_called_once_with(my_function.__qualname__)
@ittapi_native_patch('Event')
@ittapi_native_patch('StringHandle')
def test_event_creation_as_decorator_with_empty_arguments_for_function(self, event_mock, string_handle_mock):
string_handle_mock.side_effect = lambda x: x
@ittapi.event()
def my_function():
pass # pragma: no cover
event_mock.assert_called_with(my_function.__qualname__)
@ittapi_native_patch('Event')
@ittapi_native_patch('StringHandle')
def test_event_creation_as_decorator_with_name_for_function(self, event_mock, string_handle_mock):
string_handle_mock.side_effect = lambda x: x
@ittapi.event('my function')
def my_function():
pass # pragma: no cover
event_mock.assert_called_once_with('my function')
@ittapi_native_patch('Event')
@ittapi_native_patch('StringHandle')
def test_event_creation_as_decorator_with_empty_args_and_name_for_function(self, event_mock, string_handle_mock):
string_handle_mock.side_effect = lambda x: x
@ittapi.event
@ittapi.event('my function')
def my_function():
pass # pragma: no cover
expected_calls = [call('my function'),
call(my_function.__qualname__)]
event_mock.assert_has_calls(expected_calls)
@ittapi_native_patch('Event')
@ittapi_native_patch('StringHandle')
def test_event_creation_with_default_constructor_as_context_manager(self, event_mock, string_handle_mock):
string_handle_mock.side_effect = lambda x: x
caller = stack()[0]
with ittapi.event():
pass
event_mock.assert_called_once_with(f'{basename(caller.filename)}:{caller.lineno+1}')
@ittapi_native_patch('Event')
@ittapi_native_patch('StringHandle')
def test_event_creation_with_name_and_domain_as_context_manager(self, event_mock, string_handle_mock):
string_handle_mock.side_effect = lambda x: x
with ittapi.event('my event'):
pass
event_mock.assert_called_once_with('my event')
@ittapi_native_patch('Event')
@ittapi_native_patch('StringHandle')
def test_event_creation_for_callable_object(self, event_mock, string_handle_mock):
string_handle_mock.side_effect = lambda x: x
class CallableClass:
def __call__(self, *args, **kwargs):
pass # pragma: no cover
event = ittapi.event(CallableClass())
expected_name = f'{CallableClass.__name__}.__call__'
event_mock.assert_called_once_with(expected_name)
self.assertEqual(event.name(), expected_name)
@ittapi_native_patch('Event')
@ittapi_native_patch('StringHandle')
def test_unnamed_event_creation_for_callable_object(self, event_mock, string_handle_mock):
string_handle_mock.side_effect = lambda x: x
class CallableClass:
def __call__(self, *args, **kwargs):
pass # pragma: no cover
event = ittapi.event()
event(CallableClass())
expected_name = f'{CallableClass.__name__}.__call__'
event_mock.assert_called_once_with(expected_name)
self.assertEqual(event.name(), expected_name)
@ittapi_native_patch('Event')
@ittapi_native_patch('StringHandle')
def test_event_creation_for_method(self, event_mock, string_handle_mock):
string_handle_mock.side_effect = lambda x: x
class MyClass:
@ittapi.event
def my_method(self):
pass # pragma: no cover
event_mock.assert_called_once_with(f'{MyClass.my_method.__qualname__}')
class EventPropertiesTest(TestCase):
@ittapi_native_patch('Event')
@ittapi_native_patch('StringHandle')
def test_event_properties(self, event_mock, string_handle_mock):
string_handle_mock.side_effect = lambda x: x
class CallableClass:
def __call__(self, *args, **kwargs):
pass # pragma: no cover
event = ittapi.event(CallableClass())
expected_name = f'{CallableClass.__name__}.__call__'
event_mock.assert_called_once_with(expected_name)
self.assertEqual(event.name(), expected_name)
self.assertEqual(str(event), expected_name)
self.assertEqual(repr(event), f'{event.__class__.__name__}(\'{expected_name}\')')
class EventExecutionTests(TestCase):
@ittapi_native_patch('Event')
@ittapi_native_patch('StringHandle')
def test_event_for_function(self, event_mock, string_handle_mock):
string_handle_mock.return_value = 'string_handle'
@ittapi.event
def my_function():
return 42
string_handle_mock.assert_called_once_with(my_function.__qualname__)
event_mock.assert_called_once_with(string_handle_mock.return_value)
self.assertEqual(my_function(), 42)
expected_calls = [call().begin(),
call().end()]
event_mock.assert_has_calls(expected_calls)
@ittapi_native_patch('Event')
@ittapi_native_patch('StringHandle')
def test_nested_events_for_function(self, event_mock, string_handle_mock):
string_handle_mock.side_effect = lambda x: x
@ittapi.event
@ittapi.event('my function')
def my_function():
return 42
expected_calls = [call('my function'),
call(my_function.__qualname__)]
string_handle_mock.assert_has_calls(expected_calls)
event_mock.assert_has_calls(expected_calls)
self.assertEqual(my_function(), 42)
expected_calls = [call().begin(),
call().begin(),
call().end(),
call().end()]
event_mock.assert_has_calls(expected_calls)
@ittapi_native_patch('Event')
@ittapi_native_patch('StringHandle')
def test_event_as_context_manager(self, event_mock, string_handle_mock):
string_handle_mock.side_effect = lambda x: x
region_name = 'my region'
with ittapi.event(region_name):
pass
string_handle_mock.assert_called_once_with(region_name)
event_mock.assert_called_once_with(region_name)
expected_calls = [call().begin(),
call().end()]
event_mock.assert_has_calls(expected_calls)
@ittapi_native_patch('Event')
@ittapi_native_patch('StringHandle')
def test_event_for_callable_object(self, event_mock, string_handle_mock):
string_handle_mock.return_value = 'string_handle'
class CallableClass:
def __call__(self, *args, **kwargs):
return 42
callable_object = ittapi.event(CallableClass())
string_handle_mock.assert_called_once_with(f'{CallableClass.__name__}.__call__')
event_mock.assert_called_once_with(string_handle_mock.return_value)
self.assertEqual(callable_object(), 42)
expected_calls = [call().begin(),
call().end()]
event_mock.assert_has_calls(expected_calls)
def test_event_for_multiple_callable_objects(self):
class CallableClass:
def __call__(self, *args, **kwargs):
pass # pragma: no cover
event = ittapi.event()
event(CallableClass())
with self.assertRaises(RuntimeError) as context:
event(CallableClass())
self.assertEqual(str(context.exception), 'A custom name for a code region must be specified before'
' _NamedRegion.__call__() can be called more than once.')
def test_event_for_noncallable_object(self):
with self.assertRaises(TypeError) as context:
ittapi.event()(42)
self.assertEqual(str(context.exception), 'Callable object is expected as a first argument.')
@ittapi_native_patch('Event')
@ittapi_native_patch('StringHandle')
def test_event_for_method(self, event_mock, string_handle_mock):
string_handle_mock.side_effect = lambda x: x
class MyClass:
@ittapi.event
def my_method(self):
return 42
string_handle_mock.assert_called_once_with(f'{MyClass.my_method.__qualname__}')
event_mock.assert_called_once_with(f'{MyClass.my_method.__qualname__}')
my_object = MyClass()
self.assertEqual(my_object.my_method(), 42)
expected_calls = [call().begin(),
call().end()]
event_mock.assert_has_calls(expected_calls)
@ittapi_native_patch('Event')
@ittapi_native_patch('StringHandle')
def test_event_for_class_method(self, event_mock, string_handle_mock):
string_handle_mock.side_effect = lambda x: x
class MyClass:
@classmethod
@ittapi.event
def my_class_method(cls):
return 42
string_handle_mock.assert_called_once_with(f'{MyClass.my_class_method.__qualname__}')
event_mock.assert_called_once_with(f'{MyClass.my_class_method.__qualname__}')
self.assertEqual(MyClass.my_class_method(), 42)
expected_calls = [call().begin(),
call().end()]
event_mock.assert_has_calls(expected_calls)
@ittapi_native_patch('Event')
@ittapi_native_patch('StringHandle')
def test_event_for_static_method(self, event_mock, string_handle_mock):
string_handle_mock.side_effect = lambda x: x
class MyClass:
@staticmethod
@ittapi.event
def my_static_method():
return 42
string_handle_mock.assert_called_once_with(f'{MyClass.my_static_method.__qualname__}')
event_mock.assert_called_once_with(f'{MyClass.my_static_method.__qualname__}')
self.assertEqual(MyClass.my_static_method(), 42)
self.assertEqual(MyClass().my_static_method(), 42)
expected_calls = [call().begin(),
call().end(),
call().begin(),
call().end()]
event_mock.assert_has_calls(expected_calls)
@ittapi_native_patch('Event')
@ittapi_native_patch('StringHandle')
def test_event_for_static_method_with_wrong_order_of_decorators(self, event_mock, string_handle_mock):
string_handle_mock.side_effect = lambda x: x
class MyClass:
@ittapi.event
@staticmethod
def my_static_method():
return 42 # pragma: no cover
if version_info >= (3, 10):
string_handle_mock.assert_called_once_with(f'{MyClass.my_static_method.__qualname__}')
event_mock.assert_called_once_with(f'{MyClass.my_static_method.__qualname__}')
self.assertEqual(MyClass().my_static_method(), 42)
self.assertEqual(MyClass.my_static_method(), 42)
expected_calls = [call().begin(),
call().end(),
call().begin(),
call().end()]
event_mock.assert_has_calls(expected_calls)
else:
# @staticmethod decorator returns a descriptor which is not callable before Python 3.10
# therefore, it cannot be traced. @staticmethod have to be always above ittapi decorators for Python 3.9 or
# older. otherwise, the exception is thrown.
with self.assertRaises(TypeError) as context:
MyClass().my_static_method()
self.assertEqual(str(context.exception), 'Callable object is expected to be passed.')
def test_event_for_class_method_with_wrong_order_of_decorators(self):
# @classmethod decorator returns a descriptor and the descriptor is not callable object,
# therefore, it cannot be traced. @classmethod have to be always above ittapi decorators,
# otherwise, the exception is thrown.
class MyClass:
@ittapi.event
@classmethod
def my_class_method(cls):
return 42 # pragma: no cover
with self.assertRaises(TypeError) as context:
MyClass().my_class_method()
self.assertEqual(str(context.exception), 'Callable object is expected to be passed.')
with self.assertRaises(TypeError) as context:
MyClass.my_class_method()
self.assertEqual(str(context.exception), 'Callable object is expected to be passed.')
@ittapi_native_patch('Event')
@ittapi_native_patch('StringHandle')
def test_event_for_function_raised_exception(self, event_mock, string_handle_mock):
string_handle_mock.return_value = 'string_handle'
exception_msg = 'ValueError exception from my_function'
@ittapi.event
def my_function():
raise ValueError(exception_msg)
string_handle_mock.assert_called_once_with(my_function.__qualname__)
event_mock.assert_called_once_with(string_handle_mock.return_value)
with self.assertRaises(ValueError) as context:
my_function()
self.assertEqual(str(context.exception), exception_msg)
expected_calls = [call().begin(),
call().end()]
event_mock.assert_has_calls(expected_calls)
@ittapi_native_patch('Event')
@ittapi_native_patch('StringHandle')
def test_event_for_method_raised_exception(self, event_mock, string_handle_mock):
string_handle_mock.side_effect = lambda x: x
exception_msg = 'ValueError exception from my_method'
class MyClass:
@ittapi.event
def my_method(self):
raise ValueError(exception_msg)
string_handle_mock.assert_called_once_with(f'{MyClass.my_method.__qualname__}')
event_mock.assert_called_once_with(f'{MyClass.my_method.__qualname__}')
with self.assertRaises(ValueError) as context:
MyClass().my_method()
self.assertEqual(str(context.exception), exception_msg)
expected_calls = [call().begin(),
call().end()]
event_mock.assert_has_calls(expected_calls)
if __name__ == '__main__':
unittest_main() # pragma: no cover