# HG changeset patch
# User Xidorn Quan <me@upsuper.org>
# Date 1525225885 -36000
# Node ID 619efecc323332781743562873290a894ee6bd29
# Parent  4eae86081a017bcf898fc742964968290dd096fc
Bug 1457524 part 1 - Use a list for rust tests. r=froydnj

MozReview-Commit-ID: 6A0hHClXDUE

diff --git a/build/templates.mozbuild b/build/templates.mozbuild
--- a/build/templates.mozbuild
+++ b/build/templates.mozbuild
@@ -125,17 +125,10 @@ def DisableStlWrapping():
 @template
 def NoVisibilityFlags():
     COMPILE_FLAGS['VISIBILITY'] = []
 
 @template
 def AllowCompilerWarnings():
     COMPILE_FLAGS['WARNINGS_AS_ERRORS'] = []
 
-@template
-def RustTest(name, features=None):
-    RUST_TEST = name
-
-    if features:
-        RUST_TEST_FEATURES = features
-
 include('gecko_templates.mozbuild')
 include('test_templates.mozbuild')
diff --git a/config/rules.mk b/config/rules.mk
--- a/config/rules.mk
+++ b/config/rules.mk
@@ -969,24 +969,26 @@ force-cargo-library-build:
 
 force-cargo-library-check:
 	$(call CARGO_CHECK,$(target_cargo_env_vars)) --lib $(cargo_target_flag) $(rust_features_flag)
 else
 force-cargo-library-check:
 	@true
 endif # RUST_LIBRARY_FILE
 
-ifdef RUST_TEST
+ifdef RUST_TESTS
+
+rust_test_options := $(foreach test,$(RUST_TESTS),-p $(test))
 
 ifdef RUST_TEST_FEATURES
 rust_features_flag := --features "$(RUST_TEST_FEATURES)"
 endif
 
 force-cargo-test-run:
-	$(call RUN_CARGO,test $(cargo_target_flag) -p $(RUST_TEST) $(rust_features_flag),$(target_cargo_env_vars))
+	$(call RUN_CARGO,test $(cargo_target_flag) $(rust_test_options) $(rust_features_flag),$(target_cargo_env_vars))
 
 check:: force-cargo-test-run
 endif
 
 ifdef HOST_RUST_LIBRARY_FILE
 
 ifdef HOST_RUST_LIBRARY_FEATURES
 host_rust_features_flag := --features "$(HOST_RUST_LIBRARY_FEATURES)"
diff --git a/python/mozbuild/mozbuild/backend/recursivemake.py b/python/mozbuild/mozbuild/backend/recursivemake.py
--- a/python/mozbuild/mozbuild/backend/recursivemake.py
+++ b/python/mozbuild/mozbuild/backend/recursivemake.py
@@ -59,17 +59,17 @@ from ..frontend.data import (
     LocalizedPreprocessedFiles,
     ObjdirFiles,
     ObjdirPreprocessedFiles,
     PerSourceFlag,
     Program,
     RustLibrary,
     HostRustLibrary,
     RustProgram,
-    RustTest,
+    RustTests,
     SharedLibrary,
     SimpleProgram,
     Sources,
     StaticLibrary,
     TestManifest,
     VariablePassthru,
     XPIDLFile,
 )
