• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/python2
2#
3# Copyright 2008 Google Inc. All Rights Reserved.
4
5"""Test for host."""
6
7# pylint: disable=missing-docstring
8
9import sys
10import unittest
11
12import mock
13
14import common
15from autotest_lib.cli import cli_mock, host
16from autotest_lib.client.common_lib import control_data
17from autotest_lib.server import hosts
18CLIENT = control_data.CONTROL_TYPE_NAMES.CLIENT
19SERVER = control_data.CONTROL_TYPE_NAMES.SERVER
20
21class 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
57class 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
606class 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
964class 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
1213class 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
1432class 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
1522class 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    def test_remove_hostname_suffix(self):
1670        self.assertEqual(
1671            host._remove_hostname_suffix_if_present( \
1672                "a", host.MIGRATED_HOST_SUFFIX), "a")
1673        self.assertEqual( \
1674            host._remove_hostname_suffix_if_present( \
1675                "b" + host.MIGRATED_HOST_SUFFIX, \
1676            host.MIGRATED_HOST_SUFFIX), "b")
1677
1678
1679if __name__ == '__main__':
1680    unittest.main()
1681