[autotest] pull _autoserv_command_line functionality into utility module

This CL pulls the logic used by monitor_db.py to create an autoserv
command line from a job into its own function, in a separate new module
-- autoserv_utils.py. This will allow for code reuse with test_that.

monitor_db still contains a number of other functions which create
autoserv command lines for other tasks like log collection. These have
not yet been pulled out to shared utility functions, because those parts
of the scheduler didn't seem to have any unit test coverage. A future CL
may pull some of these out as well.

BUG=chromium:236471
TEST=unit tests pass. Ran a smoke suite in local autotest.
DEPLOY=scheduler

Change-Id: I6317b70aa9fb7e9968739582b9379112baa4507b
Reviewed-on: https://gerrit.chromium.org/gerrit/56136
Reviewed-by: Aviv Keshet <akeshet@chromium.org>
Tested-by: Aviv Keshet <akeshet@chromium.org>
Commit-Queue: Aviv Keshet <akeshet@chromium.org>
diff --git a/server/autoserv_utils.py b/server/autoserv_utils.py
new file mode 100644
index 0000000..7d30dc3
--- /dev/null
+++ b/server/autoserv_utils.py
@@ -0,0 +1,75 @@
+#!/usr/bin/python
+# Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import os
+
+import common
+from autotest_lib.client.common_lib import control_data
+
+
+def autoserv_run_job_command(autoserv_directory, machines,
+                             results_directory=None, extra_args=[], job=None,
+                             queue_entry=None, verbose=True,
+                             write_pidfile=True):
+    """
+    Construct an autoserv command from a job or host queue entry.
+
+    @param autoserv_directory: Absolute path to directory containing the
+                               autoserv executable.
+    @param machines: A machine or comma separated list of machines to run
+                     job on. Leave as None or empty string for hostless job
+                     (String).
+    @param results_directory: Absolute path to directory in which to deposit
+                             results.
+    @param extra_args: Additional arguments to pass to autoserv
+                       (List of Strings).
+    @param job: Job object. If supplied, -u owner, -l name, and --test-retry,
+                and -c or -s (client or server) parameters will be added.
+    @param queue_entry: HostQueueEntry object. If supplied and no job
+                        was supplied, this will be used to lookup the job.
+    @param verbose: Boolean (default: True) for autoserv verbosity.
+    @param write_pidfile: Boolean (default: True) for whether autoserv should
+                          write a pidfile.
+    @returns The autoserv command line as a list of executable + parameters.
+    """
+    command = [os.path.join(autoserv_directory, 'autoserv')]
+
+    if write_pidfile:
+        command.append('-p')
+
+    if results_directory:
+        command += ['-r', results_directory]
+
+    if machines:
+        command += ['-m', machines]
+
+    if job or queue_entry:
+        if not job:
+            job = queue_entry.job
+
+        owner = getattr(job, 'owner', None)
+        name = getattr(job, 'name', None)
+        test_retry = getattr(job, 'test_retry', None)
+        control_type = getattr(job, 'control_type', None)
+
+
+        if owner:
+            command += ['-u', owner]
+        if name:
+            command += ['-l', name]
+        if test_retry:
+            command += ['--test-retry='+str(test_retry)]
+        if control_type is not None: # still want to enter if control_type==0
+            control_type_value = control_data.CONTROL_TYPE.get_value(
+                    control_type)
+            if control_type_value == control_data.CONTROL_TYPE.CLIENT:
+                command.append('-c')
+            elif control_type_value == control_data.CONTROL_TYPE.SERVER:
+                command.append('-s')
+
+    if verbose:
+        command.append('--verbose')
+
+    return command + extra_args