Home | History | Annotate | Download | only in cli
      1 #!/usr/bin/python -u
      2 #
      3 # Copyright 2008 Google Inc. All Rights Reserved.
      4 
      5 
      6 """Tests for job."""
      7 
      8 # pylint: disable=missing-docstring
      9 
     10 import copy, getpass, unittest, sys
     11 
     12 import common
     13 from autotest_lib.cli import cli_mock, job
     14 from autotest_lib.client.common_lib.test_utils import mock
     15 from autotest_lib.client.common_lib import control_data
     16 from autotest_lib.client.common_lib import priorities
     17 
     18 CLIENT = control_data.CONTROL_TYPE_NAMES.CLIENT
     19 SERVER = control_data.CONTROL_TYPE_NAMES.SERVER
     20 
     21 class job_unittest(cli_mock.cli_unittest):
     22     def setUp(self):
     23         super(job_unittest, self).setUp()
     24         self.values = copy.deepcopy(self.values_template)
     25 
     26     results = [{u'status_counts': {u'Aborted': 1},
     27                 u'control_file':
     28                 u"job.run_test('sleeptest')\n",
     29                 u'name': u'test_job0',
     30                 u'control_type': SERVER,
     31                 u'priority':
     32                 priorities.Priority.DEFAULT,
     33                 u'owner': u'user0',
     34                 u'created_on':
     35                 u'2008-07-08 17:45:44',
     36                 u'synch_count': 2,
     37                 u'id': 180},
     38                {u'status_counts': {u'Queued': 1},
     39                 u'control_file':
     40                 u"job.run_test('sleeptest')\n",
     41                 u'name': u'test_job1',
     42                 u'control_type': CLIENT,
     43                 u'priority':
     44                 priorities.Priority.DEFAULT,
     45                 u'owner': u'user0',
     46                 u'created_on':
     47                 u'2008-07-08 12:17:47',
     48                 u'synch_count': 1,
     49                 u'id': 338}]
     50 
     51 
     52     values_template = [{u'id': 180,          # Valid job
     53                         u'priority': priorities.Priority.DEFAULT,
     54                         u'name': u'test_job0',
     55                         u'owner': u'Cringer',
     56                         u'invalid': False,
     57                         u'created_on': u'2008-07-02 13:02:40',
     58                         u'control_type': SERVER,
     59                         u'status_counts': {u'Queued': 1},
     60                         u'synch_count': 2},
     61                        {u'id': 338,          # Valid job
     62                         u'priority': priorities.Priority.DEFAULT,
     63                         u'name': u'test_job1',
     64                         u'owner': u'Fisto',
     65                         u'invalid': False,
     66                         u'created_on': u'2008-07-06 14:05:33',
     67                         u'control_type': CLIENT,
     68                         u'status_counts': {u'Queued': 1},
     69                         u'synch_count': 1},
     70                        {u'id': 339,          # Valid job
     71                         u'priority': priorities.Priority.DEFAULT,
     72                         u'name': u'test_job2',
     73                         u'owner': u'Roboto',
     74                         u'invalid': False,
     75                         u'created_on': u'2008-07-07 15:33:18',
     76                         u'control_type': SERVER,
     77                         u'status_counts': {u'Queued': 1},
     78                         u'synch_count': 1},
     79                        {u'id': 340,          # Invalid job priority
     80                         u'priority': priorities.Priority.DEFAULT,
     81                         u'name': u'test_job3',
     82                         u'owner': u'Panthor',
     83                         u'invalid': True,
     84                         u'created_on': u'2008-07-04 00:00:01',
     85                         u'control_type': SERVER,
     86                         u'status_counts': {u'Queued': 1},
     87                         u'synch_count': 2},
     88                        {u'id': 350,          # Invalid job created_on
     89                         u'priority': priorities.Priority.DEFAULT,
     90                         u'name': u'test_job4',
     91                         u'owner': u'Icer',
     92                         u'invalid': True,
     93                         u'created_on': u'Today',
     94                         u'control_type': CLIENT,
     95                         u'status_counts': {u'Queued': 1},
     96                         u'synch_count': 1},
     97                        {u'id': 420,          # Invalid job control_type
     98                         u'priority': 'Urgent',
     99                         u'name': u'test_job5',
    100                         u'owner': u'Spikor',
    101                         u'invalid': True,
    102                         u'created_on': u'2012-08-08 18:54:37',
    103                         u'control_type': u'Child',
    104                         u'status_counts': {u'Queued': 1},
    105                         u'synch_count': 2}]
    106 
    107 
    108 class job_list_unittest(job_unittest):
    109     def test_job_list_jobs(self):
    110         self.god.stub_function(getpass, 'getuser')
    111         getpass.getuser.expect_call().and_return('user0')
    112         self.run_cmd(argv=['atest', 'job', 'list'],
    113                      rpcs=[('get_jobs_summary', {'owner': 'user0',
    114                                                  'running': None},
    115                             True, self.values)],
    116                      out_words_ok=['test_job0', 'test_job1', 'test_job2'],
    117                      out_words_no=['Uber', 'Today', 'Child'])
    118 
    119 
    120     def test_job_list_jobs_only_user(self):
    121         values = [item for item in self.values if item['owner'] == 'Cringer']
    122         self.run_cmd(argv=['atest', 'job', 'list', '-u', 'Cringer'],
    123                      rpcs=[('get_jobs_summary', {'owner': 'Cringer',
    124                                                  'running': None},
    125                             True, values)],
    126                      out_words_ok=['Cringer'],
    127                      out_words_no=['Fisto', 'Roboto', 'Panthor', 'Icer',
    128                                    'Spikor'])
    129 
    130 
    131     def test_job_list_jobs_all(self):
    132         self.run_cmd(argv=['atest', 'job', 'list', '--all'],
    133                      rpcs=[('get_jobs_summary', {'running': None},
    134                             True, self.values)],
    135                      out_words_ok=['Fisto', 'Roboto', 'Panthor',
    136                                    'Icer', 'Spikor', 'Cringer'],
    137                      out_words_no=['Created', 'Priority'])
    138 
    139 
    140     def test_job_list_jobs_id(self):
    141         self.run_cmd(argv=['atest', 'job', 'list', '5964'],
    142                      rpcs=[('get_jobs_summary', {'id__in': ['5964'],
    143                                                  'running': None},
    144                             True,
    145                             [{u'status_counts': {u'Completed': 1},
    146                               u'control_file': u'kernel = \'8210088647656509311.kernel-smp-2.6.18-220.5.x86_64.rpm\'\ndef step_init():\n    job.next_step([step_test])\n\ndef step_test():\n    job.next_step(\'step0\')\n\ndef step0():\n    AUTHOR = "Autotest Team"\n    NAME = "Sleeptest"\n    TIME = "SHORT"\n    TEST_CATEGORY = "Functional"\n    TEST_CLASS = "General"\n    TEST_TYPE = "client"\n    \n    DOC = """\n    This test simply sleeps for 1 second by default.  It\'s a good way to test\n    profilers and double check that autotest is working.\n    The seconds argument can also be modified to make the machine sleep for as\n    long as needed.\n    """\n    \n    job.run_test(\'sleeptest\',                             seconds = 1)',
    147                               u'name': u'mytest',
    148                               u'control_type': CLIENT,
    149                               u'run_verify': 1,
    150                               u'priority': priorities.Priority.DEFAULT,
    151                               u'owner': u'user0',
    152                               u'created_on': u'2008-07-28 12:42:52',
    153                               u'timeout': 144,
    154                               u'synch_count': 1,
    155                               u'id': 5964}])],
    156                      out_words_ok=['user0', 'Completed', '1', '5964'],
    157                      out_words_no=['sleeptest', 'Priority', CLIENT, '2008'])
    158 
    159 
    160     def test_job_list_jobs_id_verbose(self):
    161         self.run_cmd(argv=['atest', 'job', 'list', '5964', '-v'],
    162                      rpcs=[('get_jobs_summary', {'id__in': ['5964'],
    163                                                  'running': None},
    164                             True,
    165                             [{u'status_counts': {u'Completed': 1},
    166                               u'control_file': u'kernel = \'8210088647656509311.kernel-smp-2.6.18-220.5.x86_64.rpm\'\ndef step_init():\n    job.next_step([step_test])\n\ndef step_test():\n    job.next_step(\'step0\')\n\ndef step0():\n    AUTHOR = "Autotest Team"\n    NAME = "Sleeptest"\n    TIME = "SHORT"\n    TEST_CATEGORY = "Functional"\n    TEST_CLASS = "General"\n    TEST_TYPE = "client"\n    \n    DOC = """\n    This test simply sleeps for 1 second by default.  It\'s a good way to test\n    profilers and double check that autotest is working.\n    The seconds argument can also be modified to make the machine sleep for as\n    long as needed.\n    """\n    \n    job.run_test(\'sleeptest\',                             seconds = 1)',
    167                               u'name': u'mytest',
    168                               u'control_type': CLIENT,
    169                               u'run_verify': 1,
    170                               u'priority': priorities.Priority.DEFAULT,
    171                               u'owner': u'user0',
    172                               u'created_on': u'2008-07-28 12:42:52',
    173                               u'timeout': 144,
    174                               u'synch_count': 1,
    175                               u'id': 5964}])],
    176                      out_words_ok=['user0', 'Completed', '1', '5964',
    177                                    CLIENT, '2008', 'Priority'],
    178                      out_words_no=['sleeptest'])
    179 
    180 
    181     def test_job_list_jobs_name(self):
    182         self.run_cmd(argv=['atest', 'job', 'list', 'myt*'],
    183                      rpcs=[('get_jobs_summary', {'name__startswith': 'myt',
    184                                                  'running': None},
    185                             True,
    186                             [{u'status_counts': {u'Completed': 1},
    187                               u'control_file': u'kernel = \'8210088647656509311.kernel-smp-2.6.18-220.5.x86_64.rpm\'\ndef step_init():\n    job.next_step([step_test])\n\ndef step_test():\n    job.next_step(\'step0\')\n\ndef step0():\n    AUTHOR = "Autotest Team"\n    NAME = "Sleeptest"\n    TIME = "SHORT"\n    TEST_CATEGORY = "Functional"\n    TEST_CLASS = "General"\n    TEST_TYPE = "client"\n    \n    DOC = """\n    This test simply sleeps for 1 second by default.  It\'s a good way to test\n    profilers and double check that autotest is working.\n    The seconds argument can also be modified to make the machine sleep for as\n    long as needed.\n    """\n    \n    job.run_test(\'sleeptest\',                             seconds = 1)',
    188                               u'name': u'mytest',
    189                               u'control_type': CLIENT,
    190                               u'run_verify': 1,
    191                               u'priority': priorities.Priority.DEFAULT,
    192                               u'owner': u'user0',
    193                               u'created_on': u'2008-07-28 12:42:52',
    194                               u'timeout': 144,
    195                               u'synch_count': 1,
    196                               u'id': 5964}])],
    197                      out_words_ok=['user0', 'Completed', '1', '5964'],
    198                      out_words_no=['sleeptest', 'Priority', CLIENT, '2008'])
    199 
    200 
    201     def test_job_list_jobs_all_verbose(self):
    202         self.run_cmd(argv=['atest', 'job', 'list', '--all', '--verbose'],
    203                      rpcs=[('get_jobs_summary', {'running': None},
    204                             True, self.values)],
    205                      out_words_ok=['Fisto', 'Spikor', 'Cringer', 'Priority',
    206                                    'Created'])
    207 
    208 
    209 class job_list_jobs_all_and_user_unittest(cli_mock.cli_unittest):
    210     def test_job_list_jobs_all_and_user(self):
    211         testjob = job.job_list()
    212         sys.argv = ['atest', 'job', 'list', '-a', '-u', 'user0']
    213         self.god.mock_io()
    214         (sys.exit.expect_call(mock.anything_comparator())
    215          .and_raises(cli_mock.ExitException))
    216         self.assertRaises(cli_mock.ExitException, testjob.parse)
    217         self.god.unmock_io()
    218         self.god.check_playback()
    219 
    220 
    221 class job_stat_unittest(job_unittest):
    222     def test_job_stat_job(self):
    223         results = copy.deepcopy(self.results)
    224         self.run_cmd(argv=['atest', 'job', 'stat', '180'],
    225                      rpcs=[('get_jobs_summary', {'id__in': ['180']}, True,
    226                             [results[0]]),
    227                            ('get_host_queue_entries', {'job__in': ['180']},
    228                             True,
    229                             [{u'status': u'Failed',
    230                               u'complete': 1,
    231                               u'host': {u'status': u'Repair Failed',
    232                                         u'locked': False,
    233                                         u'hostname': u'host0',
    234                                         u'invalid': True,
    235                                         u'id': 4432},
    236                               u'priority': 1,
    237                               u'meta_host': None,
    238                               u'job': {u'control_file': u"def run(machine):\n\thost = hosts.create_host(machine)\n\tat = autotest.Autotest(host)\n\tat.run_test('sleeptest')\n\nparallel_simple(run, machines)",
    239                                        u'name': u'test_sleep',
    240                                        u'control_type': SERVER,
    241                                        u'synchronizing': 0,
    242                                        u'priority': priorities.Priority.DEFAULT,
    243                                        u'owner': u'user0',
    244                                        u'created_on': u'2008-03-18 11:27:29',
    245                                        u'synch_count': 1,
    246                                        u'id': 180},
    247                               u'active': 0,
    248                               u'id': 101084}])],
    249                      out_words_ok=['test_job0', 'host0', 'Failed',
    250                                    'Aborted'])
    251 
    252 
    253 
    254     def test_job_stat_list_unassigned_host(self):
    255         self.run_cmd(argv=['atest', 'job', 'stat', '6761',
    256                            '--list-hosts'],
    257                      rpcs=[('get_jobs_summary', {'id__in': ['6761']}, True,
    258                             [{u'status_counts': {u'Queued': 1},
    259                               u'control_file': u'def step_init():\n    job.next_step(\'step0\')\n\ndef step0():\n    AUTHOR = "mbligh (at] google.com (Martin Bligh)"\n    NAME = "Kernbench"\n    TIME = "SHORT"\n    TEST_CLASS = "Kernel"\n    TEST_CATEGORY = "Benchmark"\n    TEST_TYPE = "client"\n    \n    DOC = """\n    A standard CPU benchmark. Runs a kernel compile and measures the performance.\n    """\n    \n    job.run_test(\'kernbench\')',
    260                               u'name': u'test_on_meta_hosts',
    261                               u'control_type': CLIENT,
    262                               u'run_verify': 1,
    263                               u'priority': priorities.Priority.DEFAULT,
    264                               u'owner': u'user0',
    265                               u'created_on': u'2008-07-30 22:15:43',
    266                               u'timeout': 144,
    267                               u'synch_count': 1,
    268                               u'id': 6761}]),
    269                            ('get_host_queue_entries', {'job__in': ['6761']},
    270                             True,
    271                             [{u'status': u'Queued',
    272                               u'complete': 0,
    273                               u'deleted': 0,
    274                               u'host': None,
    275                               u'priority': 1,
    276                               u'meta_host': u'Xeon',
    277                               u'job': {u'control_file': u'def step_init():\n    job.next_step(\'step0\')\n\ndef step0():\n    AUTHOR = "mbligh (at] google.com (Martin Bligh)"\n    NAME = "Kernbench"\n    TIME = "SHORT"\n    TEST_CLASS = "Kernel"\n    TEST_CATEGORY = "Benchmark"\n    TEST_TYPE = "client"\n    \n    DOC = """\n    A standard CPU benchmark. Runs a kernel compile and measures the performance.\n    """\n    \n    job.run_test(\'kernbench\')',
    278                                        u'name': u'test_on_meta_hosts',
    279                                        u'control_type': CLIENT,
    280                                        u'run_verify': 1,
    281                                        u'priority': priorities.Priority.DEFAULT,
    282                                        u'owner': u'user0',
    283                                        u'created_on': u'2008-07-30 22:15:43',
    284                                        u'timeout': 144,
    285                                        u'synch_count': 1,
    286                                        u'id': 6761},
    287                               u'active': 0,
    288                               u'id': 193166} ])],
    289                      err_words_ok=['unassigned', 'meta-hosts'],
    290                      out_words_no=['Xeon'])
    291 
    292 
    293     def test_job_stat_list_hosts(self):
    294         self.run_cmd(argv=['atest', 'job', 'stat', '6761',
    295                            '--list-hosts'],
    296                      rpcs=[('get_jobs_summary', {'id__in': ['6761']}, True,
    297                             [{u'status_counts': {u'Queued': 1},
    298                               u'control_file': u'def step_init():\n    job.next_step(\'step0\')\n\ndef step0():\n    AUTHOR = "mbligh (at] google.com (Martin Bligh)"\n    NAME = "Kernbench"\n    TIME = "SHORT"\n    TEST_CLASS = "Kernel"\n    TEST_CATEGORY = "Benchmark"\n    TEST_TYPE = "client"\n    \n    DOC = """\n    A standard CPU benchmark. Runs a kernel compile and measures the performance.\n    """\n    \n    job.run_test(\'kernbench\')',
    299                               u'name': u'test_on_meta_hosts',
    300                               u'control_type': CLIENT,
    301                               u'run_verify': 1,
    302                               u'priority': priorities.Priority.DEFAULT,
    303                               u'owner': u'user0',
    304                               u'created_on': u'2008-07-30 22:15:43',
    305                               u'timeout': 144,
    306                               u'synch_count': 1,
    307                               u'id': 6761}]),
    308                            ('get_host_queue_entries', {'job__in': ['6761']},
    309                             True,
    310                             [{u'status': u'Queued',
    311                               u'complete': 0,
    312                               u'deleted': 0,
    313                               u'host': {u'status': u'Running',
    314                                         u'lock_time': None,
    315                                         u'hostname': u'host41',
    316                                         u'locked': False,
    317                                         u'locked_by': None,
    318                                         u'invalid': False,
    319                                         u'id': 4833,
    320                                         u'protection': u'Repair filesystem only'},
    321                               u'priority': 1,
    322                               u'meta_host': u'Xeon',
    323                               u'job': {u'control_file': u'def step_init():\n    job.next_step(\'step0\')\n\ndef step0():\n    AUTHOR = "mbligh (at] google.com (Martin Bligh)"\n    NAME = "Kernbench"\n    TIME = "SHORT"\n    TEST_CLASS = "Kernel"\n    TEST_CATEGORY = "Benchmark"\n    TEST_TYPE = "client"\n    \n    DOC = """\n    A standard CPU benchmark. Runs a kernel compile and measures the performance.\n    """\n    \n    job.run_test(\'kernbench\')',
    324                                        u'name': u'test_on_meta_hosts',
    325                                        u'control_type': CLIENT,
    326                                        u'run_verify': 1,
    327                                        u'priority': priorities.Priority.DEFAULT,
    328                                        u'owner': u'user0',
    329                                        u'created_on': u'2008-07-30 22:15:43',
    330                                        u'timeout': 144,
    331                                        u'synch_count': 1,
    332                                        u'id': 6761},
    333                               u'active': 0,
    334                               u'id': 193166},
    335                             {u'status': u'Running',
    336                               u'complete': 0,
    337                               u'deleted': 0,
    338                               u'host': {u'status': u'Running',
    339                                         u'lock_time': None,
    340                                         u'hostname': u'host42',
    341                                         u'locked': False,
    342                                         u'locked_by': None,
    343                                         u'invalid': False,
    344                                         u'id': 4833,
    345                                         u'protection': u'Repair filesystem only'},
    346                               u'priority': 1,
    347                               u'meta_host': u'Xeon',
    348                               u'job': {u'control_file': u'def step_init():\n    job.next_step(\'step0\')\n\ndef step0():\n    AUTHOR = "mbligh (at] google.com (Martin Bligh)"\n    NAME = "Kernbench"\n    TIME = "SHORT"\n    TEST_CLASS = "Kernel"\n    TEST_CATEGORY = "Benchmark"\n    TEST_TYPE = "client"\n    \n    DOC = """\n    A standard CPU benchmark. Runs a kernel compile and measures the performance.\n    """\n    \n    job.run_test(\'kernbench\')',
    349                                        u'name': u'test_on_meta_hosts',
    350                                        u'control_type': CLIENT,
    351                                        u'run_verify': 1,
    352                                        u'priority': priorities.Priority.DEFAULT,
    353                                        u'owner': u'user0',
    354                                        u'created_on': u'2008-07-30 22:15:43',
    355                                        u'timeout': 144,
    356                                        u'synch_count': 1,
    357                                        u'id': 6761},
    358                               u'active': 0,
    359                               u'id': 193166} ])],
    360                      out_words_ok=['host41', 'host42'],
    361                      out_words_no=['Xeon', 'Running', 'Queued'],
    362                      err_words_no=['unassigned'])
    363 
    364 
    365     def test_job_stat_list_hosts_status(self):
    366         self.run_cmd(argv=['atest', 'job', 'stat', '6761',
    367                            '--list-hosts-status', 'Running,Queued'],
    368                      rpcs=[('get_jobs_summary', {'id__in': ['6761']}, True,
    369                             [{u'status_counts': {u'Queued': 1, u'Running': 1},
    370                               u'control_file': u'def step_init():\n    job.next_step(\'step0\')\n\ndef step0():\n    AUTHOR = "mbligh (at] google.com (Martin Bligh)"\n    NAME = "Kernbench"\n    TIME = "SHORT"\n    TEST_CLASS = "Kernel"\n    TEST_CATEGORY = "Benchmark"\n    TEST_TYPE = "client"\n    \n    DOC = """\n    A standard CPU benchmark. Runs a kernel compile and measures the performance.\n    """\n    \n    job.run_test(\'kernbench\')',
    371                               u'name': u'test',
    372                               u'control_type': CLIENT,
    373                               u'run_verify': 1,
    374                               u'priority': priorities.Priority.DEFAULT,
    375                               u'owner': u'user0',
    376                               u'created_on': u'2008-07-30 22:15:43',
    377                               u'timeout': 144,
    378                               u'synch_count': 1,
    379                               u'id': 6761}]),
    380                            ('get_host_queue_entries', {'job__in': ['6761']},
    381                             True,
    382                             [{u'status': u'Queued',
    383                               u'complete': 0,
    384                               u'deleted': 0,
    385                               u'host': {u'status': u'Queued',
    386                                         u'lock_time': None,
    387                                         u'hostname': u'host41',
    388                                         u'locked': False,
    389                                         u'locked_by': None,
    390                                         u'invalid': False,
    391                                         u'id': 4833,
    392                                         u'protection': u'Repair filesystem only'},
    393                               u'priority': 1,
    394                               u'meta_host': None,
    395                               u'job': {u'control_file': u'def step_init():\n    job.next_step(\'step0\')\n\ndef step0():\n    AUTHOR = "mbligh (at] google.com (Martin Bligh)"\n    NAME = "Kernbench"\n    TIME = "SHORT"\n    TEST_CLASS = "Kernel"\n    TEST_CATEGORY = "Benchmark"\n    TEST_TYPE = "client"\n    \n    DOC = """\n    A standard CPU benchmark. Runs a kernel compile and measures the performance.\n    """\n    \n    job.run_test(\'kernbench\')',
    396                                        u'name': u'test',
    397                                        u'control_type': CLIENT,
    398                                        u'run_verify': 1,
    399                                        u'priority': priorities.Priority.DEFAULT,
    400                                        u'owner': u'user0',
    401                                        u'created_on': u'2008-07-30 22:15:43',
    402                                        u'timeout': 144,
    403                                        u'synch_count': 1,
    404                                        u'id': 6761},
    405                               u'active': 0,
    406                               u'id': 193166},
    407                             {u'status': u'Running',
    408                               u'complete': 0,
    409                               u'deleted': 0,
    410                               u'host': {u'status': u'Running',
    411                                         u'lock_time': None,
    412                                         u'hostname': u'host42',
    413                                         u'locked': False,
    414                                         u'locked_by': None,
    415                                         u'invalid': False,
    416                                         u'id': 4833,
    417                                         u'protection': u'Repair filesystem only'},
    418                               u'priority': 1,
    419                               u'meta_host': None,
    420                               u'job': {u'control_file': u'def step_init():\n    job.next_step(\'step0\')\n\ndef step0():\n    AUTHOR = "mbligh (at] google.com (Martin Bligh)"\n    NAME = "Kernbench"\n    TIME = "SHORT"\n    TEST_CLASS = "Kernel"\n    TEST_CATEGORY = "Benchmark"\n    TEST_TYPE = "client"\n    \n    DOC = """\n    A standard CPU benchmark. Runs a kernel compile and measures the performance.\n    """\n    \n    job.run_test(\'kernbench\')',
    421                                        u'name': u'test',
    422                                        u'control_type': CLIENT,
    423                                        u'run_verify': 1,
    424                                        u'priority': priorities.Priority.DEFAULT,
    425                                        u'owner': u'user0',
    426                                        u'created_on': u'2008-07-30 22:15:43',
    427                                        u'timeout': 144,
    428                                        u'synch_count': 1,
    429                                        u'id': 6761},
    430                               u'active': 0,
    431                               u'id': 193166} ])],
    432                      out_words_ok=['Queued', 'Running', 'host41', 'host42'],
    433                      out_words_no=['Xeon'],
    434                      err_words_no=['unassigned'])
    435 
    436 
    437     def test_job_stat_job_multiple_hosts(self):
    438         self.run_cmd(argv=['atest', 'job', 'stat', '6761'],
    439                      rpcs=[('get_jobs_summary', {'id__in': ['6761']}, True,
    440                             [{u'status_counts': {u'Running': 1,
    441                                                  u'Queued': 4},
    442                               u'control_file': u'def step_init():\n    job.next_step(\'step0\')\n\ndef step0():\n    AUTHOR = "mbligh (at] google.com (Martin Bligh)"\n    NAME = "Kernbench"\n    TIME = "SHORT"\n    TEST_CLASS = "Kernel"\n    TEST_CATEGORY = "Benchmark"\n    TEST_TYPE = "client"\n    \n    DOC = """\n    A standard CPU benchmark. Runs a kernel compile and measures the performance.\n    """\n    \n    job.run_test(\'kernbench\')',
    443                               u'name': u'test_on_meta_hosts',
    444                               u'control_type': CLIENT,
    445                               u'run_verify': 1,
    446                               u'priority': priorities.Priority.DEFAULT,
    447                               u'owner': u'user0',
    448                               u'created_on': u'2008-07-30 22:15:43',
    449                               u'timeout': 144,
    450                               u'synch_count': 1,
    451                               u'id': 6761}]),
    452                            ('get_host_queue_entries', {'job__in': ['6761']},
    453                             True,
    454                             [{u'status': u'Queued',
    455                               u'complete': 0,
    456                               u'deleted': 0,
    457                               u'host': None,
    458                               u'priority': 1,
    459                               u'meta_host': u'Xeon',
    460                               u'job': {u'control_file': u'def step_init():\n    job.next_step(\'step0\')\n\ndef step0():\n    AUTHOR = "mbligh (at] google.com (Martin Bligh)"\n    NAME = "Kernbench"\n    TIME = "SHORT"\n    TEST_CLASS = "Kernel"\n    TEST_CATEGORY = "Benchmark"\n    TEST_TYPE = "client"\n    \n    DOC = """\n    A standard CPU benchmark. Runs a kernel compile and measures the performance.\n    """\n    \n    job.run_test(\'kernbench\')',
    461                                        u'name': u'test_on_meta_hosts',
    462                                        u'control_type': CLIENT,
    463                                        u'run_verify': 1,
    464                                        u'priority': priorities.Priority.DEFAULT,
    465                                        u'owner': u'user0',
    466                                        u'created_on': u'2008-07-30 22:15:43',
    467                                        u'timeout': 144,
    468                                        u'synch_count': 1,
    469                                        u'id': 6761},
    470                               u'active': 0,
    471                               u'id': 193166},
    472                              {u'status': u'Queued',
    473                               u'complete': 0,
    474                               u'deleted': 0,
    475                               u'host': None,
    476                               u'priority': 1,
    477                               u'meta_host': u'Xeon',
    478                               u'job': {u'control_file': u'def step_init():\n    job.next_step(\'step0\')\n\ndef step0():\n    AUTHOR = "mbligh (at] google.com (Martin Bligh)"\n    NAME = "Kernbench"\n    TIME = "SHORT"\n    TEST_CLASS = "Kernel"\n    TEST_CATEGORY = "Benchmark"\n    TEST_TYPE = "client"\n    \n    DOC = """\n    A standard CPU benchmark. Runs a kernel compile and measures the performance.\n    """\n    \n    job.run_test(\'kernbench\')',
    479                                        u'name': u'test_on_meta_hosts',
    480                                        u'control_type': CLIENT,
    481                                        u'run_verify': 1,
    482                                        u'priority': priorities.Priority.DEFAULT,
    483                                        u'owner': u'user0',
    484                                        u'created_on': u'2008-07-30 22:15:43',
    485                                        u'timeout': 144,
    486                                        u'synch_count': 1,
    487                                        u'id': 6761},
    488                               u'active': 0,
    489                               u'id': 193167},
    490                              {u'status': u'Queued',
    491                               u'complete': 0,
    492                               u'deleted': 0,
    493                               u'host': None,
    494                               u'priority': 1,
    495                               u'meta_host': u'Athlon',
    496                               u'job': {u'control_file': u'def step_init():\n    job.next_step(\'step0\')\n\ndef step0():\n    AUTHOR = "mbligh (at] google.com (Martin Bligh)"\n    NAME = "Kernbench"\n    TIME = "SHORT"\n    TEST_CLASS = "Kernel"\n    TEST_CATEGORY = "Benchmark"\n    TEST_TYPE = "client"\n    \n    DOC = """\n    A standard CPU benchmark. Runs a kernel compile and measures the performance.\n    """\n    \n    job.run_test(\'kernbench\')',
    497                                        u'name': u'test_on_meta_hosts',
    498                                        u'control_type': CLIENT,
    499                                        u'run_verify': 1,
    500                                        u'priority': priorities.Priority.DEFAULT,
    501                                        u'owner': u'user0',
    502                                        u'created_on': u'2008-07-30 22:15:43',
    503                                        u'timeout': 144,
    504                                        u'synch_count': 1,
    505                                        u'id': 6761},
    506                               u'active': 0,
    507                               u'id': 193168},
    508                              {u'status': u'Queued',
    509                               u'complete': 0,
    510                               u'deleted': 0,
    511                               u'host': None,
    512                               u'priority': 1,
    513                               u'meta_host': u'x286',
    514                               u'job': {u'control_file': u'def step_init():\n    job.next_step(\'step0\')\n\ndef step0():\n    AUTHOR = "mbligh (at] google.com (Martin Bligh)"\n    NAME = "Kernbench"\n    TIME = "SHORT"\n    TEST_CLASS = "Kernel"\n    TEST_CATEGORY = "Benchmark"\n    TEST_TYPE = "client"\n    \n    DOC = """\n    A standard CPU benchmark. Runs a kernel compile and measures the performance.\n    """\n    \n    job.run_test(\'kernbench\')',
    515                                        u'name': u'test_on_meta_hosts',
    516                                        u'control_type': CLIENT,
    517                                        u'run_verify': 1,
    518                                        u'priority': priorities.Priority.DEFAULT,
    519                                        u'owner': u'user0',
    520                                        u'created_on': u'2008-07-30 22:15:43',
    521                                        u'timeout': 144,
    522                                        u'synch_count': 1,
    523                                        u'id': 6761},
    524                               u'active': 0,
    525                               u'id': 193169},
    526                              {u'status': u'Running',
    527                               u'complete': 0,
    528                               u'deleted': 0,
    529                               u'host': {u'status': u'Running',
    530                                         u'lock_time': None,
    531                                         u'hostname': u'host42',
    532                                         u'locked': False,
    533                                         u'locked_by': None,
    534                                         u'invalid': False,
    535                                         u'id': 4833,
    536                                         u'protection': u'Repair filesystem only'},
    537                               u'priority': 1,
    538                               u'meta_host': u'Athlon',
    539                               u'job': {u'control_file': u'def step_init():\n    job.next_step(\'step0\')\n\ndef step0():\n    AUTHOR = "mbligh (at] google.com (Martin Bligh)"\n    NAME = "Kernbench"\n    TIME = "SHORT"\n    TEST_CLASS = "Kernel"\n    TEST_CATEGORY = "Benchmark"\n    TEST_TYPE = "client"\n    \n    DOC = """\n    A standard CPU benchmark. Runs a kernel compile and measures the performance.\n    """\n    \n    job.run_test(\'kernbench\')',
    540                                        u'name': u'test_on_meta_hosts',
    541                                        u'control_type': CLIENT,
    542                                        u'run_verify': 1,
    543                                        u'priority': priorities.Priority.DEFAULT,
    544                                        u'owner': u'user0',
    545                                        u'created_on': u'2008-07-30 22:15:43',
    546                                        u'timeout': 144,
    547                                        u'synch_count': 1,
    548                                        u'id': 6761},
    549                               u'active': 1,
    550                               u'id': 193170} ])],
    551                      out_words_ok=['test_on_meta_hosts',
    552                                    'host42', 'Queued', 'Running'],
    553                      out_words_no=['Athlon', 'Xeon', 'x286'])
    554 
    555 
    556     def test_job_stat_job_no_host_in_qes(self):
    557         results = copy.deepcopy(self.results)
    558         self.run_cmd(argv=['atest', 'job', 'stat', '180'],
    559                      rpcs=[('get_jobs_summary', {'id__in': ['180']}, True,
    560                             [results[0]]),
    561                            ('get_host_queue_entries', {'job__in': ['180']},
    562                             True,
    563                             [{u'status': u'Failed',
    564                               u'complete': 1,
    565                               u'host': None,
    566                               u'priority': 1,
    567                               u'meta_host': None,
    568                               u'job': {u'control_file': u"def run(machine):\n\thost = hosts.create_host(machine)\n\tat = autotest.Autotest(host)\n\tat.run_test('sleeptest')\n\nparallel_simple(run, machines)",
    569                                        u'name': u'test_sleep',
    570                                        u'control_type': SERVER,
    571                                        u'priority': priorities.Priority.DEFAULT,
    572                                        u'owner': u'user0',
    573                                        u'created_on': u'2008-03-18 11:27:29',
    574                                        u'synch_count': 1,
    575                                        u'id': 180},
    576                               u'active': 0,
    577                               u'id': 101084}])],
    578                      err_words_ok=['unassigned', 'meta-hosts'])
    579 
    580 
    581     def test_job_stat_multi_jobs(self):
    582         results = copy.deepcopy(self.results)
    583         self.run_cmd(argv=['atest', 'job', 'stat', '180', '338'],
    584                      rpcs=[('get_jobs_summary', {'id__in': ['180', '338']},
    585                             True, results),
    586                            ('get_host_queue_entries',
    587                             {'job__in': ['180', '338']},
    588                             True,
    589                             [{u'status': u'Failed',
    590                               u'complete': 1,
    591                               u'host': {u'status': u'Repair Failed',
    592                                         u'locked': False,
    593                                         u'hostname': u'host0',
    594                                         u'invalid': True,
    595                                         u'id': 4432},
    596                               u'priority': 1,
    597                               u'meta_host': None,
    598                               u'job': {u'control_file': u"def run(machine):\n\thost = hosts.create_host(machine)\n\tat = autotest.Autotest(host)\n\tat.run_test('sleeptest')\n\nparallel_simple(run, machines)",
    599                                        u'name': u'test_sleep',
    600                                        u'control_type': SERVER,
    601                                        u'priority': priorities.Priority.DEFAULT,
    602                                        u'owner': u'user0',
    603                                        u'created_on': u'2008-03-18 11:27:29',
    604                                        u'synch_count': 1,
    605                                        u'id': 180},
    606                               u'active': 0,
    607                               u'id': 101084},
    608                              {u'status': u'Failed',
    609                               u'complete': 1,
    610                               u'host': {u'status': u'Repair Failed',
    611                                         u'locked': False,
    612                                         u'hostname': u'host10',
    613                                         u'invalid': True,
    614                                         u'id': 4432},
    615                               u'priority': 1,
    616                               u'meta_host': None,
    617                               u'job': {u'control_file': u"def run(machine):\n\thost = hosts.create_host(machine)\n\tat = autotest.Autotest(host)\n\tat.run_test('sleeptest')\n\nparallel_simple(run, machines)",
    618                                        u'name': u'test_sleep',
    619                                        u'control_type': SERVER,
    620                                        u'priority': priorities.Priority.DEFAULT,
    621                                        u'owner': u'user0',
    622                                        u'created_on': u'2008-03-18 11:27:29',
    623                                        u'synch_count': 1,
    624                                        u'id': 338},
    625                               u'active': 0,
    626                               u'id': 101084}])],
    627                      out_words_ok=['test_job0', 'test_job1'])
    628 
    629 
    630     def test_job_stat_multi_jobs_name_id(self):
    631         self.run_cmd(argv=['atest', 'job', 'stat', 'mytest', '180'],
    632                      rpcs=[('get_jobs_summary', {'id__in': ['180']},
    633                             True,
    634                             [{u'status_counts': {u'Aborted': 1},
    635                              u'control_file':
    636                              u"job.run_test('sleeptest')\n",
    637                              u'name': u'job0',
    638                              u'control_type': SERVER,
    639                              u'priority':
    640                              priorities.Priority.DEFAULT,
    641                              u'owner': u'user0',
    642                              u'created_on':
    643                              u'2008-07-08 17:45:44',
    644                              u'synch_count': 2,
    645                              u'id': 180}]),
    646                            ('get_jobs_summary', {'name__in': ['mytest']},
    647                             True,
    648                             [{u'status_counts': {u'Queued': 1},
    649                              u'control_file':
    650                              u"job.run_test('sleeptest')\n",
    651                              u'name': u'mytest',
    652                              u'control_type': CLIENT,
    653                              u'priority':
    654                              priorities.Priority.DEFAULT,
    655                              u'owner': u'user0',
    656                              u'created_on': u'2008-07-08 12:17:47',
    657                              u'synch_count': 1,
    658                              u'id': 338}]),
    659                            ('get_host_queue_entries',
    660                             {'job__in': ['180']},
    661                             True,
    662                             [{u'status': u'Failed',
    663                               u'complete': 1,
    664                               u'host': {u'status': u'Repair Failed',
    665                                         u'locked': False,
    666                                         u'hostname': u'host0',
    667                                         u'invalid': True,
    668                                         u'id': 4432},
    669                               u'priority': 1,
    670                               u'meta_host': None,
    671                               u'job': {u'control_file': u"def run(machine):\n\thost = hosts.create_host(machine)\n\tat = autotest.Autotest(host)\n\tat.run_test('sleeptest')\n\nparallel_simple(run, machines)",
    672                                        u'name': u'test_sleep',
    673                                        u'control_type': SERVER,
    674                                        u'synchronizing': 0,
    675                                        u'priority': priorities.Priority.DEFAULT,
    676                                        u'owner': u'user0',
    677                                        u'created_on': u'2008-03-18 11:27:29',
    678                                        u'synch_count': 1,
    679                                        u'id': 180},
    680                               u'active': 0,
    681                               u'id': 101084}]),
    682                            ('get_host_queue_entries',
    683                             {'job__name__in': ['mytest']},
    684                             True,
    685                             [{u'status': u'Failed',
    686                               u'complete': 1,
    687                               u'host': {u'status': u'Repair Failed',
    688                                         u'locked': False,
    689                                         u'hostname': u'host10',
    690                                         u'invalid': True,
    691                                         u'id': 4432},
    692                               u'priority': 1,
    693                               u'meta_host': None,
    694                               u'job': {u'control_file': u"def run(machine):\n\thost = hosts.create_host(machine)\n\tat = autotest.Autotest(host)\n\tat.run_test('sleeptest')\n\nparallel_simple(run, machines)",
    695                                        u'name': u'test_sleep',
    696                                        u'control_type': SERVER,
    697                                        u'synchronizing': 0,
    698                                        u'priority': priorities.Priority.DEFAULT,
    699                                        u'owner': u'user0',
    700                                        u'created_on': u'2008-03-18 11:27:29',
    701                                        u'synch_count': 1,
    702                                        u'id': 338},
    703                               u'active': 0,
    704                               u'id': 101084}])],
    705                      out_words_ok=['job0', 'mytest', 'Aborted', 'Queued',
    706                                    'Failed', str(priorities.Priority.DEFAULT)])
    707 
    708 
    709 class job_create_unittest(cli_mock.cli_unittest):
    710     ctrl_file = '\ndef step_init():\n    job.next_step(\'step0\')\n\ndef step0():\n    AUTHOR = "Autotest Team"\n    NAME = "Sleeptest"\n  TIME =\n    "SHORT"\n    TEST_CATEGORY = "Functional"\n    TEST_CLASS = "General"\n\n    TEST_TYPE = "client"\n \n    DOC = """\n    This test simply sleeps for 1\n    second by default.  It\'s a good way to test\n    profilers and double check\n    that autotest is working.\n The seconds argument can also be modified to\n    make the machine sleep for as\n    long as needed.\n    """\n   \n\n    job.run_test(\'sleeptest\', seconds = 1)'
    711 
    712     kernel_ctrl_file = 'kernel = \'kernel\'\ndef step_init():\n    job.next_step([step_test])\n\ndef step_test():\n    job.next_step(\'step0\')\n\ndef step0():\n    AUTHOR = "Autotest Team"\n    NAME = "Sleeptest"\n    TIME = "SHORT"\n    TEST_CATEGORY = "Functional"\n    TEST_CLASS = "General"\n    TEST_TYPE = "client"\n    \n    DOC = """\n    This test simply sleeps for 1 second by default.  It\'s a good way to test\n    profilers and double check that autotest is working.\n    The seconds argument can also be modified to make the machine sleep for as\n    long as needed.\n    """\n    \n    job.run_test(\'sleeptest\', seconds = 1)'
    713 
    714     trivial_ctrl_file = 'print "Hello"\n'
    715 
    716     data = {'priority': priorities.Priority.DEFAULT, 'control_file': ctrl_file,
    717             'hosts': ['host0'],
    718             'name': 'test_job0', 'control_type': CLIENT, 'email_list': '',
    719             'meta_hosts': [], 'synch_count': 1, 'dependencies': [],
    720             'require_ssp': False}
    721 
    722 
    723     def test_execute_create_job(self):
    724         self.run_cmd(argv=['atest', 'job', 'create', '-t', 'sleeptest',
    725                            'test_job0', '-m', 'host0'],
    726                      rpcs=[('generate_control_file',
    727                             {'tests': ['sleeptest']},
    728                             True,
    729                             {'control_file' : self.ctrl_file,
    730                              'synch_count' : 1,
    731                              'is_server' : False,
    732                              'dependencies' : []}),
    733                            ('create_job', self.data, True, 180)],
    734                      out_words_ok=['test_job0', 'Created'],
    735                      out_words_no=['Uploading', 'Done'])
    736 
    737 
    738     def test_execute_create_job_with_control(self):
    739         file_temp = cli_mock.create_file(self.ctrl_file)
    740         self.run_cmd(argv=['atest', 'job', 'create', '-f', file_temp.name,
    741                            'test_job0', '-m', 'host0'],
    742                      rpcs=[('create_job', self.data, True, 42)],
    743                      out_words_ok=['test_job0', 'Created'],
    744                      out_words_no=['Uploading', 'Done'])
    745         file_temp.clean()
    746 
    747 
    748     def test_execute_create_job_with_control_and_email(self):
    749         data = self.data.copy()
    750         data['email_list'] = 'em'
    751         file_temp = cli_mock.create_file(self.ctrl_file)
    752         self.run_cmd(argv=['atest', 'job', 'create', '-f', file_temp.name,
    753                            'test_job0', '-m', 'host0', '-e', 'em'],
    754                      rpcs=[('create_job', data, True, 42)],
    755                      out_words_ok=['test_job0', 'Created'],
    756                      out_words_no=['Uploading', 'Done'])
    757         file_temp.clean()
    758 
    759 
    760     def test_execute_create_job_with_control_and_dependencies(self):
    761         data = self.data.copy()
    762         data['dependencies'] = ['dep1', 'dep2']
    763         file_temp = cli_mock.create_file(self.ctrl_file)
    764         self.run_cmd(argv=['atest', 'job', 'create', '-f', file_temp.name,
    765                            'test_job0', '-m', 'host0', '-d', 'dep1, dep2 '],
    766                      rpcs=[('create_job', data, True, 42)],
    767                      out_words_ok=['test_job0', 'Created'],
    768                      out_words_no=['Uploading', 'Done'])
    769         file_temp.clean()
    770 
    771 
    772     def test_execute_create_job_with_control_and_comma_dependencies(self):
    773         data = self.data.copy()
    774         data['dependencies'] = ['dep2,False', 'dep1,True']
    775         file_temp = cli_mock.create_file(self.ctrl_file)
    776         self.run_cmd(argv=['atest', 'job', 'create', '-f', file_temp.name,
    777                            'test_job0', '-m', 'host0', '-d',
    778                            'dep1\,True, dep2\,False '],
    779                      rpcs=[('create_job', data, True, 42)],
    780                      out_words_ok=['test_job0', 'Created'],
    781                      out_words_no=['Uploading', 'Done'])
    782         file_temp.clean()
    783 
    784 
    785     def test_execute_create_job_with_synch_count(self):
    786         data = self.data.copy()
    787         data['synch_count'] = 2
    788         file_temp = cli_mock.create_file(self.ctrl_file)
    789         self.run_cmd(argv=['atest', 'job', 'create', '-f', file_temp.name,
    790                            'test_job0', '-m', 'host0', '-y', '2'],
    791                      rpcs=[('create_job', data, True, 42)],
    792                      out_words_ok=['test_job0', 'Created'],
    793                      out_words_no=['Uploading', 'Done'])
    794         file_temp.clean()
    795 
    796 
    797     def test_execute_create_job_with_test_and_dependencies(self):
    798         data = self.data.copy()
    799         data['dependencies'] = ['dep1', 'dep2', 'dep3']
    800         self.run_cmd(argv=['atest', 'job', 'create', '-t', 'sleeptest',
    801                            'test_job0', '-m', 'host0', '-d', 'dep1, dep2 '],
    802                      rpcs=[('generate_control_file',
    803                             {'tests': ['sleeptest']},
    804                             True,
    805                             {'control_file' : self.ctrl_file,
    806                              'synch_count' : 1,
    807                              'is_server' : False,
    808                              'dependencies' : ['dep3']}),
    809                            ('create_job', data, True, 42)],
    810                      out_words_ok=['test_job0', 'Created'],
    811                      out_words_no=['Uploading', 'Done'])
    812 
    813 
    814     def test_execute_create_job_with_test_and_comma_dependencies(self):
    815         data = self.data.copy()
    816         data['dependencies'] = ['dep1,True', 'dep2,False', 'dep3,123']
    817         self.run_cmd(argv=['atest', 'job', 'create', '-t', 'sleeptest',
    818                            'test_job0', '-m', 'host0', '-d',
    819                            'dep1\,True dep2\,False '],
    820                      rpcs=[('generate_control_file',
    821                             {'tests': ['sleeptest']},
    822                             True,
    823                             {'control_file' : self.ctrl_file,
    824                              'synch_count' : 1,
    825                              'is_server' : False,
    826                              'dependencies' : ['dep3,123']}),
    827                            ('create_job', data, True, 42)],
    828                      out_words_ok=['test_job0', 'Created'],
    829                      out_words_no=['Uploading', 'Done'])
    830 
    831 
    832     def test_execute_create_job_no_args(self):
    833         testjob = job.job_create()
    834         sys.argv = ['atest', 'job', 'create']
    835         self.god.mock_io()
    836         (sys.exit.expect_call(mock.anything_comparator())
    837          .and_raises(cli_mock.ExitException))
    838         self.assertRaises(cli_mock.ExitException, testjob.parse)
    839         self.god.unmock_io()
    840         self.god.check_playback()
    841 
    842 
    843     def test_execute_create_job_no_hosts(self):
    844         testjob = job.job_create()
    845         file_temp = cli_mock.create_file(self.ctrl_file)
    846         sys.argv = ['atest', '-f', file_temp.name, 'test_job0']
    847         self.god.mock_io()
    848         (sys.exit.expect_call(mock.anything_comparator())
    849          .and_raises(cli_mock.ExitException))
    850         self.assertRaises(cli_mock.ExitException, testjob.parse)
    851         self.god.unmock_io()
    852         self.god.check_playback()
    853         file_temp.clean()
    854 
    855 
    856     def test_execute_create_job_cfile_and_tests(self):
    857         testjob = job.job_create()
    858         sys.argv = ['atest', 'job', 'create', '-t', 'sleeptest', '-f',
    859                     'control_file', 'test_job0', '-m', 'host0']
    860         self.god.mock_io()
    861         (sys.exit.expect_call(mock.anything_comparator())
    862          .and_raises(cli_mock.ExitException))
    863         self.assertRaises(cli_mock.ExitException, testjob.parse)
    864         self.god.unmock_io()
    865         self.god.check_playback()
    866 
    867 
    868     def test_execute_create_job_bad_cfile(self):
    869         testjob = job.job_create()
    870         sys.argv = ['atest', 'job', 'create', '-f', 'control_file',
    871                     'test_job0', '-m', 'host0']
    872         self.god.mock_io()
    873         (sys.exit.expect_call(mock.anything_comparator())
    874          .and_raises(IOError))
    875         self.assertRaises(IOError, testjob.parse)
    876         self.god.unmock_io()
    877 
    878 
    879     def test_execute_create_job_bad_priority(self):
    880         testjob = job.job_create()
    881         sys.argv = ['atest', 'job', 'create', '-t', 'sleeptest', '-p', 'Uber',
    882                     '-m', 'host0', 'test_job0']
    883         self.god.mock_io()
    884         (sys.exit.expect_call(mock.anything_comparator())
    885          .and_raises(cli_mock.ExitException))
    886         self.assertRaises(cli_mock.ExitException, testjob.parse)
    887         self.god.unmock_io()
    888         self.god.check_playback()
    889 
    890 
    891     def test_execute_create_job_with_mfile(self):
    892         data = self.data.copy()
    893         data['hosts'] = ['host3', 'host2', 'host1', 'host0']
    894         ctemp = cli_mock.create_file(self.ctrl_file)
    895         file_temp = cli_mock.create_file('host0\nhost1\nhost2\nhost3')
    896         self.run_cmd(argv=['atest', 'job', 'create', '--mlist', file_temp.name,
    897                            '-f', ctemp.name, 'test_job0'],
    898                      rpcs=[('create_job', data, True, 42)],
    899                      out_words_ok=['test_job0', 'Created'])
    900         ctemp.clean()
    901         file_temp.clean()
    902 
    903 
    904     def test_execute_create_job_with_timeout(self):
    905         data = self.data.copy()
    906         data['timeout_mins'] = '13320'
    907         file_temp = cli_mock.create_file(self.ctrl_file)
    908         self.run_cmd(argv=['atest', 'job', 'create', '-f', file_temp.name,
    909                            'test_job0', '-m', 'host0', '-o', '13320'],
    910                      rpcs=[('create_job', data, True, 42)],
    911                      out_words_ok=['test_job0', 'Created'],)
    912         file_temp.clean()
    913 
    914 
    915     def test_execute_create_job_with_max_runtime(self):
    916         data = self.data.copy()
    917         data['max_runtime_mins'] = '13320'
    918         file_temp = cli_mock.create_file(self.ctrl_file)
    919         self.run_cmd(argv=['atest', 'job', 'create', '-f', file_temp.name,
    920                            'test_job0', '-m', 'host0', '--max_runtime',
    921                            '13320'],
    922                      rpcs=[('create_job', data, True, 42)],
    923                      out_words_ok=['test_job0', 'Created'],)
    924         file_temp.clean()
    925 
    926 
    927 
    928     def test_execute_create_job_with_noverify(self):
    929         data = self.data.copy()
    930         data['run_verify'] = False
    931         file_temp = cli_mock.create_file(self.ctrl_file)
    932         self.run_cmd(argv=['atest', 'job', 'create', '-f', file_temp.name,
    933                            'test_job0', '-m', 'host0', '-n'],
    934                      rpcs=[('create_job', data, True, 42)],
    935                      out_words_ok=['test_job0', 'Created'],)
    936         file_temp.clean()
    937 
    938 
    939     def test_execute_create_job_oth(self):
    940         data = self.data.copy()
    941         data['hosts'] = []
    942         data['one_time_hosts'] = ['host0']
    943         self.run_cmd(argv=['atest', 'job', 'create', '-t', 'sleeptest',
    944                            'test_job0', '--one-time-hosts', 'host0'],
    945                      rpcs=[('generate_control_file',
    946                             {'tests': ['sleeptest']},
    947                             True,
    948                             {'control_file' : self.ctrl_file,
    949                              'synch_count' : 1,
    950                              'is_server' : False,
    951                              'dependencies' : []}),
    952                            ('create_job', data, True, 180)],
    953                      out_words_ok=['test_job0', 'Created'],
    954                      out_words_no=['Uploading', 'Done'])
    955 
    956 
    957     def test_execute_create_job_multi_oth(self):
    958         data = self.data.copy()
    959         data['hosts'] = []
    960         data['one_time_hosts'] = ['host1', 'host0']
    961         self.run_cmd(argv=['atest', 'job', 'create', '-t', 'sleeptest',
    962                            'test_job0', '--one-time-hosts', 'host0,host1'],
    963                      rpcs=[('generate_control_file',
    964                             {'tests': ['sleeptest']},
    965                             True,
    966                             {'control_file' : self.ctrl_file,
    967                              'synch_count' : 1,
    968                              'is_server' : False,
    969                              'dependencies' : []}),
    970                            ('create_job', data, True, 180)],
    971                      out_words_ok=['test_job0', 'Created'],
    972                      out_words_no=['Uploading', 'Done'])
    973 
    974 
    975     def test_execute_create_job_oth_exists(self):
    976         data = self.data.copy()
    977         data['hosts'] = []
    978         data['one_time_hosts'] = ['host0']
    979         self.run_cmd(argv=['atest', 'job', 'create', '-t', 'sleeptest',
    980                            'test_job0', '--one-time-hosts', 'host0'],
    981                      rpcs=[('generate_control_file',
    982                             {'tests': ['sleeptest']},
    983                             True,
    984                             {'control_file' : self.ctrl_file,
    985                              'synch_count' : 1,
    986                              'is_server' : False,
    987                              'dependencies' : []}),
    988                            ('create_job', data, False,
    989                             '''ValidationError: {'hostname': 'host0 '''
    990                             '''already exists in the autotest DB.  '''
    991                             '''Select it rather than entering it as '''
    992                             '''a one time host.'}''')],
    993                      out_words_no=['test_job0', 'Created'],
    994                      err_words_ok=['failed', 'already exists'])
    995 
    996 
    997     def test_execute_create_job_with_control_and_labels(self):
    998         data = self.data.copy()
    999         data['hosts'] = ['host0', 'host1', 'host2']
   1000         file_temp = cli_mock.create_file(self.ctrl_file)
   1001         self.run_cmd(argv=['atest', 'job', 'create', '-f', file_temp.name,
   1002                            'test_job0', '-m', 'host0', '-b', 'label1,label2'],
   1003                      rpcs=[('get_hosts', {'multiple_labels': ['label1',
   1004                             'label2']}, True,
   1005                             [{u'status': u'Running', u'lock_time': None,
   1006                               u'hostname': u'host1', u'locked': False,
   1007                               u'locked_by': None, u'invalid': False, u'id': 42,
   1008                               u'labels': [u'label1'], u'platform':
   1009                               u'Warp18_Diskfull', u'protection':
   1010                               u'Repair software only', u'dirty': True},
   1011                              {u'status': u'Running', u'lock_time': None,
   1012                               u'hostname': u'host2', u'locked': False,
   1013                               u'locked_by': None, u'invalid': False, u'id': 43,
   1014                               u'labels': [u'label2'], u'platform':
   1015                               u'Warp18_Diskfull', u'protection':
   1016                               u'Repair software only', u'dirty': True}]),
   1017                             ('create_job', data, True, 42)],
   1018                      out_words_ok=['test_job0', 'Created'],
   1019                      out_words_no=['Uploading', 'Done'])
   1020         file_temp.clean()
   1021 
   1022 
   1023     def test_execute_create_job_with_label_and_duplicate_hosts(self):
   1024         data = self.data.copy()
   1025         data['hosts'] = ['host1', 'host0']
   1026         file_temp = cli_mock.create_file(self.ctrl_file)
   1027         self.run_cmd(argv=['atest', 'job', 'create', '-f', file_temp.name,
   1028                            'test_job0', '-m', 'host0,host1', '-b', 'label1'],
   1029                      rpcs=[('get_hosts', {'multiple_labels': ['label1']}, True,
   1030                             [{u'status': u'Running', u'lock_time': None,
   1031                               u'hostname': u'host1', u'locked': False,
   1032                               u'locked_by': None, u'invalid': False, u'id': 42,
   1033                               u'labels': [u'label1'], u'platform':
   1034                               u'Warp18_Diskfull', u'protection':
   1035                               u'Repair software only', u'dirty': True}]),
   1036                             ('create_job', data, True, 42)],
   1037                      out_words_ok=['test_job0', 'Created'],
   1038                      out_words_no=['Uploading', 'Done'])
   1039         file_temp.clean()
   1040 
   1041 
   1042     def test_execute_create_job_with_label_commas_and_duplicate_hosts(self):
   1043         data = self.data.copy()
   1044         data['hosts'] = ['host1', 'host0']
   1045         file_temp = cli_mock.create_file(self.ctrl_file)
   1046         self.run_cmd(argv=['atest', 'job', 'create', '-f', file_temp.name,
   1047                            'test_job0', '-m', 'host0,host1', '-b',
   1048                            'label1,label\\,2'],
   1049                      rpcs=[('get_hosts', {'multiple_labels': ['label1',
   1050                             'label,2']}, True,
   1051                             [{u'status': u'Running', u'lock_time': None,
   1052                               u'hostname': u'host1', u'locked': False,
   1053                               u'locked_by': None, u'invalid': False, u'id': 42,
   1054                               u'labels': [u'label1', u'label,2'], u'platform':
   1055                               u'Warp18_Diskfull', u'protection':
   1056                               u'Repair software only', u'dirty': True}]),
   1057                             ('create_job', data, True, 42)],
   1058                      out_words_ok=['test_job0', 'Created'],
   1059                      out_words_no=['Uploading', 'Done'])
   1060         file_temp.clean()
   1061 
   1062 
   1063     def test_execute_create_job_with_label_escaping_and_duplicate_hosts(self):
   1064         data = self.data.copy()
   1065         data['hosts'] = ['host1', 'host0']
   1066         file_temp = cli_mock.create_file(self.ctrl_file)
   1067         self.run_cmd(argv=['atest', 'job', 'create', '-f', file_temp.name,
   1068                            'test_job0', '-m', 'host0,host1', '-b',
   1069                            'label1,label\\,2\\\\,label3'],
   1070                      rpcs=[('get_hosts', {'multiple_labels': ['label,2\\',
   1071                             'label1', 'label3']}, True,
   1072                             [{u'status': u'Running', u'lock_time': None,
   1073                               u'hostname': u'host1', u'locked': False,
   1074                               u'locked_by': None, u'invalid': False, u'id': 42,
   1075                               u'labels': [u'label1', u'label,2\\', u'label3'],
   1076                               u'platform': u'Warp18_Diskfull', u'protection':
   1077                               u'Repair software only', u'dirty': True}]),
   1078                             ('create_job', data, True, 42)],
   1079                      out_words_ok=['test_job0', 'Created'],
   1080                      out_words_no=['Uploading', 'Done'])
   1081         file_temp.clean()
   1082 
   1083 
   1084     def _test_parse_hosts(self, args, exp_hosts=[], exp_meta_hosts=[]):
   1085         testjob = job.job_create_or_clone()
   1086         (hosts, meta_hosts) = testjob._parse_hosts(args)
   1087         self.assertEqualNoOrder(hosts, exp_hosts)
   1088         self.assertEqualNoOrder(meta_hosts, exp_meta_hosts)
   1089 
   1090 
   1091     def test_parse_hosts_regular(self):
   1092         self._test_parse_hosts(['host0'], ['host0'])
   1093 
   1094 
   1095     def test_parse_hosts_regulars(self):
   1096         self._test_parse_hosts(['host0', 'host1'], ['host0', 'host1'])
   1097 
   1098 
   1099     def test_parse_hosts_meta_one(self):
   1100         self._test_parse_hosts(['*meta0'], [], ['meta0'])
   1101 
   1102 
   1103     def test_parse_hosts_meta_five(self):
   1104         self._test_parse_hosts(['5*meta0'], [], ['meta0']*5)
   1105 
   1106 
   1107     def test_parse_hosts_metas_five(self):
   1108         self._test_parse_hosts(['5*meta0', '2*meta1'], [],
   1109                                ['meta0']*5 + ['meta1']*2)
   1110 
   1111 
   1112     def test_parse_hosts_mix(self):
   1113         self._test_parse_hosts(['5*meta0', 'host0', '2*meta1', 'host1',
   1114                                 '*meta2'], ['host0', 'host1'],
   1115                                ['meta0']*5 + ['meta1']*2 + ['meta2'])
   1116 
   1117 
   1118 class job_clone_unittest(cli_mock.cli_unittest):
   1119     job_data = {'control_file': u'NAME = \'Server Sleeptest\'\nAUTHOR = \'mbligh (at] google.com (Martin Bligh)\'\nTIME = \'SHORT\'\nTEST_CLASS = \'Software\'\nTEST_CATEGORY = \'Functional\'\nTEST_TYPE = \'server\'\nEXPERIMENTAL = \'False\'\n\nDOC = """\nruns sleep for one second on the list of machines.\n"""\n\ndef run(machine):\n    host = hosts.create_host(machine)\n    job.run_test(\'sleeptest\')\n\njob.parallel_simple(run, machines)\n',
   1120                     'control_type': SERVER,
   1121                     'dependencies': [],
   1122                     'email_list': u'',
   1123                     'max_runtime_mins': 28800,
   1124                     'parse_failed_repair': True,
   1125                     'priority': priorities.Priority.DEFAULT,
   1126                     'reboot_after': u'Always',
   1127                     'reboot_before': u'If dirty',
   1128                     'run_verify': True,
   1129                     'synch_count': 1,
   1130                     'timeout_mins': 480}
   1131 
   1132     local_hosts = [{u'acls': [u'acl0'],
   1133                     u'attributes': {},
   1134                     u'dirty': False,
   1135                     u'hostname': u'host0',
   1136                     u'id': 8,
   1137                     u'invalid': False,
   1138                     u'labels': [u'label0', u'label1'],
   1139                     u'lock_time': None,
   1140                     u'locked': False,
   1141                     u'locked_by': None,
   1142                     u'other_labels': u'label0, label1',
   1143                     u'platform': u'plat0',
   1144                     u'protection': u'Repair software only',
   1145                     u'status': u'Ready'},
   1146                    {u'acls': [u'acl0'],
   1147                     u'attributes': {},
   1148                     u'dirty': False,
   1149                     u'hostname': u'host1',
   1150                     u'id': 9,
   1151                     u'invalid': False,
   1152                     u'labels': [u'label0', u'label1'],
   1153                     u'lock_time': None,
   1154                     u'locked': False,
   1155                     u'locked_by': None,
   1156                     u'other_labels': u'label0, label1',
   1157                     u'platform': u'plat0',
   1158                     u'protection': u'Repair software only',
   1159                     u'status': u'Ready'}]
   1160 
   1161 
   1162     def setUp(self):
   1163         super(job_clone_unittest, self).setUp()
   1164         self.job_data_clone_info = copy.deepcopy(self.job_data)
   1165         self.job_data_clone_info['created_on'] = '2009-07-23 16:21:29'
   1166         self.job_data_clone_info['name'] = 'testing_clone'
   1167         self.job_data_clone_info['id'] = 42
   1168         self.job_data_clone_info['owner'] = 'user0'
   1169 
   1170         self.job_data_cloned = copy.deepcopy(self.job_data)
   1171         self.job_data_cloned['name'] = 'cloned'
   1172         self.job_data_cloned['hosts'] = [u'host0']
   1173         self.job_data_cloned['meta_hosts'] = []
   1174 
   1175 
   1176     def test_backward_compat(self):
   1177         self.run_cmd(argv=['atest', 'job', 'create', '--clone', '42',
   1178                            '-r', 'cloned'],
   1179                      rpcs=[('get_info_for_clone', {'id': '42',
   1180                                                    'preserve_metahosts': True},
   1181                             True,
   1182                             {u'hosts': [{u'acls': [u'acl0'],
   1183                                          u'attributes': {},
   1184                                          u'dirty': False,
   1185                                          u'hostname': u'host0',
   1186                                          u'id': 4378,
   1187                                          u'invalid': False,
   1188                                          u'labels': [u'label0', u'label1'],
   1189                                          u'lock_time': None,
   1190                                          u'locked': False,
   1191                                          u'locked_by': None,
   1192                                          u'other_labels': u'label0, label1',
   1193                                          u'platform': u'plat0',
   1194                                          u'protection': u'Repair software only',
   1195                                          u'status': u'Ready'}],
   1196                              u'job': self.job_data_clone_info,
   1197                              u'meta_host_counts': {}}),
   1198                            ('create_job', self.job_data_cloned, True, 43)],
   1199                      out_words_ok=['Created job', '43'])
   1200 
   1201 
   1202     def test_clone_reuse_hosts(self):
   1203         self.job_data_cloned['hosts'] = [u'host0', 'host1']
   1204         self.run_cmd(argv=['atest', 'job', 'clone', '--id', '42',
   1205                            '-r', 'cloned'],
   1206                      rpcs=[('get_info_for_clone', {'id': '42',
   1207                                                    'preserve_metahosts': True},
   1208                             True,
   1209                             {u'hosts': self.local_hosts,
   1210                              u'job': self.job_data_clone_info,
   1211                              u'meta_host_counts': {}}),
   1212                            ('create_job', self.job_data_cloned, True, 43)],
   1213                      out_words_ok=['Created job', '43'])
   1214 
   1215 
   1216     def test_clone_reuse_metahosts(self):
   1217         self.job_data_cloned['hosts'] = []
   1218         self.job_data_cloned['meta_hosts'] = ['type1']*4 +  ['type0']
   1219         self.run_cmd(argv=['atest', 'job', 'clone', '--id', '42',
   1220                            '-r', 'cloned'],
   1221                      rpcs=[('get_info_for_clone', {'id': '42',
   1222                                                    'preserve_metahosts': True},
   1223                             True,
   1224                             {u'hosts': [],
   1225                              u'job': self.job_data_clone_info,
   1226                              u'meta_host_counts': {u'type0': 1,
   1227                                                    u'type1': 4}}),
   1228                            ('create_job', self.job_data_cloned, True, 43)],
   1229                      out_words_ok=['Created job', '43'])
   1230 
   1231 
   1232     def test_clone_reuse_both(self):
   1233         self.job_data_cloned['hosts'] = [u'host0', 'host1']
   1234         self.job_data_cloned['meta_hosts'] = ['type1']*4 +  ['type0']
   1235         self.run_cmd(argv=['atest', 'job', 'clone', '--id', '42',
   1236                            '-r', 'cloned'],
   1237                      rpcs=[('get_info_for_clone', {'id': '42',
   1238                                                    'preserve_metahosts': True},
   1239                             True,
   1240                             {
   1241                              u'hosts': self.local_hosts,
   1242                              u'job': self.job_data_clone_info,
   1243                              u'meta_host_counts': {u'type0': 1,
   1244                                                    u'type1': 4}}),
   1245                            ('create_job', self.job_data_cloned, True, 43)],
   1246                      out_words_ok=['Created job', '43'])
   1247 
   1248 
   1249     def test_clone_no_hosts(self):
   1250         self.run_cmd(argv=['atest', 'job', 'clone', '--id', '42', 'cloned'],
   1251                      exit_code=1,
   1252                      out_words_ok=['usage'],
   1253                      err_words_ok=['machine'])
   1254 
   1255 
   1256     def test_clone_reuse_and_hosts(self):
   1257         self.run_cmd(argv=['atest', 'job', 'clone', '--id', '42',
   1258                            '-r', '-m', 'host5', 'cloned'],
   1259                      exit_code=1,
   1260                      out_words_ok=['usage'],
   1261                      err_words_ok=['specify'])
   1262 
   1263 
   1264     def test_clone_new_multiple_hosts(self):
   1265         self.job_data_cloned['hosts'] = [u'host5', 'host4', 'host3']
   1266         self.run_cmd(argv=['atest', 'job', 'clone', '--id', '42',
   1267                            '-m', 'host5,host4,host3', 'cloned'],
   1268                      rpcs=[('get_info_for_clone', {'id': '42',
   1269                                                    'preserve_metahosts': False},
   1270                             True,
   1271                             {u'hosts': self.local_hosts,
   1272                              u'job': self.job_data_clone_info,
   1273                              u'meta_host_counts': {}}),
   1274                            ('create_job', self.job_data_cloned, True, 43)],
   1275                      out_words_ok=['Created job', '43'])
   1276 
   1277 
   1278     def test_clone_oth(self):
   1279         self.job_data_cloned['hosts'] = []
   1280         self.job_data_cloned['one_time_hosts'] = [u'host5']
   1281         self.run_cmd(argv=['atest', 'job', 'clone', '--id', '42',
   1282                            '--one-time-hosts', 'host5', 'cloned'],
   1283                      rpcs=[('get_info_for_clone', {'id': '42',
   1284                                                    'preserve_metahosts': False},
   1285                             True,
   1286                             {u'hosts': self.local_hosts,
   1287                              u'job': self.job_data_clone_info,
   1288                              u'meta_host_counts': {}}),
   1289                            ('create_job', self.job_data_cloned, True, 43)],
   1290                      out_words_ok=['Created job', '43'])
   1291 
   1292 
   1293 class job_abort_unittest(cli_mock.cli_unittest):
   1294     results = [{u'status_counts': {u'Aborted': 1}, u'control_file':
   1295                 u"job.run_test('sleeptest')\n", u'name': u'test_job0',
   1296                 u'control_type': SERVER, u'priority':
   1297                 priorities.Priority.DEFAULT, u'owner': u'user0', u'created_on':
   1298                 u'2008-07-08 17:45:44', u'synch_count': 2, u'id': 180}]
   1299 
   1300     def test_execute_job_abort(self):
   1301         self.run_cmd(argv=['atest', 'job', 'abort', '180'],
   1302                      rpcs=[('abort_host_queue_entries',
   1303                             {'job__id__in': ['180']}, True, None)],
   1304                      out_words_ok=['Aborting', '180'])
   1305 
   1306 
   1307 if __name__ == '__main__':
   1308     unittest.main()
   1309