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""" 6The job module contains the objects and methods used to 7manage jobs in Autotest. 8 9The valid actions are: 10list: lists job(s) 11create: create a job 12abort: abort job(s) 13stat: detailed listing of job(s) 14 15The common options are: 16 17See topic_common.py for a High Level Design and Algorithm. 18""" 19 20import warnings 21 22from autotest_lib.cli import topic_common, action_common 23 24 25class 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 33class suite_help(suite): 34 """Just here to get the atest logic working. 35 Usage is set by its parent""" 36 pass 37 38 39class 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