Bug 1316077 part 1: Support buildbot-bridge for talos tests. r=dustin draft
authorWander Lairson Costa <wcosta@mozilla.com>
Fri, 18 Nov 2016 16:52:15 -0200
changeset 441341 ede38a683abdf411612e885f6985c79b0532cb46
parent 441209 a103e1713a2eda3b4e88d71df82d140487c8db87
child 441342 76ad3993d50cb3dccca6b56652eec9568f5e5abb
push id36397
push userwcosta@mozilla.com
push dateFri, 18 Nov 2016 18:52:45 +0000
reviewersdustin
bugs1316077
milestone53.0a1
Bug 1316077 part 1: Support buildbot-bridge for talos tests. r=dustin While we don't have physical machines running taskcluster-worker, we want to schedule talos tests on Taskcluster and run them on buildbot. buildbot-bridge acts as a worker that runs its tasks in buildbot machines. Any talos task is redirected to buildbot-bridge. MozReview-Commit-ID: Im9IhhT0Mr1
taskcluster/taskgraph/transforms/task.py
taskcluster/taskgraph/transforms/tests/all_kinds.py
taskcluster/taskgraph/transforms/tests/make_task_description.py
taskcluster/taskgraph/transforms/tests/test_description.py
taskcluster/taskgraph/try_option_syntax.py
--- a/taskcluster/taskgraph/transforms/task.py
+++ b/taskcluster/taskgraph/transforms/task.py
@@ -466,16 +466,27 @@ def build_macosx_engine_payload(config, 
 
     task_def['payload'] = {
         'link': worker['link'],
         'command': worker['command'],
         'env': worker['env'],
         'artifacts': artifacts,
     }
 
+
+@payload_builder('buildbot-bridge')
+def build_buildbot_bridge_payload(config, task, task_def):
+    worker = task['worker']
+    task_def['payload'] = {
+        'buildername': worker['buildername'],
+        'sourcestamp': worker['sourcestamp'],
+        'properties': worker['properties'],
+    }
+
+
 transforms = TransformSequence()
 
 
 @transforms.add
 def validate(config, tasks):
     for task in tasks:
         yield validate_schema(
             task_description_schema, task,
--- a/taskcluster/taskgraph/transforms/tests/all_kinds.py
+++ b/taskcluster/taskgraph/transforms/tests/all_kinds.py
@@ -19,17 +19,19 @@ import copy
 
 transforms = TransformSequence()
 
 
 @transforms.add
 def set_worker_implementation(config, tests):
     """Set the worker implementation based on the test platform."""
     for test in tests:
-        if test['test-platform'].startswith('win'):
+        if test.get('suite', '') == 'talos':
+            test['worker-implementation'] = 'buildbot-bridge'
+        elif test['test-platform'].startswith('win'):
             test['worker-implementation'] = 'generic-worker'
         elif test['test-platform'].startswith('macosx'):
             test['worker-implementation'] = 'macosx-engine'
         else:
             test['worker-implementation'] = 'docker-worker'
         yield test
 
 
--- a/taskcluster/taskgraph/transforms/tests/make_task_description.py
+++ b/taskcluster/taskgraph/transforms/tests/make_task_description.py
@@ -43,16 +43,28 @@ WORKER_TYPE = {
 
 ARTIFACTS = [
     # (artifact name prefix, in-image path)
     ("public/logs/", "build/upload/logs/"),
     ("public/test", "artifacts/"),
     ("public/test_info/", "build/blobber_upload_dir/"),
 ]
 
+BUILDER_NAME_PREFIX = {
+    'linux64-pgo': 'Ubuntu VM 12.04 x64',
+    'linux64': 'Ubuntu VM 12.04 x64',
+    'linux64-asan': 'Ubuntu ASAN VM 12.04 x64',
+    'linux64-ccov': 'Ubuntu Code Coverage VM 12.04 x64',
+    'linux64-jsdcov': 'Ubuntu Code Coverage VM 12.04 x64',
+    'macosx64': 'Rev7 MacOSX Yosemite 10.10.5',
+    'android-4.3-arm7-api-15': 'Android 4.3 armv7 API 15+',
+    'android-4.2-x86': 'Android 4.2 x86 Emulator',
+    'android-4.3-arm7-api-15-gradle': 'Android 4.3 armv7 API 15+',
+}
+
 logger = logging.getLogger(__name__)
 
 transforms = TransformSequence()
 
 
 @transforms.add
 def make_task_description(config, tests):
     """Convert *test* descriptions to *task* descriptions (input to
@@ -60,17 +72,22 @@ def make_task_description(config, tests)
 
     for test in tests:
         label = '{}-{}-{}'.format(config.kind, test['test-platform'], test['test-name'])
         if test['chunks'] > 1:
             label += '-{}'.format(test['this-chunk'])
 
         build_label = test['build-label']
 
-        unittest_try_name = test.get('unittest-try-name', test['test-name'])
+        if 'talos-try-name' in test:
+            try_name = test['talos-try-name']
+            attr_try_name = 'talos_try_name'
+        else:
+            try_name = test.get('unittest-try-name', test['test-name'])
+            attr_try_name = 'unittest_try_name'
 
         attr_build_platform, attr_build_type = test['build-platform'].split('/', 1)
 
         suite = test['suite']
         if '/' in suite:
             suite, flavor = suite.split('/', 1)
         else:
             flavor = suite
@@ -79,17 +96,17 @@ def make_task_description(config, tests)
         attributes.update({
             'build_platform': attr_build_platform,
             'build_type': attr_build_type,
             # only keep the first portion of the test platform
             'test_platform': test['test-platform'].split('/')[0],
             'test_chunk': str(test['this-chunk']),
             'unittest_suite': suite,
             'unittest_flavor': flavor,
-            'unittest_try_name': unittest_try_name,
+            attr_try_name: try_name,
         })
 
         taskdesc = {}
         taskdesc['label'] = label
         taskdesc['description'] = test['description']
         taskdesc['attributes'] = attributes
         taskdesc['dependencies'] = {'build': build_label}
         taskdesc['deadline-after'] = '1 day'
@@ -438,8 +455,58 @@ def macosx_engine_setup(config, test, ta
             for i, c in enumerate(command):
                 if isinstance(c, basestring) and c.startswith('--test-suite'):
                     command[i] += suffix
 
     if 'download-symbols' in mozharness:
         download_symbols = mozharness['download-symbols']
         download_symbols = {True: 'true', False: 'false'}.get(download_symbols, download_symbols)
         command.append('--download-symbols=' + download_symbols)
+
+
+@worker_setup_function("buildbot-bridge")
+def buildbot_bridge_setup(config, test, taskdesc):
+    branch = config.params['project']
+    platform, build_type = test['build-platform'].split('/')
+    test_name = test.get('talos-try-name', test['test-name'])
+    mozharness = test['mozharness']
+
+    if test['e10s'] and not test_name.endswith('-e10s'):
+        test_name += '-e10s'
+
+    if mozharness.get('chunked', False):
+        this_chunk = test.get('this-chunk')
+        test_name = '{}-{}'.format(test_name, this_chunk)
+
+    worker = taskdesc['worker'] = {}
+    worker['implementation'] = test['worker-implementation']
+
+    taskdesc['worker-type'] = 'buildbot-bridge/buildbot-bridge'
+
+    if test.get('suite', '') == 'talos':
+        buildername = '{} {} talos {}'.format(
+            BUILDER_NAME_PREFIX[platform],
+            branch,
+            test_name
+        )
+        if buildername.startswith('Ubuntu'):
+            buildername = buildername.replace('VM', 'HW')
+    else:
+        buildername = '{} {} {} test {}'.format(
+            BUILDER_NAME_PREFIX[platform],
+            branch,
+            build_type,
+            test_name
+        )
+
+    worker.update({
+        'buildername': buildername,
+        'sourcestamp': {
+            'branch': branch,
+            'repository': config.params['head_repository'],
+            'revision': config.params['head_rev'],
+        },
+        'properties': {
+            'product': test.get('product', 'firefox'),
+            'who': config.params['owner'],
+            'installer_path': mozharness['build-artifact-name'],
+        }
+    })
--- a/taskcluster/taskgraph/transforms/tests/test_description.py
+++ b/taskcluster/taskgraph/transforms/tests/test_description.py
@@ -36,16 +36,19 @@ test_description_schema = Schema({
         basestring,
         {'by-test-platform': {basestring: basestring}},
     ),
 
     # the name by which this test suite is addressed in try syntax; defaults to
     # the test-name
     Optional('unittest-try-name'): basestring,
 
+    # the name by which this talos test is addressed in try syntax
+    Optional('talos-try-name'): basestring,
+
     # the symbol, or group(symbol), under which this task should appear in
     # treeherder.
     'treeherder-symbol': basestring,
 
     # the value to place in task.extra.treeherder.machine.platform; ideally
     # this is the same as build-platform, and that is the default, but in
     # practice it's not always a match.
     Optional('treeherder-machine-platform'): basestring,
@@ -220,16 +223,19 @@ test_description_schema = Schema({
     'build-label': basestring,
 
     # the platform on which the tests will run
     'test-platform': basestring,
 
     # the name of the test (the key in tests.yml)
     'test-name': basestring,
 
+    # the product name, defaults to firefox
+    Optional('product'): basestring,
+
 }, required=True)
 
 
 # TODO: can we have validate and validate_full for before and after?
 def validate(config, tests):
     for test in tests:
         yield validate_schema(test_description_schema, test,
                               "In test {!r}:".format(test['test-name']))
--- a/taskcluster/taskgraph/try_option_syntax.py
+++ b/taskcluster/taskgraph/try_option_syntax.py
@@ -518,17 +518,18 @@ class TryOptionSyntax(object):
                 return False
             if 'platforms' in test and attr('test_platform') not in test['platforms']:
                 return False
             if 'only_chunks' in test and attr('test_chunk') not in test['only_chunks']:
                 return False
             return True
 
         if attr('kind') in ('desktop-test', 'android-test'):
-            return match_test(self.unittests, 'unittest_try_name')
+            return match_test(self.unittests, 'unittest_try_name') \
+                 or match_test(self.talos, 'talos_try_name')
         elif attr('kind') in JOB_KINDS:
             # This will add 'job' tasks to the target set even if no try syntax was specified.
             if not self.jobs:
                 return True
             if attr('build_platform') in self.jobs:
                 return True
         elif attr('kind') in BUILD_KINDS:
             if attr('build_type') not in self.build_types:
@@ -548,13 +549,14 @@ class TryOptionSyntax(object):
             if list is None:
                 return '<all>'
             return ', '.join(str(e) for e in list)
 
         return "\n".join([
             "build_types: " + ", ".join(self.build_types),
             "platforms: " + none_for_all(self.platforms),
             "unittests: " + none_for_all(self.unittests),
+            "talos: " + none_for_all(self.talos),
             "jobs: " + none_for_all(self.jobs),
             "trigger_tests: " + str(self.trigger_tests),
             "interactive: " + str(self.interactive),
             "notifications: " + self.notifications,
         ])