1de781113c3a9238899c1bb1919eb1ee5041b7acbAlex Miller#!/usr/bin/python -t
2de781113c3a9238899c1bb1919eb1ee5041b7acbAlex Miller#
3de781113c3a9238899c1bb1919eb1ee5041b7acbAlex Miller# Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
4de781113c3a9238899c1bb1919eb1ee5041b7acbAlex Miller# Use of this source code is governed by a BSD-style license that can be
5de781113c3a9238899c1bb1919eb1ee5041b7acbAlex Miller# found in the LICENSE file.
6de781113c3a9238899c1bb1919eb1ee5041b7acbAlex Miller
7de781113c3a9238899c1bb1919eb1ee5041b7acbAlex Miller
8de781113c3a9238899c1bb1919eb1ee5041b7acbAlex Miller"""
9de781113c3a9238899c1bb1919eb1ee5041b7acbAlex MillerUsage: ./abort_suite.py [-i and -s you passed to run_suite.py]
10de781113c3a9238899c1bb1919eb1ee5041b7acbAlex Miller
11de781113c3a9238899c1bb1919eb1ee5041b7acbAlex MillerThis code exists to allow buildbot to abort a HWTest run if another part of
12de781113c3a9238899c1bb1919eb1ee5041b7acbAlex Millerthe build fails while HWTesting is going on.  If we're going to fail the
13de781113c3a9238899c1bb1919eb1ee5041b7acbAlex Millerbuild anyway, there's no point in continuing to run tests.
14de781113c3a9238899c1bb1919eb1ee5041b7acbAlex Miller
15de781113c3a9238899c1bb1919eb1ee5041b7acbAlex MillerOne can also pass just the build version to -i, to abort all boards running the
16de781113c3a9238899c1bb1919eb1ee5041b7acbAlex Millersuite against that version. ie. |./abort_suite.py -i R28-3993.0.0 -s dummy|
17de781113c3a9238899c1bb1919eb1ee5041b7acbAlex Millerwould abort all boards running dummy on R28-3993.0.0.
18de781113c3a9238899c1bb1919eb1ee5041b7acbAlex Miller
1963b0e4558330e57db5ed11f5a925c4769802c502Fang DengTo achieve better performance, this script aborts suite jobs and relies on
2063b0e4558330e57db5ed11f5a925c4769802c502Fang Dengautotest scheduler to aborts its subjobs instead of directly aborting subjobs.
2163b0e4558330e57db5ed11f5a925c4769802c502Fang DengSo only synchronous suites is supported.
2263b0e4558330e57db5ed11f5a925c4769802c502Fang Deng
23de781113c3a9238899c1bb1919eb1ee5041b7acbAlex Miller"""
24de781113c3a9238899c1bb1919eb1ee5041b7acbAlex Miller
25de781113c3a9238899c1bb1919eb1ee5041b7acbAlex Miller
26de781113c3a9238899c1bb1919eb1ee5041b7acbAlex Millerimport argparse
27de781113c3a9238899c1bb1919eb1ee5041b7acbAlex Millerimport getpass
2863b0e4558330e57db5ed11f5a925c4769802c502Fang Dengimport logging
2983184356b60f4352e46e69488d54222032d426c0MK Ryuimport os
30de781113c3a9238899c1bb1919eb1ee5041b7acbAlex Millerimport sys
31de781113c3a9238899c1bb1919eb1ee5041b7acbAlex Miller
32de781113c3a9238899c1bb1919eb1ee5041b7acbAlex Millerimport common
33de781113c3a9238899c1bb1919eb1ee5041b7acbAlex Millerfrom autotest_lib.server import frontend
3483184356b60f4352e46e69488d54222032d426c0MK Ryufrom autotest_lib.server import utils
35de781113c3a9238899c1bb1919eb1ee5041b7acbAlex Miller
36de781113c3a9238899c1bb1919eb1ee5041b7acbAlex Miller
3783184356b60f4352e46e69488d54222032d426c0MK RyuLOG_NAME_TEMPLATE = 'abort_suite-%s.log'
38de781113c3a9238899c1bb1919eb1ee5041b7acbAlex MillerSUITE_JOB_NAME_TEMPLATE = '%s-test_suites/control.%s'
39de781113c3a9238899c1bb1919eb1ee5041b7acbAlex Miller
40de781113c3a9238899c1bb1919eb1ee5041b7acbAlex Miller
41de781113c3a9238899c1bb1919eb1ee5041b7acbAlex Millerdef parse_args():
42de781113c3a9238899c1bb1919eb1ee5041b7acbAlex Miller    """
43de781113c3a9238899c1bb1919eb1ee5041b7acbAlex Miller    Parse the arguments to this script.
44de781113c3a9238899c1bb1919eb1ee5041b7acbAlex Miller
45de781113c3a9238899c1bb1919eb1ee5041b7acbAlex Miller    @return The arguments to this script.
46de781113c3a9238899c1bb1919eb1ee5041b7acbAlex Miller
47de781113c3a9238899c1bb1919eb1ee5041b7acbAlex Miller    """
48de781113c3a9238899c1bb1919eb1ee5041b7acbAlex Miller    parser = argparse.ArgumentParser()
49de781113c3a9238899c1bb1919eb1ee5041b7acbAlex Miller    parser.add_argument('-s', '--suite_name', dest='name')
50de781113c3a9238899c1bb1919eb1ee5041b7acbAlex Miller    parser.add_argument('-i', '--build', dest='build')
51de781113c3a9238899c1bb1919eb1ee5041b7acbAlex Miller    return parser.parse_args()
52de781113c3a9238899c1bb1919eb1ee5041b7acbAlex Miller
53de781113c3a9238899c1bb1919eb1ee5041b7acbAlex Miller
5463b0e4558330e57db5ed11f5a925c4769802c502Fang Dengdef abort_suites(afe, substring):
55de781113c3a9238899c1bb1919eb1ee5041b7acbAlex Miller    """
5663b0e4558330e57db5ed11f5a925c4769802c502Fang Deng    Abort the suite.
5763b0e4558330e57db5ed11f5a925c4769802c502Fang Deng
5863b0e4558330e57db5ed11f5a925c4769802c502Fang Deng    This method aborts the suite jobs whose name contains |substring|.
5963b0e4558330e57db5ed11f5a925c4769802c502Fang Deng    Aborting a suite job will lead to all its child jobs to be aborted
6063b0e4558330e57db5ed11f5a925c4769802c502Fang Deng    by autotest scheduler.
61de781113c3a9238899c1bb1919eb1ee5041b7acbAlex Miller
6263b0e4558330e57db5ed11f5a925c4769802c502Fang Deng    @param afe: An instance of frontend.AFE to make RPCs with.
63f31d36c9d6773dfa468838b0af0e0581acf08731Prathmesh Prabhu    @param substring: A string used to search for the jobs (case insensitive
64f31d36c9d6773dfa468838b0af0e0581acf08731Prathmesh Prabhu            matching).
65de781113c3a9238899c1bb1919eb1ee5041b7acbAlex Miller
66de781113c3a9238899c1bb1919eb1ee5041b7acbAlex Miller    """
6763b0e4558330e57db5ed11f5a925c4769802c502Fang Deng    hqe_info = afe.run('abort_host_queue_entries',
68f31d36c9d6773dfa468838b0af0e0581acf08731Prathmesh Prabhu            job__name__icontains=substring, job__owner=getpass.getuser(),
6963b0e4558330e57db5ed11f5a925c4769802c502Fang Deng            job__parent_job__isnull=True)
7063b0e4558330e57db5ed11f5a925c4769802c502Fang Deng    if hqe_info:
7163b0e4558330e57db5ed11f5a925c4769802c502Fang Deng        logging.info('The following suites have been aborted:\n%s', hqe_info)
7263b0e4558330e57db5ed11f5a925c4769802c502Fang Deng    else:
7363b0e4558330e57db5ed11f5a925c4769802c502Fang Deng        logging.info('No suites have been aborted. The suite jobs may have '
7463b0e4558330e57db5ed11f5a925c4769802c502Fang Deng                     'already been aborted/completed? Note this script does '
7563b0e4558330e57db5ed11f5a925c4769802c502Fang Deng                     'not support asynchronus suites.')
76de781113c3a9238899c1bb1919eb1ee5041b7acbAlex Miller
77de781113c3a9238899c1bb1919eb1ee5041b7acbAlex Miller
78de781113c3a9238899c1bb1919eb1ee5041b7acbAlex Millerdef main():
79de781113c3a9238899c1bb1919eb1ee5041b7acbAlex Miller    """Main."""
80de781113c3a9238899c1bb1919eb1ee5041b7acbAlex Miller    args = parse_args()
8183184356b60f4352e46e69488d54222032d426c0MK Ryu
8283184356b60f4352e46e69488d54222032d426c0MK Ryu    log_dir = os.path.join(common.autotest_dir, 'logs')
8383184356b60f4352e46e69488d54222032d426c0MK Ryu    if not os.path.exists(log_dir):
8483184356b60f4352e46e69488d54222032d426c0MK Ryu        os.makedirs(log_dir)
8583184356b60f4352e46e69488d54222032d426c0MK Ryu    log_name = LOG_NAME_TEMPLATE % args.build.replace('/', '_')
8683184356b60f4352e46e69488d54222032d426c0MK Ryu    log_name = os.path.join(log_dir, log_name)
8783184356b60f4352e46e69488d54222032d426c0MK Ryu
882d0a364b21297418bef4d7f32acee8831e4eeefeMK Ryu    utils.setup_logging(logfile=log_name, prefix=True)
8983184356b60f4352e46e69488d54222032d426c0MK Ryu
9083184356b60f4352e46e69488d54222032d426c0MK Ryu    afe = frontend.AFE()
91de781113c3a9238899c1bb1919eb1ee5041b7acbAlex Miller    name = SUITE_JOB_NAME_TEMPLATE % (args.build, args.name)
92c0c10611f77d1d634cd317b1fb7c914a099cfde0Ningning Xia
9363b0e4558330e57db5ed11f5a925c4769802c502Fang Deng    abort_suites(afe, name)
94de781113c3a9238899c1bb1919eb1ee5041b7acbAlex Miller    return 0
95de781113c3a9238899c1bb1919eb1ee5041b7acbAlex Miller
96de781113c3a9238899c1bb1919eb1ee5041b7acbAlex Miller
97de781113c3a9238899c1bb1919eb1ee5041b7acbAlex Millerif __name__ == '__main__':
98de781113c3a9238899c1bb1919eb1ee5041b7acbAlex Miller    sys.exit(main())
99