• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright 2013 The Chromium Authors. All rights reserved.
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
5"""Generates test runner factory and tests for performance tests."""
6
7import json
8import fnmatch
9import logging
10import os
11import shutil
12
13from devil.android import device_list
14from devil.android import device_utils
15from pylib import constants
16from pylib.perf import test_runner
17from pylib.utils import test_environment
18
19
20def _GetAllDevices(active_devices, devices_path):
21  # TODO(rnephew): Delete this when recipes change to pass file path.
22  if not devices_path:
23    logging.warning('Known devices file path not being passed. For device '
24                    'affinity to work properly, it must be passed.')
25    devices_path = os.path.join(os.environ.get('CHROMIUM_OUT_DIR', 'out'),
26                                device_list.LAST_DEVICES_FILENAME)
27  try:
28    if devices_path:
29      devices = [device_utils.DeviceUtils(s)
30                 for s in device_list.GetPersistentDeviceList(devices_path)]
31    else:
32      logging.warning('Known devices file path not being passed. For device '
33                      'affinity to work properly, it must be passed.')
34      devices = active_devices
35  except IOError as e:
36    logging.error('Unable to find %s [%s]', devices_path, e)
37    devices = active_devices
38  return sorted(devices)
39
40
41def _GetStepsDictFromSingleStep(test_options):
42  # Running a single command, build the tests structure.
43  steps_dict = {
44    'version': 1,
45    'steps': {
46        'single_step': {
47          'device_affinity': 0,
48          'cmd': test_options.single_step
49        },
50    }
51  }
52  return steps_dict
53
54
55def _GetStepsDict(test_options):
56  if test_options.single_step:
57    return _GetStepsDictFromSingleStep(test_options)
58  if test_options.steps:
59    with file(test_options.steps, 'r') as f:
60      steps = json.load(f)
61
62      # Already using the new format.
63      assert steps['version'] == 1
64      return steps
65
66
67def Setup(test_options, active_devices):
68  """Create and return the test runner factory and tests.
69
70  Args:
71    test_options: A PerformanceOptions object.
72
73  Returns:
74    A tuple of (TestRunnerFactory, tests, devices).
75  """
76  # TODO(bulach): remove this once the bot side lands. BUG=318369
77  constants.SetBuildType('Release')
78  if os.path.exists(constants.PERF_OUTPUT_DIR):
79    shutil.rmtree(constants.PERF_OUTPUT_DIR)
80  os.makedirs(constants.PERF_OUTPUT_DIR)
81
82  # Before running the tests, kill any leftover server.
83  test_environment.CleanupLeftoverProcesses(active_devices)
84
85  # We want to keep device affinity, so return all devices ever seen.
86  all_devices = _GetAllDevices(active_devices, test_options.known_devices_file)
87
88  steps_dict = _GetStepsDict(test_options)
89  sorted_step_names = sorted(steps_dict['steps'].keys())
90
91  if test_options.test_filter:
92    sorted_step_names = fnmatch.filter(sorted_step_names,
93                                       test_options.test_filter)
94
95  flaky_steps = []
96  if test_options.flaky_steps:
97    with file(test_options.flaky_steps, 'r') as f:
98      flaky_steps = json.load(f)
99
100  def TestRunnerFactory(device, shard_index):
101    return test_runner.TestRunner(
102        test_options, device, shard_index, len(all_devices),
103        steps_dict, flaky_steps)
104
105  return (TestRunnerFactory, sorted_step_names, all_devices)
106