Change --dependencies flag to --labels flag to be more consistent.  Also
let people add their own dependencies even if they specified a test
via --test.

Risk: Low
Visibility: High

Signed-off-by: Jeremy Orlow <jorlow@google.com>



git-svn-id: http://test.kernel.org/svn/autotest/trunk@2356 592f7852-d20e-0410-864c-8624ca9c26a4
diff --git a/cli/cli_mock.py b/cli/cli_mock.py
index 4260bff..59d15b5 100755
--- a/cli/cli_mock.py
+++ b/cli/cli_mock.py
@@ -10,6 +10,7 @@
 from autotest_lib.frontend.afe.json_rpc import proxy
 from autotest_lib.client.common_lib.test_utils import mock
 
+CLI_USING_PDB = False
 CLI_UT_DEBUG = False
 
 def create_file(content):
@@ -96,7 +97,7 @@
 
         self.mock_rpcs(rpcs)
 
-        if not CLI_UT_DEBUG:
+        if not (CLI_USING_PDB and CLI_UT_DEBUG):
             self.god.mock_io()
         if exit_code != None:
             sys.exit.expect_call(exit_code).and_raises(ExitException)
diff --git a/cli/job.py b/cli/job.py
index 4fe3c5b..359d1db 100755
--- a/cli/job.py
+++ b/cli/job.py
@@ -202,7 +202,7 @@
     [--is-synchronous] [--container] [--control-file </path/to/cfile>]
     [--on-server] [--test <test1,test2>] [--kernel <http://kernel>]
     [--mlist </path/to/machinelist>] [--machine <host1 host2 host3>]
-    [--dependencies <list of dependency labels>]
+    [--labels <labels this job is dependent on>]
     [--reboot_before <option>] [--reboot_after <option>]
     job_name
 
@@ -236,10 +236,8 @@
                                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 dependencies for this test.  (NOTE: '
-                               'this feature is experimental and may change '
-                               'in the next release!)', default='')
+        self.parser.add_option('-b', '--labels', help='Comma separated list of '
+                               'labels this job is dependent on.', default='')
         self.parser.add_option('-m', '--machine', help='List of machines to '
                                'run on')
         self.parser.add_option('-M', '--mlist',
@@ -248,7 +246,7 @@
         self.parser.add_option('-e', '--email', help='A comma seperated list '
                                'of email addresses to notify of job completion',
                                default='')
-        self.parser.add_option('-b', '--reboot_before',
+        self.parser.add_option('-B', '--reboot_before',
                                help='Whether or not to reboot the machine '
                                     'before the job (never/if dirty/always)',
                                type='choice',
@@ -310,19 +308,16 @@
             if options.container:
                 self.invalid_syntax('Containers (--container) can only be added'
                                     ' with --test, not --control-file.')
-            deps = options.dependencies.split(',')
-            deps = [dep.strip() for dep in deps if dep.strip()]
-            self.data['dependencies'] = deps
             try:
                 self.data['control_file'] = open(options.control_file).read()
             except IOError:
                 self.generic_error('Unable to read from specified '
                                    'control-file: %s' % options.control_file)
         if options.test:
-            if options.server or options.synchronous or options.dependencies:
-                self.invalid_syntax('If you specify tests, the client/server, '
-                                    'synchronous, and dependency settings are '
-                                    'implicit and  cannot be overriden.')
+            if options.server or options.synchronous:
+                self.invalid_syntax('If you specify tests, then the '
+                                    'client/server and synchronous settings '
+                                    'are implicit and cannot be overriden.')
             tests = [t.strip() for t in options.test.split(',') if t.strip()]
             self.ctrl_file_data = {'tests': tests}
             if options.kernel:
@@ -347,6 +342,9 @@
         (self.data['hosts'],
          self.data['meta_hosts']) = self.parse_hosts(self.hosts)
 
+        deps = options.labels.split(',')
+        deps = [dep.strip() for dep in deps if dep.strip()]
+        self.data['dependencies'] = deps
 
         self.data['email_list'] = options.email
         self.data['is_synchronous'] = options.synchronous
@@ -378,7 +376,10 @@
             else:
                 self.data['control_type'] = 'Client'
 
-            self.data['dependencies'] = cf_info['dependencies']
+            # Get the union of the 2 sets of dependencies
+            deps = set(self.data['dependencies'])
+            deps.union(cf_info['dependencies'])
+            self.data['dependencies'] = list(deps)
 
         socket.setdefaulttimeout(topic_common.LIST_SOCKET_TIMEOUT)
         # This RPC takes a while when there are lots of hosts.
diff --git a/cli/job_unittest.py b/cli/job_unittest.py
index 00f68df..a5a9447 100755
--- a/cli/job_unittest.py
+++ b/cli/job_unittest.py
@@ -602,17 +602,34 @@
                      out_words_no=['Uploading', 'Done'])
 
 
-    def test_execute_create_job_with_control_and_dependencies(self):
+    def test_execute_create_job_with_control_and_label(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', '-d', 'dep1, dep2 '],
+                           'test_job0', '-m', 'host0', '-b', 'dep1, dep2 '],
                      rpcs=[('create_job', data, True, 42)],
                      out_words_ok=['test_job0', 'Created'],
                      out_words_no=['Uploading', 'Done'])
 
 
+    def test_execute_create_job_with_test_and_label(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 '],
+                     rpcs=[('generate_control_file',
+                            {'tests': ['sleeptest'], 'use_container': False},
+                            True,
+                            {'control_file' : self.ctrl_file,
+                             'is_synchronous' : False,
+                             'is_server' : False,
+                             'dependencies' : ['dep3']}),
+                           ('create_job', data, True, 42)],
+                     out_words_ok=['test_job0', 'Created'],
+                     out_words_no=['Uploading', 'Done'])
+
+
     def test_execute_create_job_with_kernel(self):
         data = self.data.copy()
         data['control_file'] = self.kernel_ctrl_file
@@ -722,16 +739,6 @@
         self.god.unmock_io()
 
 
-    def test_execute_create_job_test_and_dep(self):
-        testjob = job.job_create()
-        sys.argv = ['atest', 'job', 'create', '-t', 'test1, test2 ',
-                    'test_job0', '-m', 'host0', '--dependencies', 'dep1,dep2']
-        self.god.mock_io()
-        sys.exit.expect_call(1).and_raises(cli_mock.ExitException)
-        self.assertRaises(cli_mock.ExitException, testjob.parse)
-        self.god.unmock_io()
-
-
     def test_execute_create_job_bad_priority(self):
         testjob = job.job_create()
         sys.argv = ['atest', 'job', 'create', '-t', 'sleeptest', '-p', 'Uber',