1be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik# Copyright 2014 The Chromium Authors. All rights reserved.
2be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik# Use of this source code is governed by a BSD-style license that can be
3be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik# found in the LICENSE file.
4be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik
5be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik"""A module to keep track of devices across builds."""
6be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik
7a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craikimport json
8a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craikimport logging
9be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craikimport os
10be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik
11ee838d1c4002134ff5af32da272140586c4d31deJohn Recklogger = logging.getLogger(__name__)
12ee838d1c4002134ff5af32da272140586c4d31deJohn Reck
13be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik
14be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craikdef GetPersistentDeviceList(file_name):
15be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik  """Returns a list of devices.
16be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik
17be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik  Args:
18be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik    file_name: the file name containing a list of devices.
19be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik
20be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik  Returns: List of device serial numbers that were on the bot.
21be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik  """
22a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik  if not os.path.isfile(file_name):
23ee838d1c4002134ff5af32da272140586c4d31deJohn Reck    logger.warning("Device file %s doesn't exist.", file_name)
24a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik    return []
25a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik
26a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik  try:
27a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik    with open(file_name) as f:
28a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik      devices = json.load(f)
29a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik    if not isinstance(devices, list) or not all(isinstance(d, basestring)
30a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik                                                for d in devices):
31ee838d1c4002134ff5af32da272140586c4d31deJohn Reck      logger.warning('Unrecognized device file format: %s', devices)
32a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik      return []
33a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik    return [d for d in devices if d != '(error)']
34a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik  except ValueError:
35ee838d1c4002134ff5af32da272140586c4d31deJohn Reck    logger.exception(
36a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik        'Error reading device file %s. Falling back to old format.', file_name)
37a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik
38a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik  # TODO(bpastene) Remove support for old unstructured file format.
39be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik  with open(file_name) as f:
40a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik    return [d for d in f.read().splitlines() if d != '(error)']
41be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik
42be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik
43be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craikdef WritePersistentDeviceList(file_name, device_list):
44be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik  path = os.path.dirname(file_name)
45a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik  assert isinstance(device_list, list)
46a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik  # If there is a problem with ADB "(error)" can be added to the device list.
47a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik  # These should be removed before saving.
48a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik  device_list = [d for d in device_list if d != '(error)']
49be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik  if not os.path.exists(path):
50be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik    os.makedirs(path)
51be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik  with open(file_name, 'w') as f:
52a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik    json.dump(device_list, f)
53