[autotest] Enable job_retry in suite_scheduler

With this change, one can add "job_retry: True" in suite_scheduler.ini to enable
job retry. file_bugs should also be set to True for job retry to work.

BUG=chromium:534742
TEST=unittest

DEPOLY=suite_scheduler

Change-Id: I0b4fa5d2c797abef23ce668e09bc1a16891ef03e
Reviewed-on: https://chromium-review.googlesource.com/301387
Commit-Ready: Dan Shi <dshi@chromium.org>
Tested-by: Dan Shi <dshi@chromium.org>
Reviewed-by: Fang Deng <fdeng@chromium.org>
Reviewed-by: Mungyung Ryu <mkryu@google.com>
diff --git a/site_utils/suite_scheduler/task.py b/site_utils/suite_scheduler/task.py
index 3fa0980..aaa74b1 100644
--- a/site_utils/suite_scheduler/task.py
+++ b/site_utils/suite_scheduler/task.py
@@ -156,7 +156,7 @@
 
         allowed = set(['suite', 'run_on', 'branch_specs', 'pool', 'num',
                        'boards', 'file_bugs', 'cros_build_spec',
-                       'firmware_rw_build_spec', 'test_source'])
+                       'firmware_rw_build_spec', 'test_source', 'job_retry'])
         # The parameter of union() is the keys under the section in the config
         # The union merges this with the allowed set, so if any optional keys
         # are omitted, then they're filled in. If any extra keys are present,
@@ -177,6 +177,7 @@
         firmware_rw_build_spec = config.getstring(
                 section, 'firmware_rw_build_spec')
         test_source = config.getstring(section, 'test_source')
+        job_retry = config.getboolean(section, 'job_retry')
         for klass in driver.Driver.EVENT_CLASSES:
             if klass.KEYWORD == keyword:
                 priority = klass.PRIORITY
@@ -202,7 +203,7 @@
                              file_bugs=file_bugs if file_bugs else False,
                              cros_build_spec=cros_build_spec,
                              firmware_rw_build_spec=firmware_rw_build_spec,
-                             test_source=test_source)
+                             test_source=test_source, job_retry=job_retry)
 
 
     @staticmethod
@@ -235,7 +236,7 @@
     def __init__(self, name, suite, branch_specs, pool=None, num=None,
                  boards=None, priority=None, timeout=None, file_bugs=False,
                  cros_build_spec=None, firmware_rw_build_spec=None,
-                 test_source=None):
+                 test_source=None, job_retry=False):
         """Constructor
 
         Given an iterable in |branch_specs|, pre-vetted using CheckBranchSpecs,
@@ -301,6 +302,8 @@
         @param test_source: The source of test code when firmware will be
                             updated in the test. The value can be `firmware_rw`
                             or `cros`.
+        @param job_retry: Set to True to enable job-level retry. Default is
+                          False.
         """
         self._name = name
         self._suite = suite
@@ -313,6 +316,7 @@
         self._cros_build_spec = cros_build_spec
         self._firmware_rw_build_spec = firmware_rw_build_spec
         self._test_source = test_source
+        self._job_retry = job_retry
 
         if ((self._firmware_rw_build_spec or cros_build_spec) and
             not self.test_source in [Builds.FIRMWARE_RW, Builds.CROS]):
@@ -674,7 +678,8 @@
                         self._priority, self._timeout, force,
                         file_bugs=self._file_bugs,
                         firmware_rw_build=firmware_rw_build,
-                        test_source_build=test_source_build):
+                        test_source_build=test_source_build,
+                        job_retry=self._job_retry):
                     logging.info('Skipping scheduling %s on %s for %s',
                                  self._suite, builds, board)
             except deduping_scheduler.DedupingSchedulerException as e: