Skip to content

Commit

Permalink
Merge remote-tracking branch 'clebergnu/safeloader_relative_with_name'
Browse files Browse the repository at this point in the history
Signed-off-by: Cleber Rosa <[email protected]>
  • Loading branch information
clebergnu committed Mar 31, 2021
2 parents 333015a + c22ffbe commit 933c920
Show file tree
Hide file tree
Showing 2 changed files with 145 additions and 7 deletions.
14 changes: 11 additions & 3 deletions avocado/core/safeloader.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,20 +103,28 @@ def is_matching_klass(self, klass):
return True
return False

@staticmethod
def _get_adjusted_path_for_level(statement, path):
level = getattr(statement, 'level', 0)
if level is None:
level = 0
for _ in range(level - 1):
path = os.path.dirname(path)
return path

def add_imported_object(self, statement):
"""
Keeps track of objects names and importable entities
"""
path = os.path.abspath(os.path.dirname(self.path))
if getattr(statement, 'module', None) is not None:
path = self._get_adjusted_path_for_level(statement, path)
module_path = statement.module.replace('.', os.path.sep)
path = os.path.join(path, module_path)
else:
# Module has no name, its path is relative to the directory
# structure
level = getattr(statement, 'level', 0)
for _ in range(level - 1):
path = os.path.dirname(path)
path = self._get_adjusted_path_for_level(statement, path)
for name in statement.names:
full_path = os.path.join(path, name.name.replace('.', os.path.sep))
final_name = self._get_name_from_alias_statement(name)
Expand Down
138 changes: 134 additions & 4 deletions selftests/unit/test_safeloader.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@
import os
import re
import sys
import unittest
import unittest.mock

from avocado.core import safeloader
from avocado.utils import script

from .. import BASEDIR, setup_avocado_loggers
from .. import BASEDIR, TestCaseTmpDir, setup_avocado_loggers

setup_avocado_loggers()

