servo: log and skip any sort of uart capture failures

We have some DUTs deployed on v3 that have cr50 or usbpd overlays. These
duts will cause capture issues as they do have the control, but the
control is fake. This change fixes this issue by ignoring and logging
all uart capture issues in autotest.
In general, throwing an error here is not very helpful, as this is just
collecting more diagnostics.

This also fixes a second bug. If 'not_applicable' is the response to
turning on capture, then the capture failed, unlike the current code
indicates.

BUG=chromium:1000456, chromium:996328
TEST=None

Change-Id: Ie6289b32af9bb27116a71ba513c6dc6c42ca5e5a
Signed-off-by: Ruben Rodriguez Buchillon <coconutruben@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/autotest/+/1783502
Legacy-Commit-Queue: Commit Bot <commit-bot@chromium.org>
Reviewed-by: Garry Wang <xianuowang@chromium.org>
diff --git a/server/cros/servo/servo.py b/server/cros/servo/servo.py
index ee5c807..8098263 100644
--- a/server/cros/servo/servo.py
+++ b/server/cros/servo/servo.py
@@ -157,25 +157,33 @@
         @param uart:  The UART name to start/stop capturing.
         @param start:  True to start capturing, otherwise stop.
 
-        @returns True if the operation completes successfully. False if the UART
-                 capturing is not supported or failed due to an error.
+        @returns True if the operation completes successfully.
+                 False if the UART capturing is not supported or failed due to
+                 an error.
         """
         logging.debug('%s capturing %s UART.', 'Start' if start else 'Stop',
                       uart)
         uart_cmd = '%s_uart_capture' % uart
+        target_level = 'on' if start else 'off'
+        level = None
         if self._servo.has_control(uart_cmd):
             # Do our own implementation of set() here as not_applicable
             # should also count as a valid control.
-            level = 'on' if start else 'off'
-            logging.debug('Trying to set %s to %s.', uart_cmd, level)
-            self._servo.set_nocheck(uart_cmd, level)
-            result = self._servo.get(uart_cmd)
-            if result in [level, 'not_applicable']:
-              logging.debug('Managed to set %s to %s.', uart_cmd, result)
-              return True
-            logging.debug('Failed to set %s to %s. Got %s.', uart_cmd, level,
-                          result)
-        return False
+            logging.debug('Trying to set %s to %s.', uart_cmd, target_level)
+            try:
+                self._servo.set_nocheck(uart_cmd, target_level)
+                level = self._servo.get(uart_cmd)
+            except error.TestFail as e:
+                # Any sort of test failure here should not stop the test. This
+                # is just to capture more output. Log and move on.
+                logging.warning('Failed to set %s to %s. %s. Ignoring.',
+                                uart_cmd, target_level, str(e))
+            if level == target_level:
+              logging.debug('Managed to set %s to %s.', uart_cmd, level)
+            else:
+              logging.debug('Failed to set %s to %s. Got %s.', uart_cmd,
+                            target_level, level)
+        return level == target_level
 
     def start_capture(self):
         """Start capturing UART streams."""