Bug 1380338 - Convert taskgraph unit tests to the |mach python-test| framework, r=dustin
☠☠ backed out by c272abf614a3 ☠ ☠
authorAndrew Halberstadt <ahalberstadt@mozilla.com>
Wed, 12 Jul 2017 10:47:14 -0400
changeset 419612 54e4545b0fe03e103b464011738f60caa5f621a6
parent 419611 03be1f2d0e456231d802721b1403e5c7459f9b3c
child 419613 07faa05d6e824fd0d6cd9643358a8e8db3c26812
push id1517
push userjlorenzo@mozilla.com
push dateThu, 14 Sep 2017 16:50:54 +0000
treeherdermozilla-release@3b41fd564418 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdustin
bugs1380338
milestone56.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1380338 - Convert taskgraph unit tests to the |mach python-test| framework, r=dustin These tests can now be run with: ./mach python-test taskcluster/taskgraph or: ./mach python-test taskcluster They can now run in parallel by passing in -j. MozReview-Commit-ID: JXeZV8B04Sf
taskcluster/ci/source-test/python-tests.yml
taskcluster/mach_commands.py
taskcluster/moz.build
taskcluster/taskgraph/test/python.ini
taskcluster/taskgraph/test/test_create.py
taskcluster/taskgraph/test/test_decision.py
taskcluster/taskgraph/test/test_files_changed.py
taskcluster/taskgraph/test/test_graph.py
taskcluster/taskgraph/test/test_morph.py
taskcluster/taskgraph/test/test_optimize.py
taskcluster/taskgraph/test/test_parameters.py
taskcluster/taskgraph/test/test_target_tasks.py
taskcluster/taskgraph/test/test_taskgraph.py
taskcluster/taskgraph/test/test_try_option_syntax.py
taskcluster/taskgraph/test/test_util_attributes.py
taskcluster/taskgraph/test/test_util_docker.py
taskcluster/taskgraph/test/test_util_python_path.py
taskcluster/taskgraph/test/test_util_treeherder.py
taskcluster/taskgraph/test/test_util_yaml.py
--- a/taskcluster/ci/source-test/python-tests.yml
+++ b/taskcluster/ci/source-test/python-tests.yml
@@ -6,17 +6,17 @@ taskgraph-tests:
         kind: test
         tier: 2
     worker-type: aws-provisioner-v1/gecko-t-linux-xlarge
     worker:
         docker-image: {in-tree: "lint"}
         max-run-time: 1800
     run:
         using: mach
-        mach: taskgraph python-tests
+        mach: python-test --subsuite taskgraph
     when:
         files-changed:
             - 'taskcluster/**/*.py'
             - 'config/mozunit.py'
             - 'python/mach/**/*.py'
 
 marionette-harness:
     description: testing/marionette/harness unit tests
--- a/taskcluster/mach_commands.py
+++ b/taskcluster/mach_commands.py
@@ -65,27 +65,16 @@ class MachCommands(MachCommandBase):
              description="Manipulate TaskCluster task graphs defined in-tree")
     def taskgraph(self):
         """The taskgraph subcommands all relate to the generation of task graphs
         for Gecko continuous integration.  A task graph is a set of tasks linked
         by dependencies: for example, a binary must be built before it is tested,
         and that build may further depend on various toolchains, libraries, etc.
         """
 
-    @SubCommand('taskgraph', 'python-tests',
-                description='Run the taskgraph unit tests')
-    def taskgraph_python_tests(self, **options):
-        import unittest
-        import mozunit
-        suite = unittest.defaultTestLoader.discover('taskgraph.test')
-        runner = mozunit.MozTestRunner(verbosity=2)
-        result = runner.run(suite)
-        if not result.wasSuccessful():
-            sys.exit(1)
-
     @ShowTaskGraphSubCommand('taskgraph', 'tasks',
                              description="Show all tasks in the taskgraph")
     def taskgraph_tasks(self, **options):
         return self.show_taskgraph('full_task_set', options)
 
     @ShowTaskGraphSubCommand('taskgraph', 'full',
                              description="Show the full taskgraph")
     def taskgraph_full(self, **options):
--- a/taskcluster/moz.build
+++ b/taskcluster/moz.build
@@ -21,9 +21,12 @@ with Files('docs/**'):
 
 #NOTE: scripts/* files included in docker images
 with Files('scripts/**'):
     BUG_COMPONENT = ('Taskcluster', 'Docker Images')
 
 with Files('taskgraph/**'):
     BUG_COMPONENT = ('Taskcluster', 'Task Configuration')
 
+PYTHON_UNITTEST_MANIFESTS += [
+    'taskgraph/test/python.ini',
+]
 SPHINX_TREES['taskcluster'] = 'docs'
