text: #!/usr/bin/env python
  # Copyright 2018 The Chromium Authors. All rights reserved.
  # Use of this source code is governed by a BSD-style license that can be
  # found in the LICENSE file.
  
  """Checks that the main console and subconsole configs are consistent."""
  
  import collections
  import difflib
  import os
  import sys
  
  THIS_DIR = os.path.dirname(os.path.abspath(__file__))
  SRC_ROOT = os.path.join(THIS_DIR, '..', '..')
  sys.path.insert(1, os.path.join(
      SRC_ROOT, "third_party", "protobuf", "python"))
  
  import google.protobuf.text_format
  import project_pb2
  
  
  def compare_builders(name, main_builders, sub_builders):
    # Checks that the builders on a subwaterfall on the main waterfall
    # are consistent with the builders on that subwaterfall's main page.
    # For example, checks that the builders on the "chromium.win" section
    # are the same as on the dedicated standalone chromium.win waterfall.
    def to_list(builders, category_prefix=''):
      desc_list = []
      for builder in builders:
        desc_list.append('name: ' + ', '.join(builder.name))
        # A bot with "chromium.win|foo|bar" on the main waterfall should have
        # a category of "foo|bar" on the "chromium.win" subwaterfall.
        category = builder.category
        if category_prefix:
          if category:
            category = category_prefix + '|' + category
          else:
            category = category_prefix
        desc_list.append('category: ' + category)
        desc_list.append('short_name: ' + builder.short_name)
      return desc_list
    main_desc = to_list(main_builders)
    sub_desc = to_list(sub_builders, name)
  
    if main_desc != sub_desc:
      print ('bot lists different between main waterfall ' +
             'and stand-alone %s waterfall:' % name)
      print '\n'.join(difflib.unified_diff(main_desc, sub_desc,
                                           fromfile='main', tofile=name,
                                           lineterm=''))
      print
      return False
    return True
  
  
  def main():
    project = project_pb2.Project()
    with open(os.path.join(THIS_DIR, 'generated', 'luci-milo.cfg'), 'rb') as f:
      google.protobuf.text_format.Parse(f.read(), project)
  
    # Maps subwaterfall name to list of builders on that subwaterfall
    # on the main waterfall.
    subwaterfalls = collections.defaultdict(list)
    for console in project.consoles:
      if console.id == 'main':
        # Chromium main waterfall console.
        for builder in console.builders:
          subwaterfall = builder.category.split('|', 1)[0]
          subwaterfalls[subwaterfall].append(builder)
  
    # subwaterfalls contains the waterfalls referenced by the main console
    # Check that every referenced subwaterfall has its own console, unless it's
    # explicitly excluded below.
    excluded_names = [
        # This is the chrome console in src-internal.
        'chrome',
    ]
    all_console_names = [console.id for console in project.consoles]
    referenced_names = set(subwaterfalls.keys())
    missing_names = referenced_names - set(all_console_names + excluded_names)
    if missing_names:
      print 'Missing subwaterfall console for', missing_names
      return 1
  
    # Check that the bots on a subwaterfall match the corresponding bots on the
    # main waterfall
    all_good = True
    for console in project.consoles:
      if console.id in subwaterfalls:
        if not compare_builders(console.id, subwaterfalls[console.id],
                                console.builders):
          all_good = False
    return 0 if all_good else 1
  
  
  if __name__ == '__main__':
    sys.exit(main())
  