generate_buildbot_json.py: Mixins must be sorted

Uses python AST parsing to ensure that the keys for swarming mixins are
sorted.

Change-Id: I450a683454903ad8a5a730a3abc3c9ef2c482f29
Reviewed-on: https://chromium-review.googlesource.com/1231832
Commit-Queue: Stephen Martinis <[email protected]>
Reviewed-by: Kenneth Russell <[email protected]>
Cr-Commit-Position: refs/heads/master@{#592271}
diff --git a/testing/buildbot/generate_buildbot_json_unittest.py b/testing/buildbot/generate_buildbot_json_unittest.py
index 06b933a9..622f4f6 100755
--- a/testing/buildbot/generate_buildbot_json_unittest.py
+++ b/testing/buildbot/generate_buildbot_json_unittest.py
@@ -209,6 +209,29 @@
 ]
 """
 
+FOO_GTESTS_SORTING_MIXINS_WATERFALL = """\
+[
+  {
+    'swarming_mixins': ['a_mixin', 'b_mixin', 'c_mixin'],
+    'name': 'chromium.test',
+    'machines': {
+      'Fake Tester': {
+        'swarming': {
+          'dimension_sets': [
+            {
+              'kvm': '1',
+            },
+          ],
+        },
+        'test_suites': {
+          'gtest_tests': 'foo_tests',
+        },
+      },
+    },
+  },
+]
+"""
+
 FOO_LINUX_GTESTS_WATERFALL = """\
 [
   {
@@ -1350,6 +1373,8 @@
 }
 """
 
+# These mixins are invalid; if passed to check_input_file_consistency, they will
+# fail. These are used for output file consistency checks.
 SWARMING_MIXINS = """\
 {
   'dimension_mixin': {
@@ -1369,6 +1394,34 @@
 }
 """
 
+SWARMING_MIXINS_UNSORTED = """\
+{
+  'b_mixin': {
+    'b': 'b',
+  },
+  'a_mixin': {
+    'a': 'a',
+  },
+  'c_mixin': {
+    'c': 'c',
+  },
+}
+"""
+
+SWARMING_MIXINS_SORTED = """\
+{
+  'a_mixin': {
+    'a': 'a',
+  },
+  'b_mixin': {
+    'b': 'b',
+  },
+  'c_mixin': {
+    'c': 'c',
+  },
+}
+"""
+
 class UnitTest(unittest.TestCase):
   def test_base_generator(self):
     # Only needed for complete code coverage.
@@ -1755,6 +1808,22 @@
     with self.assertRaises(generate_buildbot_json.BBGenErr):
       fbb.check_output_file_consistency(verbose=True)
 
+  def test_swarming_mixins_must_be_sorted(self):
+    fbb = FakeBBGen(FOO_GTESTS_SORTING_MIXINS_WATERFALL,
+                    FOO_TEST_SUITE,
+                    EMPTY_PYL_FILE,
+                    SWARMING_MIXINS_UNSORTED,
+                    LUCI_MILO_CFG)
+    with self.assertRaises(generate_buildbot_json.BBGenErr):
+      fbb.check_input_file_consistency()
+
+    fbb = FakeBBGen(FOO_GTESTS_SORTING_MIXINS_WATERFALL,
+                    FOO_TEST_SUITE,
+                    EMPTY_PYL_FILE,
+                    SWARMING_MIXINS_SORTED,
+                    LUCI_MILO_CFG)
+    fbb.check_input_file_consistency()
+
 
 if __name__ == '__main__':
   unittest.main()