new file mode 100644
--- /dev/null
+++ b/taskcluster/taskgraph/test/python.ini
@@ -0,0 +1,24 @@
+[DEFAULT]
+subsuite = taskgraph
+
+[test_create.py]
+[test_cron_util.py]
+[test_decision.py]
+[test_files_changed.py]
+[test_generator.py]
+[test_graph.py]
+[test_morph.py]
+[test_optimize.py]
+[test_parameters.py]
+[test_target_tasks.py]
+[test_taskgraph.py]
+[test_transforms_base.py]
+[test_try_option_syntax.py]
+[test_util_attributes.py]
+[test_util_docker.py]
+[test_util_python_path.py]
+[test_util_schema.py]
+[test_util_templates.py]
+[test_util_time.py]
+[test_util_treeherder.py]
+[test_util_yaml.py]
--- a/taskcluster/taskgraph/test/test_create.py
+++ b/taskcluster/taskgraph/test/test_create.py
@@ -2,20 +2,20 @@
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 from __future__ import absolute_import, print_function, unicode_literals
 
 import unittest
 import os
 
-from .. import create
-from ..graph import Graph
-from ..taskgraph import TaskGraph
-from ..task import Task
+from taskgraph import create
+from taskgraph.graph import Graph
+from taskgraph.taskgraph import TaskGraph
+from taskgraph.task import Task
 
 from mozunit import main
 
 
 class TestCreate(unittest.TestCase):
 
     def setUp(self):
         self.old_task_id = os.environ.get('TASK_ID')
--- a/taskcluster/taskgraph/test/test_decision.py
+++ b/taskcluster/taskgraph/test/test_decision.py
@@ -6,17 +6,17 @@ from __future__ import absolute_import, 
 
 import os
 import json
 import yaml
 import shutil
 import unittest
 import tempfile
 
-from .. import decision
+from taskgraph import decision
 from mozunit import main
 
 
 class TestDecision(unittest.TestCase):
 
     def test_write_artifact_json(self):
         data = [{'some': 'data'}]
         tmpdir = tempfile.mkdtemp()
--- a/taskcluster/taskgraph/test/test_files_changed.py
+++ b/taskcluster/taskgraph/test/test_files_changed.py
@@ -3,17 +3,18 @@
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 from __future__ import absolute_import, print_function, unicode_literals
 
 import json
 import os
 import unittest
 