Expand Down Expand Up @@ -102,6 +102,53 @@ def test_child(self):
pass
"""

# The following definitions will be used while creating a directory
# structure that contains a pre-defined set of modules that will be
# used on tests bellow

# A level 0 library containing a base test class
L0_LIB = """
from avocado import Test
class BaseL0(Test):
def test_l0(self):
pass
"""

L1_LIB1 = """
from ..l0lib import BaseL0
class BaseL1(BaseL0):
def test_l1(self):
pass
"""

L1_LIB2 = """
from .. import l0lib
class BaseL1(l0lib.BaseL0):
def test_l1(self):
pass
"""

L2_LIB1 = """
from ...l0lib import BaseL0
class BaseL2(BaseL0):
def test_l2(self):
pass
"""

L2_LIB2 = """
from ... import l0lib
class BaseL2(l0lib.BaseL0):
def test_l2(self):
pass
"""

L2_LIB3 = """
from l0lib import BaseL0
class BaseL2(BaseL0):
def test_l3(self):
pass
"""


def get_this_file():
this_file = __file__
Expand Down Expand Up @@ -355,7 +402,14 @@ def test_self(self):
'test_import_not_on_parent',
'test_recursive_discovery',
'test_recursive_discovery_python_unittest'],
'UnlimitedDiff': ['setUp']
'UnlimitedDiff': ['setUp'],
'MultiLevel': ['setUp',
'test_base_level0',
'test_relative_level0_name_from_level1',
'test_relative_level0_from_level1',
'test_relative_level0_name_from_level2',
'test_relative_level0_from_level2',
'test_non_relative_level0_from_level2'],
}
found = safeloader.find_class_and_methods(get_this_file())
self.assertEqual(reference, found)
Expand Down Expand Up @@ -403,7 +457,13 @@ def test_with_pattern(self):
'test_import_not_on_parent',
'test_recursive_discovery',
'test_recursive_discovery_python_unittest'],
'UnlimitedDiff': []
'UnlimitedDiff': [],
'MultiLevel': ['test_base_level0',
'test_relative_level0_name_from_level1',
'test_relative_level0_from_level1',
'test_relative_level0_name_from_level2',
'test_relative_level0_from_level2',
'test_non_relative_level0_from_level2'],
}
found = safeloader.find_class_and_methods(get_this_file(),
re.compile(r'test.*'))
Expand Down Expand Up @@ -572,5 +632,75 @@ def test_import_relative(self):
self.assertIn('TestCaseTmpDir', module.imported_objects)


class MultiLevel(TestCaseTmpDir):

def setUp(self):
super(MultiLevel, self).setUp()
init = script.Script(os.path.join(self.tmpdir.name, '__init__.py'),
'', mode=script.READ_ONLY_MODE)
init.save()
l0 = script.Script(os.path.join(self.tmpdir.name, 'l0lib.py'),
L0_LIB, mode=script.READ_ONLY_MODE)
l0.save()

l1_dir = os.path.join(self.tmpdir.name, 'l1')
os.mkdir(l1_dir)
l11 = script.Script(os.path.join(l1_dir, 'l1lib1.py'),
L1_LIB1, mode=script.READ_ONLY_MODE)
l11.save()
l12 = script.Script(os.path.join(l1_dir, 'l1lib2.py'),
L1_LIB2, mode=script.READ_ONLY_MODE)
l12.save()

l2_dir = os.path.join(l1_dir, 'l2')
os.mkdir(l2_dir)
l21 = script.Script(os.path.join(l2_dir, 'l2lib1.py'),
L2_LIB1, mode=script.READ_ONLY_MODE)
l21.save()
l22 = script.Script(os.path.join(l2_dir, 'l2lib2.py'),
L2_LIB2, mode=script.READ_ONLY_MODE)
l22.save()
l23 = script.Script(os.path.join(l2_dir, 'l2lib3.py'),
L2_LIB3, mode=script.READ_ONLY_MODE)
l23.save()

def test_base_level0(self):
path = os.path.join(self.tmpdir.name, 'l0lib.py')
self.assertEqual(safeloader.find_avocado_tests(path)[0],
{'BaseL0': [('test_l0', {}, [])]})

def test_relative_level0_name_from_level1(self):
path = os.path.join(self.tmpdir.name, 'l1', 'l1lib1.py')
self.assertEqual(safeloader.find_avocado_tests(path)[0],
{'BaseL1': [('test_l1', {}, []),
('test_l0', {}, [])]})

def test_relative_level0_from_level1(self):
path = os.path.join(self.tmpdir.name, 'l1', 'l1lib2.py')
self.assertEqual(safeloader.find_avocado_tests(path)[0],
{'BaseL1': [('test_l1', {}, []),
('test_l0', {}, [])]})

def test_relative_level0_name_from_level2(self):
path = os.path.join(self.tmpdir.name, 'l1', 'l2', 'l2lib1.py')
self.assertEqual(safeloader.find_avocado_tests(path)[0],
{'BaseL2': [('test_l2', {}, []),
('test_l0', {}, [])]})

def test_relative_level0_from_level2(self):
path = os.path.join(self.tmpdir.name, 'l1', 'l2', 'l2lib2.py')
self.assertEqual(safeloader.find_avocado_tests(path)[0],
{'BaseL2': [('test_l2', {}, []),
('test_l0', {}, [])]})

def test_non_relative_level0_from_level2(self):
path = os.path.join(self.tmpdir.name, 'l1', 'l2', 'l2lib3.py')
sys_path = sys.path + [self.tmpdir.name]
with unittest.mock.patch('sys.path', sys_path):
self.assertEqual(safeloader.find_avocado_tests(path)[0],
{'BaseL2': [('test_l3', {}, []),
('test_l0', {}, [])]})


if __name__ == '__main__':
unittest.main()

0 comments on commit 933c920

Please sign in to comment.