host_history.py revision 5952fbe77ee7f33a642d19aa1d13ffeae0b92117
15952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang#!/usr/bin/env python 25952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang 35952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang# Copyright (c) 2014 The Chromium OS Authors. All rights reserved. 45952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang# Use of this source code is governed by a BSD-style license that can be 55952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang# found in the LICENSE file. 65952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang 75952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang# This file defines script for getting host_history for DUTs in Autotest. 85952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang 95952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang"""Script for checking host history for a selected group of hosts. 105952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang 115952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael LiangCurrently only supports aggregating stats for each host. 125952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael LiangTODOs: 135952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang Write unit tests for host_history_utils 145952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang Aggregate stats for > 1 host 155952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang Incorporate jobs 165952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang 175952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael LiangExample usage: 185952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang python host_history.py --index=cautotest -n 10000 \ 195952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang -l 24 --board=daisy 205952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang 215952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael LiangOutput: 225952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang 235952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang trying to get all duts... 245952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang making the query... 255952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang found all duts. Time to get host_history. 265952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang usage stats for host: chromeos2-row5-rack1-host6 275952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang 2014-07-24 10:24:07 - 2014-07-25 10:24:07 285952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang Verifying: 0.00 % 295952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang Running: 0.00 % 305952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang Ready: 100.00 % 315952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang Repairing: 0.00 % 325952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang Repair Failed: 0.00 % 335952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang Cleaning: 0.00 % 345952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang Pending: 0.00 % 355952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang Resetting: 0.00 % 365952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang Provisioning: 0.00 % 375952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang Locked: 0.00 % 385952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang - -- --- ---- ----- ---- --- -- - 395952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang 405952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael LiangExample usage2: more than one host: 415952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang python host_history.py --index=cautotest -n 1000 -l 2 \ 425952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang --hosts chromeos2-row5-rack4-host6 chromeos4-row12-rack11-host2 435952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang 445952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang ['chromeos2-row5-rack4-host6', 'chromeos4-row12-rack11-host2'] 455952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang found all duts. Time to get host_history. 465952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang usage stats for host: chromeos2-row5-rack4-host6 475952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang 2014-07-25 13:02:22 - 2014-07-25 15:02:22 485952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang Num entries found in this interval: 0 495952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang Verifying: 0.00 % 505952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang Running: 0.00 % 515952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang Ready: 100.00 % 525952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang Repairing: 0.00 % 535952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang Repair Failed: 0.00 % 545952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang Cleaning: 0.00 % 555952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang Pending: 0.00 % 565952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang Resetting: 0.00 % 575952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang Provisioning: 0.00 % 585952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang Locked: 0.00 % 595952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang - -- --- ---- ----- ---- --- -- - 605952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang 615952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang usage stats for host: chromeos4-row12-rack11-host2 625952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang 2014-07-25 13:02:22 - 2014-07-25 15:02:22 635952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang Num entries found in this interval: 138 645952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang Verifying: 0.00 % 655952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang Running: 70.45 % 665952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang Ready: 17.79 % 675952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang Repairing: 0.00 % 685952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang Repair Failed: 0.00 % 695952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang Cleaning: 0.00 % 705952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang Pending: 1.24 % 715952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang Resetting: 10.78 % 725952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang Provisioning: 0.00 % 735952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang Locked: 0.00 % 745952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang - -- --- ---- ----- ---- --- -- - 755952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang""" 765952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang 775952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liangimport multiprocessing 785952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liangimport multiprocessing.pool 795952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liangimport argparse 805952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liangimport time 815952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang 825952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liangimport common 835952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liangimport host_history_utils 845952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liangfrom autotest_lib.server import frontend 855952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang 865952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang 875952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liangdef should_care(board, pool, dut): 885952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang """Whether we should care to print stats for this dut out 895952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang 905952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang @param board: board we want, i.e. 'daisy' 915952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang @param pool: pool we want, i.e. 'bvt' 925952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang @param dut: Host object representing DUT. 935952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang @returns: True if the dut's stats should be counted. 945952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang """ 955952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang if not board and not pool: 965952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang return True 975952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang found_board = False if board else True 985952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang found_pool = False if pool else True 995952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang for label in dut.labels: 1005952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang if label.startswith('pool:%s' % (pool)): 1015952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang found_pool = True 1025952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang if label.startswith('board:%s' % (board)): 1035952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang found_board = True 1045952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang return found_board and found_pool 1055952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang 1065952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang 1075952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liangdef main(): 1085952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang """main script. """ 1095952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang parser = argparse.ArgumentParser() 1105952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang parser.add_argument('--index', type=str, dest='index') 1115952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang parser.add_argument('-v', action='store_true', dest='verbose', 1125952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang default=False, 1135952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang help='--show to print out ALL entries.') 1145952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang parser.add_argument('-n', type=int, dest='size', 1155952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang help='Maximum number of entries to return.', 1165952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang default=10000) 1175952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang parser.add_argument('-l', type=float, dest='last', 1185952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang help='last hours to search results across', 1195952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang default=24) 1205952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang parser.add_argument('--board', type=str, dest='board', 1215952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang help='restrict query by board, not implemented yet', 1225952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang default=None) 1235952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang parser.add_argument('--pool', type=str, dest='pool', 1245952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang help='restrict query by pool, not implemented yet', 1255952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang default=None) 1265952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang parser.add_argument('--hosts', nargs='+', dest='hosts', 1275952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang help='Enter space deliminated hostnames', 1285952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang default=[]) 1295952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang options = parser.parse_args() 1305952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang 1315952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang 1325952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang time_now = time.time() 1335952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang if options.hosts: 1345952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang hosts = options.hosts 1355952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang else: 1365952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang hosts = [] 1375952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang print 'trying to get all duts...' 1385952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang afe = frontend.AFE() 1395952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang print 'making the query...' 1405952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang duts = afe.get_hosts() 1415952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang for dut in duts: 1425952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang if should_care(options.board, options.pool, dut): 1435952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang hosts.append(dut.hostname) 1445952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang print 'found all duts. Time to get host_history.' 1455952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang 1465952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang args = [] 1475952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang for hostname in hosts: 1485952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang args.append({'t_start': time_now - 3600*options.last, 1495952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang 't_end': time_now, 1505952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang 'hostname': hostname, 1515952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang 'size': options.size, 1525952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang 'print_each_interval': options.verbose}) 1535952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang 1545952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang # Parallizing this process. 1555952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang pool = multiprocessing.pool.ThreadPool() 1565952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang results = pool.imap_unordered(get_host_history, args) 1575952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang time.sleep(5) 1585952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang for result in results: 1595952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang print result 1605952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang 1615952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang 1625952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liangdef get_host_history(input): 1635952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang """Gets the host history. 1645952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang 1655952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang @param input: A dictionary of input arguments to 1665952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang host_history_utils.host_history_stats. 1675952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang Must contain these keys: 1685952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang 't_start', 1695952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang 't_end', 1705952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang 'hostname', 1715952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang 'size,' 1725952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang 'print_each_interval' 1735952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang @returns: result which is a ordered dictionary with 1745952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang key being (ti, tf) and value being (status, dbg_str) 1755952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang status = status of the host. e.g. 'Repair Failed' 1765952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang ti is the beginning of the interval where the DUT's has that status 1775952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang tf is the end of the interval where the DUT has that status 1785952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang dbg_str is the self.dbg_str from the host. An example would be: 1795952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang 'Special Task 18858263 (host 172.22.169.106, 1805952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang task Repair, 1815952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang time 2014-07-27 20:01:15)' 1825952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang """ 1835952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang result = host_history_utils.host_history_stats_report( 1845952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang t_start=input['t_start'], 1855952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang t_end=input['t_end'], 1865952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang hostname=input['hostname'], 1875952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang size=input['size'], 1885952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang print_each_interval=input['print_each_interval']) 1895952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang return result 1905952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang 1915952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang 1925952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liangif __name__ == '__main__': 1935952fbe77ee7f33a642d19aa1d13ffeae0b92117Michael Liang main() 194