-from .. import files_changed
+from taskgraph import files_changed
+from mozunit import main
 
 PARAMS = {
     'head_repository': 'https://hg.mozilla.org/mozilla-central',
     'head_rev': 'a14f88a9af7a',
 }
 
 FILES_CHANGED = [
     'devtools/client/debugger/new/index.html',
@@ -66,8 +67,12 @@ class TestCheck(unittest.TestCase):
     def test_check_no_params(self):
         self.assertTrue(files_changed.check({}, ["ignored"]))
 
     def test_check_no_match(self):
         self.assertFalse(files_changed.check(PARAMS, ["nosuch/**"]))
 
     def test_check_match(self):
         self.assertTrue(files_changed.check(PARAMS, ["devtools/**"]))
+
+
+if __name__ == '__main__':
+    main()
--- a/taskcluster/taskgraph/test/test_graph.py
+++ b/taskcluster/taskgraph/test/test_graph.py
@@ -3,17 +3,17 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 from __future__ import absolute_import, print_function, unicode_literals
 
 import unittest
 
-from ..graph import Graph
+from taskgraph.graph import Graph
 from mozunit import main
 
 
 class TestGraph(unittest.TestCase):
 
     tree = Graph(set(['a', 'b', 'c', 'd', 'e', 'f', 'g']), {
         ('a', 'b', 'L'),
         ('a', 'c', 'L'),
--- a/taskcluster/taskgraph/test/test_morph.py
+++ b/taskcluster/taskgraph/test/test_morph.py
@@ -1,20 +1,20 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 from __future__ import absolute_import, print_function, unicode_literals
 
 import unittest
 
-from .. import morph
-from ..graph import Graph
-from ..taskgraph import TaskGraph
-from ..task import Task
+from taskgraph import morph
+from taskgraph.graph import Graph
+from taskgraph.taskgraph import TaskGraph
+from taskgraph.task import Task
 
 from mozunit import main
 
 
 class TestIndexTask(unittest.TestCase):
 
     def test_make_index_tasks(self):
         task_def = {
--- a/taskcluster/taskgraph/test/test_optimize.py
+++ b/taskcluster/taskgraph/test/test_optimize.py
@@ -1,21 +1,22 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 from __future__ import absolute_import, print_function, unicode_literals
 
 import unittest
 
-from ..optimize import optimize_task_graph, resolve_task_references, optimization
-from ..optimize import annotate_task_graph, get_subgraph
-from ..taskgraph import TaskGraph
-from .. import graph
-from ..task import Task
+from taskgraph.optimize import optimize_task_graph, resolve_task_references, optimization
+from taskgraph.optimize import annotate_task_graph, get_subgraph
+from taskgraph.taskgraph import TaskGraph
+from taskgraph import graph
+from taskgraph.task import Task
+from mozunit import main
 
 
 class TestResolveTaskReferences(unittest.TestCase):
 
     def do(self, input, output):
         taskid_for_edge_name = {'edge%d' % n: 'tid%d' % n for n in range(1, 4)}
         self.assertEqual(resolve_task_references('subject', input, taskid_for_edge_name), output)
 
@@ -237,8 +238,12 @@ class TestOptimize(unittest.TestCase):
             self.make_task('task3', ['no-optimize']),
             ('task2', 'task1', 'build'),
             ('task2', 'task3', 'image'),
         )
         opt, label_to_taskid = optimize_task_graph(input, {}, set())
         self.assertEqual(opt.graph, graph.Graph(
             {label_to_taskid['task2'], label_to_taskid['task3']},
             {(label_to_taskid['task2'], label_to_taskid['task3'], 'image')}))
+
+
+if __name__ == '__main__':
+    main()
--- a/taskcluster/taskgraph/test/test_parameters.py
+++ b/taskcluster/taskgraph/test/test_parameters.py
@@ -1,17 +1,17 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 from __future__ import absolute_import, print_function, unicode_literals
 
 import unittest
 
-from ..parameters import Parameters, load_parameters_file, PARAMETER_NAMES
+from taskgraph.parameters import Parameters, load_parameters_file, PARAMETER_NAMES
 from mozunit import main, MockedOpen
 
 
 class TestParameters(unittest.TestCase):
 
     vals = {n: n for n in PARAMETER_NAMES}
 
     def test_Parameters_immutable(self):
--- a/taskcluster/taskgraph/test/test_target_tasks.py
+++ b/taskcluster/taskgraph/test/test_target_tasks.py
@@ -1,21 +1,21 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 from __future__ import absolute_import, print_function, unicode_literals
 
 import unittest
 
-from .. import target_tasks
-from .. import try_option_syntax
-from ..graph import Graph
-from ..taskgraph import TaskGraph
-from ..task import Task
+from taskgraph import target_tasks
+from taskgraph import try_option_syntax
+from taskgraph.graph import Graph
+from taskgraph.taskgraph import TaskGraph
+from taskgraph.task import Task
 from mozunit import main
 
 
 class FakeTryOptionSyntax(object):
 
     def __init__(self, message, task_graph):
         self.trigger_tests = 0
         self.talos_trigger_tests = 0
--- a/taskcluster/taskgraph/test/test_taskgraph.py
+++ b/taskcluster/taskgraph/test/test_taskgraph.py
@@ -1,19 +1,19 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 from __future__ import absolute_import, print_function, unicode_literals
 
 import unittest
 
-from ..graph import Graph
-from ..task import Task
-from ..taskgraph import TaskGraph
+from taskgraph.graph import Graph
+from taskgraph.task import Task
+from taskgraph.taskgraph import TaskGraph
 from mozunit import main
 
 
 class TestTaskGraph(unittest.TestCase):
 
     maxDiff = None
 
     def test_taskgraph_to_json(self):
--- a/taskcluster/taskgraph/test/test_try_option_syntax.py
+++ b/taskcluster/taskgraph/test/test_try_option_syntax.py
@@ -1,21 +1,21 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 from __future__ import absolute_import, print_function, unicode_literals
 
 import unittest
 
-from ..try_option_syntax import TryOptionSyntax
-from ..try_option_syntax import RIDEALONG_BUILDS
-from ..graph import Graph
-from ..taskgraph import TaskGraph
-from ..task import Task
+from taskgraph.try_option_syntax import TryOptionSyntax
+from taskgraph.try_option_syntax import RIDEALONG_BUILDS
+from taskgraph.graph import Graph
+from taskgraph.taskgraph import TaskGraph
+from taskgraph.task import Task
 from mozunit import main
 
 
 def unittest_task(n, tp, bt='opt'):
     return (n, Task('test', n, {
         'unittest_try_name': n,
         'test_platform': tp.split('/')[0],
         'build_type': bt,
--- a/taskcluster/taskgraph/test/test_util_attributes.py
+++ b/taskcluster/taskgraph/test/test_util_attributes.py
@@ -4,16 +4,17 @@
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 import unittest
 from taskgraph.util.attributes import (
     attrmatch,
     match_run_on_projects,
 )
+from mozunit import main
 
 
 class Attrmatch(unittest.TestCase):
 
     def test_trivial_match(self):
         """Given no conditions, anything matches"""
         self.assertTrue(attrmatch({}))
 
@@ -84,8 +85,12 @@ class MatchRunOnProjects(unittest.TestCa
         self.assertTrue(match_run_on_projects('try', ['release', 'try', 'date']))
         self.assertFalse(match_run_on_projects('larch', ['release', 'try', 'date']))
         self.assertTrue(match_run_on_projects('date', ['release', 'try', 'date']))
         self.assertFalse(match_run_on_projects('autoland', ['release', 'try', 'date']))
         self.assertFalse(match_run_on_projects('mozilla-inbound', ['release', 'try', 'date']))
         self.assertTrue(match_run_on_projects('mozilla-central', ['release', 'try', 'date']))
         self.assertTrue(match_run_on_projects('mozilla-beta', ['release', 'try', 'date']))
         self.assertTrue(match_run_on_projects('mozilla-release', ['release', 'try', 'date']))
+
+
+if __name__ == '__main__':
+    main()
--- a/taskcluster/taskgraph/test/test_util_docker.py
+++ b/taskcluster/taskgraph/test/test_util_docker.py
@@ -6,18 +6,18 @@ from __future__ import absolute_import, 
 
 import os
 import shutil
 import stat
 import tarfile
 import tempfile
 import unittest
 
-from ..util import docker
-from mozunit import MockedOpen
+from taskgraph.util import docker
+from mozunit import main, MockedOpen
 
 
 MODE_STANDARD = stat.S_IRUSR | stat.S_IWUSR | stat.S_IRGRP | stat.S_IROTH
 
 
 class TestDocker(unittest.TestCase):
 
     def test_generate_context_hash(self):
@@ -205,8 +205,12 @@ class TestDocker(unittest.TestCase):
                     'my_image/Dockerfile',
                     'my_image/topsrcdir/extra/file0',
                     'my_image/topsrcdir/extra/file1',
                     'my_image/topsrcdir/extra/file2',
                     'my_image/topsrcdir/file0',
                 ])
         finally:
             shutil.rmtree(tmp)
+
+
+if __name__ == '__main__':
+    main()
--- a/taskcluster/taskgraph/test/test_util_python_path.py
+++ b/taskcluster/taskgraph/test/test_util_python_path.py
@@ -1,16 +1,17 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 from __future__ import absolute_import, print_function, unicode_literals
 
 import unittest
-from ..util import python_path
+from taskgraph.util import python_path
+from mozunit import main
 
 
 class TestObject(object):
 
     testClassProperty = object()
 
 
 class TestPythonPath(unittest.TestCase):
@@ -21,11 +22,16 @@ class TestPythonPath(unittest.TestCase):
 
     def test_find_object_no_such_object(self):
         """find_object raises AttributeError for a nonexistent object"""
         self.assertRaises(AttributeError, python_path.find_object,
                           "taskgraph.test.test_util_python_path:NoSuchObject")
 
     def test_find_object_exists(self):
         """find_object finds an existing object"""
+        from taskgraph.test.test_util_python_path import TestObject
         obj = python_path.find_object(
             "taskgraph.test.test_util_python_path:TestObject.testClassProperty")
         self.assertIs(obj, TestObject.testClassProperty)
+
+
+if __name__ == '__main__':
+    main()
--- a/taskcluster/taskgraph/test/test_util_treeherder.py
+++ b/taskcluster/taskgraph/test/test_util_treeherder.py
@@ -1,23 +1,28 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 from __future__ import absolute_import, print_function, unicode_literals
 
 import unittest
 from taskgraph.util.treeherder import split_symbol, join_symbol
+from mozunit import main
 
 
 class TestSymbols(unittest.TestCase):
 
     def test_split_no_group(self):
         self.assertEqual(split_symbol('xy'), ('?', 'xy'))
 
     def test_split_with_group(self):
         self.assertEqual(split_symbol('ab(xy)'), ('ab', 'xy'))
 
     def test_join_no_group(self):
         self.assertEqual(join_symbol('?', 'xy'), 'xy')
 
     def test_join_with_group(self):
         self.assertEqual(join_symbol('ab', 'xy'), 'ab(xy)')
+
+
+if __name__ == '__main__':
+    main()
--- a/taskcluster/taskgraph/test/test_util_yaml.py
+++ b/taskcluster/taskgraph/test/test_util_yaml.py
@@ -1,23 +1,27 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 from __future__ import absolute_import, print_function, unicode_literals
 
 import unittest
 
-from ..util import yaml
-from mozunit import MockedOpen
+from taskgraph.util import yaml
+from mozunit import main, MockedOpen
 
 FOO_YML = """\
 prop:
     - val1
 """
 
 
 class TestYaml(unittest.TestCase):
 
     def test_load(self):
         with MockedOpen({'/dir1/dir2/foo.yml': FOO_YML}):
             self.assertEqual(yaml.load_yaml("/dir1/dir2", "foo.yml"),
                              {'prop': ['val1']})
+
+
+if __name__ == '__main__':
+    main()