faft: check power state in the test, not in servod (revised)

This is a redo of CL:1895163, this time unsetting the regex before
running the command, to ensure the servod caching doesn't break it.
It also now reports a specific error message for cases where the output
did not match.

TEST=Run firmware_ECLidShutdown.
BUG=b:141519692
BUG=chromium:1031604

Change-Id: I11ab9927c363a24b793f6c0841888618a7dfd8c4
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/autotest/+/1955479
Tested-by: Dana Goyette <dgoyette@chromium.org>
Commit-Queue: Dana Goyette <dgoyette@chromium.org>
Reviewed-by: Ruben Rodriguez Buchillon <coconutruben@chromium.org>
diff --git a/server/cros/faft/firmware_test.py b/server/cros/faft/firmware_test.py
index 0978907..2da8cf8 100644
--- a/server/cros/faft/firmware_test.py
+++ b/server/cros/faft/firmware_test.py
@@ -904,12 +904,6 @@
             if uart_file:
                 self.servo.set('%s_uart_capture' % uart, 'off')
 
-    def _get_power_state(self, power_state):
-        """
-        Return the current power state of the AP
-        """
-        return self.ec.send_command_get_output("powerinfo", [power_state])
-
     def wait_power_state(self, power_state, retries):
         """
         Wait for certain power state.
@@ -918,17 +912,27 @@
         @param retries: retries.  This is necessary if AP is powering down
         and transitioning through different states.
         """
-        logging.info('Checking power state "%s" maximum %d times.',
-                     power_state, retries)
-        while retries > 0:
-            logging.info("try count: %d", retries)
-            try:
-                retries = retries - 1
-                ret = self._get_power_state(power_state)
-                return True
-            except error.TestFail:
-                pass
-        return False
+        pattern = r'power state (\w+) = (\w+)'
+
+        def _state_matches():
+            match = self.ec.send_command_get_output("powerinfo", [pattern])
+            if not match:
+                raise error.TestFail(
+                        "powerinfo output did not match pattern: %r" % pattern)
+            (line, state_num, state_name) = match[0]
+            logging.debug("%s", line)
+            return state_name == power_state
+
+        # clear the regexp to ensure send_command_get_output actually sets it
+        self.ec.set_uart_regexp('None')
+
+        # old get() logic waited 3 seconds per try
+        timeout = retries * 3
+        logging.info('Waiting for power state "%s" maximum %d seconds.',
+                     power_state, timeout)
+        return utils.poll_for_condition_ex(
+                condition=_state_matches, timeout=timeout, sleep_interval=1.5,
+                desc='power state "%s"' % power_state)
 
     def suspend(self):
         """Suspends the DUT."""