Home | History | Annotate | Download | only in cli
      1 # Copyright (c) 2012 The Chromium OS 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 """
      6 The job module contains the objects and methods used to
      7 manage jobs in Autotest.
      8 
      9 The valid actions are:
     10 list:    lists job(s)
     11 create:  create a job
     12 abort:   abort job(s)
     13 stat:    detailed listing of job(s)
     14 
     15 The common options are:
     16 
     17 See topic_common.py for a High Level Design and Algorithm.
     18 """
     19 
     20 import warnings
     21 
     22 from autotest_lib.cli import topic_common, action_common
     23 
     24 
     25 class suite(topic_common.atest):
     26     """Suite class
     27     atest suite [create] [options]"""
     28     usage_action = '[create]'
     29     topic = msg_topic = 'suite'
     30     msg_items = ''
     31 
     32 
     33 class suite_help(suite):
     34     """Just here to get the atest logic working.
     35     Usage is set by its parent"""
     36     pass
     37 
     38 
     39 class suite_create(action_common.atest_create, suite):
     40     """Class containing the code for creating a suite."""
     41     msg_items = 'suite_id'
     42 
     43     def __init__(self):
     44         super(suite_create, self).__init__()
     45 
     46         self.parser.add_option('-b', '--board', help='Board to test. Required.',
     47                                metavar='BOARD')
     48         self.parser.add_option('-i', '--build',
     49                                help='OS image to install before running the '
     50                                     'test, e.g. '
     51                                     'x86-alex-release/R17-1412.144.0-a1-b115.'
     52                                     ' Required.',
     53                                metavar='BUILD')
     54         self.parser.add_option('-c', '--check_hosts',
     55                                default=False,
     56                                help='Check that enough live hosts exist to '\
     57                                     'run this suite. Default False.',
     58                                action='store_true',
     59                                metavar='CHECK_HOSTS')
     60         self.parser.add_option('-f', '--file_bugs', default=False,
     61                                help='File bugs on test failures.',
     62                                action='store_true', metavar='FILE_BUGS')
     63         self.parser.add_option('-n', '--num', type=int,
     64                                help='Number of machines to schedule across.',
     65                                metavar='NUM')
     66         self.parser.add_option('-p', '--pool', help='Pool of machines to use.',
     67                                metavar='POOL')
     68         self.parser.add_option('-w', '--wait_for_results',
     69                                default=True,
     70                                help=('Set to False for suite job to exit '
     71                                      'without waiting for test jobs to finish. '
     72                                      'Default is True.'),
     73                                metavar='WAIT_FOR_RESULTS')
     74         self.parser.add_option('-d', '--delay_minutes', type=int, default=0,
     75                                help=('Delay the creation of test jobs for a '
     76                                      'given number of minutes. This argument '
     77                                      'can be used to force provision jobs '
     78                                      'being delayed, which helps to distribute '
     79                                      'loads across devservers.'),
     80                                metavar='DELAY_MINUTES')
     81 
     82 
     83     def parse(self):
     84         board_info = topic_common.item_parse_info(attribute_name='board',
     85                                                   inline_option='board')
     86         build_info = topic_common.item_parse_info(attribute_name='build',
     87                                                   inline_option='build')
     88         pool_info = topic_common.item_parse_info(attribute_name='pool',
     89                                                  inline_option='pool')
     90         num_info = topic_common.item_parse_info(attribute_name='num',
     91                                                 inline_option='num')
     92         check_info = topic_common.item_parse_info(attribute_name='check_hosts',
     93                                                   inline_option='check_hosts')
     94         bugs_info = topic_common.item_parse_info(attribute_name='file_bugs',
     95                                                  inline_option='file_bugs')
     96         suite_info = topic_common.item_parse_info(attribute_name='name',
     97                                                   use_leftover=True)
     98         wait_for_results_info = topic_common.item_parse_info(
     99                 attribute_name='wait_for_results',
    100                 inline_option='wait_for_results')
    101         delay_minutes_info = topic_common.item_parse_info(
    102                 attribute_name='delay_minutes',
    103                 inline_option='delay_minutes')
    104 
    105         options, leftover = suite.parse(
    106             self,
    107             [suite_info, board_info, build_info, pool_info, num_info,
    108              check_info, bugs_info, wait_for_results_info, delay_minutes_info],
    109             req_items='name')
    110         self.data = {}
    111         name = getattr(self, 'name')
    112         if len(name) > 1:
    113             self.invalid_syntax('Too many arguments specified, only expected '
    114                                 'to receive suite name: %s' % name)
    115         self.data['suite_name'] = name[0]
    116         self.data['pool'] = options.pool  # None is OK.
    117         if options.num is not None:
    118             warnings.warn('num is deprecated')
    119         del options.num
    120         self.data['check_hosts'] = options.check_hosts
    121         self.data['file_bugs'] = options.file_bugs
    122         self.data['wait_for_results'] = options.wait_for_results
    123         self.data['delay_minutes'] = options.delay_minutes
    124         if options.board:
    125             self.data['board'] = options.board
    126         else:
    127             self.invalid_syntax('--board is required.')
    128         if options.build:
    129             self.data['build'] = options.build
    130         else:
    131             self.invalid_syntax('--build is required.')
    132 
    133         return options, leftover
    134 
    135 
    136     def execute(self):
    137         return [self.execute_rpc(op='create_suite_job', **self.data)]
    138