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