Home | History | Annotate | Download | only in cli
      1 #!/usr/bin/python
      2 #
      3 # Copyright 2008 Google Inc. All Rights Reserved.
      4 
      5 """Test for host."""
      6 
      7 # pylint: disable=missing-docstring
      8 
      9 import sys
     10 import unittest
     11 
     12 import mock
     13 
     14 import common
     15 from autotest_lib.cli import cli_mock, host
     16 from autotest_lib.client.common_lib import control_data
     17 from autotest_lib.server import hosts
     18 CLIENT = control_data.CONTROL_TYPE_NAMES.CLIENT
     19 SERVER = control_data.CONTROL_TYPE_NAMES.SERVER
     20 
     21 class host_ut(cli_mock.cli_unittest):
     22     def test_parse_lock_options_both_set(self):
     23         hh = host.host()
     24         class opt(object):
     25             lock = True
     26             unlock = True
     27         options = opt()
     28         self.usage = "unused"
     29         sys.exit.expect_call(1).and_raises(cli_mock.ExitException)
     30         self.god.mock_io()
     31         self.assertRaises(cli_mock.ExitException,
     32                           hh._parse_lock_options, options)
     33         self.god.unmock_io()
     34 
     35 
     36     def test_cleanup_labels_with_platform(self):
     37         labels = ['l0', 'l1', 'l2', 'p0', 'l3']
     38         hh = host.host()
     39         self.assertEqual(['l0', 'l1', 'l2', 'l3'],
     40                          hh._cleanup_labels(labels, 'p0'))
     41 
     42 
     43     def test_cleanup_labels_no_platform(self):
     44         labels = ['l0', 'l1', 'l2', 'l3']
     45         hh = host.host()
     46         self.assertEqual(['l0', 'l1', 'l2', 'l3'],
     47                          hh._cleanup_labels(labels))
     48 
     49 
     50     def test_cleanup_labels_with_non_avail_platform(self):
     51         labels = ['l0', 'l1', 'l2', 'l3']
     52         hh = host.host()
     53         self.assertEqual(['l0', 'l1', 'l2', 'l3'],
     54                          hh._cleanup_labels(labels, 'p0'))
     55 
     56 
     57 class host_list_unittest(cli_mock.cli_unittest):
     58     def test_parse_host_not_required(self):
     59         hl = host.host_list()
     60         sys.argv = ['atest']
     61         (options, leftover) = hl.parse()
     62         self.assertEqual([], hl.hosts)
     63         self.assertEqual([], leftover)
     64 
     65 
     66     def test_parse_with_hosts(self):
     67         hl = host.host_list()
     68         mfile = cli_mock.create_file('host0\nhost3\nhost4\n')
     69         sys.argv = ['atest', 'host1', '--mlist', mfile.name, 'host3']
     70         (options, leftover) = hl.parse()
     71         self.assertEqualNoOrder(['host0', 'host1','host3', 'host4'],
     72                                 hl.hosts)
     73         self.assertEqual(leftover, [])
     74         mfile.clean()
     75 
     76 
     77     def test_parse_with_labels(self):
     78         hl = host.host_list()
     79         sys.argv = ['atest', '--label', 'label0']
     80         (options, leftover) = hl.parse()
     81         self.assertEqual(['label0'], hl.labels)
     82         self.assertEqual(leftover, [])
     83 
     84 
     85     def test_parse_with_multi_labels(self):
     86         hl = host.host_list()
     87         sys.argv = ['atest', '--label', 'label0,label2']
     88         (options, leftover) = hl.parse()
     89         self.assertEqualNoOrder(['label0', 'label2'], hl.labels)
     90         self.assertEqual(leftover, [])
     91 
     92 
     93     def test_parse_with_escaped_commas_label(self):
     94         hl = host.host_list()
     95         sys.argv = ['atest', '--label', 'label\\,0']
     96         (options, leftover) = hl.parse()
     97         self.assertEqual(['label,0'], hl.labels)
     98         self.assertEqual(leftover, [])
     99 
    100 
    101     def test_parse_with_escaped_commas_multi_labels(self):
    102         hl = host.host_list()
    103         sys.argv = ['atest', '--label', 'label\\,0,label\\,2']
    104         (options, leftover) = hl.parse()
    105         self.assertEqualNoOrder(['label,0', 'label,2'], hl.labels)
    106         self.assertEqual(leftover, [])
    107 
    108 
    109     def test_parse_with_both(self):
    110         hl = host.host_list()
    111         mfile = cli_mock.create_file('host0\nhost3\nhost4\n')
    112         sys.argv = ['atest', 'host1', '--mlist', mfile.name, 'host3',
    113                     '--label', 'label0']
    114         (options, leftover) = hl.parse()
    115         self.assertEqualNoOrder(['host0', 'host1','host3', 'host4'],
    116                                 hl.hosts)
    117         self.assertEqual(['label0'], hl.labels)
    118         self.assertEqual(leftover, [])
    119         mfile.clean()
    120 
    121 
    122     def test_execute_list_all_no_labels(self):
    123         self.run_cmd(argv=['atest', 'host', 'list'],
    124                      rpcs=[('get_hosts', {},
    125                             True,
    126                             [{u'status': u'Ready',
    127                               u'hostname': u'host0',
    128                               u'locked': False,
    129                               u'locked_by': 'user0',
    130                               u'lock_time': u'2008-07-23 12:54:15',
    131                               u'lock_reason': u'',
    132                               u'labels': [],
    133                               u'invalid': False,
    134                               u'platform': None,
    135                               u'shard': None,
    136                               u'id': 1},
    137                              {u'status': u'Ready',
    138                               u'hostname': u'host1',
    139                               u'locked': True,
    140                               u'locked_by': 'user0',
    141                               u'lock_time': u'2008-07-23 12:54:15',
    142                               u'lock_reason': u'',
    143                               u'labels': [u'plat1'],
    144                               u'invalid': False,
    145                               u'platform': u'plat1',
    146                               u'shard': None,
    147                               u'id': 2}])],
    148                      out_words_ok=['host0', 'host1', 'Ready',
    149                                    'plat1', 'False', 'True', 'None'])
    150 
    151 
    152     def test_execute_list_all_with_labels(self):
    153         self.run_cmd(argv=['atest', 'host', 'list'],
    154                      rpcs=[('get_hosts', {},
    155                             True,
    156                             [{u'status': u'Ready',
    157                               u'hostname': u'host0',
    158                               u'locked': False,
    159                               u'locked_by': 'user0',
    160                               u'lock_time': u'2008-07-23 12:54:15',
    161                               u'lock_reason': u'',
    162                               u'labels': [u'label0', u'label1'],
    163                               u'invalid': False,
    164                               u'platform': None,
    165                               u'shard': None,
    166                               u'id': 1},
    167                              {u'status': u'Ready',
    168                               u'hostname': u'host1',
    169                               u'locked': True,
    170                               u'locked_by': 'user0',
    171                               u'lock_time': u'2008-07-23 12:54:15',
    172                               u'lock_reason': u'',
    173                               u'labels': [u'label2', u'label3', u'plat1'],
    174                               u'invalid': False,
    175                               u'shard': None,
    176                               u'platform': u'plat1',
    177                               u'id': 2}])],
    178                      out_words_ok=['host0', 'host1', 'Ready', 'plat1',
    179                                    'label0', 'label1', 'label2', 'label3',
    180                                    'False', 'True', 'None'])
    181 
    182 
    183     def test_execute_list_filter_one_host(self):
    184         self.run_cmd(argv=['atest', 'host', 'list', 'host1'],
    185                      rpcs=[('get_hosts', {'hostname__in': ['host1']},
    186                             True,
    187                             [{u'status': u'Ready',
    188                               u'hostname': u'host1',
    189                               u'locked': True,
    190                               u'locked_by': 'user0',
    191                               u'lock_time': u'2008-07-23 12:54:15',
    192                               u'lock_reason': u'',
    193                               u'labels': [u'label2', u'label3', u'plat1'],
    194                               u'invalid': False,
    195                               u'platform': u'plat1',
    196                               u'shard': None,
    197                               u'id': 2}])],
    198                      out_words_ok=['host1', 'Ready', 'plat1',
    199                                    'label2', 'label3', 'True', 'None'],
    200                      out_words_no=['host0', 'host2',
    201                                    'label1', 'False'])
    202 
    203 
    204     def test_execute_list_filter_two_hosts(self):
    205         mfile = cli_mock.create_file('host2')
    206         self.run_cmd(argv=['atest', 'host', 'list', 'host1',
    207                            '--mlist', mfile.name],
    208                      # This is a bit fragile as the list order may change...
    209                      rpcs=[('get_hosts', {'hostname__in': ['host2', 'host1']},
    210                             True,
    211                             [{u'status': u'Ready',
    212                               u'hostname': u'host1',
    213                               u'locked': True,
    214                               u'locked_by': 'user0',
    215                               u'lock_time': u'2008-07-23 12:54:15',
    216                               u'lock_reason': u'',
    217                               u'labels': [u'label2', u'label3', u'plat1'],
    218                               u'invalid': False,
    219                               u'platform': u'plat1',
    220                               u'shard': None,
    221                               u'id': 2},
    222                              {u'status': u'Ready',
    223                               u'hostname': u'host2',
    224                               u'locked': True,
    225                               u'locked_by': 'user0',
    226                               u'lock_time': u'2008-07-23 12:54:15',
    227                               u'lock_reason': u'',
    228                               u'labels': [u'label3', u'plat1'],
    229                               u'invalid': False,
    230                               u'shard': None,
    231                               u'platform': u'plat1',
    232                               u'id': 3}])],
    233                      out_words_ok=['host1', 'Ready', 'plat1',
    234                                    'label2', 'label3', 'True',
    235                                    'host2', 'None'],
    236                      out_words_no=['host0', 'label1', 'False'])
    237         mfile.clean()
    238 
    239 
    240     def test_execute_list_filter_two_hosts_one_not_found(self):
    241         mfile = cli_mock.create_file('host2')
    242         self.run_cmd(argv=['atest', 'host', 'list', 'host1',
    243                            '--mlist', mfile.name],
    244                      # This is a bit fragile as the list order may change...
    245                      rpcs=[('get_hosts', {'hostname__in': ['host2', 'host1']},
    246                             True,
    247                             [{u'status': u'Ready',
    248                               u'hostname': u'host2',
    249                               u'locked': True,
    250                               u'locked_by': 'user0',
    251                               u'lock_time': u'2008-07-23 12:54:15',
    252                               u'lock_reason': u'',
    253                               u'labels': [u'label3', u'plat1'],
    254                               u'invalid': False,
    255                               u'shard': None,
    256                               u'platform': u'plat1',
    257                               u'id': 3}])],
    258                      out_words_ok=['Ready', 'plat1',
    259                                    'label3', 'True', 'None'],
    260                      out_words_no=['host1', 'False'],
    261                      err_words_ok=['host1'])
    262         mfile.clean()
    263 
    264 
    265     def test_execute_list_filter_two_hosts_none_found(self):
    266         self.run_cmd(argv=['atest', 'host', 'list',
    267                            'host1', 'host2'],
    268                      # This is a bit fragile as the list order may change...
    269                      rpcs=[('get_hosts', {'hostname__in': ['host2', 'host1']},
    270                             True,
    271                             [])],
    272                      out_words_ok=[],
    273                      out_words_no=['Hostname', 'Status'],
    274                      err_words_ok=['Unknown', 'host1', 'host2'])
    275 
    276 
    277     def test_execute_list_filter_label(self):
    278         self.run_cmd(argv=['atest', 'host', 'list',
    279                            '-b', 'label3'],
    280                      rpcs=[('get_hosts', {'labels__name__in': ['label3']},
    281                             True,
    282                             [{u'status': u'Ready',
    283                               u'hostname': u'host1',
    284                               u'locked': True,
    285                               u'locked_by': 'user0',
    286                               u'lock_time': u'2008-07-23 12:54:15',
    287                               u'lock_reason': u'',
    288                               u'labels': [u'label2', u'label3', u'plat1'],
    289                               u'invalid': False,
    290                               u'platform': u'plat1',
    291                               u'shard': None,
    292                               u'id': 2},
    293                              {u'status': u'Ready',
    294                               u'hostname': u'host2',
    295                               u'locked': True,
    296                               u'locked_by': 'user0',
    297                               u'lock_time': u'2008-07-23 12:54:15',
    298                               u'lock_reason': u'',
    299                               u'labels': [u'label3', u'plat1'],
    300                               u'invalid': False,
    301                               u'shard': None,
    302                               u'platform': u'plat1',
    303                               u'id': 3}])],
    304                      out_words_ok=['host1', 'Ready', 'plat1',
    305                                    'label2', 'label3', 'True',
    306                                    'host2', 'None'],
    307                      out_words_no=['host0', 'label1', 'False'])
    308 
    309 
    310     def test_execute_list_filter_multi_labels(self):
    311         self.run_cmd(argv=['atest', 'host', 'list',
    312                            '-b', 'label3,label2'],
    313                      rpcs=[('get_hosts', {'multiple_labels': ['label2',
    314                                                               'label3']},
    315                             True,
    316                             [{u'status': u'Ready',
    317                               u'hostname': u'host1',
    318                               u'locked': True,
    319                               u'locked_by': 'user0',
    320                               u'lock_time': u'2008-07-23 12:54:15',
    321                               u'lock_reason': u'',
    322                               u'labels': [u'label2', u'label3', u'plat0'],
    323                               u'invalid': False,
    324                               u'shard': None,
    325                               u'platform': u'plat0',
    326                               u'id': 2},
    327                              {u'status': u'Ready',
    328                               u'hostname': u'host3',
    329                               u'locked': True,
    330                               u'locked_by': 'user0',
    331                               u'lock_time': u'2008-07-23 12:54:15',
    332                               u'lock_reason': u'',
    333                               u'labels': [u'label3', u'label2', u'plat2'],
    334                               u'invalid': False,
    335                               u'shard': None,
    336                               u'platform': u'plat2',
    337                               u'id': 4}])],
    338                      out_words_ok=['host1', 'host3', 'Ready', 'plat0',
    339                                    'label2', 'label3', 'plat2', 'None'],
    340                      out_words_no=['host2', 'False', 'plat1'])
    341 
    342 
    343     def test_execute_list_filter_three_labels(self):
    344         self.run_cmd(argv=['atest', 'host', 'list',
    345                            '-b', 'label3,label2'],
    346                      rpcs=[('get_hosts', {'multiple_labels': ['label2',
    347                                                               'label3']},
    348                             True,
    349                             [{u'status': u'Ready',
    350                               u'hostname': u'host2',
    351                               u'locked': True,
    352                               u'locked_by': 'user0',
    353                               u'lock_time': u'2008-07-23 12:54:15',
    354                               u'lock_reason': u'',
    355                               u'labels': [u'label3', u'label2', u'plat1'],
    356                               u'invalid': False,
    357                               u'platform': u'plat1',
    358                               u'shard': None,
    359                               u'id': 3}])],
    360                      out_words_ok=['host2', 'plat1',
    361                                    'label2', 'label3', 'None'],
    362                      out_words_no=['host1', 'host3'])
    363 
    364 
    365     def test_execute_list_filter_wild_labels(self):
    366         self.run_cmd(argv=['atest', 'host', 'list',
    367                            '-b', 'label*'],
    368                      rpcs=[('get_hosts',
    369                             {'labels__name__startswith': 'label'},
    370                             True,
    371                             [{u'status': u'Ready',
    372                               u'hostname': u'host2',
    373                               u'locked': 1,
    374                               u'shard': None,
    375                               u'locked_by': 'user0',
    376                               u'lock_time': u'2008-07-23 12:54:15',
    377                               u'lock_reason': u'',
    378                               u'labels': [u'label3', u'label2', u'plat1'],
    379                               u'invalid': 0,
    380                               u'platform': u'plat1',
    381                               u'id': 3}])],
    382                      out_words_ok=['host2', 'plat1',
    383                                    'label2', 'label3', 'None'],
    384                      out_words_no=['host1', 'host3'])
    385 
    386 
    387     def test_execute_list_filter_multi_labels_no_results(self):
    388         self.run_cmd(argv=['atest', 'host', 'list',
    389                            '-b', 'label3,label2, '],
    390                      rpcs=[('get_hosts', {'multiple_labels': ['label2',
    391                                                               'label3']},
    392                             True,
    393                             [])],
    394                      out_words_ok=[],
    395                      out_words_no=['host1', 'host2', 'host3',
    396                                    'label2', 'label3'])
    397 
    398 
    399     def test_execute_list_filter_label_and_hosts(self):
    400         self.run_cmd(argv=['atest', 'host', 'list', 'host1',
    401                            '-b', 'label3', 'host2'],
    402                      rpcs=[('get_hosts', {'labels__name__in': ['label3'],
    403                                           'hostname__in': ['host2', 'host1']},
    404                             True,
    405                             [{u'status': u'Ready',
    406                               u'hostname': u'host1',
    407                               u'locked': True,
    408                               u'locked_by': 'user0',
    409                               u'lock_time': u'2008-07-23 12:54:15',
    410                               u'labels': [u'label2', u'label3', u'plat1'],
    411                               u'lock_reason': u'',
    412                               u'invalid': False,
    413                               u'platform': u'plat1',
    414                               u'shard': None,
    415                               u'id': 2},
    416                              {u'status': u'Ready',
    417                               u'hostname': u'host2',
    418                               u'locked': True,
    419                               u'locked_by': 'user0',
    420                               u'lock_time': u'2008-07-23 12:54:15',
    421                               u'lock_reason': u'',
    422                               u'labels': [u'label3', u'plat1'],
    423                               u'invalid': False,
    424                               u'shard': None,
    425                               u'platform': u'plat1',
    426                               u'id': 3}])],
    427                      out_words_ok=['host1', 'Ready', 'plat1',
    428                                    'label2', 'label3', 'True',
    429                                    'host2', 'None'],
    430                      out_words_no=['host0', 'label1', 'False'])
    431 
    432 
    433     def test_execute_list_filter_label_and_hosts_none(self):
    434         self.run_cmd(argv=['atest', 'host', 'list', 'host1',
    435                            '-b', 'label3', 'host2'],
    436                      rpcs=[('get_hosts', {'labels__name__in': ['label3'],
    437                                           'hostname__in': ['host2', 'host1']},
    438                             True,
    439                             [])],
    440                      out_words_ok=[],
    441                      out_words_no=['Hostname', 'Status'],
    442                      err_words_ok=['Unknown', 'host1', 'host2'])
    443 
    444 
    445     def test_execute_list_filter_status(self):
    446         self.run_cmd(argv=['atest', 'host', 'list',
    447                            '-s', 'Ready'],
    448                      rpcs=[('get_hosts', {'status__in': ['Ready']},
    449                             True,
    450                             [{u'status': u'Ready',
    451                               u'hostname': u'host1',
    452                               u'locked': True,
    453                               u'locked_by': 'user0',
    454                               u'lock_time': u'2008-07-23 12:54:15',
    455                               u'lock_reason': u'',
    456                               u'labels': [u'label2', u'label3', u'plat1'],
    457                               u'invalid': False,
    458                               u'platform': u'plat1',
    459                               u'shard': None,
    460                               u'id': 2},
    461                              {u'status': u'Ready',
    462                               u'hostname': u'host2',
    463                               u'locked': True,
    464                               u'locked_by': 'user0',
    465                               u'lock_time': u'2008-07-23 12:54:15',
    466                               u'lock_reason': u'',
    467                               u'labels': [u'label3', u'plat1'],
    468                               u'invalid': False,
    469                               u'shard': None,
    470                               u'platform': u'plat1',
    471                               u'id': 3}])],
    472                      out_words_ok=['host1', 'Ready', 'plat1',
    473                                    'label2', 'label3', 'True',
    474                                    'host2', 'None'],
    475                      out_words_no=['host0', 'label1', 'False'])
    476 
    477 
    478 
    479     def test_execute_list_filter_status_and_hosts(self):
    480         self.run_cmd(argv=['atest', 'host', 'list', 'host1',
    481                            '-s', 'Ready', 'host2'],
    482                      rpcs=[('get_hosts', {'status__in': ['Ready'],
    483                                           'hostname__in': ['host2', 'host1']},
    484                             True,
    485                             [{u'status': u'Ready',
    486                               u'hostname': u'host1',
    487                               u'locked': True,
    488                               u'locked_by': 'user0',
    489                               u'lock_time': u'2008-07-23 12:54:15',
    490                               u'lock_reason': u'',
    491                               u'labels': [u'label2', u'label3', u'plat1'],
    492                               u'invalid': False,
    493                               u'platform': u'plat1',
    494                               u'shard': None,
    495                               u'id': 2},
    496                              {u'status': u'Ready',
    497                               u'hostname': u'host2',
    498                               u'locked': True,
    499                               u'locked_by': 'user0',
    500                               u'lock_time': u'2008-07-23 12:54:15',
    501                               u'lock_reason': u'',
    502                               u'labels': [u'label3', u'plat1'],
    503                               u'invalid': False,
    504                               u'shard': None,
    505                               u'platform': u'plat1',
    506                               u'id': 3}])],
    507                      out_words_ok=['host1', 'Ready', 'plat1',
    508                                    'label2', 'label3', 'True',
    509                                    'host2', 'None'],
    510                      out_words_no=['host0', 'label1', 'False'])
    511 
    512 
    513     def test_execute_list_filter_status_and_hosts_none(self):
    514         self.run_cmd(argv=['atest', 'host', 'list', 'host1',
    515                            '--status', 'Repair',
    516                            'host2'],
    517                      rpcs=[('get_hosts', {'status__in': ['Repair'],
    518                                           'hostname__in': ['host2', 'host1']},
    519                             True,
    520                             [])],
    521                      out_words_ok=[],
    522                      out_words_no=['Hostname', 'Status'],
    523                      err_words_ok=['Unknown', 'host2'])
    524 
    525 
    526     def test_execute_list_filter_statuses_and_hosts_none(self):
    527         self.run_cmd(argv=['atest', 'host', 'list', 'host1',
    528                            '--status', 'Repair',
    529                            'host2'],
    530                      rpcs=[('get_hosts', {'status__in': ['Repair'],
    531                                           'hostname__in': ['host2', 'host1']},
    532                             True,
    533                             [])],
    534                      out_words_ok=[],
    535                      out_words_no=['Hostname', 'Status'],
    536                      err_words_ok=['Unknown', 'host2'])
    537 
    538 
    539     def test_execute_list_filter_locked(self):
    540         self.run_cmd(argv=['atest', 'host', 'list', 'host1',
    541                            '--locked', 'host2'],
    542                      rpcs=[('get_hosts', {'locked': True,
    543                                           'hostname__in': ['host2', 'host1']},
    544                             True,
    545                             [{u'status': u'Ready',
    546                               u'hostname': u'host1',
    547                               u'locked': True,
    548                               u'locked_by': 'user0',
    549                               u'lock_reason': u'',
    550                               u'lock_time': u'2008-07-23 12:54:15',
    551                               u'labels': [u'label2', u'label3', u'plat1'],
    552                               u'invalid': False,
    553                               u'platform': u'plat1',
    554                               u'shard': None,
    555                               u'id': 2},
    556                              {u'status': u'Ready',
    557                               u'hostname': u'host2',
    558                               u'locked': True,
    559                               u'locked_by': 'user0',
    560                               u'lock_reason': u'',
    561                               u'lock_time': u'2008-07-23 12:54:15',
    562                               u'labels': [u'label3', u'plat1'],
    563                               u'invalid': False,
    564                               u'shard': None,
    565                               u'platform': u'plat1',
    566                               u'id': 3}])],
    567                      out_words_ok=['host1', 'Ready', 'plat1',
    568                                    'label2', 'label3', 'True',
    569                                    'host2', 'None'],
    570                      out_words_no=['host0', 'label1', 'False'])
    571 
    572 
    573     def test_execute_list_filter_unlocked(self):
    574         self.run_cmd(argv=['atest', 'host', 'list',
    575                            '--unlocked'],
    576                      rpcs=[('get_hosts', {'locked': False},
    577                             True,
    578                             [{u'status': u'Ready',
    579                               u'hostname': u'host1',
    580                               u'locked': False,
    581                               u'locked_by': 'user0',
    582                               u'lock_time': u'2008-07-23 12:54:15',
    583                               u'lock_reason': u'',
    584                               u'labels': [u'label2', u'label3', u'plat1'],
    585                               u'invalid': False,
    586                               u'shard': None,
    587                               u'platform': u'plat1',
    588                               u'id': 2},
    589                              {u'status': u'Ready',
    590                               u'hostname': u'host2',
    591                               u'locked': False,
    592                               u'locked_by': 'user0',
    593                               u'lock_time': u'2008-07-23 12:54:15',
    594                               u'lock_reason': u'',
    595                               u'labels': [u'label3', u'plat1'],
    596                               u'invalid': False,
    597                               u'shard': None,
    598                               u'platform': u'plat1',
    599                               u'id': 3}])],
    600                      out_words_ok=['host1', 'Ready', 'plat1',
    601                                    'label2', 'label3', 'False',
    602                                    'host2', 'None'],
    603                      out_words_no=['host0', 'label1', 'True'])
    604 
    605 
    606 class host_stat_unittest(cli_mock.cli_unittest):
    607     def test_execute_stat_two_hosts(self):
    608         # The order of RPCs between host1 and host0 could change...
    609         self.run_cmd(argv=['atest', 'host', 'stat', 'host0', 'host1'],
    610                      rpcs=[('get_hosts', {'hostname': 'host1'},
    611                             True,
    612                             [{u'status': u'Ready',
    613                               u'hostname': u'host1',
    614                               u'locked': True,
    615                               u'lock_time': u'2008-07-23 12:54:15',
    616                               u'locked_by': 'user0',
    617                               u'lock_reason': u'',
    618                               u'protection': 'No protection',
    619                               u'labels': [u'label3', u'plat1'],
    620                               u'invalid': False,
    621                               u'shard': None,
    622                               u'platform': u'plat1',
    623                               u'id': 3,
    624                               u'attributes': {}}]),
    625                            ('get_hosts', {'hostname': 'host0'},
    626                             True,
    627                             [{u'status': u'Ready',
    628                               u'hostname': u'host0',
    629                               u'locked': False,
    630                               u'locked_by': 'user0',
    631                               u'lock_time': u'2008-07-23 12:54:15',
    632                               u'lock_reason': u'',
    633                               u'protection': u'No protection',
    634                               u'labels': [u'label0', u'plat0'],
    635                               u'invalid': False,
    636                               u'shard': None,
    637                               u'platform': u'plat0',
    638                               u'id': 2,
    639                               u'attributes': {}}]),
    640                            ('get_acl_groups', {'hosts__hostname': 'host1'},
    641                             True,
    642                             [{u'description': u'',
    643                               u'hosts': [u'host0', u'host1'],
    644                               u'id': 1,
    645                               u'name': u'Everyone',
    646                               u'users': [u'user2', u'debug_user', u'user0']}]),
    647                            ('get_labels', {'host__hostname': 'host1'},
    648                             True,
    649                             [{u'id': 2,
    650                               u'platform': 1,
    651                               u'name': u'jme',
    652                               u'invalid': False,
    653                               u'kernel_config': u''}]),
    654                            ('get_acl_groups', {'hosts__hostname': 'host0'},
    655                             True,
    656                             [{u'description': u'',
    657                               u'hosts': [u'host0', u'host1'],
    658                               u'id': 1,
    659                               u'name': u'Everyone',
    660                               u'users': [u'user0', u'debug_user']},
    661                              {u'description': u'myacl0',
    662                               u'hosts': [u'host0'],
    663                               u'id': 2,
    664                               u'name': u'acl0',
    665                               u'users': [u'user0']}]),
    666                            ('get_labels', {'host__hostname': 'host0'},
    667                             True,
    668                             [{u'id': 4,
    669                               u'platform': 0,
    670                               u'name': u'label0',
    671                               u'invalid': False,
    672                               u'kernel_config': u''},
    673                              {u'id': 5,
    674                               u'platform': 1,
    675                               u'name': u'plat0',
    676                               u'invalid': False,
    677                               u'kernel_config': u''}])],
    678                      out_words_ok=['host0', 'host1', 'plat0', 'plat1',
    679                                    'Everyone', 'acl0', 'label0'])
    680 
    681 
    682     def test_execute_stat_one_bad_host_verbose(self):
    683         self.run_cmd(argv=['atest', 'host', 'stat', 'host0',
    684                            'host1', '-v'],
    685                      rpcs=[('get_hosts', {'hostname': 'host1'},
    686                             True,
    687                             []),
    688                            ('get_hosts', {'hostname': 'host0'},
    689                             True,
    690                             [{u'status': u'Ready',
    691                               u'hostname': u'host0',
    692                               u'locked': False,
    693                               u'locked_by': 'user0',
    694                               u'lock_time': u'2008-07-23 12:54:15',
    695                               u'lock_reason': u'',
    696                               u'protection': u'No protection',
    697                               u'labels': [u'label0', u'plat0'],
    698                               u'invalid': False,
    699                               u'platform': u'plat0',
    700                               u'id': 2,
    701                               u'attributes': {}}]),
    702                            ('get_acl_groups', {'hosts__hostname': 'host0'},
    703                             True,
    704                             [{u'description': u'',
    705                               u'hosts': [u'host0', u'host1'],
    706                               u'id': 1,
    707                               u'name': u'Everyone',
    708                               u'users': [u'user0', u'debug_user']},
    709                              {u'description': u'myacl0',
    710                               u'hosts': [u'host0'],
    711                               u'id': 2,
    712                               u'name': u'acl0',
    713                               u'users': [u'user0']}]),
    714                            ('get_labels', {'host__hostname': 'host0'},
    715                             True,
    716                             [{u'id': 4,
    717                               u'platform': 0,
    718                               u'name': u'label0',
    719                               u'invalid': False,
    720                               u'kernel_config': u''},
    721                              {u'id': 5,
    722                               u'platform': 1,
    723                               u'name': u'plat0',
    724                               u'invalid': False,
    725                               u'kernel_config': u''}])],
    726                      out_words_ok=['host0', 'plat0',
    727                                    'Everyone', 'acl0', 'label0'],
    728                      out_words_no=['host1'],
    729                      err_words_ok=['host1', 'Unknown host'],
    730                      err_words_no=['host0'])
    731 
    732 
    733     def test_execute_stat_one_bad_host(self):
    734         self.run_cmd(argv=['atest', 'host', 'stat', 'host0', 'host1'],
    735                      rpcs=[('get_hosts', {'hostname': 'host1'},
    736                             True,
    737                             []),
    738                            ('get_hosts', {'hostname': 'host0'},
    739                             True,
    740                             [{u'status': u'Ready',
    741                               u'hostname': u'host0',
    742                               u'locked': False,
    743                               u'locked_by': 'user0',
    744                               u'lock_time': u'2008-07-23 12:54:15',
    745                               u'lock_reason': u'',
    746                               u'protection': u'No protection',
    747                               u'labels': [u'label0', u'plat0'],
    748                               u'invalid': False,
    749                               u'platform': u'plat0',
    750                               u'id': 2,
    751                               u'attributes': {}}]),
    752                            ('get_acl_groups', {'hosts__hostname': 'host0'},
    753                             True,
    754                             [{u'description': u'',
    755                               u'hosts': [u'host0', u'host1'],
    756                               u'id': 1,
    757                               u'name': u'Everyone',
    758                               u'users': [u'user0', u'debug_user']},
    759                              {u'description': u'myacl0',
    760                               u'hosts': [u'host0'],
    761                               u'id': 2,
    762                               u'name': u'acl0',
    763                               u'users': [u'user0']}]),
    764                            ('get_labels', {'host__hostname': 'host0'},
    765                             True,
    766                             [{u'id': 4,
    767                               u'platform': 0,
    768                               u'name': u'label0',
    769                               u'invalid': False,
    770                               u'kernel_config': u''},
    771                              {u'id': 5,
    772                               u'platform': 1,
    773                               u'name': u'plat0',
    774                               u'invalid': False,
    775                               u'kernel_config': u''}])],
    776                      out_words_ok=['host0', 'plat0',
    777                                    'Everyone', 'acl0', 'label0'],
    778                      out_words_no=['host1'],
    779                      err_words_ok=['host1', 'Unknown host'],
    780                      err_words_no=['host0'])
    781 
    782 
    783     def test_execute_stat_wildcard(self):
    784         # The order of RPCs between host1 and host0 could change...
    785         self.run_cmd(argv=['atest', 'host', 'stat', 'ho*'],
    786                      rpcs=[('get_hosts', {'hostname__startswith': 'ho'},
    787                             True,
    788                             [{u'status': u'Ready',
    789                               u'hostname': u'host1',
    790                               u'locked': True,
    791                               u'lock_time': u'2008-07-23 12:54:15',
    792                               u'locked_by': 'user0',
    793                               u'lock_reason': u'',
    794                               u'protection': 'No protection',
    795                               u'labels': [u'label3', u'plat1'],
    796                               u'invalid': False,
    797                               u'platform': u'plat1',
    798                               u'id': 3,
    799                               u'attributes': {}},
    800                             {u'status': u'Ready',
    801                               u'hostname': u'host0',
    802                               u'locked': False,
    803                               u'locked_by': 'user0',
    804                               u'lock_time': u'2008-07-23 12:54:15',
    805                               u'lock_reason': u'',
    806                               u'protection': u'No protection',
    807                               u'labels': [u'label0', u'plat0'],
    808                               u'invalid': False,
    809                               u'platform': u'plat0',
    810                               u'id': 2,
    811                               u'attributes': {}}]),
    812                            ('get_acl_groups', {'hosts__hostname': 'host1'},
    813                             True,
    814                             [{u'description': u'',
    815                               u'hosts': [u'host0', u'host1'],
    816                               u'id': 1,
    817                               u'name': u'Everyone',
    818                               u'users': [u'user2', u'debug_user', u'user0']}]),
    819                            ('get_labels', {'host__hostname': 'host1'},
    820                             True,
    821                             [{u'id': 2,
    822                               u'platform': 1,
    823                               u'name': u'jme',
    824                               u'invalid': False,
    825                               u'kernel_config': u''}]),
    826                            ('get_acl_groups', {'hosts__hostname': 'host0'},
    827                             True,
    828                             [{u'description': u'',
    829                               u'hosts': [u'host0', u'host1'],
    830                               u'id': 1,
    831                               u'name': u'Everyone',
    832                               u'users': [u'user0', u'debug_user']},
    833                              {u'description': u'myacl0',
    834                               u'hosts': [u'host0'],
    835                               u'id': 2,
    836                               u'name': u'acl0',
    837                               u'users': [u'user0']}]),
    838                            ('get_labels', {'host__hostname': 'host0'},
    839                             True,
    840                             [{u'id': 4,
    841                               u'platform': 0,
    842                               u'name': u'label0',
    843                               u'invalid': False,
    844                               u'kernel_config': u''},
    845                              {u'id': 5,
    846                               u'platform': 1,
    847                               u'name': u'plat0',
    848                               u'invalid': False,
    849                               u'kernel_config': u''}])],
    850                      out_words_ok=['host0', 'host1', 'plat0', 'plat1',
    851                                    'Everyone', 'acl0', 'label0'])
    852 
    853 
    854     def test_execute_stat_wildcard_and_host(self):
    855         # The order of RPCs between host1 and host0 could change...
    856         self.run_cmd(argv=['atest', 'host', 'stat', 'ho*', 'newhost0'],
    857                      rpcs=[('get_hosts', {'hostname': 'newhost0'},
    858                             True,
    859                             [{u'status': u'Ready',
    860                               u'hostname': u'newhost0',
    861                               u'locked': False,
    862                               u'locked_by': 'user0',
    863                               u'lock_time': u'2008-07-23 12:54:15',
    864                               u'lock_reason': u'',
    865                               u'protection': u'No protection',
    866                               u'labels': [u'label0', u'plat0'],
    867                               u'invalid': False,
    868                               u'platform': u'plat0',
    869                               u'id': 5,
    870                               u'attributes': {}}]),
    871                            ('get_hosts', {'hostname__startswith': 'ho'},
    872                             True,
    873                             [{u'status': u'Ready',
    874                               u'hostname': u'host1',
    875                               u'locked': True,
    876                               u'lock_time': u'2008-07-23 12:54:15',
    877                               u'locked_by': 'user0',
    878                               u'lock_reason': u'',
    879                               u'protection': 'No protection',
    880                               u'labels': [u'label3', u'plat1'],
    881                               u'invalid': False,
    882                               u'platform': u'plat1',
    883                               u'id': 3,
    884                               u'attributes': {}},
    885                             {u'status': u'Ready',
    886                               u'hostname': u'host0',
    887                               u'locked': False,
    888                               u'locked_by': 'user0',
    889                               u'lock_reason': u'',
    890                               u'protection': 'No protection',
    891                               u'lock_time': u'2008-07-23 12:54:15',
    892                               u'labels': [u'label0', u'plat0'],
    893                               u'invalid': False,
    894                               u'platform': u'plat0',
    895                               u'id': 2,
    896                               u'attributes': {}}]),
    897                            ('get_acl_groups', {'hosts__hostname': 'newhost0'},
    898                             True,
    899                             [{u'description': u'',
    900                               u'hosts': [u'newhost0', 'host1'],
    901                               u'id': 42,
    902                               u'name': u'my_acl',
    903                               u'users': [u'user0', u'debug_user']},
    904                              {u'description': u'my favorite acl',
    905                               u'hosts': [u'newhost0'],
    906                               u'id': 2,
    907                               u'name': u'acl10',
    908                               u'users': [u'user0']}]),
    909                            ('get_labels', {'host__hostname': 'newhost0'},
    910                             True,
    911                             [{u'id': 4,
    912                               u'platform': 0,
    913                               u'name': u'label0',
    914                               u'invalid': False,
    915                               u'kernel_config': u''},
    916                              {u'id': 5,
    917                               u'platform': 1,
    918                               u'name': u'plat0',
    919                               u'invalid': False,
    920                               u'kernel_config': u''}]),
    921                            ('get_acl_groups', {'hosts__hostname': 'host1'},
    922                             True,
    923                             [{u'description': u'',
    924                               u'hosts': [u'host0', u'host1'],
    925                               u'id': 1,
    926                               u'name': u'Everyone',
    927                               u'users': [u'user2', u'debug_user', u'user0']}]),
    928                            ('get_labels', {'host__hostname': 'host1'},
    929                             True,
    930                             [{u'id': 2,
    931                               u'platform': 1,
    932                               u'name': u'jme',
    933                               u'invalid': False,
    934                               u'kernel_config': u''}]),
    935                            ('get_acl_groups', {'hosts__hostname': 'host0'},
    936                             True,
    937                             [{u'description': u'',
    938                               u'hosts': [u'host0', u'host1'],
    939                               u'id': 1,
    940                               u'name': u'Everyone',
    941                               u'users': [u'user0', u'debug_user']},
    942                              {u'description': u'myacl0',
    943                               u'hosts': [u'host0'],
    944                               u'id': 2,
    945                               u'name': u'acl0',
    946                               u'users': [u'user0']}]),
    947                            ('get_labels', {'host__hostname': 'host0'},
    948                             True,
    949                             [{u'id': 4,
    950                               u'platform': 0,
    951                               u'name': u'label0',
    952                               u'invalid': False,
    953                               u'kernel_config': u''},
    954                              {u'id': 5,
    955                               u'platform': 1,
    956                               u'name': u'plat0',
    957                               u'invalid': False,
    958                               u'kernel_config': u''}])],
    959                      out_words_ok=['host0', 'host1', 'newhost0',
    960                                    'plat0', 'plat1',
    961                                    'Everyone', 'acl10', 'label0'])
    962 
    963 
    964 class host_jobs_unittest(cli_mock.cli_unittest):
    965     def test_execute_jobs_one_host(self):
    966         self.run_cmd(argv=['atest', 'host', 'jobs', 'host0'],
    967                      rpcs=[('get_host_queue_entries',
    968                             {'host__hostname': 'host0', 'query_limit': 20,
    969                              'sort_by': ['-job__id']},
    970                             True,
    971                             [{u'status': u'Failed',
    972                               u'complete': 1,
    973                               u'host': {u'status': u'Ready',
    974                                         u'locked': True,
    975                                         u'locked_by': 'user0',
    976                                         u'hostname': u'host0',
    977                                         u'invalid': False,
    978                                         u'id': 3232},
    979                               u'priority': 0,
    980                               u'meta_host': u'meta0',
    981                               u'job': {u'control_file':
    982                                        (u"def step_init():\n"
    983                                         "\tjob.next_step([step_test])\n"
    984                                         "def step_test():\n"
    985                                         "\tjob.run_test('kernbench')\n\n"),
    986                                        u'name': u'kernel-smp-2.6.xyz.x86_64',
    987                                        u'control_type': CLIENT,
    988                                        u'synchronizing': None,
    989                                        u'priority': u'Low',
    990                                        u'owner': u'user0',
    991                                        u'created_on': u'2008-01-09 10:45:12',
    992                                        u'synch_count': None,
    993                                        u'id': 216},
    994                                        u'active': 0,
    995                                        u'id': 2981},
    996                               {u'status': u'Aborted',
    997                                u'complete': 1,
    998                                u'host': {u'status': u'Ready',
    999                                          u'locked': True,
   1000                                          u'locked_by': 'user0',
   1001                                          u'hostname': u'host0',
   1002                                          u'invalid': False,
   1003                                          u'id': 3232},
   1004                                u'priority': 0,
   1005                                u'meta_host': None,
   1006                                u'job': {u'control_file':
   1007                                         u"job.run_test('sleeptest')\n\n",
   1008                                         u'name': u'testjob',
   1009                                         u'control_type': CLIENT,
   1010                                         u'synchronizing': 0,
   1011                                         u'priority': u'Low',
   1012                                         u'owner': u'user1',
   1013                                         u'created_on': u'2008-01-17 15:04:53',
   1014                                         u'synch_count': None,
   1015                                         u'id': 289},
   1016                                u'active': 0,
   1017                                u'id': 3167}])],
   1018                      out_words_ok=['216', 'user0', 'Failed',
   1019                                    'kernel-smp-2.6.xyz.x86_64', 'Aborted',
   1020                                    '289', 'user1', 'Aborted',
   1021                                    'testjob'])
   1022 
   1023 
   1024     def test_execute_jobs_wildcard(self):
   1025         self.run_cmd(argv=['atest', 'host', 'jobs', 'ho*'],
   1026                      rpcs=[('get_hosts', {'hostname__startswith': 'ho'},
   1027                             True,
   1028                             [{u'status': u'Ready',
   1029                               u'hostname': u'host1',
   1030                               u'locked': True,
   1031                               u'lock_time': u'2008-07-23 12:54:15',
   1032                               u'locked_by': 'user0',
   1033                               u'labels': [u'label3', u'plat1'],
   1034                               u'invalid': False,
   1035                               u'platform': u'plat1',
   1036                               u'id': 3},
   1037                             {u'status': u'Ready',
   1038                               u'hostname': u'host0',
   1039                               u'locked': False,
   1040                               u'locked_by': 'user0',
   1041                               u'lock_time': u'2008-07-23 12:54:15',
   1042                               u'labels': [u'label0', u'plat0'],
   1043                               u'invalid': False,
   1044                               u'platform': u'plat0',
   1045                               u'id': 2}]),
   1046                            ('get_host_queue_entries',
   1047                             {'host__hostname': 'host1', 'query_limit': 20,
   1048                              'sort_by': ['-job__id']},
   1049                             True,
   1050                             [{u'status': u'Failed',
   1051                               u'complete': 1,
   1052                               u'host': {u'status': u'Ready',
   1053                                         u'locked': True,
   1054                                         u'locked_by': 'user0',
   1055                                         u'hostname': u'host1',
   1056                                         u'invalid': False,
   1057                                         u'id': 3232},
   1058                               u'priority': 0,
   1059                               u'meta_host': u'meta0',
   1060                               u'job': {u'control_file':
   1061                                        (u"def step_init():\n"
   1062                                         "\tjob.next_step([step_test])\n"
   1063                                         "def step_test():\n"
   1064                                         "\tjob.run_test('kernbench')\n\n"),
   1065                                        u'name': u'kernel-smp-2.6.xyz.x86_64',
   1066                                        u'control_type': CLIENT,
   1067                                        u'synchronizing': None,
   1068                                        u'priority': u'Low',
   1069                                        u'owner': u'user0',
   1070                                        u'created_on': u'2008-01-09 10:45:12',
   1071                                        u'synch_count': None,
   1072                                        u'id': 216},
   1073                                        u'active': 0,
   1074                                        u'id': 2981},
   1075                               {u'status': u'Aborted',
   1076                                u'complete': 1,
   1077                                u'host': {u'status': u'Ready',
   1078                                          u'locked': True,
   1079                                          u'locked_by': 'user0',
   1080                                          u'hostname': u'host1',
   1081                                          u'invalid': False,
   1082                                          u'id': 3232},
   1083                                u'priority': 0,
   1084                                u'meta_host': None,
   1085                                u'job': {u'control_file':
   1086                                         u"job.run_test('sleeptest')\n\n",
   1087                                         u'name': u'testjob',
   1088                                         u'control_type': CLIENT,
   1089                                         u'synchronizing': 0,
   1090                                         u'priority': u'Low',
   1091                                         u'owner': u'user1',
   1092                                         u'created_on': u'2008-01-17 15:04:53',
   1093                                         u'synch_count': None,
   1094                                         u'id': 289},
   1095                                u'active': 0,
   1096                                u'id': 3167}]),
   1097                            ('get_host_queue_entries',
   1098                             {'host__hostname': 'host0', 'query_limit': 20,
   1099                              'sort_by': ['-job__id']},
   1100                             True,
   1101                             [{u'status': u'Failed',
   1102                               u'complete': 1,
   1103                               u'host': {u'status': u'Ready',
   1104                                         u'locked': True,
   1105                                         u'locked_by': 'user0',
   1106                                         u'hostname': u'host0',
   1107                                         u'invalid': False,
   1108                                         u'id': 3232},
   1109                               u'priority': 0,
   1110                               u'meta_host': u'meta0',
   1111                               u'job': {u'control_file':
   1112                                        (u"def step_init():\n"
   1113                                         "\tjob.next_step([step_test])\n"
   1114                                         "def step_test():\n"
   1115                                         "\tjob.run_test('kernbench')\n\n"),
   1116                                        u'name': u'kernel-smp-2.6.xyz.x86_64',
   1117                                        u'control_type': CLIENT,
   1118                                        u'synchronizing': None,
   1119                                        u'priority': u'Low',
   1120                                        u'owner': u'user0',
   1121                                        u'created_on': u'2008-01-09 10:45:12',
   1122                                        u'synch_count': None,
   1123                                        u'id': 216},
   1124                                        u'active': 0,
   1125                                        u'id': 2981},
   1126                               {u'status': u'Aborted',
   1127                                u'complete': 1,
   1128                                u'host': {u'status': u'Ready',
   1129                                          u'locked': True,
   1130                                          u'locked_by': 'user0',
   1131                                          u'hostname': u'host0',
   1132                                          u'invalid': False,
   1133                                          u'id': 3232},
   1134                                u'priority': 0,
   1135                                u'meta_host': None,
   1136                                u'job': {u'control_file':
   1137                                         u"job.run_test('sleeptest')\n\n",
   1138                                         u'name': u'testjob',
   1139                                         u'control_type': CLIENT,
   1140                                         u'synchronizing': 0,
   1141                                         u'priority': u'Low',
   1142                                         u'owner': u'user1',
   1143                                         u'created_on': u'2008-01-17 15:04:53',
   1144                                         u'synch_count': None,
   1145                                         u'id': 289},
   1146                                u'active': 0,
   1147                                u'id': 3167}])],
   1148                      out_words_ok=['216', 'user0', 'Failed',
   1149                                    'kernel-smp-2.6.xyz.x86_64', 'Aborted',
   1150                                    '289', 'user1', 'Aborted',
   1151                                    'testjob'])
   1152 
   1153 
   1154     def test_execute_jobs_one_host_limit(self):
   1155         self.run_cmd(argv=['atest', 'host', 'jobs', 'host0', '-q', '10'],
   1156                      rpcs=[('get_host_queue_entries',
   1157                             {'host__hostname': 'host0', 'query_limit': 10,
   1158                              'sort_by': ['-job__id']},
   1159                             True,
   1160                             [{u'status': u'Failed',
   1161                               u'complete': 1,
   1162                               u'host': {u'status': u'Ready',
   1163                                         u'locked': True,
   1164                                         u'locked_by': 'user0',
   1165                                         u'hostname': u'host0',
   1166                                         u'invalid': False,
   1167                                         u'id': 3232},
   1168                               u'priority': 0,
   1169                               u'meta_host': u'meta0',
   1170                               u'job': {u'control_file':
   1171                                        (u"def step_init():\n"
   1172                                         "\tjob.next_step([step_test])\n"
   1173                                         "def step_test():\n"
   1174                                         "\tjob.run_test('kernbench')\n\n"),
   1175                                        u'name': u'kernel-smp-2.6.xyz.x86_64',
   1176                                        u'control_type': CLIENT,
   1177                                        u'synchronizing': None,
   1178                                        u'priority': u'Low',
   1179                                        u'owner': u'user0',
   1180                                        u'created_on': u'2008-01-09 10:45:12',
   1181                                        u'synch_count': None,
   1182                                        u'id': 216},
   1183                                        u'active': 0,
   1184                                        u'id': 2981},
   1185                               {u'status': u'Aborted',
   1186                                u'complete': 1,
   1187                                u'host': {u'status': u'Ready',
   1188                                          u'locked': True,
   1189                                          u'locked_by': 'user0',
   1190                                          u'hostname': u'host0',
   1191                                          u'invalid': False,
   1192                                          u'id': 3232},
   1193                                u'priority': 0,
   1194                                u'meta_host': None,
   1195                                u'job': {u'control_file':
   1196                                         u"job.run_test('sleeptest')\n\n",
   1197                                         u'name': u'testjob',
   1198                                         u'control_type': CLIENT,
   1199                                         u'synchronizing': 0,
   1200                                         u'priority': u'Low',
   1201                                         u'owner': u'user1',
   1202                                         u'created_on': u'2008-01-17 15:04:53',
   1203                                         u'synch_count': None,
   1204                                         u'id': 289},
   1205                                u'active': 0,
   1206                                u'id': 3167}])],
   1207                      out_words_ok=['216', 'user0', 'Failed',
   1208                                    'kernel-smp-2.6.xyz.x86_64', 'Aborted',
   1209                                    '289', 'user1', 'Aborted',
   1210                                    'testjob'])
   1211 
   1212 
   1213 class host_mod_create_tests(object):
   1214 
   1215     def _gen_attributes_rpcs(self, host, attributes):
   1216         """Generate RPCs expected to add attributes to host.
   1217 
   1218         @param host: hostname
   1219         @param attributes: dict of attributes
   1220 
   1221         @return: list of rpcs to expect
   1222         """
   1223         rpcs = []
   1224         for attr, val in attributes.iteritems():
   1225             rpcs.append(('set_host_attribute',
   1226                          {
   1227                              'hostname': host,
   1228                              'attribute': attr,
   1229                              'value': val,
   1230                          },
   1231                          True, None))
   1232         return rpcs
   1233 
   1234 
   1235     def _gen_labels_rpcs(self, labels, platform=False, host_id=None):
   1236         """Generate RPCS expected to add labels.
   1237 
   1238         @param labels: list of label names
   1239         @param platform: labels are platform labels
   1240         @param host_id: Host id old labels will be deleted from (if host exists)
   1241         """
   1242         rpcs = []
   1243         if host_id:
   1244             rpcs.append(('get_labels', {'host': host_id}, True, []))
   1245         for label in labels:
   1246             rpcs += [
   1247                 ('get_labels', {'name': label}, True, []),
   1248                 ('add_label', {'name': label}, True, None)
   1249             ]
   1250             if platform:
   1251                 rpcs[-1][1]['platform'] = True
   1252         return rpcs
   1253 
   1254 
   1255     def _gen_acls_rpcs(self, hosts, acls, host_ids=[]):
   1256         """Generate RPCs expected to add acls.
   1257 
   1258         @param hosts: list of hostnames
   1259         @param acls: list of acl names
   1260         @param host_ids: List of host_ids if hosts already exist
   1261         """
   1262         rpcs = []
   1263         for host_id in host_ids:
   1264             rpcs.append(('get_acl_groups', {'hosts': host_id}, True, []))
   1265         for acl in acls:
   1266             rpcs.append(('get_acl_groups', {'name': acl}, True, []))
   1267             rpcs.append(('add_acl_group', {'name': acl}, True, None))
   1268         for acl in acls:
   1269             rpcs.append((
   1270                 'acl_group_add_hosts',
   1271                 {
   1272                     'hosts': hosts,
   1273                     'id': acl,
   1274                 },
   1275                 True,
   1276                 None,
   1277             ))
   1278         return rpcs
   1279 
   1280 
   1281     def test_lock_one_host(self):
   1282         """Test locking host / creating host locked."""
   1283         lock_reason = 'Because'
   1284         rpcs, out = self._gen_expectations(locked=True, lock_reason=lock_reason)
   1285         self.run_cmd(argv=self._command_single + ['--lock', '--lock_reason',
   1286                                                   lock_reason],
   1287                      rpcs=rpcs, out_words_ok=out)
   1288 
   1289 
   1290     def test_unlock_multiple_hosts(self):
   1291         """Test unlocking host / creating host unlocked."""
   1292         rpcs, out = self._gen_expectations(hosts=self._hosts, locked=False)
   1293         self.run_cmd(argv=self._command_multiple + ['--unlock'], rpcs=rpcs,
   1294                      out_words_ok=out)
   1295 
   1296 
   1297     def test_machine_list(self):
   1298         """Test action an machines from machine list file."""
   1299         mfile = cli_mock.create_file(','.join(self._hosts))
   1300         rpcs, out = self._gen_expectations(hosts=self._hosts, locked=False)
   1301         try:
   1302             self.run_cmd(argv=self._command_multiple + ['--unlock'], rpcs=rpcs,
   1303                          out_words_ok=out)
   1304         finally:
   1305             mfile.clean()
   1306 
   1307 
   1308     def test_single_attributes(self):
   1309         """Test applying one attribute to one host."""
   1310         attrs = {'foo': 'bar'}
   1311         rpcs, out = self._gen_expectations(attributes=attrs)
   1312         self.run_cmd(self._command_single + ['--attribute', 'foo=bar'],
   1313                      rpcs=rpcs, out_words_ok=out)
   1314 
   1315 
   1316     def test_attributes_comma(self):
   1317         """Test setting an attribute with a comma in the value."""
   1318         attrs = {'foo': 'bar,zip'}
   1319         rpcs, out = self._gen_expectations(attributes=attrs)
   1320         self.run_cmd(self._command_single + ['--attribute', 'foo=bar,zip'],
   1321                      rpcs=rpcs, out_words_ok=out)
   1322 
   1323 
   1324     def test_multiple_attributes_comma(self):
   1325         """Test setting attributes when one of the values contains a comma."""
   1326         attrs = {'foo': 'bar,zip', 'zang': 'poodle'}
   1327         rpcs, out = self._gen_expectations(attributes=attrs)
   1328         self.run_cmd(self._command_single + ['--attribute', 'foo=bar,zip',
   1329                                              '--attribute', 'zang=poodle'],
   1330                      rpcs=rpcs, out_words_ok=out)
   1331 
   1332 
   1333     def test_multiple_attributes_multiple_hosts(self):
   1334         """Test applying multiple attributes to multiple hosts."""
   1335         attrs = {'foo': 'bar', 'baz': 'zip'}
   1336         rpcs, out = self._gen_expectations(hosts=self._hosts, attributes=attrs)
   1337         self.run_cmd(self._command_multiple + ['--attribute', 'foo=bar',
   1338                                                '--attribute', 'baz=zip'],
   1339                      rpcs=rpcs, out_words_ok=out)
   1340 
   1341 
   1342     def test_platform(self):
   1343         """Test applying platform label."""
   1344         rpcs, out = self._gen_expectations(platform='some_platform')
   1345         self.run_cmd(argv=self._command_single + ['--platform',
   1346                                                   'some_platform'],
   1347                      rpcs=rpcs, out_words_ok=out)
   1348 
   1349 
   1350     def test_labels(self):
   1351         """Test applying labels."""
   1352         labels = ['label0', 'label1']
   1353         rpcs, out = self._gen_expectations(labels=labels)
   1354         self.run_cmd(argv=self._command_single + ['--labels', ','.join(labels)],
   1355                      rpcs=rpcs, out_words_ok=out)
   1356 
   1357 
   1358     def test_labels_from_file(self):
   1359         """Test applying labels from file."""
   1360         labels = ['label0', 'label1']
   1361         rpcs, out = self._gen_expectations(labels=labels)
   1362         labelsf = cli_mock.create_file(','.join(labels))
   1363         try:
   1364             self.run_cmd(argv=self._command_single + ['--blist', labelsf.name],
   1365                          rpcs=rpcs, out_words_ok=out)
   1366         finally:
   1367             labelsf.clean()
   1368 
   1369 
   1370     def test_acls(self):
   1371         """Test applying acls."""
   1372         acls = ['acl0', 'acl1']
   1373         rpcs, out = self._gen_expectations(acls=acls)
   1374         self.run_cmd(argv=self._command_single + ['--acls', ','.join(acls)],
   1375                      rpcs=rpcs, out_words_ok=out)
   1376 
   1377 
   1378     def test_acls_from_file(self):
   1379         """Test applying acls from file."""
   1380         acls = ['acl0', 'acl1']
   1381         rpcs, out = self._gen_expectations(acls=acls)
   1382         aclsf = cli_mock.create_file(','.join(acls))
   1383         try:
   1384             self.run_cmd(argv=self._command_single + ['-A', aclsf.name],
   1385                          rpcs=rpcs, out_words_ok=out)
   1386         finally:
   1387             aclsf.clean()
   1388 
   1389 
   1390     def test_protection(self):
   1391         """Test applying host protection."""
   1392         protection = 'Do not repair'
   1393         rpcs, out = self._gen_expectations(protection=protection)
   1394         self.run_cmd(argv=self._command_single + ['--protection', protection],
   1395                      rpcs=rpcs,out_words_ok=out)
   1396 
   1397 
   1398     def test_protection_invalid(self):
   1399         """Test invalid protection causes failure."""
   1400         protection = 'Invalid protection'
   1401         rpcs, out = self._gen_expectations(hosts=[])
   1402         self.run_cmd(argv=self._command_single + ['--protection', protection],
   1403                      exit_code=2, err_words_ok=['invalid', 'choice'] +
   1404                      protection.split())
   1405 
   1406 
   1407     def test_complex(self):
   1408         """Test applying multiple modifications / creating a complex host."""
   1409         lock_reason = 'Because I said so.'
   1410         platform = 'some_platform'
   1411         labels = ['label0', 'label1']
   1412         acls = ['acl0', 'acl1']
   1413         protection = 'Do not verify'
   1414         labelsf = cli_mock.create_file(labels[1])
   1415         aclsf = cli_mock.create_file(acls[1])
   1416         cmd_args = ['-l', '-r', lock_reason, '-t', platform, '-b', labels[0],
   1417                     '-B', labelsf.name, '-a', acls[0], '-A', aclsf.name, '-p',
   1418                     protection]
   1419         rpcs, out = self._gen_expectations(locked=True, lock_reason=lock_reason,
   1420                                            acls=acls, labels=labels,
   1421                                            platform=platform,
   1422                                            protection=protection)
   1423 
   1424         try:
   1425             self.run_cmd(argv=self._command_single + cmd_args, rpcs=rpcs,
   1426                          out_words_ok=out)
   1427         finally:
   1428             labelsf.clean()
   1429             aclsf.clean()
   1430 
   1431 
   1432 class host_mod_unittest(host_mod_create_tests, cli_mock.cli_unittest):
   1433     """Tests specific to the mod action and expectation generator for shared
   1434     tests.
   1435     """
   1436     _hosts = ['localhost', '127.0.0.1']
   1437     _host_ids = [1, 2]
   1438     _command_base = ['atest', 'host', 'mod']
   1439     _command_single = _command_base + [_hosts[0]]
   1440     _command_multiple = _command_base + _hosts
   1441 
   1442     def _gen_expectations(self, hosts=['localhost'], locked=None,
   1443                           lock_reason='', force_lock=False, protection=None,
   1444                           acls=[], labels=[], platform=None, attributes={}):
   1445         rpcs = []
   1446         out = set()
   1447         hosts = hosts[:]
   1448         hosts.reverse()
   1449 
   1450         # Genarate result for get_hosts command to include all known hosts
   1451         host_dicts = []
   1452         for h, h_id in zip(self._hosts, self._host_ids):
   1453             host_dicts.append({'hostname': h, 'id': h_id})
   1454         rpcs.append(('get_hosts', {'hostname__in': hosts}, True, host_dicts))
   1455 
   1456         # Expect actions only for known hosts
   1457         host_ids = []
   1458         for host in hosts:
   1459             if host not in self._hosts:
   1460                 continue
   1461             host_id = self._host_ids[self._hosts.index(host)]
   1462             host_ids.append(host_id)
   1463             modify_args = {'id': host}
   1464 
   1465             if locked is not None:
   1466                 out.add('Locked' if locked else 'Unlocked')
   1467                 modify_args['locked'] = locked
   1468                 modify_args['lock_reason'] = lock_reason
   1469             if force_lock:
   1470                 modify_args['force_modify_locking'] = True
   1471             if protection:
   1472                 modify_args['protection'] = protection
   1473 
   1474             if len(modify_args.keys()) > 1:
   1475                 out.add(host)
   1476                 rpcs.append(('modify_host', modify_args, True, None))
   1477 
   1478             if labels:
   1479                 rpcs += self._gen_labels_rpcs(labels, host_id=host_id)
   1480                 rpcs.append(('host_add_labels', {'id': host, 'labels': labels},
   1481                              True, None))
   1482 
   1483             if platform:
   1484                 rpcs += self._gen_labels_rpcs([platform], platform=True,
   1485                                               host_id=host_id)
   1486                 rpcs.append(('host_add_labels', {'id': host,
   1487                                                  'labels': [platform]},
   1488                              True, None))
   1489 
   1490             rpcs += self._gen_attributes_rpcs(host, attributes)
   1491 
   1492         if acls:
   1493             rpcs += self._gen_acls_rpcs(hosts, acls, host_ids=host_ids)
   1494 
   1495         return rpcs, list(out)
   1496 
   1497 
   1498     def test_mod_force_lock_one_host(self):
   1499         """Test mod with forced locking."""
   1500         lock_reason = 'Because'
   1501         rpcs, out = self._gen_expectations(locked=True, force_lock=True,
   1502                                            lock_reason=lock_reason)
   1503         self.run_cmd(argv=self._command_single + [
   1504                             '--lock', '--force_modify_locking', '--lock_reason',
   1505                             lock_reason],
   1506                      rpcs=rpcs, out_words_ok=out)
   1507 
   1508     def test_mod_force_unlock_one_host(self):
   1509         """Test mod forced unlocking."""
   1510         rpcs, out = self._gen_expectations(locked=False, force_lock=True)
   1511         self.run_cmd(argv=self._command_single + ['--unlock',
   1512                                                    '--force_modify_locking'],
   1513                       rpcs=rpcs, out_words_ok=out)
   1514 
   1515     def test_mod_fail_unknown_host(self):
   1516         """Test mod fails with unknown host."""
   1517         rpcs, out = self._gen_expectations(hosts=['nope'], locked=True)
   1518         self.run_cmd(argv=self._command_base + ['nope', '--lock'],
   1519                      rpcs=rpcs, err_words_ok=['Cannot', 'modify', 'nope'])
   1520 
   1521 
   1522 class host_create_unittest(host_mod_create_tests, cli_mock.cli_unittest):
   1523     """Test specific to create action and expectation generator for shared
   1524     tests.
   1525     """
   1526     _hosts = ['localhost', '127.0.0.1']
   1527     _command_base = ['atest', 'host', 'create']
   1528     _command_single = _command_base + [_hosts[0]]
   1529     _command_multiple = _command_base + _hosts
   1530 
   1531 
   1532     def setUp(self):
   1533         """Mock out the create_host method.
   1534         """
   1535         super(host_create_unittest, self).setUp()
   1536         self._orig_create_host = hosts.create_host
   1537 
   1538 
   1539     def tearDown(self):
   1540         """Undo mock.
   1541         """
   1542         super(host_create_unittest, self).tearDown()
   1543         hosts.create_host = self._orig_create_host
   1544 
   1545 
   1546     def _mock_host(self, platform=None, labels=[]):
   1547         """Update the return values of the mocked host object.
   1548 
   1549         @param platform: return value of Host.get_platform()
   1550         @param labels: return value of Host.get_labels()
   1551         """
   1552         mock_host = mock.MagicMock()
   1553         mock_host.get_platform.return_value = platform
   1554         mock_host.get_labels.return_value = labels
   1555         hosts.create_host = mock.MagicMock()
   1556         hosts.create_host.return_value = mock_host
   1557 
   1558 
   1559     def _gen_expectations(self, hosts=['localhost'], locked=False,
   1560                           lock_reason=None, platform=None,
   1561                           discovered_platform=None, labels=[],
   1562                           discovered_labels=[], acls=[], protection=None,
   1563                           attributes={}):
   1564         """Build a list of expected RPC calls based on values to host command.
   1565 
   1566         @param hosts: list of hostname being created (default ['localhost'])
   1567         @param locked: end state of host (bool)
   1568         @param lock_reason: reason for host to be locked
   1569         @param platform: platform label
   1570         @param discovered_platform: platform discovered automatically by host
   1571         @param labels: list of host labels (excluding platform)
   1572         @param discovered_labels: list of labels discovered automatically
   1573         @param acls: list of host acls
   1574         @param protection: host protection level
   1575 
   1576         @return: list of expect rpc calls (each call is (op, args, success,
   1577             result))
   1578         """
   1579         hosts = hosts[:]
   1580         hosts.reverse() # No idea why
   1581         lock_reason = lock_reason or 'Forced lock on device creation'
   1582         acls = acls or []
   1583 
   1584         rpcs = []
   1585         out = ['Added', 'host'] + hosts
   1586 
   1587         # Mock platform and label detection results
   1588         self._mock_host(discovered_platform, discovered_labels)
   1589 
   1590         for host in hosts:
   1591             add_args = {
   1592                 'hostname': host,
   1593                 'status': 'Ready',
   1594                 'locked': True,
   1595                 'lock_reason': lock_reason,
   1596             }
   1597             if protection:
   1598                 add_args['protection'] = protection
   1599             rpcs.append(('add_host', add_args, True, None))
   1600 
   1601             rpcs += self._gen_labels_rpcs(labels)
   1602             if labels:
   1603                 rpcs.append(('host_add_labels', {'id': host, 'labels': labels},
   1604                              True, None))
   1605 
   1606             if platform:
   1607                 rpcs += self._gen_labels_rpcs([platform], platform=True)
   1608                 rpcs.append(('host_add_labels', {'id': host,
   1609                                                  'labels': [platform]},
   1610                              True, None))
   1611 
   1612             rpcs += self._gen_attributes_rpcs(host, attributes)
   1613 
   1614         rpcs += self._gen_acls_rpcs(hosts, acls)
   1615 
   1616         if not locked:
   1617             for host in hosts:
   1618                 rpcs.append((
   1619                     'modify_host',
   1620                     {
   1621                         'id': host,
   1622                         'locked': False,
   1623                         'lock_reason': '',
   1624                     },
   1625                     True,
   1626                     None,
   1627                 ))
   1628         return rpcs, out
   1629 
   1630     def test_create_no_args(self):
   1631         """Test simple creation with to arguments."""
   1632         rpcs, out = self._gen_expectations()
   1633         self.run_cmd(argv=self._command_single, rpcs=rpcs, out_words_ok=out)
   1634 
   1635 
   1636     def test_create_with_discovered_platform(self):
   1637         """Test discovered platform is used when platform isn't specified."""
   1638         rpcs, out = self._gen_expectations(platform='some_platform',
   1639                                            discovered_platform='some_platform')
   1640         self.run_cmd(argv=self._command_single, rpcs=rpcs, out_words_ok=out)
   1641 
   1642 
   1643     def test_create_specified_platform_overrides_discovered_platform(self):
   1644         """Test that the specified platform overrides the discovered platform.
   1645         """
   1646         rpcs, out = self._gen_expectations(platform='some_platform',
   1647                                            discovered_platform='wrong_platform')
   1648         self.run_cmd(argv=self._command_single + ['--platform',
   1649                                                   'some_platform'],
   1650                      rpcs=rpcs, out_words_ok=out)
   1651 
   1652 
   1653     def test_create_discovered_labels(self):
   1654         """Test applying automatically discovered labels."""
   1655         labels = ['label0', 'label1']
   1656         rpcs, out = self._gen_expectations(labels=labels,
   1657                                            discovered_labels=labels)
   1658         self.run_cmd(argv=self._command_single, rpcs=rpcs, out_words_ok=out)
   1659 
   1660 
   1661     def test_create_specified_discovered_labels_combine(self):
   1662         """Test applying both discovered and specified labels."""
   1663         labels = ['label0', 'label1']
   1664         rpcs, out = self._gen_expectations(labels=labels,
   1665                                            discovered_labels=[labels[0]])
   1666         self.run_cmd(argv=self._command_single + ['--labels', labels[1]],
   1667                      rpcs=rpcs, out_words_ok=out)
   1668 
   1669 
   1670 if __name__ == '__main__':
   1671     unittest.main()
   1672