autotest: Detect servo_updater issue as servo_state

Cherry picked from labpack change https://crrev.com/c/2869408

BUG=b:181960566
TEST=run local repair

Change-Id: Ib3a5d23778820ea1748b44a28c8cbaf8ce00a5c8
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/autotest/+/2879513
Tested-by: Otabek Kasimov <otabek@google.com>
Auto-Submit: Otabek Kasimov <otabek@google.com>
Commit-Queue: Otabek Kasimov <otabek@google.com>
Reviewed-by: Garry Wang <xianuowang@chromium.org>
diff --git a/server/hosts/servo_constants.py b/server/hosts/servo_constants.py
index 09e3436..9cfe90c 100644
--- a/server/hosts/servo_constants.py
+++ b/server/hosts/servo_constants.py
@@ -55,6 +55,7 @@
 SERVO_STATE_SERVO_HOST_ISSUE = 'SERVO_HOST_ISSUE'
 SERVO_STATE_NOT_CONNECTED = 'NOT_CONNECTED'
 SERVO_STATE_SERIAL_MISMATCH = 'SERVO_SERIAL_MISMATCH'
+SERVO_STATE_SERVO_UPDATER_ISSUE = 'SERVO_UPDATER_ISSUE'
 SERVO_STATE_NEED_REPLACEMENT = 'NEED_REPLACEMENT'
 SERVO_STATE_CR50_CONSOLE_MISSING = 'CR50_CONSOLE_MISSING'
 SERVO_STATE_CCD_TESTLAB_ISSUE = 'CCD_TESTLAB_ISSUE'
diff --git a/server/hosts/servo_host.py b/server/hosts/servo_host.py
index 363783f..193afba 100644
--- a/server/hosts/servo_host.py
+++ b/server/hosts/servo_host.py
@@ -1292,6 +1292,7 @@
                 'servo_root_present')
         servo_v3_present = self.get_verifier_state('servo_v3_root_present')
         servo_fw = self.get_verifier_state('servo_fw')
+        servo_fw_update = self.get_repair_strategy_node('servo_fw_update')
         disk_space = self.get_verifier_state('servo_disk_space')
         start_servod = self.get_verifier_state('start_servod')
         servod_started = self.get_verifier_state('servod_started')
@@ -1323,6 +1324,9 @@
             # if we cannot find required board on servo_v3
             return servo_constants.SERVO_STATE_NEED_REPLACEMENT
         if servo_fw == hosts.VERIFY_FAILED:
+            logging.info(servo_fw_update)
+            if hasattr(servo_fw_update, 'servo_updater_issue_detected'):
+                return servo_constants.SERVO_STATE_SERVO_UPDATER_ISSUE
             return servo_constants.SERVO_STATE_NEED_REPLACEMENT
 
         if dut_connected == hosts.VERIFY_FAILED:
diff --git a/server/hosts/servo_repair.py b/server/hosts/servo_repair.py
index 4245c86..af7e404 100644
--- a/server/hosts/servo_repair.py
+++ b/server/hosts/servo_repair.py
@@ -1271,10 +1271,15 @@
 
     @timeout_util.TimeoutDecorator(cros_constants.REPAIR_TIMEOUT_SEC)
     def repair(self, host):
-        servo_updater.update_servo_firmware(host,
-                                            try_attempt_count=3,
-                                            force_update=False,
-                                            try_force_update=True)
+        try:
+            servo_updater.update_servo_firmware(host,
+                                                try_attempt_count=3,
+                                                force_update=False,
+                                                try_force_update=True)
+        except servo_updater.ServoUpdaterError as er:
+            # Catch servo_updater issue to cache it.
+            self.servo_updater_issue_detected = True
+            raise hosts.AutoservVerifyError('ServoUpdater issue detected')
 
     def _is_applicable(self, host):
         # Run only for servo_v4 and servo_v4p1.
diff --git a/site_utils/admin_audit/servo_updater.py b/site_utils/admin_audit/servo_updater.py
index be56a12..88a5973 100644
--- a/site_utils/admin_audit/servo_updater.py
+++ b/site_utils/admin_audit/servo_updater.py
@@ -20,6 +20,10 @@
     """Raised when Available version is not detected."""
 
 
+class ServoUpdaterError(Exception):
+    """Raised when detected issue with servo_updater."""
+
+
 class _BaseUpdateServoFw(object):
     """Base class to update firmware on servo"""
 
@@ -279,6 +283,9 @@
         topology_constants.ST_SWEETBERRY_TYPE: UpdateSweetberryFw,
 }
 
+# List known, tracking issue related to servo_updater.
+SERVO_UPDATER_ISSUE_MSGS = ('Configuration not set', )
+
 
 def _run_update_attempt(updater, topology, try_count, force_update,
                         ignore_version, channel):
@@ -308,8 +315,13 @@
             if not updater.need_update(ignore_version=ignore_version,
                                        channel=channel):
                 success = True
-        except Exception as e:
-            logging.debug('(Not critical) fail to update %s; %s', board, e)
+        except Exception as er:
+            error_message = str(er)
+            logging.debug('(Not critical) fail to update %s; %s', board,
+                          error_message)
+            for message in SERVO_UPDATER_ISSUE_MSGS:
+                if message in error_message:
+                    raise ServoUpdaterError()
         if success:
             break
     return success