summaryrefslogtreecommitdiff
path: root/buildscripts/tests
diff options
context:
space:
mode:
authorYves Duhem <yves.duhem@mongodb.com>2017-09-12 12:30:45 -0400
committerYves Duhem <yves.duhem@mongodb.com>2017-09-27 11:11:35 -0400
commit02e1ac97d8453dfbf7b9ac2cb5a5ee3abf3ef45e (patch)
tree882605a76877907551562d7d9f354491c7b507a9 /buildscripts/tests
parent6bc284630b40fd90f6a8f1521d2d8c881e153a23 (diff)
downloadmongo-02e1ac97d8453dfbf7b9ac2cb5a5ee3abf3ef45e.tar.gz
SERVER-30980 Add tag selector expressions support
Diffstat (limited to 'buildscripts/tests')
-rw-r--r--buildscripts/tests/resmokelib/test_selector.py389
1 files changed, 389 insertions, 0 deletions
diff --git a/buildscripts/tests/resmokelib/test_selector.py b/buildscripts/tests/resmokelib/test_selector.py
new file mode 100644
index 00000000000..b8aba13ff87
--- /dev/null
+++ b/buildscripts/tests/resmokelib/test_selector.py
@@ -0,0 +1,389 @@
+
+"""Unit tests for the buildscripts.resmokelib.selector module."""
+
+from __future__ import absolute_import
+
+import fnmatch
+import unittest
+
+import buildscripts.resmokelib.selector as selector
+import buildscripts.resmokelib.utils.globstar as globstar
+import buildscripts.resmokelib.config
+import buildscripts.resmokeconfig
+
+
+class TestExpressions(unittest.TestCase):
+ """Unit tests for the tag matching expressions."""
+
+ def test_match_expression(self):
+ tag = "test_tag"
+ tags_with = ["other_tag", tag]
+ tags_without = ["other_tag", "some_tag"]
+ expression = selector.make_expression(tag)
+ self.assertIsInstance(expression, selector._MatchExpression)
+ self.assertTrue(expression(tags_with))
+ self.assertFalse(expression(tags_without))
+ self.assertFalse(expression([]))
+
+ def test_allof_expression(self):
+ tag1 = "test_tag"
+ tag2 = "other_tag"
+ tags_match = [tag2, tag1, "third_tag"]
+ tags_nomatch = [tag2, "some_tag"]
+ expression = selector.make_expression({
+ "$allOf": [tag1, tag2]})
+ self.assertIsInstance(expression, selector._AllOfExpression)
+ self.assertTrue(expression(tags_match))
+ self.assertFalse(expression(tags_nomatch))
+ self.assertFalse(expression([]))
+
+ def test_anyof_expression(self):
+ tag1 = "test_tag"
+ tag2 = "other_tag"
+ tags_match = [tag1, "third_tag"]
+ tags_nomatch = ["third_tag", "some_tag"]
+ expression = selector.make_expression({
+ "$anyOf": [tag1, tag2]})
+ self.assertIsInstance(expression, selector._AnyOfExpression)
+ self.assertTrue(expression(tags_match))
+ self.assertFalse(expression(tags_nomatch))
+ self.assertFalse(expression([]))
+
+ def test_not_expression(self):
+ tag = "test_tag"
+ tags_match = ["other_tag_1"]
+ tags_nomatch = ["other_tag_1", tag]
+ expression = selector.make_expression({"$not": tag})
+ self.assertIsInstance(expression, selector._NotExpression)
+ self.assertTrue(expression(tags_match))
+ self.assertTrue(expression([]))
+ self.assertFalse(expression(tags_nomatch))
+
+ def test_allof_anyof_expression(self):
+ tag1 = "test_tag_1"
+ tag2 = "test_tag_2"
+ tag3 = "test_tag_3"
+ tags_match_1 = [tag1, tag3]
+ tags_match_2 = [tag2, tag3]
+ tags_nomatch_1 = ["other_tag_1", tag3]
+ tags_nomatch_2 = [tag1, "other_tag_2"]
+ tags_nomatch_3 = [tag2, "other_tag_2"]
+ tags_nomatch_4 = [tag2]
+ tags_nomatch_5 = ["other_tag_2"]
+ expression = selector.make_expression({
+ "$allOf": [
+ {"$anyOf": [tag1, tag2]},
+ tag3,
+ ]})
+ self.assertIsInstance(expression, selector._AllOfExpression)
+ self.assertTrue(expression(tags_match_1))
+ self.assertTrue(expression(tags_match_2))
+ self.assertFalse(expression(tags_nomatch_1))
+ self.assertFalse(expression(tags_nomatch_2))
+ self.assertFalse(expression(tags_nomatch_3))
+ self.assertFalse(expression(tags_nomatch_4))
+ self.assertFalse(expression(tags_nomatch_5))
+ self.assertFalse(expression([]))
+
+ def test_invalid_expression(self):
+ with self.assertRaises(ValueError):
+ selector.make_expression({"invalid": ["tag1", "tag2"]})
+ with self.assertRaises(ValueError):
+ selector.make_expression({"$anyOf": ["tag1", "tag2"],
+ "invalid": "tag3"})
+
+
+class TestTestFileExplorer(unittest.TestCase):
+
+ @classmethod
+ def setUpClass(cls):
+ cls.test_file_explorer = selector.TestFileExplorer()
+
+ def test_is_glob_pattern(self):
+ self.assertTrue(self.test_file_explorer.is_glob_pattern("directory/*file.js"))
+ self.assertFalse(self.test_file_explorer.is_glob_pattern("directory/file.js"))
+
+ def test_fnmatchcase(self):
+ pattern = "dir*/file.js"
+ self.assertTrue(self.test_file_explorer.fnmatchcase("directory/file.js", pattern))
+ self.assertFalse(self.test_file_explorer.fnmatchcase("other/file.js", pattern))
+
+
+class MockTestFileExplorer(object):
+ """Component giving access to mock test files data."""
+ def __init__(self):
+ self.files = ["dir/subdir1/test11.js",
+ "dir/subdir1/test12.js",
+ "dir/subdir2/test21.js",
+ "dir/subdir3/a/test3a1.js"]
+ self.tags = {"dir/subdir1/test11.js": ["tag1", "tag2"],
+ "dir/subdir1/test12.js": ["tag3"],
+ "dir/subdir2/test21.js": ["tag2", "tag4"],
+ "dir/subdir3/a/test3a1.js": ["tag4", "tag5"]}
+ self.binary = "bin/executable"
+ self.jstest_tag_file = {"dir/subdir1/test11.js": "tagA",
+ "dir/subdir3/a/test3a1.js": "tagB"}
+
+ def is_glob_pattern(self, pattern):
+ return globstar.is_glob_pattern(pattern)
+
+ def iglob(self, pattern):
+ globbed = []
+ for test_file in self.files:
+ if fnmatch.fnmatchcase(test_file, pattern):
+ globbed.append(test_file)
+ return globbed
+
+ def jstest_tags(self, file_path):
+ return self.tags.get(file_path, [])
+
+ def read_root_file(self, root_file_path):
+ return ["dir/root/testA.cpp", "dir/root/testB.cpp"]
+
+ def fnmatchcase(self, name, pattern):
+ return fnmatch.fnmatchcase(name, pattern)
+
+ def isfile(self, path):
+ return path == self.binary
+
+ def list_dbtests(self, binary):
+ return ["dbtestA", "dbtestB", "dbtestC"]
+
+ def parse_tag_file(self, test_kind):
+ if test_kind == "js_test":
+ return self.jstest_tag_file
+
+
+class TestTestList(unittest.TestCase):
+
+ @classmethod
+ def setUpClass(cls):
+ cls.test_file_explorer = MockTestFileExplorer()
+ cls.tags_from_file = cls.test_file_explorer.jstest_tag_file
+
+ def test_roots(self):
+ roots = ["a", "b"]
+ test_list = selector._TestList(self.test_file_explorer, roots)
+ self.assertEqual(roots, test_list.get_tests())
+
+ def test_roots_with_glob(self):
+ glob_roots = ["dir/subdir1/*.js"]
+ expected_roots = ["dir/subdir1/test11.js", "dir/subdir1/test12.js"]
+ test_list = selector._TestList(self.test_file_explorer, glob_roots)
+ self.assertEqual(expected_roots, test_list.get_tests())
+
+ def test_include_files(self):
+ roots = ["dir/subdir1/*.js", "dir/subdir2/test21.*"]
+ test_list = selector._TestList(self.test_file_explorer, roots)
+ test_list.include_files(["dir/subdir2/test21.js"])
+ self.assertEqual(["dir/subdir2/test21.js"], test_list.get_tests())
+
+ def test_include_files_no_match(self):
+ roots = ["dir/subdir1/*.js", "dir/subdir2/test21.*"]
+ test_list = selector._TestList(self.test_file_explorer, roots)
+ test_list.include_files(["dir/subdir2/test26.js"])
+ self.assertEqual([], test_list.get_tests())
+
+ def test_exclude_files(self):
+ roots = ["dir/subdir1/*.js", "dir/subdir2/test21.*"]
+ test_list = selector._TestList(self.test_file_explorer, roots)
+ test_list.exclude_files(["dir/subdir2/test21.js"])
+ self.assertEqual(["dir/subdir1/test11.js",
+ "dir/subdir1/test12.js"], test_list.get_tests())
+
+ def test_exclude_files_no_match(self):
+ roots = ["dir/subdir1/*.js", "dir/subdir2/test21.*"]
+ test_list = selector._TestList(self.test_file_explorer, roots)
+ with self.assertRaisesRegexp(ValueError, "Unrecognized test file: .*$"):
+ test_list.exclude_files(["dir/subdir2/test26.js"])
+
+ def test_exclude_files_glob(self):
+ roots = ["dir/subdir1/*.js", "dir/subdir2/test21.*"]
+ test_list = selector._TestList(self.test_file_explorer, roots)
+ test_list.exclude_files(["dir/subdir2/*.js"])
+ self.assertEqual(["dir/subdir1/test11.js",
+ "dir/subdir1/test12.js"], test_list.get_tests())
+
+ def test_match_tag_expression(self):
+ roots = ["dir/subdir1/*.js", "dir/subdir2/test21.*"]
+ test_list = selector._TestList(self.test_file_explorer, roots)
+ expression = selector.make_expression({"$anyOf": [
+ {"$allOf": ["tag1", "tag2"]},
+ "tag3",
+ {"$allOf": ["tag5", "tag6"]}]})
+
+ def get_tags(test_file):
+ return self.test_file_explorer.jstest_tags(test_file)
+
+ test_list.match_tag_expression(expression, get_tags)
+ self.assertEqual(["dir/subdir1/test11.js",
+ "dir/subdir1/test12.js"], test_list.get_tests())
+
+ def test_match_pattern(self):
+ roots = ["dir/subdir1/*.js", "dir/subdir2/test21.*", "dir/subdir3/a/test3a1.js"]
+ test_list = selector._TestList(self.test_file_explorer, roots)
+ test_list.match_pattern("dir/*3/a/*")
+ self.assertEqual(["dir/subdir3/a/test3a1.js"], test_list.get_tests())
+
+ def test_include_tests_no_force(self):
+ roots = ["dir/subdir1/*.js", "dir/subdir2/test21.*"]
+ test_list = selector._TestList(self.test_file_explorer, roots)
+ test_list.exclude_files(["dir/subdir1/test11.js"])
+ test_list.include_files(["dir/subdir1/test11.js"], force=False)
+ self.assertEqual([], test_list.get_tests())
+
+ def test_include_tests_force(self):
+ roots = ["dir/subdir1/*.js", "dir/subdir2/test21.*"]
+ test_list = selector._TestList(self.test_file_explorer, roots)
+ test_list.exclude_files(["dir/subdir1/test11.js"])
+ test_list.include_files(["dir/subdir1/test11.js"], force=True)
+ self.assertEqual(["dir/subdir1/test11.js"], test_list.get_tests())
+
+
+class TestSelectorConfig(unittest.TestCase):
+ def test_root_roots(self):
+ with self.assertRaises(ValueError):
+ selector._SelectorConfig(root="path_to_root", roots=["test1", "test2"])
+
+ def test_include_exclude_tags(self):
+ with self.assertRaises(ValueError):
+ selector._SelectorConfig(include_tags="tag1", exclude_tags="tag2")
+
+
+class TestSelector(unittest.TestCase):
+ @classmethod
+ def setUpClass(cls):
+ cls.selector = selector._Selector(MockTestFileExplorer())
+
+ def test_select_all(self):
+ config = selector._SelectorConfig(roots=["dir/subdir1/*.js", "dir/subdir2/*.js",
+ "dir/subdir3/a/*.js"])
+ selected = self.selector.select(config)
+ self.assertEqual(["dir/subdir1/test11.js",
+ "dir/subdir1/test12.js",
+ "dir/subdir2/test21.js",
+ "dir/subdir3/a/test3a1.js"], selected)
+
+ def test_select_exclude_files(self):
+ config = selector._SelectorConfig(roots=["dir/subdir1/*.js", "dir/subdir2/*.js",
+ "dir/subdir3/a/*.js"],
+ exclude_files=["dir/subdir2/test21.js"])
+ selected = self.selector.select(config)
+ self.assertEqual(["dir/subdir1/test11.js",
+ "dir/subdir1/test12.js",
+ "dir/subdir3/a/test3a1.js"], selected)
+
+ def test_select_include_files(self):
+ config = selector._SelectorConfig(roots=["dir/subdir1/*.js", "dir/subdir2/*.js",
+ "dir/subdir3/a/*.js"],
+ include_files=["dir/subdir2/test21.js"])
+ selected = self.selector.select(config)
+ self.assertEqual(["dir/subdir2/test21.js"], selected)
+
+ def test_select_include_tags(self):
+ config = selector._SelectorConfig(roots=["dir/subdir1/*.js", "dir/subdir2/*.js",
+ "dir/subdir3/a/*.js"],
+ include_tags="tag1")
+ selected = self.selector.select(config)
+ self.assertEqual([], selected)
+
+ def test_select_include_any_tags(self):
+ config = selector._SelectorConfig(roots=["dir/subdir1/*.js", "dir/subdir2/*.js",
+ "dir/subdir3/a/*.js"],
+ include_with_any_tags=["tag1"])
+ selected = self.selector.select(config)
+ self.assertEqual([], selected)
+
+
+class TestFilterTests(unittest.TestCase):
+
+ @classmethod
+ def setUpClass(cls):
+ cls.test_file_explorer = MockTestFileExplorer()
+
+ def test_unknown_test_kind(self):
+ with self.assertRaises(ValueError):
+ selector.filter_tests("unknown_test", {})
+
+ def test_cpp_all(self):
+ config = {"root": "integrationtest.txt"}
+ selected = selector.filter_tests("cpp_integration_test", config, self.test_file_explorer)
+ self.assertEqual(["dir/root/testA.cpp", "dir/root/testB.cpp"], selected)
+
+ def test_cpp_with_any_tags(self):
+ buildscripts.resmokelib.config.INCLUDE_WITH_ANY_TAGS = ["tag1"]
+ try:
+ selector_config = {"root": "unittest.txt"}
+ selected = selector.filter_tests(
+ "cpp_unit_test",
+ selector_config,
+ test_file_explorer=self.test_file_explorer)
+ self.assertEqual([], selected)
+ finally:
+ buildscripts.resmokelib.config.INCLUDE_WITH_ANY_TAGS = None
+
+ def test_jstest_include_tags(self):
+ config = {"roots": ["dir/subdir1/*.js", "dir/subdir2/*.js", "dir/subdir3/a/*.js"],
+ "include_tags": "tag1"}
+ selected = selector.filter_tests("js_test", config, self.test_file_explorer)
+ self.assertEqual(["dir/subdir1/test11.js"], selected)
+
+ def test_jstest_exclude_tags(self):
+ config = {"roots": ["dir/subdir1/*.js", "dir/subdir2/*.js", "dir/subdir3/a/*.js"],
+ "exclude_tags": "tag1"}
+ selected = selector.filter_tests("js_test", config, self.test_file_explorer)
+ self.assertEqual(["dir/subdir1/test12.js",
+ "dir/subdir2/test21.js",
+ "dir/subdir3/a/test3a1.js"], selected)
+
+ def test_jstest_force_include(self):
+ config = {"roots": ["dir/subdir1/*.js", "dir/subdir2/*.js", "dir/subdir3/a/*.js"],
+ "include_files": ["dir/subdir1/*.js"],
+ "exclude_tags": "tag1"}
+ selected = selector.filter_tests("js_test", config, self.test_file_explorer)
+ self.assertEqual(["dir/subdir1/test11.js",
+ "dir/subdir1/test12.js"], selected)
+
+ def test_jstest_all(self):
+ config = {"roots": ["dir/subdir1/*.js", "dir/subdir2/*.js", "dir/subdir3/a/*.js"]}
+ selected = selector.filter_tests("js_test", config, self.test_file_explorer)
+ self.assertEqual(["dir/subdir1/test11.js",
+ "dir/subdir1/test12.js",
+ "dir/subdir2/test21.js",
+ "dir/subdir3/a/test3a1.js"], selected)
+
+ def test_jstest_include_with_any_tags(self):
+ config = {"roots": ["dir/subdir1/*.js", "dir/subdir2/*.js", "dir/subdir3/a/*.js"],
+ "include_with_any_tags": ["tag2"]}
+ selected = selector.filter_tests("js_test", config, self.test_file_explorer)
+ self.assertEqual(["dir/subdir1/test11.js",
+ "dir/subdir2/test21.js"], selected)
+
+ def test_json_schema_exclude_files(self):
+ config = {"roots": ["dir/subdir1/*.js", "dir/subdir2/*.js", "dir/subdir3/a/*.js"],
+ "exclude_files": ["dir/subdir2/test21.js"]}
+ selected = selector.filter_tests("json_schema_test", config, self.test_file_explorer)
+ self.assertEqual(["dir/subdir1/test11.js",
+ "dir/subdir1/test12.js",
+ "dir/subdir3/a/test3a1.js"], selected)
+
+ def test_json_shcema_include_files(self):
+ config = {"roots": ["dir/subdir1/*.js", "dir/subdir2/*.js", "dir/subdir3/a/*.js"],
+ "include_files": ["dir/subdir2/test21.js"]}
+ selected = selector.filter_tests("json_schema_test", config, self.test_file_explorer)
+ self.assertEqual(["dir/subdir2/test21.js"], selected)
+
+ def test_db_tests_all(self):
+ config = {"binary": self.test_file_explorer.binary}
+ selected = selector.filter_tests("db_test", config, self.test_file_explorer)
+ self.assertEqual(["dbtestA", "dbtestB", "dbtestC"], selected)
+
+ def test_db_tests_include_suites(self):
+ config = {"binary": self.test_file_explorer.binary,
+ "include_suites": ["dbtestB"]}
+ selected = selector.filter_tests("db_test", config, self.test_file_explorer)
+ self.assertEqual(["dbtestB"], selected)
+
+
+if __name__ == "__main__":
+ unittest.main()