host_history.py revision 5952fbe77ee7f33a642d19aa1d13ffeae0b92117
1#!/usr/bin/env python 2 3# Copyright (c) 2014 The Chromium OS Authors. All rights reserved. 4# Use of this source code is governed by a BSD-style license that can be 5# found in the LICENSE file. 6 7# This file defines script for getting host_history for DUTs in Autotest. 8 9"""Script for checking host history for a selected group of hosts. 10 11Currently only supports aggregating stats for each host. 12TODOs: 13 Write unit tests for host_history_utils 14 Aggregate stats for > 1 host 15 Incorporate jobs 16 17Example usage: 18 python host_history.py --index=cautotest -n 10000 \ 19 -l 24 --board=daisy 20 21Output: 22 23 trying to get all duts... 24 making the query... 25 found all duts. Time to get host_history. 26 usage stats for host: chromeos2-row5-rack1-host6 27 2014-07-24 10:24:07 - 2014-07-25 10:24:07 28 Verifying: 0.00 % 29 Running: 0.00 % 30 Ready: 100.00 % 31 Repairing: 0.00 % 32 Repair Failed: 0.00 % 33 Cleaning: 0.00 % 34 Pending: 0.00 % 35 Resetting: 0.00 % 36 Provisioning: 0.00 % 37 Locked: 0.00 % 38 - -- --- ---- ----- ---- --- -- - 39 40Example usage2: more than one host: 41 python host_history.py --index=cautotest -n 1000 -l 2 \ 42 --hosts chromeos2-row5-rack4-host6 chromeos4-row12-rack11-host2 43 44 ['chromeos2-row5-rack4-host6', 'chromeos4-row12-rack11-host2'] 45 found all duts. Time to get host_history. 46 usage stats for host: chromeos2-row5-rack4-host6 47 2014-07-25 13:02:22 - 2014-07-25 15:02:22 48 Num entries found in this interval: 0 49 Verifying: 0.00 % 50 Running: 0.00 % 51 Ready: 100.00 % 52 Repairing: 0.00 % 53 Repair Failed: 0.00 % 54 Cleaning: 0.00 % 55 Pending: 0.00 % 56 Resetting: 0.00 % 57 Provisioning: 0.00 % 58 Locked: 0.00 % 59 - -- --- ---- ----- ---- --- -- - 60 61 usage stats for host: chromeos4-row12-rack11-host2 62 2014-07-25 13:02:22 - 2014-07-25 15:02:22 63 Num entries found in this interval: 138 64 Verifying: 0.00 % 65 Running: 70.45 % 66 Ready: 17.79 % 67 Repairing: 0.00 % 68 Repair Failed: 0.00 % 69 Cleaning: 0.00 % 70 Pending: 1.24 % 71 Resetting: 10.78 % 72 Provisioning: 0.00 % 73 Locked: 0.00 % 74 - -- --- ---- ----- ---- --- -- - 75""" 76 77import multiprocessing 78import multiprocessing.pool 79import argparse 80import time 81 82import common 83import host_history_utils 84from autotest_lib.server import frontend 85 86 87def should_care(board, pool, dut): 88 """Whether we should care to print stats for this dut out 89 90 @param board: board we want, i.e. 'daisy' 91 @param pool: pool we want, i.e. 'bvt' 92 @param dut: Host object representing DUT. 93 @returns: True if the dut's stats should be counted. 94 """ 95 if not board and not pool: 96 return True 97 found_board = False if board else True 98 found_pool = False if pool else True 99 for label in dut.labels: 100 if label.startswith('pool:%s' % (pool)): 101 found_pool = True 102 if label.startswith('board:%s' % (board)): 103 found_board = True 104 return found_board and found_pool 105 106 107def main(): 108 """main script. """ 109 parser = argparse.ArgumentParser() 110 parser.add_argument('--index', type=str, dest='index') 111 parser.add_argument('-v', action='store_true', dest='verbose', 112 default=False, 113 help='--show to print out ALL entries.') 114 parser.add_argument('-n', type=int, dest='size', 115 help='Maximum number of entries to return.', 116 default=10000) 117 parser.add_argument('-l', type=float, dest='last', 118 help='last hours to search results across', 119 default=24) 120 parser.add_argument('--board', type=str, dest='board', 121 help='restrict query by board, not implemented yet', 122 default=None) 123 parser.add_argument('--pool', type=str, dest='pool', 124 help='restrict query by pool, not implemented yet', 125 default=None) 126 parser.add_argument('--hosts', nargs='+', dest='hosts', 127 help='Enter space deliminated hostnames', 128 default=[]) 129 options = parser.parse_args() 130 131 132 time_now = time.time() 133 if options.hosts: 134 hosts = options.hosts 135 else: 136 hosts = [] 137 print 'trying to get all duts...' 138 afe = frontend.AFE() 139 print 'making the query...' 140 duts = afe.get_hosts() 141 for dut in duts: 142 if should_care(options.board, options.pool, dut): 143 hosts.append(dut.hostname) 144 print 'found all duts. Time to get host_history.' 145 146 args = [] 147 for hostname in hosts: 148 args.append({'t_start': time_now - 3600*options.last, 149 't_end': time_now, 150 'hostname': hostname, 151 'size': options.size, 152 'print_each_interval': options.verbose}) 153 154 # Parallizing this process. 155 pool = multiprocessing.pool.ThreadPool() 156 results = pool.imap_unordered(get_host_history, args) 157 time.sleep(5) 158 for result in results: 159 print result 160 161 162def get_host_history(input): 163 """Gets the host history. 164 165 @param input: A dictionary of input arguments to 166 host_history_utils.host_history_stats. 167 Must contain these keys: 168 't_start', 169 't_end', 170 'hostname', 171 'size,' 172 'print_each_interval' 173 @returns: result which is a ordered dictionary with 174 key being (ti, tf) and value being (status, dbg_str) 175 status = status of the host. e.g. 'Repair Failed' 176 ti is the beginning of the interval where the DUT's has that status 177 tf is the end of the interval where the DUT has that status 178 dbg_str is the self.dbg_str from the host. An example would be: 179 'Special Task 18858263 (host 172.22.169.106, 180 task Repair, 181 time 2014-07-27 20:01:15)' 182 """ 183 result = host_history_utils.host_history_stats_report( 184 t_start=input['t_start'], 185 t_end=input['t_end'], 186 hostname=input['hostname'], 187 size=input['size'], 188 print_each_interval=input['print_each_interval']) 189 return result 190 191 192if __name__ == '__main__': 193 main() 194