[autotest] Allow test to skip provision job

This change adds a new actionable label `skip_provision`. If the label
is listed in the DEPENDENCIES of a test, provision job won't run before
the test starts.
This is useful for AU test which doesn't require dut has a particular
build installed before test starts.

BUG=chromium:582353
TEST=in a devserver, modify the test control file for the dummy suite by
inject following line in the control file:
DEPENDENCIES = "skip_provision"
run dummy suite for the build:
./site_utils/run_suite.py -b veyron_jerry -i veyron_jerry-release/R50-7871.0.0 -s dummy
confirm no provision job was started, instead, reset is run.

Change-Id: I1755eb65327bd7db9f66011fbfa8f71a5e5dd8dd
Reviewed-on: https://chromium-review.googlesource.com/328392
Commit-Ready: Dan Shi <dshi@google.com>
Tested-by: Dan Shi <dshi@google.com>
Reviewed-by: Fang Deng <fdeng@chromium.org>
Reviewed-by: Simran Basi <sbasi@chromium.org>
diff --git a/scheduler/rdb_lib.py b/scheduler/rdb_lib.py
index 0eac03c..8f0ee73 100644
--- a/scheduler/rdb_lib.py
+++ b/scheduler/rdb_lib.py
@@ -45,10 +45,10 @@
         job_id = queue_entry.job_id
         job_deps, job_preferred_deps = [], []
         for dep in self._job_deps.get(job_id, []):
-           if not provision.is_for_special_action(self._labels[dep].name):
-               job_deps.append(dep)
-           elif provision.Provision.acts_on(self._labels[dep].name):
-               job_preferred_deps.append(dep)
+            if not provision.is_for_special_action(self._labels[dep].name):
+                job_deps.append(dep)
+            elif provision.Provision.acts_on(self._labels[dep].name):
+                job_preferred_deps.append(dep)
 
         job_acls = self._job_acls.get(job_id, [])
         parent_id = queue_entry.job.parent_job_id
diff --git a/scheduler/scheduler_models.py b/scheduler/scheduler_models.py
index 92c795e..320efd2 100644
--- a/scheduler/scheduler_models.py
+++ b/scheduler/scheduler_models.py
@@ -1332,6 +1332,9 @@
         # host_scheduler.py:is_host_eligable_for_job() where we discard all
         # actionable labels when assigning jobs to hosts.)
         job_labels = {x.name for x in queue_entry.get_labels()}
+        # Skip provision if `skip_provision` is listed in the job labels.
+        if provision.SKIP_PROVISION in job_labels:
+            return False
         _, host_labels = queue_entry.host.platform_and_labels()
         # If there are any labels on the job that are not on the host and they
         # are labels that provisioning knows how to change, then that means
diff --git a/server/cros/provision.py b/server/cros/provision.py
index c12f48f..0215f3f 100644
--- a/server/cros/provision.py
+++ b/server/cros/provision.py
@@ -15,6 +15,9 @@
 FW_RW_VERSION_PREFIX = 'fwrw-version'
 FW_RO_VERSION_PREFIX = 'fwro-version'
 
+# Special label to skip provision and run reset instead.
+SKIP_PROVISION = 'skip_provision'
+
 # Default number of provisions attempts to try if we believe the devserver is
 # flaky.
 FLAKY_DEVSERVER_ATTEMPTS = 2
@@ -119,7 +122,11 @@
         configurations = set()
 
         for label in labels:
-            if cls.acts_on(label):
+            if label == SKIP_PROVISION:
+                # skip_provision is neither actionable or a capability label.
+                # It doesn't need any handling.
+                continue
+            elif cls.acts_on(label):
                 configurations.add(label)
             else:
                 capabilities.add(label)
@@ -223,7 +230,8 @@
     return (Verify.acts_on(label) or
             Provision.acts_on(label) or
             Cleanup.acts_on(label) or
-            Repair.acts_on(label))
+            Repair.acts_on(label) or
+            label == SKIP_PROVISION)
 
 
 def filter_labels(labels):