1be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik#!/usr/bin/env python
2be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik# Copyright 2015 The Chromium Authors. All rights reserved.
3be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik# Use of this source code is governed by a BSD-style license that can be
4be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik# found in the LICENSE file.
5be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik
6be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craikimport argparse
7be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craikimport json
833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reckimport os
9be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craikimport sys
10be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik
1133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reckif __name__ == '__main__':
1233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck  sys.path.append(
1333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck      os.path.abspath(os.path.join(os.path.dirname(__file__),
1433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck                                   '..', '..', '..')))
1533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck
16be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craikfrom devil.android import device_blacklist
17be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craikfrom devil.android import device_utils
18be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craikfrom devil.utils import run_tests_helper
19be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik
20be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik
21be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craikdef main():
22be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik  parser = argparse.ArgumentParser(
23be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik      'Run an adb shell command on selected devices')
24be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik  parser.add_argument('cmd', help='Adb shell command to run.', nargs="+")
25be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik  parser.add_argument('-d', '--device', action='append', dest='devices',
26a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik                      default=[],
27be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik                      help='Device to run cmd on. Runs on all devices if not '
28be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik                           'specified. Set multiple times for multiple devices')
29be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik  parser.add_argument('-v', '--verbose', default=0, action='count',
30be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik                      help='Verbose level (multiple times for more)')
31be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik  parser.add_argument('--blacklist-file', help='Device blacklist file.')
32be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik  parser.add_argument('--as-root', action='store_true', help='Run as root.')
33be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik  parser.add_argument('--json-output',
34be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik                      help='File to dump json output to.')
35be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik  args = parser.parse_args()
36be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik  run_tests_helper.SetLogLevel(args.verbose)
37be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik
38be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik  args.blacklist_file = device_blacklist.Blacklist(
39be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik      args.blacklist_file) if args.blacklist_file else None
40a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik  devices = device_utils.DeviceUtils.HealthyDevices(
41a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik      blacklist=args.blacklist_file, device_arg=args.devices)
42be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik
43a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik  p_out = (device_utils.DeviceUtils.parallel(devices).RunShellCommand(
44be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik      args.cmd, large_output=True, as_root=args.as_root, check_return=True)
45be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik      .pGet(None))
46be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik
47be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik  data = {}
48a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik  for device, output in zip(devices, p_out):
49be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik    for line in output:
50be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik      print '%s: %s' % (device, line)
51be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik    data[str(device)] = output
52be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik
53be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik  if args.json_output:
54be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik    with open(args.json_output, 'w') as f:
55be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik      json.dump(data, f)
56be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik
57be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik  return 0
58be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik
59be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik
60be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craikif __name__ == '__main__':
61be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik  sys.exit(main())
62