summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--framework/profile.py16
-rw-r--r--framework/programs/print_commands.py2
-rw-r--r--unittests/framework/test_profile.py52
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."""