diff options
-rw-r--r-- | framework/profile.py | 16 | ||||
-rw-r--r-- | framework/programs/print_commands.py | 2 | ||||
-rw-r--r-- | unittests/framework/test_profile.py | 52 |
3 files changed, 69 insertions, 1 deletions
diff --git a/framework/profile.py b/framework/profile.py index 4d111bfe4..a64855ed1 100644 --- a/framework/profile.py +++ b/framework/profile.py @@ -31,6 +31,7 @@ from __future__ import ( ) import collections import contextlib +import copy import importlib import itertools import multiprocessing @@ -398,6 +399,21 @@ class TestProfile(object): def teardown(self): """Method to od post-run teardown.""" + def copy(self): + """Create a copy of the TestProfile. + + This method creates a copy with references to the original instance + (using copy.copy), except for the test_list attribute, which is copied + using copy.deepcopy, which is necessary to ensure that filter_tests + only affects the right instance. This allows profiles to be + "subclassed" by other profiles, without modifying the original. + """ + new = copy.copy(self) + new.test_list = copy.deepcopy(self.test_list) + new.forced_test_list = copy.copy(self.forced_test_list) + new.filters = copy.copy(self.filters) + return new + def load_test_profile(filename): """Load a python module and return it's profile attribute. diff --git a/framework/programs/print_commands.py b/framework/programs/print_commands.py index 033ca870b..6e68eb56d 100644 --- a/framework/programs/print_commands.py +++ b/framework/programs/print_commands.py @@ -95,7 +95,7 @@ def main(input_): profile_ = profile.load_test_profile(args.testProfile) - profile_._prepare_test_list() + profile_.prepare_test_list() for name, test in six.iteritems(profile_.test_list): assert isinstance(test, Test) print(args.format_string.format( diff --git a/unittests/framework/test_profile.py b/unittests/framework/test_profile.py index 66713497b..5ef95e4c3 100644 --- a/unittests/framework/test_profile.py +++ b/unittests/framework/test_profile.py @@ -285,6 +285,58 @@ class TestTestProfile(object): assert grouptools.join('foo', 'abc') in self.profile.test_list + class TestCopy(object): + """Tests for the copy method.""" + + @pytest.fixture + def fixture(self): + orig = profile.TestProfile() + orig.test_list['foo'] = utils.Test(['foo']) + orig.test_list['bar'] = utils.Test(['bar']) + orig.filters = [lambda name, _: name != 'bar'] + orig.forced_test_list = ['foo'] + return orig + + def test_filters(self, fixture): + """The filters attribute is copied correctly.""" + new = fixture.copy() + + # Assert that the fixtures are equivalent, but not the same + assert fixture.filters == new.filters + assert fixture.filters is not new.filters + + # And double check by modifying one of them and asserting that the + # other has not changed. + new.filters.append(lambda name, _: name != 'oink') + assert len(fixture.filters) == 1 + + def test_forced_test_list(self, fixture): + """The forced_test_list attribute is copied correctly.""" + new = fixture.copy() + + # Assert that the fixtures are equivalent, but not the same + assert fixture.forced_test_list == new.forced_test_list + assert fixture.forced_test_list is not new.forced_test_list + + # And double check by modifying one of them and asserting that the + # other has not changed. + del new.forced_test_list[0] + assert fixture.forced_test_list[0] == 'foo' + + def test_test_list(self, fixture): + """The test_list attribute is copied correctly.""" + new = fixture.copy() + + # Assert that the fixtures are equivalent, but not the same + assert fixture.test_list == new.test_list + assert fixture.test_list is not new.test_list + + def test_prepare_test_list(self, fixture): + """The prepare_test_list method doesn't affect both.""" + new = fixture.copy() + new.prepare_test_list() + assert new.test_list != fixture.test_list + class TestTestDict(object): """Tests for the TestDict object.""" |