setup.py revision 8bcbed890bc3ce4d7a057a8f32cab53fa534672e
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 psutil 12import signal 13import shutil 14import time 15 16from pylib import android_commands 17from pylib import cmd_helper 18from pylib import constants 19from pylib import forwarder 20from pylib import ports 21 22import test_runner 23 24 25def _KillPendingServers(): 26 for retry in range(5): 27 for server in ['lighttpd', 'web-page-replay']: 28 pids = [p.pid for p in psutil.process_iter() if server in p.name] 29 for pid in pids: 30 try: 31 logging.warning('Killing %s %s', server, pid) 32 os.kill(pid, signal.SIGQUIT) 33 except Exception as e: 34 logging.warning('Failed killing %s %s %s', server, pid, e) 35 # Restart the adb server with taskset to set a single CPU affinity. 36 cmd_helper.RunCmd(['adb', 'kill-server']) 37 cmd_helper.RunCmd(['taskset', '-c', '0', 'adb', 'start-server']) 38 cmd_helper.RunCmd(['taskset', '-c', '0', 'adb', 'root']) 39 i = 1 40 while not android_commands.GetAttachedDevices(): 41 time.sleep(i) 42 i *= 2 43 if i > 10: 44 break 45 # Reset the test port allocation. It's important to do it before starting 46 # to dispatch any step. 47 if not ports.ResetTestServerPortAllocation(): 48 raise Exception('Failed to reset test server port.') 49 50 forwarder.Forwarder.UseMultiprocessing() 51 52 53def Setup(test_options): 54 """Create and return the test runner factory and tests. 55 56 Args: 57 test_options: A PerformanceOptions object. 58 59 Returns: 60 A tuple of (TestRunnerFactory, tests). 61 """ 62 if os.path.exists(constants.PERF_OUTPUT_DIR): 63 shutil.rmtree(constants.PERF_OUTPUT_DIR) 64 os.makedirs(constants.PERF_OUTPUT_DIR) 65 66 # Before running the tests, kill any leftover server. 67 _KillPendingServers() 68 69 with file(test_options.steps, 'r') as f: 70 tests = json.load(f) 71 72 # The list is necessary to keep the steps order, but internally 73 # the format is squashed from a list of lists into a single dict: 74 # [["A", "cmd"], ["B", "cmd"]] into {"A": "cmd", "B": "cmd"} 75 sorted_test_names = [i[0] for i in tests] 76 tests_dict = dict(tests) 77 78 if test_options.test_filter: 79 sorted_test_names = fnmatch.filter(sorted_test_names, 80 test_options.test_filter) 81 tests_dict = dict((k, v) for k, v in tests_dict.iteritems() 82 if k in sorted_test_names) 83 84 flaky_steps = [] 85 if test_options.flaky_steps: 86 with file(test_options.flaky_steps, 'r') as f: 87 flaky_steps = json.load(f) 88 89 def TestRunnerFactory(device, shard_index): 90 return test_runner.TestRunner( 91 test_options, device, tests_dict, flaky_steps) 92 93 return (TestRunnerFactory, sorted_test_names) 94