Update CLI to allow scheduling jobs against labels
Signed-off-by: Ryan Kubiak <[email protected]>
git-svn-id: http://test.kernel.org/svn/autotest/trunk@3070 592f7852-d20e-0410-864c-8624ca9c26a4
diff --git a/cli/action_common.py b/cli/action_common.py
index 388c4ac..e926d47 100755
--- a/cli/action_common.py
+++ b/cli/action_common.py
@@ -185,8 +185,8 @@
meta_hosts += int(num) * [host]
elif re.match('^[*](\w*)', host):
meta_hosts += [re.match('^[*](\w*)', host).group(1)]
- elif host != '':
- # Real hostname
+ elif host != '' and host not in hosts:
+ # Real hostname and not a duplicate
hosts.append(host)
return (hosts, meta_hosts)
diff --git a/cli/job.py b/cli/job.py
index 0b291a1..51c13fb 100755
--- a/cli/job.py
+++ b/cli/job.py
@@ -202,10 +202,10 @@
[--synch_count] [--control-file </path/to/cfile>]
[--on-server] [--test <test1,test2>] [--kernel <http://kernel>]
[--mlist </path/to/machinelist>] [--machine <host1 host2 host3>]
- [--labels <labels this job is dependent on>]
+ [--labels <list of labels of machines to run on>]
[--reboot_before <option>] [--reboot_after <option>]
[--noverify] [--timeout <timeout>] [--one-time-hosts <hosts>]
- [--email <email>]
+ [--email <email>] [--dependencies <labels this job is dependent on>]
job_name
Creating a job is rather different from the other create operations,
@@ -235,8 +235,11 @@
help='List of tests to run')
self.parser.add_option('-k', '--kernel', help='Install kernel from this'
' URL before beginning job')
+ self.parser.add_option('-d', '--dependencies', help='Comma separated '
+ 'list of labels this job is dependent on.',
+ default='')
self.parser.add_option('-b', '--labels', help='Comma separated list of '
- 'labels this job is dependent on.', default='')
+ 'labels to get machine list from.', default='')
self.parser.add_option('-m', '--machine', help='List of machines to '
'run on')
self.parser.add_option('-M', '--mlist',
@@ -294,9 +297,10 @@
self.reuse_hosts = options.reuse_hosts
return (options, leftover)
- if len(self.hosts) == 0 and not options.one_time_hosts:
+ if (len(self.hosts) == 0 and not options.one_time_hosts
+ and not options.labels):
self.invalid_syntax('Must specify at least one machine '
- '(-m, -M or --one-time-hosts).')
+ '(-m, -M, -b or --one-time-hosts).')
if not options.control_file and not options.test:
self.invalid_syntax('Must specify either --test or --control-file'
' to create a job.')
@@ -349,13 +353,20 @@
if options.one_time_hosts:
one_time_hosts = self._file_list(options, opt_list='one_time_hosts')
self.data['one_time_hosts'] = one_time_hosts
+ if options.labels:
+ labels = options.labels.split(',')
+ labels = [label.strip() for label in labels if label.strip()]
+ label_hosts = self.execute_rpc(op='get_hosts',
+ multiple_labels=labels)
+ for host in label_hosts:
+ self.hosts.append(host['hostname'])
self.data['name'] = self.jobname
(self.data['hosts'],
self.data['meta_hosts']) = self.parse_hosts(self.hosts)
- deps = options.labels.split(',')
+ deps = options.dependencies.split(',')
deps = [dep.strip() for dep in deps if dep.strip()]
self.data['dependencies'] = deps
diff --git a/cli/job_unittest.py b/cli/job_unittest.py
index 279ebe9..7b5d0c9 100755
--- a/cli/job_unittest.py
+++ b/cli/job_unittest.py
@@ -601,12 +601,12 @@
out_words_no=['Uploading', 'Done'])
- def test_execute_create_job_with_control_and_label(self):
+ def test_execute_create_job_with_control_and_dependencies(self):
data = self.data.copy()
data['dependencies'] = ['dep1', 'dep2']
filename = cli_mock.create_file(self.ctrl_file)
self.run_cmd(argv=['atest', 'job', 'create', '-f', filename,
- 'test_job0', '-m', 'host0', '-b', 'dep1, dep2 ',
+ 'test_job0', '-m', 'host0', '-d', 'dep1, dep2 ',
'--ignore_site_file'],
rpcs=[('create_job', data, True, 42)],
out_words_ok=['test_job0', 'Created'],
@@ -625,11 +625,11 @@
out_words_no=['Uploading', 'Done'])
- def test_execute_create_job_with_test_and_label(self):
+ def test_execute_create_job_with_test_and_dependencies(self):
data = self.data.copy()
data['dependencies'] = ['dep1', 'dep2', 'dep3']
self.run_cmd(argv=['atest', 'job', 'create', '-t', 'sleeptest',
- 'test_job0', '-m', 'host0', '-b', 'dep1, dep2 ',
+ 'test_job0', '-m', 'host0', '-d', 'dep1, dep2 ',
'--ignore_site_file'],
rpcs=[('generate_control_file',
{'tests': ['sleeptest']},
@@ -832,6 +832,54 @@
err_words_ok=['failed', 'already exists'])
+ def test_execute_create_job_with_control_and_labels(self):
+ data = self.data.copy()
+ data['hosts'] = ['host0', 'host1', 'host2']
+ filename = cli_mock.create_file(self.ctrl_file)
+ self.run_cmd(argv=['atest', 'job', 'create', '-f', filename,
+ 'test_job0', '-m', 'host0', '-b', 'label1,label2',
+ '--ignore_site_file'],
+ rpcs=[('get_hosts', {'multiple_labels': ['label1',
+ 'label2']}, True,
+ [{u'status': u'Running', u'lock_time': None,
+ u'hostname': u'host1', u'locked': False,
+ u'locked_by': None, u'invalid': False, u'id': 42,
+ u'labels': [u'label1'], u'platform':
+ u'Warp18_Diskfull', u'protection':
+ u'Repair software only', u'dirty':
+ True, u'synch_id': None},
+ {u'status': u'Running', u'lock_time': None,
+ u'hostname': u'host2', u'locked': False,
+ u'locked_by': None, u'invalid': False, u'id': 43,
+ u'labels': [u'label2'], u'platform':
+ u'Warp18_Diskfull', u'protection':
+ u'Repair software only', u'dirty': True,
+ u'synch_id': None}]),
+ ('create_job', data, True, 42)],
+ out_words_ok=['test_job0', 'Created'],
+ out_words_no=['Uploading', 'Done'])
+
+
+ def test_execute_create_job_with_label_and_duplicate_hosts(self):
+ data = self.data.copy()
+ data['hosts'] = ['host1', 'host0']
+ filename = cli_mock.create_file(self.ctrl_file)
+ self.run_cmd(argv=['atest', 'job', 'create', '-f', filename,
+ 'test_job0', '-m', 'host0,host1', '-b', 'label1',
+ '--ignore_site_file'],
+ rpcs=[('get_hosts', {'multiple_labels': ['label1']}, True,
+ [{u'status': u'Running', u'lock_time': None,
+ u'hostname': u'host1', u'locked': False,
+ u'locked_by': None, u'invalid': False, u'id': 42,
+ u'labels': [u'label1'], u'platform':
+ u'Warp18_Diskfull', u'protection':
+ u'Repair software only', u'dirty':
+ True, u'synch_id': None}]),
+ ('create_job', data, True, 42)],
+ out_words_ok=['test_job0', 'Created'],
+ out_words_no=['Uploading', 'Done'])
+
+
def _test_parse_hosts(self, args, exp_hosts=[], exp_meta_hosts=[]):
testjob = job.job_create()
(hosts, meta_hosts) = testjob.parse_hosts(args)