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