blob: 31db14fa031e0cccfe8b573bb6bc0b56f9dbaaeb [file] [log] [blame]
Ben Murdoch342c50c2016-05-18 11:27:45 +01001# 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)