@@ -603,18 +603,18 @@ class RecursiveMakeBackend(CommonBackend
             self._compile_graph[build_target]
 
         elif isinstance(obj, HostRustProgram):
             self._process_host_rust_program(obj, backend_file)
             # Hook the program into the compile graph.
             build_target = self._build_target_for_obj(obj)
             self._compile_graph[build_target]
 
-        elif isinstance(obj, RustTest):
-            self._process_rust_test(obj, backend_file)
+        elif isinstance(obj, RustTests):
+            self._process_rust_tests(obj, backend_file)
 
         elif isinstance(obj, Program):
             self._process_program(obj, backend_file)
             self._process_linked_libraries(obj, backend_file)
             self._no_skip['syms'].add(backend_file.relobjdir)
 
         elif isinstance(obj, HostProgram):
             self._process_host_program(obj.program, backend_file)
@@ -1144,20 +1144,20 @@ class RecursiveMakeBackend(CommonBackend
                                         'RUST_PROGRAMS',
                                         'RUST_CARGO_PROGRAMS')
 
     def _process_host_rust_program(self, obj, backend_file):
         self._process_rust_program_base(obj, backend_file,
                                         'HOST_RUST_PROGRAMS',
                                         'HOST_RUST_CARGO_PROGRAMS')
 
-    def _process_rust_test(self, obj, backend_file):
+    def _process_rust_tests(self, obj, backend_file):
         self._no_skip['check'].add(backend_file.relobjdir)
         backend_file.write_once('CARGO_FILE := $(srcdir)/Cargo.toml\n')
-        backend_file.write_once('RUST_TEST := %s\n' % obj.name)
+        backend_file.write_once('RUST_TESTS := %s\n' % ' '.join(obj.names))
         backend_file.write_once('RUST_TEST_FEATURES := %s\n' % ' '.join(obj.features))
 
     def _process_simple_program(self, obj, backend_file):
         if obj.is_unit_test:
             backend_file.write('CPP_UNIT_TESTS += %s\n' % obj.program)
             assert obj.cxx_link
         else:
             backend_file.write('SIMPLE_PROGRAMS += %s\n' % obj.program)
diff --git a/python/mozbuild/mozbuild/frontend/context.py b/python/mozbuild/mozbuild/frontend/context.py
--- a/python/mozbuild/mozbuild/frontend/context.py
+++ b/python/mozbuild/mozbuild/frontend/context.py
@@ -1243,28 +1243,22 @@ VARIABLES = {
 
     'HOST_RUST_LIBRARY_FEATURES': (List, list,
         """Cargo features to activate for this host library.
 
         This variable should not be used directly; you should be using the
         HostRustLibrary template instead.
         """),
 
-    'RUST_TEST': (unicode, unicode,
-        """Name of a Rust test to build and run via `cargo test`.
-
-        This variable should not be used directly; you should be using the
-        RustTest template instead.
+    'RUST_TESTS': (TypedList(unicode), list,
+        """Names of Rust tests to build and run via `cargo test`.
         """),
 
-    'RUST_TEST_FEATURES': (List, list,
-        """Cargo features to activate for RUST_TEST.
-
-        This variable should not be used directly; you should be using the
-        RustTest template instead.
+    'RUST_TEST_FEATURES': (TypedList(unicode), list,
+        """Cargo features to activate for RUST_TESTS.
         """),
 
     'UNIFIED_SOURCES': (ContextDerivedTypedList(SourcePath, StrictOrderingOnAppendList), list,
         """Source code files that can be compiled together.
 
         This variable contains a list of source code files to compile,
         that can be concatenated all together and built as a single source
         file. This can help make the build faster and reduce the debug info
diff --git a/python/mozbuild/mozbuild/frontend/data.py b/python/mozbuild/mozbuild/frontend/data.py
--- a/python/mozbuild/mozbuild/frontend/data.py
+++ b/python/mozbuild/mozbuild/frontend/data.py
@@ -572,25 +572,25 @@ class RustProgram(BaseRustProgram):
 
 
 class HostRustProgram(BaseRustProgram):
     SUFFIX_VAR = 'HOST_BIN_SUFFIX'
     KIND = 'host'
     TARGET_SUBST_VAR = 'RUST_HOST_TARGET'
 
 
-class RustTest(ContextDerived):
+class RustTests(ContextDerived):
     __slots__ = (
-        'name',
+        'names',
         'features',
     )
 
-    def __init__(self, context, name, features):
+    def __init__(self, context, names, features):
         ContextDerived.__init__(self, context)
-        self.name = name
+        self.names = names
         self.features = features
 
 
 class BaseLibrary(Linkable):
     """Generic context derived container object for libraries."""
     __slots__ = (
         'basename',
         'lib_name',
diff --git a/python/mozbuild/mozbuild/frontend/emitter.py b/python/mozbuild/mozbuild/frontend/emitter.py
--- a/python/mozbuild/mozbuild/frontend/emitter.py
+++ b/python/mozbuild/mozbuild/frontend/emitter.py
@@ -56,17 +56,17 @@ from .data import (
     ObjdirFiles,
     ObjdirPreprocessedFiles,
     PerSourceFlag,
     WebIDLCollection,
     Program,
     RustLibrary,
     HostRustLibrary,
     RustProgram,
-    RustTest,
+    RustTests,
     SharedLibrary,
     SimpleProgram,
     Sources,
     StaticLibrary,
     TestHarnessFiles,
     TestManifest,
     UnifiedSources,
     VariablePassthru,
@@ -1263,23 +1263,23 @@ class TreeMetadataEmitter(LoggingMixin):
 
         for c in components:
             if c.endswith('.manifest'):
                 yield ChromeManifestEntry(context, 'chrome.manifest',
                                           Manifest('components',
                                                    mozpath.basename(c)))
 
         if self.config.substs.get('MOZ_RUST_TESTS', None):
-            rust_test = context.get('RUST_TEST', None)
-            if rust_test:
+            rust_tests = context.get('RUST_TESTS', [])
+            if rust_tests:
                 # TODO: more sophisticated checking of the declared name vs.
                 # contents of the Cargo.toml file.
                 features = context.get('RUST_TEST_FEATURES', [])
 
-                yield RustTest(context, rust_test, features)
+                yield RustTests(context, rust_tests, features)
 
         for obj in self._process_test_manifests(context):
             yield obj
 
         for obj in self._process_jar_manifests(context):
             yield obj
 
         for name, jar in context.get('JAVA_JAR_TARGETS', {}).items():
diff --git a/testing/geckodriver/moz.build b/testing/geckodriver/moz.build
--- a/testing/geckodriver/moz.build
+++ b/testing/geckodriver/moz.build
@@ -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/.
 
 RUST_PROGRAMS += ["geckodriver"]
 
 # https://bugzil.la/1425365
 if CONFIG["OS_ARCH"] != "WINNT":
-    RustTest("geckodriver")
+    RUST_TESTS = ["geckodriver"]
 
 with Files("**"):
     BUG_COMPONENT = ("Testing", "Marionette")
 
 SPHINX_TREES["geckodriver"] = "doc"
 
 with Files('doc/**'):
     SCHEDULES.exclusive = ['docs']
diff --git a/toolkit/library/rust/moz.build b/toolkit/library/rust/moz.build
--- a/toolkit/library/rust/moz.build
+++ b/toolkit/library/rust/moz.build
@@ -5,9 +5,12 @@
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 include('gkrust-features.mozbuild')
 
 RustLibrary('gkrust', gkrust_features, '..')
 
 # Target directory doesn't matter a lot here, since we can't share panic=abort
 # compilation artifacts with gkrust.
-RustTest('stylo_tests', gkrust_features)
+RUST_TESTS = [
+    'stylo_tests',
+]
+RUST_TEST_FEATURES = gkrust_features
