@@ -0,0 +1,2500 @@
+#!/usr/bin/env python%0A# Copyright (c) 2015 The Chromium Authors. All rights reserved.%0A# Use of this source code is governed by a BSD-style license that can be%0A# found in the LICENSE file.%0A%0A%22%22%22Dumps a list of known slaves, along with their OS and master.%22%22%22%0A%0Aimport argparse%0Aimport collections%0Aimport json%0Aimport logging%0Aimport os%0Aimport subprocess%0Aimport sys%0A%0A# This file is located inside tests. Update this path if that changes.%0ABUILD = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))%0ASCRIPTS = os.path.join(BUILD, 'scripts')%0ALIST_SLAVES = os.path.join(SCRIPTS, 'tools', 'list_slaves.py')%0A%0Asys.path.append(SCRIPTS)%0A%0Afrom common import chromium_utils%0A%0A%0Adef main():%0A  parser = argparse.ArgumentParser()%0A  parser.add_argument(%0A    '-g',%0A    '--gen',%0A    '--generate',%0A    action='store_true',%0A    dest='generate',%0A    help='Generate slaves.expected for all masters.',%0A  )%0A  args = parser.parse_args()%0A%0A  masters = chromium_utils.ListMastersWithSlaves()%0A  master_map = %7B%7D%0A%0A  for master_path in masters:%0A    # Convert ~/%3Csomewhere%3E/master.%3Cwhatever%3E to just whatever.%0A    master = os.path.basename(master_path).split('.', 1)%5B-1%5D%0A    botmap = json.loads(subprocess.check_output(%5B%0A        LIST_SLAVES, '--json', '--master', master%5D))%0A%0A    slave_map = collections.defaultdict(set)%0A%0A    for entry in botmap:%0A      assert entry%5B'mastername'%5D == 'master.%25s' %25 master%0A%0A      for builder in entry%5B'builder'%5D:%0A        slave_map%5Bbuilder%5D.add(entry%5B'hostname'%5D)%0A%0A    master_map%5Bmaster_path%5D = %7B%7D%0A%0A    for buildername in sorted(slave_map.keys()):%0A      master_map%5Bmaster_path%5D%5Bbuildername%5D = sorted(slave_map%5Bbuildername%5D)%0A%0A  retcode = 0%0A%0A  for master_path, slaves_expectation in master_map.iteritems():%0A    if os.path.exists(master_path):%0A      slaves_expectation_file = os.path.join(master_path, 'slaves.expected')%0A%0A      if args.generate:%0A        with open(slaves_expectation_file, 'w') as fp:%0A          json.dump(slaves_expectation, fp, indent=2, sort_keys=True)%0A        print 'Wrote expectation: %25s.' %25 slaves_expectation_file%0A      else:%0A        if os.path.exists(slaves_expectation_file):%0A          with open(slaves_expectation_file) as fp:%0A            if json.load(fp) != slaves_expectation:%0A              logging.error(%0A                  'Mismatched expectation: %25s.', slaves_expectation_file)%0A              retcode = 1%0A        else:%0A          logging.error('File not found: %25s.', slaves_expectation_file)%0A          retcode = 1%0A%0A  return retcode%0A%0A%0Aif __name__ == '__main__':%0A  sys.exit(main())%0A

Add script for generating slave expectations