job_unittest.py revision 648a35c560f78874c05582349e1c09632ce210d6
1#!/usr/bin/python -u
2#
3# Copyright 2008 Google Inc. All Rights Reserved.
4
5#TODO(rkubiak): Add unittest for job cloning
6
7"""Tests for job."""
8
9import copy, getpass, unittest, sys, os
10
11import common
12from autotest_lib.cli import cli_mock, topic_common, job
13
14
15class job_unittest(cli_mock.cli_unittest):
16    def setUp(self):
17        super(job_unittest, self).setUp()
18        self.god.stub_function(getpass, 'getuser')
19        getpass.getuser.expect_call().and_return('user0')
20        self.values = copy.deepcopy(self.values_template)
21
22    results = [{u'status_counts': {u'Aborted': 1},
23                u'control_file':
24                u"job.run_test('sleeptest')\n",
25                u'name': u'test_job0',
26                u'control_type': u'Server',
27                u'priority':
28                u'Medium',
29                u'owner': u'user0',
30                u'created_on':
31                u'2008-07-08 17:45:44',
32                u'synch_count': 2,
33                u'id': 180},
34               {u'status_counts': {u'Queued': 1},
35                u'control_file':
36                u"job.run_test('sleeptest')\n",
37                u'name': u'test_job1',
38                u'control_type': u'Client',
39                u'priority':
40                u'High',
41                u'owner': u'user0',
42                u'created_on':
43                u'2008-07-08 12:17:47',
44                u'synch_count': 1,
45                u'id': 338}]
46
47
48    values_template = [{u'id': 180,          # Valid job
49                        u'priority': u'Low',
50                        u'name': u'test_job0',
51                        u'owner': u'Cringer',
52                        u'invalid': False,
53                        u'created_on': u'2008-07-02 13:02:40',
54                        u'control_type': u'Server',
55                        u'status_counts': {u'Queued': 1},
56                        u'synch_count': 2},
57                       {u'id': 338,          # Valid job
58                        u'priority': 'High',
59                        u'name': u'test_job1',
60                        u'owner': u'Fisto',
61                        u'invalid': False,
62                        u'created_on': u'2008-07-06 14:05:33',
63                        u'control_type': u'Client',
64                        u'status_counts': {u'Queued': 1},
65                        u'synch_count': 1},
66                       {u'id': 339,          # Valid job
67                        u'priority': 'Medium',
68                        u'name': u'test_job2',
69                        u'owner': u'Roboto',
70                        u'invalid': False,
71                        u'created_on': u'2008-07-07 15:33:18',
72                        u'control_type': u'Server',
73                        u'status_counts': {u'Queued': 1},
74                        u'synch_count': 1},
75                       {u'id': 340,          # Invalid job priority
76                        u'priority': u'Uber',
77                        u'name': u'test_job3',
78                        u'owner': u'Panthor',
79                        u'invalid': True,
80                        u'created_on': u'2008-07-04 00:00:01',
81                        u'control_type': u'Server',
82                        u'status_counts': {u'Queued': 1},
83                        u'synch_count': 2},
84                       {u'id': 350,          # Invalid job created_on
85                        u'priority': 'Medium',
86                        u'name': u'test_job4',
87                        u'owner': u'Icer',
88                        u'invalid': True,
89                        u'created_on': u'Today',
90                        u'control_type': u'Client',
91                        u'status_counts': {u'Queued': 1},
92                        u'synch_count': 1},
93                       {u'id': 420,          # Invalid job control_type
94                        u'priority': 'Urgent',
95                        u'name': u'test_job5',
96                        u'owner': u'Spikor',
97                        u'invalid': True,
98                        u'created_on': u'2012-08-08 18:54:37',
99                        u'control_type': u'Child',
100                        u'status_counts': {u'Queued': 1},
101                        u'synch_count': 2}]
102
103
104class job_list_unittest(job_unittest):
105    def test_job_list_jobs(self):
106        getpass.getuser.expect_call().and_return('user0')
107        self.run_cmd(argv=['atest', 'job', 'list', '--ignore_site_file'],
108                     rpcs=[('get_jobs_summary', {'owner': 'user0',
109                                                 'running': None},
110                            True, self.values)],
111                     out_words_ok=['test_job0', 'test_job1', 'test_job2'],
112                     out_words_no=['Uber', 'Today', 'Child'])
113
114
115    def test_job_list_jobs_only_user(self):
116        values = [item for item in self.values if item['owner'] == 'Cringer']
117        self.run_cmd(argv=['atest', 'job', 'list', '-u', 'Cringer',
118                           '--ignore_site_file'],
119                     rpcs=[('get_jobs_summary', {'owner': 'Cringer',
120                                                 'running': None},
121                            True, values)],
122                     out_words_ok=['Cringer'],
123                     out_words_no=['Fisto', 'Roboto', 'Panthor', 'Icer',
124                                   'Spikor'])
125
126
127    def test_job_list_jobs_all(self):
128        self.run_cmd(argv=['atest', 'job', 'list', '--all',
129                           '--ignore_site_file'],
130                     rpcs=[('get_jobs_summary', {'running': None},
131                            True, self.values)],
132                     out_words_ok=['Fisto', 'Roboto', 'Panthor',
133                                   'Icer', 'Spikor', 'Cringer'],
134                     out_words_no=['Created', 'Priority'])
135
136
137    def test_job_list_jobs_id(self):
138        self.run_cmd(argv=['atest', 'job', 'list', '5964',
139                           '--ignore_site_file'],
140                     rpcs=[('get_jobs_summary', {'id__in': ['5964'],
141                                                 'running': None},
142                            True,
143                            [{u'status_counts': {u'Completed': 1},
144                              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    testkernel = job.kernel(\'8210088647656509311.kernel-smp-2.6.18-220.5.x86_64.rpm\')\n    \n    testkernel.install()\n    testkernel.boot(args=\'console_always_print=1\')\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)',
145                              u'name': u'mytest',
146                              u'control_type': u'Client',
147                              u'run_verify': 1,
148                              u'priority': u'Medium',
149                              u'owner': u'user0',
150                              u'created_on': u'2008-07-28 12:42:52',
151                              u'timeout': 144,
152                              u'synch_count': 1,
153                              u'id': 5964}])],
154                     out_words_ok=['user0', 'Completed', '1', '5964'],
155                     out_words_no=['sleeptest', 'Priority', 'Client', '2008'])
156
157
158    def test_job_list_jobs_id_verbose(self):
159        self.run_cmd(argv=['atest', 'job', 'list', '5964', '-v',
160                           '--ignore_site_file'],
161                     rpcs=[('get_jobs_summary', {'id__in': ['5964'],
162                                                 'running': None},
163                            True,
164                            [{u'status_counts': {u'Completed': 1},
165                              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    testkernel = job.kernel(\'8210088647656509311.kernel-smp-2.6.18-220.5.x86_64.rpm\')\n    \n    testkernel.install()\n    testkernel.boot(args=\'console_always_print=1\')\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)',
166                              u'name': u'mytest',
167                              u'control_type': u'Client',
168                              u'run_verify': 1,
169                              u'priority': u'Medium',
170                              u'owner': u'user0',
171                              u'created_on': u'2008-07-28 12:42:52',
172                              u'timeout': 144,
173                              u'synch_count': 1,
174                              u'id': 5964}])],
175                     out_words_ok=['user0', 'Completed', '1', '5964',
176                                   'Client', '2008', 'Priority'],
177                     out_words_no=['sleeptest'])
178
179
180    def test_job_list_jobs_name(self):
181        self.run_cmd(argv=['atest', 'job', 'list', 'myt*',
182                           '--ignore_site_file'],
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    testkernel = job.kernel(\'8210088647656509311.kernel-smp-2.6.18-220.5.x86_64.rpm\')\n    \n    testkernel.install()\n    testkernel.boot(args=\'console_always_print=1\')\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': u'Client',
190                              u'run_verify': 1,
191                              u'priority': u'Medium',
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                           '--ignore_site_file'],
204                     rpcs=[('get_jobs_summary', {'running': None},
205                            True, self.values)],
206                     out_words_ok=['Fisto', 'Spikor', 'Cringer', 'Priority',
207                                   'Created'])
208
209
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                    '--ignore_site_file']
214        self.god.mock_io()
215        sys.exit.expect_call(1).and_raises(cli_mock.ExitException)
216        self.assertRaises(cli_mock.ExitException, testjob.parse)
217        self.god.unmock_io()
218
219
220class job_stat_unittest(job_unittest):
221    def test_job_stat_job(self):
222        results = copy.deepcopy(self.results)
223        self.run_cmd(argv=['atest', 'job', 'stat', '180',
224                           '--ignore_site_file'],
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'synch_id': None},
237                              u'priority': 1,
238                              u'meta_host': None,
239                              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)",
240                                       u'name': u'test_sleep',
241                                       u'control_type': u'Server',
242                                       u'synchronizing': 0,
243                                       u'priority': u'Medium',
244                                       u'owner': u'user0',
245                                       u'created_on': u'2008-03-18 11:27:29',
246                                       u'synch_count': 1,
247                                       u'id': 180},
248                              u'active': 0,
249                              u'id': 101084}])],
250                     out_words_ok=['test_job0', 'host0', 'Failed',
251                                   'Aborted'])
252
253
254    def test_job_stat_job_multiple_hosts(self):
255        self.run_cmd(argv=['atest', 'job', 'stat', '6761',
256                           '--ignore_site_file'],
257                     rpcs=[('get_jobs_summary', {'id__in': ['6761']}, True,
258                            [{u'status_counts': {u'Running': 1,
259                                                 u'Queued': 4},
260                              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\')',
261                              u'name': u'test_on_meta_hosts',
262                              u'control_type': u'Client',
263                              u'run_verify': 1,
264                              u'priority': u'Medium',
265                              u'owner': u'user0',
266                              u'created_on': u'2008-07-30 22:15:43',
267                              u'timeout': 144,
268                              u'synch_count': 1,
269                              u'id': 6761}]),
270                           ('get_host_queue_entries', {'job__in': ['6761']},
271                            True,
272                            [{u'status': u'Queued',
273                              u'complete': 0,
274                              u'deleted': 0,
275                              u'host': None,
276                              u'priority': 1,
277                              u'meta_host': u'Xeon',
278                              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\')',
279                                       u'name': u'test_on_meta_hosts',
280                                       u'control_type': u'Client',
281                                       u'run_verify': 1,
282                                       u'priority': u'Medium',
283                                       u'owner': u'user0',
284                                       u'created_on': u'2008-07-30 22:15:43',
285                                       u'timeout': 144,
286                                       u'synch_count': 1,
287                                       u'id': 6761},
288                              u'active': 0,
289                              u'id': 193166},
290                             {u'status': u'Queued',
291                              u'complete': 0,
292                              u'deleted': 0,
293                              u'host': None,
294                              u'priority': 1,
295                              u'meta_host': u'Xeon',
296                              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\')',
297                                       u'name': u'test_on_meta_hosts',
298                                       u'control_type': u'Client',
299                                       u'run_verify': 1,
300                                       u'priority': u'Medium',
301                                       u'owner': u'user0',
302                                       u'created_on': u'2008-07-30 22:15:43',
303                                       u'timeout': 144,
304                                       u'synch_count': 1,
305                                       u'id': 6761},
306                              u'active': 0,
307                              u'id': 193167},
308                             {u'status': u'Queued',
309                              u'complete': 0,
310                              u'deleted': 0,
311                              u'host': None,
312                              u'priority': 1,
313                              u'meta_host': u'Athlon',
314                              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\')',
315                                       u'name': u'test_on_meta_hosts',
316                                       u'control_type': u'Client',
317                                       u'run_verify': 1,
318                                       u'priority': u'Medium',
319                                       u'owner': u'user0',
320                                       u'created_on': u'2008-07-30 22:15:43',
321                                       u'timeout': 144,
322                                       u'synch_count': 1,
323                                       u'id': 6761},
324                              u'active': 0,
325                              u'id': 193168},
326                             {u'status': u'Queued',
327                              u'complete': 0,
328                              u'deleted': 0,
329                              u'host': None,
330                              u'priority': 1,
331                              u'meta_host': u'x286',
332                              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\')',
333                                       u'name': u'test_on_meta_hosts',
334                                       u'control_type': u'Client',
335                                       u'run_verify': 1,
336                                       u'priority': u'Medium',
337                                       u'owner': u'user0',
338                                       u'created_on': u'2008-07-30 22:15:43',
339                                       u'timeout': 144,
340                                       u'synch_count': 1,
341                                       u'id': 6761},
342                              u'active': 0,
343                              u'id': 193169},
344                             {u'status': u'Running',
345                              u'complete': 0,
346                              u'deleted': 0,
347                              u'host': {u'status': u'Running',
348                                        u'lock_time': None,
349                                        u'hostname': u'host42',
350                                        u'locked': False,
351                                        u'locked_by': None,
352                                        u'invalid': False,
353                                        u'id': 4833,
354                                        u'protection': u'Repair filesystem only',
355                                        u'synch_id': None},
356                              u'priority': 1,
357                              u'meta_host': u'Athlon',
358                              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\')',
359                                       u'name': u'test_on_meta_hosts',
360                                       u'control_type': u'Client',
361                                       u'run_verify': 1,
362                                       u'priority': u'Medium',
363                                       u'owner': u'user0',
364                                       u'created_on': u'2008-07-30 22:15:43',
365                                       u'timeout': 144,
366                                       u'synch_count': 1,
367                                       u'id': 6761},
368                              u'active': 1,
369                              u'id': 193170} ])],
370                     out_words_ok=['test_on_meta_hosts',
371                                   'host42', 'Queued', 'Running'],
372                     out_words_no=['Athlon', 'Xeon', 'x286'])
373
374
375    def test_job_stat_job_no_host_in_qes(self):
376        results = copy.deepcopy(self.results)
377        self.run_cmd(argv=['atest', 'job', 'stat', '180',
378                           '--ignore_site_file'],
379                     rpcs=[('get_jobs_summary', {'id__in': ['180']}, True,
380                            [results[0]]),
381                           ('get_host_queue_entries', {'job__in': ['180']},
382                            True,
383                            [{u'status': u'Failed',
384                              u'complete': 1,
385                              u'host': None,
386                              u'priority': 1,
387                              u'meta_host': None,
388                              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)",
389                                       u'name': u'test_sleep',
390                                       u'control_type': u'Server',
391                                       u'priority': u'Medium',
392                                       u'owner': u'user0',
393                                       u'created_on': u'2008-03-18 11:27:29',
394                                       u'synch_count': 1,
395                                       u'id': 180},
396                              u'active': 0,
397                              u'id': 101084}])],
398                     out_words_ok=['test_job0', 'Aborted'])
399
400
401    def test_job_stat_multi_jobs(self):
402        results = copy.deepcopy(self.results)
403        self.run_cmd(argv=['atest', 'job', 'stat', '180', '338',
404                           '--ignore_site_file'],
405                     rpcs=[('get_jobs_summary', {'id__in': ['180', '338']},
406                            True, results),
407                           ('get_host_queue_entries',
408                            {'job__in': ['180', '338']},
409                            True,
410                            [{u'status': u'Failed',
411                              u'complete': 1,
412                              u'host': {u'status': u'Repair Failed',
413                                        u'locked': False,
414                                        u'hostname': u'host0',
415                                        u'invalid': True,
416                                        u'id': 4432,
417                                        u'synch_id': None},
418                              u'priority': 1,
419                              u'meta_host': None,
420                              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)",
421                                       u'name': u'test_sleep',
422                                       u'control_type': u'Server',
423                                       u'priority': u'Medium',
424                                       u'owner': u'user0',
425                                       u'created_on': u'2008-03-18 11:27:29',
426                                       u'synch_count': 1,
427                                       u'id': 180},
428                              u'active': 0,
429                              u'id': 101084},
430                             {u'status': u'Failed',
431                              u'complete': 1,
432                              u'host': {u'status': u'Repair Failed',
433                                        u'locked': False,
434                                        u'hostname': u'host10',
435                                        u'invalid': True,
436                                        u'id': 4432,
437                                        u'synch_id': None},
438                              u'priority': 1,
439                              u'meta_host': None,
440                              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)",
441                                       u'name': u'test_sleep',
442                                       u'control_type': u'Server',
443                                       u'priority': u'Medium',
444                                       u'owner': u'user0',
445                                       u'created_on': u'2008-03-18 11:27:29',
446                                       u'synch_count': 1,
447                                       u'id': 338},
448                              u'active': 0,
449                              u'id': 101084}])],
450                     out_words_ok=['test_job0', 'test_job1'])
451
452
453    def test_job_stat_multi_jobs_name_id(self):
454        self.run_cmd(argv=['atest', 'job', 'stat', 'mytest', '180',
455                           '--ignore_site_file'],
456                     rpcs=[('get_jobs_summary', {'id__in': ['180']},
457                            True,
458                            [{u'status_counts': {u'Aborted': 1},
459                             u'control_file':
460                             u"job.run_test('sleeptest')\n",
461                             u'name': u'job0',
462                             u'control_type': u'Server',
463                             u'priority':
464                             u'Medium',
465                             u'owner': u'user0',
466                             u'created_on':
467                             u'2008-07-08 17:45:44',
468                             u'synch_count': 2,
469                             u'id': 180}]),
470                           ('get_jobs_summary', {'name__in': ['mytest']},
471                            True,
472                            [{u'status_counts': {u'Queued': 1},
473                             u'control_file':
474                             u"job.run_test('sleeptest')\n",
475                             u'name': u'mytest',
476                             u'control_type': u'Client',
477                             u'priority':
478                             u'High',
479                             u'owner': u'user0',
480                             u'created_on': u'2008-07-08 12:17:47',
481                             u'synch_count': 1,
482                             u'id': 338}]),
483                           ('get_host_queue_entries',
484                            {'job__in': ['180']},
485                            True,
486                            [{u'status': u'Failed',
487                              u'complete': 1,
488                              u'host': {u'status': u'Repair Failed',
489                                        u'locked': False,
490                                        u'hostname': u'host0',
491                                        u'invalid': True,
492                                        u'id': 4432,
493                                        u'synch_id': None},
494                              u'priority': 1,
495                              u'meta_host': None,
496                              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)",
497                                       u'name': u'test_sleep',
498                                       u'control_type': u'Server',
499                                       u'synchronizing': 0,
500                                       u'priority': u'Medium',
501                                       u'owner': u'user0',
502                                       u'created_on': u'2008-03-18 11:27:29',
503                                       u'synch_count': 1,
504                                       u'id': 180},
505                              u'active': 0,
506                              u'id': 101084}]),
507                           ('get_host_queue_entries',
508                            {'job__name__in': ['mytest']},
509                            True,
510                            [{u'status': u'Failed',
511                              u'complete': 1,
512                              u'host': {u'status': u'Repair Failed',
513                                        u'locked': False,
514                                        u'hostname': u'host10',
515                                        u'invalid': True,
516                                        u'id': 4432,
517                                        u'synch_id': None},
518                              u'priority': 1,
519                              u'meta_host': None,
520                              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)",
521                                       u'name': u'test_sleep',
522                                       u'control_type': u'Server',
523                                       u'synchronizing': 0,
524                                       u'priority': u'Medium',
525                                       u'owner': u'user0',
526                                       u'created_on': u'2008-03-18 11:27:29',
527                                       u'synch_count': 1,
528                                       u'id': 338},
529                              u'active': 0,
530                              u'id': 101084}])],
531                     out_words_ok=['job0', 'mytest', 'Aborted', 'Queued',
532                                   'Failed', 'Medium', 'High'])
533
534
535class job_create_unittest(cli_mock.cli_unittest):
536    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)'
537
538    kernel_ctrl_file = 'kernel = \'kernel\'\ndef step_init():\n    job.next_step([step_test])\n    testkernel = job.kernel(\'kernel\')\n    \n    testkernel.install()\n    testkernel.boot(args=\'console_always_print=1\')\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)'
539
540    trivial_ctrl_file = 'print "Hello"\n'
541
542    data = {'priority': 'Medium', 'control_file': ctrl_file, 'hosts': ['host0'],
543            'name': 'test_job0', 'control_type': 'Client', 'email_list': '',
544            'meta_hosts': [], 'synch_count': 1, 'dependencies': []}
545
546
547    def test_execute_create_job(self):
548        self.run_cmd(argv=['atest', 'job', 'create', '-t', 'sleeptest',
549                           'test_job0', '-m', 'host0', '--ignore_site_file'],
550                     rpcs=[('generate_control_file',
551                            {'tests': ['sleeptest']},
552                            True,
553                            {'control_file' : self.ctrl_file,
554                             'synch_count' : 1,
555                             'is_server' : False,
556                             'dependencies' : []}),
557                           ('create_job', self.data, True, 180)],
558                     out_words_ok=['test_job0', 'Created'],
559                     out_words_no=['Uploading', 'Done'])
560
561
562    def test_execute_create_job_with_atomic_group(self):
563        data = dict(self.data)
564        data['atomic_group_name'] = 'my-atomic-group'
565        data['control_type'] = 'Server'
566        mock_ctrl_file = 'mock control file'
567        data['control_file'] = mock_ctrl_file
568        data['synch_count'] = 2
569        data['hosts'] = []
570        self.run_cmd(argv=['atest', 'job', 'create', '-t', 'mocktest',
571                           'test_job0', '--ignore_site_file',
572                           '-G', 'my-atomic-group'],
573                     rpcs=[('generate_control_file',
574                            {'tests': ['mocktest']},
575                            True,
576                            {'control_file' : mock_ctrl_file,
577                             'synch_count' : 2,
578                             'is_server' : True,
579                             'dependencies' : []}),
580                           ('create_job', data, True, 180)],
581                     out_words_ok=['test_job0', 'Created'],
582                     out_words_no=['Uploading', 'Done'])
583
584
585    def test_execute_create_job_with_control(self):
586        filename = cli_mock.create_file(self.ctrl_file)
587        self.run_cmd(argv=['atest', 'job', 'create', '-f', filename,
588                           'test_job0', '-m', 'host0', '--ignore_site_file'],
589                     rpcs=[('create_job', self.data, True, 42)],
590                     out_words_ok=['test_job0', 'Created'],
591                     out_words_no=['Uploading', 'Done'])
592
593
594    def test_execute_create_job_with_control_and_kernel(self):
595        data = self.data.copy()
596        data['control_file'] = '# Made up control "file" for unittest.'
597        filename = cli_mock.create_file(self.trivial_ctrl_file)
598        self.run_cmd(argv=['atest', 'job', 'create', '-f', filename,
599                           '-k', 'Kernel', 'test_job0', '-m', 'host0',
600                           '--ignore_site_file'],
601                     rpcs=[('generate_control_file',
602                            {'client_control_file': self.trivial_ctrl_file,
603                             'do_push_packages': True,
604                             'kernel': 'Kernel'},
605                            True,
606                            {'control_file': data['control_file'],
607                             'synch_count': 1,
608                             'is_server': False,
609                             'dependencies': []}),
610                           ('create_job', data, True, 42)],
611                     out_words_ok=['test_job0', 'Created',
612                                   'Uploading', 'Done'])
613
614
615    def test_execute_create_job_with_control_and_email(self):
616        data = self.data.copy()
617        data['email_list'] = 'em'
618        filename = cli_mock.create_file(self.ctrl_file)
619        self.run_cmd(argv=['atest', 'job', 'create', '-f', filename,
620                           'test_job0', '-m', 'host0', '-e', 'em',
621                           '--ignore_site_file'],
622                     rpcs=[('create_job', data, True, 42)],
623                     out_words_ok=['test_job0', 'Created'],
624                     out_words_no=['Uploading', 'Done'])
625
626
627    def test_execute_create_job_with_control_and_dependencies(self):
628        data = self.data.copy()
629        data['dependencies'] = ['dep1', 'dep2']
630        filename = cli_mock.create_file(self.ctrl_file)
631        self.run_cmd(argv=['atest', 'job', 'create', '-f', filename,
632                           'test_job0', '-m', 'host0', '-d', 'dep1, dep2 ',
633                           '--ignore_site_file'],
634                     rpcs=[('create_job', data, True, 42)],
635                     out_words_ok=['test_job0', 'Created'],
636                     out_words_no=['Uploading', 'Done'])
637
638
639    def test_execute_create_job_with_synch_count(self):
640        data = self.data.copy()
641        data['synch_count'] = 2
642        filename = cli_mock.create_file(self.ctrl_file)
643        self.run_cmd(argv=['atest', 'job', 'create', '-f', filename,
644                           'test_job0', '-m', 'host0', '-y', '2',
645                           '--ignore_site_file'],
646                     rpcs=[('create_job', data, True, 42)],
647                     out_words_ok=['test_job0', 'Created'],
648                     out_words_no=['Uploading', 'Done'])
649
650
651    def test_execute_create_job_with_test_and_dependencies(self):
652        data = self.data.copy()
653        data['dependencies'] = ['dep1', 'dep2', 'dep3']
654        self.run_cmd(argv=['atest', 'job', 'create', '-t', 'sleeptest',
655                           'test_job0', '-m', 'host0', '-d', 'dep1, dep2 ',
656                           '--ignore_site_file'],
657                     rpcs=[('generate_control_file',
658                            {'tests': ['sleeptest']},
659                            True,
660                            {'control_file' : self.ctrl_file,
661                             'synch_count' : 1,
662                             'is_server' : False,
663                             'dependencies' : ['dep3']}),
664                           ('create_job', data, True, 42)],
665                     out_words_ok=['test_job0', 'Created'],
666                     out_words_no=['Uploading', 'Done'])
667
668
669    def test_execute_create_job_with_kernel(self):
670        data = self.data.copy()
671        data['control_file'] = self.kernel_ctrl_file
672        self.run_cmd(argv=['atest', 'job', 'create', '-t', 'sleeptest',
673                           '-k', 'kernel', 'test_job0', '-m', 'host0',
674                           '--ignore_site_file'],
675                     rpcs=[('generate_control_file',
676                            {'tests': ['sleeptest'],
677                             'kernel': 'kernel', 'do_push_packages': True},
678                            True,
679                            {'control_file' : self.kernel_ctrl_file,
680                             'synch_count' : 1,
681                             'is_server' : False,
682                             'dependencies' : []}),
683                           ('create_job', data, True, 180)],
684                     out_words_ok=['test_job0', 'Created',
685                                   'Uploading', 'Done'])
686
687
688    def test_execute_create_job_with_kernel_spaces(self):
689        data = self.data.copy()
690        data['control_file'] = self.kernel_ctrl_file
691        data['name'] = 'test job	with  spaces'
692        self.run_cmd(argv=['atest', 'job', 'create', '-t', 'sleeptest',
693                           '-k', 'kernel', 'test job	with  spaces',
694                           '-m', 'host0', '--ignore_site_file'],
695                     rpcs=[('generate_control_file',
696                            {'tests': ['sleeptest'],
697                             'kernel': 'kernel', 'do_push_packages': True},
698                            True,
699                            {'control_file' : self.kernel_ctrl_file,
700                             'synch_count' : 1,
701                             'is_server' : False,
702                             'dependencies' : []}),
703                           ('create_job', data, True, 180)],
704                     # This is actually 8 spaces,
705                     # the tab has been converted by print.
706                     out_words_ok=['test job        with  spaces', 'Created',
707                                   'id', '180'])
708
709
710    def test_execute_create_job_no_args(self):
711        testjob = job.job_create()
712        sys.argv = ['atest', 'job', 'create', '--ignore_site_file']
713        self.god.mock_io()
714        sys.exit.expect_call(1).and_raises(cli_mock.ExitException)
715        self.assertRaises(cli_mock.ExitException, testjob.parse)
716        self.god.unmock_io()
717
718
719    def test_execute_create_job_no_hosts(self):
720        testjob = job.job_create()
721        filename = cli_mock.create_file(self.ctrl_file)
722        sys.argv = ['atest', '-f', filename, 'test_job0', '--ignore_site_file']
723        self.god.mock_io()
724        sys.exit.expect_call(1).and_raises(cli_mock.ExitException)
725        self.assertRaises(cli_mock.ExitException, testjob.parse)
726        self.god.unmock_io()
727
728
729    def test_execute_create_job_cfile_and_tests(self):
730        testjob = job.job_create()
731        sys.argv = ['atest', 'job', 'create', '-t', 'sleeptest', '-f',
732                    'control_file', 'test_job0', '-m', 'host0',
733                    '--ignore_site_file']
734        self.god.mock_io()
735        sys.exit.expect_call(1).and_raises(cli_mock.ExitException)
736        self.assertRaises(cli_mock.ExitException, testjob.parse)
737        self.god.unmock_io()
738
739
740    def test_execute_create_job_cfile_and_kernel(self):
741        testjob = job.job_create()
742        sys.argv = ['atest', 'job', 'create', '-f', 'control_file', '-k',
743                    'kernel', 'test_job0', '-m', 'host0', '--ignore_site_file']
744        self.god.mock_io()
745        sys.exit.expect_call(1).and_raises(cli_mock.ExitException)
746        self.assertRaises(cli_mock.ExitException, testjob.parse)
747        self.god.unmock_io()
748
749
750    def test_execute_create_job_bad_cfile(self):
751        testjob = job.job_create()
752        sys.argv = ['atest', 'job', 'create', '-f', 'control_file',
753                    'test_job0', '-m', 'host0', '--ignore_site_file']
754        self.god.mock_io()
755        sys.exit.expect_call(1).and_raises(IOError)
756        self.assertRaises(IOError, testjob.parse)
757        self.god.unmock_io()
758
759
760    def test_execute_create_job_bad_priority(self):
761        testjob = job.job_create()
762        sys.argv = ['atest', 'job', 'create', '-t', 'sleeptest', '-p', 'Uber',
763                    '-m', 'host0', 'test_job0', '--ignore_site_file']
764        self.god.mock_io()
765        sys.exit.expect_call(2).and_raises(cli_mock.ExitException)
766        self.assertRaises(cli_mock.ExitException, testjob.parse)
767        self.god.unmock_io()
768
769
770    def test_execute_create_job_with_mfile(self):
771        data = self.data.copy()
772        data['hosts'] = ['host3', 'host2', 'host1', 'host0']
773        cfile = cli_mock.create_file(self.ctrl_file)
774        filename = cli_mock.create_file('host0\nhost1\nhost2\nhost3')
775        self.run_cmd(argv=['atest', 'job', 'create', '--mlist', filename, '-f',
776                           cfile, 'test_job0', '--ignore_site_file'],
777                     rpcs=[('create_job', data, True, 42)],
778                     out_words_ok=['test_job0', 'Created'])
779
780
781    def test_execute_create_job_with_timeout(self):
782        data = self.data.copy()
783        data['timeout'] = '222'
784        filename = cli_mock.create_file(self.ctrl_file)
785        self.run_cmd(argv=['atest', 'job', 'create', '-f', filename,
786                           'test_job0', '-m', 'host0', '-o', '222',
787                           '--ignore_site_file'],
788                     rpcs=[('create_job', data, True, 42)],
789                     out_words_ok=['test_job0', 'Created'],)
790
791
792    def test_execute_create_job_with_noverify(self):
793        data = self.data.copy()
794        data['run_verify'] = False
795        filename = cli_mock.create_file(self.ctrl_file)
796        self.run_cmd(argv=['atest', 'job', 'create', '-f', filename,
797                           'test_job0', '-m', 'host0', '-n',
798                           '--ignore_site_file'],
799                     rpcs=[('create_job', data, True, 42)],
800                     out_words_ok=['test_job0', 'Created'],)
801
802
803    def test_execute_create_job_oth(self):
804        data = self.data.copy()
805        data['one_time_hosts'] = ['host0']
806        self.run_cmd(argv=['atest', 'job', 'create', '-t', 'sleeptest',
807                           'test_job0', '--one-time-hosts', 'host0'],
808                     rpcs=[('generate_control_file',
809                            {'tests': ['sleeptest']},
810                            True,
811                            {'control_file' : self.ctrl_file,
812                             'synch_count' : 1,
813                             'is_server' : False,
814                             'dependencies' : []}),
815                           ('create_job', data, True, 180)],
816                     out_words_ok=['test_job0', 'Created'],
817                     out_words_no=['Uploading', 'Done'])
818
819
820    def test_execute_create_job_multi_oth(self):
821        data = self.data.copy()
822        data['one_time_hosts'] = ['host1', 'host0']
823        self.run_cmd(argv=['atest', 'job', 'create', '-t', 'sleeptest',
824                           'test_job0', '--one-time-hosts', 'host0,host1'],
825                     rpcs=[('generate_control_file',
826                            {'tests': ['sleeptest']},
827                            True,
828                            {'control_file' : self.ctrl_file,
829                             'synch_count' : 1,
830                             'is_server' : False,
831                             'dependencies' : []}),
832                           ('create_job', data, True, 180)],
833                     out_words_ok=['test_job0', 'Created'],
834                     out_words_no=['Uploading', 'Done'])
835
836
837    def test_execute_create_job_oth_exists(self):
838        data = self.data.copy()
839        data['one_time_hosts'] = ['host0']
840        self.run_cmd(argv=['atest', 'job', 'create', '-t', 'sleeptest',
841                           'test_job0', '--one-time-hosts', 'host0'],
842                     rpcs=[('generate_control_file',
843                            {'tests': ['sleeptest']},
844                            True,
845                            {'control_file' : self.ctrl_file,
846                             'synch_count' : 1,
847                             'is_server' : False,
848                             'dependencies' : []}),
849                           ('create_job', data, False,
850                            '''ValidationError: {'hostname': 'host0 '''
851                            '''already exists in the autotest DB.  '''
852                            '''Select it rather than entering it as '''
853                            '''a one time host.'}''')],
854                     out_words_no=['test_job0', 'Created'],
855                     err_words_ok=['failed', 'already exists'])
856
857
858    def test_execute_create_job_with_control_and_labels(self):
859        data = self.data.copy()
860        data['hosts'] = ['host0', 'host1', 'host2']
861        filename = cli_mock.create_file(self.ctrl_file)
862        self.run_cmd(argv=['atest', 'job', 'create', '-f', filename,
863                           'test_job0', '-m', 'host0', '-b', 'label1,label2',
864                           '--ignore_site_file'],
865                     rpcs=[('get_hosts', {'multiple_labels': ['label1',
866                            'label2']}, True,
867                            [{u'status': u'Running', u'lock_time': None,
868                              u'hostname': u'host1', u'locked': False,
869                              u'locked_by': None, u'invalid': False, u'id': 42,
870                              u'labels': [u'label1'], u'platform':
871                              u'Warp18_Diskfull', u'protection':
872                              u'Repair software only', u'dirty':
873                              True, u'synch_id': None},
874                             {u'status': u'Running', u'lock_time': None,
875                              u'hostname': u'host2', u'locked': False,
876                              u'locked_by': None, u'invalid': False, u'id': 43,
877                              u'labels': [u'label2'], u'platform':
878                              u'Warp18_Diskfull', u'protection':
879                              u'Repair software only', u'dirty': True,
880                              u'synch_id': None}]),
881                            ('create_job', data, True, 42)],
882                     out_words_ok=['test_job0', 'Created'],
883                     out_words_no=['Uploading', 'Done'])
884
885
886    def test_execute_create_job_with_label_and_duplicate_hosts(self):
887        data = self.data.copy()
888        data['hosts'] = ['host1', 'host0']
889        filename = cli_mock.create_file(self.ctrl_file)
890        self.run_cmd(argv=['atest', 'job', 'create', '-f', filename,
891                           'test_job0', '-m', 'host0,host1', '-b', 'label1',
892                           '--ignore_site_file'],
893                     rpcs=[('get_hosts', {'multiple_labels': ['label1']}, True,
894                            [{u'status': u'Running', u'lock_time': None,
895                              u'hostname': u'host1', u'locked': False,
896                              u'locked_by': None, u'invalid': False, u'id': 42,
897                              u'labels': [u'label1'], u'platform':
898                              u'Warp18_Diskfull', u'protection':
899                              u'Repair software only', u'dirty':
900                              True, u'synch_id': None}]),
901                            ('create_job', data, True, 42)],
902                     out_words_ok=['test_job0', 'Created'],
903                     out_words_no=['Uploading', 'Done'])
904
905
906    def _test_parse_hosts(self, args, exp_hosts=[], exp_meta_hosts=[]):
907        testjob = job.job_create()
908        (hosts, meta_hosts) = testjob.parse_hosts(args)
909        self.assertEqualNoOrder(hosts, exp_hosts)
910        self.assertEqualNoOrder(meta_hosts, exp_meta_hosts)
911
912
913    def test_parse_hosts_regular(self):
914        self._test_parse_hosts(['host0'], ['host0'])
915
916
917    def test_parse_hosts_regulars(self):
918        self._test_parse_hosts(['host0', 'host1'], ['host0', 'host1'])
919
920
921    def test_parse_hosts_meta_one(self):
922        self._test_parse_hosts(['*meta0'], [], ['meta0'])
923
924
925    def test_parse_hosts_meta_five(self):
926        self._test_parse_hosts(['5*meta0'], [], ['meta0']*5)
927
928
929    def test_parse_hosts_metas_five(self):
930        self._test_parse_hosts(['5*meta0', '2*meta1'], [],
931                               ['meta0']*5 + ['meta1']*2)
932
933
934    def test_parse_hosts_mix(self):
935        self._test_parse_hosts(['5*meta0', 'host0', '2*meta1', 'host1',
936                                '*meta2'], ['host0', 'host1'],
937                               ['meta0']*5 + ['meta1']*2 + ['meta2'])
938
939
940class job_abort_unittest(cli_mock.cli_unittest):
941    results = [{u'status_counts': {u'Aborted': 1}, u'control_file':
942                u"job.run_test('sleeptest')\n", u'name': u'test_job0',
943                u'control_type': u'Server', u'priority':
944                u'Medium', u'owner': u'user0', u'created_on':
945                u'2008-07-08 17:45:44', u'synch_count': 2, u'id': 180}]
946
947    def test_execute_job_abort(self):
948        self.run_cmd(argv=['atest', 'job', 'abort', '180',
949                           '--ignore_site_file'],
950                     rpcs=[('abort_host_queue_entries',
951                            {'job__id__in': ['180']}, True, None)],
952                     out_words_ok=['Aborting', '180'])
953
954
955if __name__ == '__main__':
956    unittest.main()
957