firmware_Cr50RddG3: check Rdd connect in G3 am: 17e77f1496 am: a98d660783 am: 7bc8acbd6e am: becbd3470a

Change-Id: Ic301a642279e7b332a9e23a21d09f9672ab322ee
diff --git a/server/site_tests/firmware_Cr50RddG3/control b/server/site_tests/firmware_Cr50RddG3/control
index 0c4bb6d..0b266fc 100644
--- a/server/site_tests/firmware_Cr50RddG3/control
+++ b/server/site_tests/firmware_Cr50RddG3/control
@@ -12,11 +12,11 @@
 TEST_TYPE = "server"
 DEPENDENCIES = "servo"
 
-DOC = """Verify Rdd in G3.
+DOC = """Verify Rdd connect and disconnect in G3.
 
-Some boards always detect Rdd is connected when the EC is in hibernate. Add a
-test to detect this, so we know the behavior of current boards and we can
-prevent new boards from being released with this issue.
+Rdd may break when entering G3. This test verifies the behavior of the DUT.
+Add the information to the faft config so other tests can act appropriately or
+fix the hardware, so Rdd isn't broken.
 """
 
 if 'args_dict' not in locals():
diff --git a/server/site_tests/firmware_Cr50RddG3/firmware_Cr50RddG3.py b/server/site_tests/firmware_Cr50RddG3/firmware_Cr50RddG3.py
index fcf1022..6e778fd 100644
--- a/server/site_tests/firmware_Cr50RddG3/firmware_Cr50RddG3.py
+++ b/server/site_tests/firmware_Cr50RddG3/firmware_Cr50RddG3.py
@@ -2,6 +2,7 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
+import logging
 import time
 
 from autotest_lib.client.common_lib import error
@@ -9,42 +10,90 @@
 
 
 class firmware_Cr50RddG3(Cr50Test):
-    """Verify Rdd in G3."""
+    """Verify Rdd connect and disconnect in G3."""
     version = 1
 
     WAIT_FOR_STATE = 10
+    # Cr50 debounces disconnects. We need to wait before checking Rdd state
+    RDD_DEBOUNCE = 3
 
     def rdd_is_connected(self):
         """Return True if Cr50 detects Rdd."""
         time.sleep(2)
         return self.cr50.get_ccdstate()['Rdd'] == 'connected'
 
+
+    def check_rdd_status(self, dts_mode, err_desc, capability=''):
+        """Check the rdd state.
+
+        @param dts_mode: 'on' if Rdd should be connected. 'off' if it should be
+                         disconnected.
+        @param err_desc: Description of the rdd error.
+        @param capability: ignore err_desc if this capability string is found in
+                           the faft board config.
+        @param raises TestFail if rdd state doesn't match the expected rdd state
+                      or if it does and the board has the capability set.
+        """
+        time.sleep(self.RDD_DEBOUNCE)
+        err_msg = None
+        rdd_enabled = self.rdd_is_connected()
+        logging.info('dts: %r rdd: %r', dts_mode,
+                     'connected' if rdd_enabled else 'disconnected')
+        has_cap = capability and self.check_cr50_capability([capability])
+        if rdd_enabled != (dts_mode == 'on'):
+            if has_cap:
+                logging.info('Found %r. %r still applies to board.', capability,
+                             err_desc)
+            else:
+                err_msg = err_desc
+        elif has_cap:
+            err_msg = 'Found %r, but %r did not occur.' % (capability, err_desc)
+        if err_msg:
+            logging.warning(err_msg)
+            self.rdd_failures.append(err_msg)
+
+
     def run_once(self):
         """Verify Rdd in G3."""
+        self.rdd_failures = []
         if not hasattr(self, 'ec'):
             raise error.TestNAError('Board does not have an EC.')
-        if self.check_cr50_capability(['rdd_leakage']):
-            raise error.TestNAError('Leakage on the rdd signals breaks '
-                                    'detection in G3')
 
         self.servo.set_dts_mode('on')
-        if not self.rdd_is_connected():
-            raise error.TestNAError('Cr50 does not detect Rdd with dts mode on')
+        self.check_rdd_status('on', 'Cr50 did not detect Rdd with dts mode on')
 
         self.servo.set_dts_mode('off')
+        self.check_rdd_status('off', 'Cr50 did not detect Rdd disconnect in S0')
 
-        if self.rdd_is_connected():
-            raise error.TestFail('Cr50 detects Rdd with dts mode off')
-
+        logging.info('Checking Rdd is disconnected with the EC in hibernate')
         self.faft_client.system.run_shell_command('poweroff')
         time.sleep(self.WAIT_FOR_STATE)
         self.ec.send_command('hibernate')
-
         time.sleep(self.WAIT_FOR_STATE)
-        rdd_connected = self.rdd_is_connected()
 
+        self.check_rdd_status('off', 'Rdd connected after EC hibernate',
+                              'rdd_leakage')
+
+        logging.info('Checking Rdd can be connected in G3.')
         self.servo.set_dts_mode('on')
-        self._try_to_bring_dut_up()
+        self.check_rdd_status('on', 'Cr50 did not detect Rdd connect in G3')
 
-        if rdd_connected:
-            raise error.TestFail('Rdd is broken in G3')
+        # Turn the DUT on, then reenter G3 to make sure the system handles Rdd
+        # while entering G3 ok.
+        self._try_to_bring_dut_up()
+        self.check_rdd_status('on', 'Rdd disconnected entering S0')
+
+        logging.info('Checking Rdd is connected with the EC in hibernate.')
+        self.faft_client.system.run_shell_command('poweroff')
+        time.sleep(self.WAIT_FOR_STATE)
+        self.ec.send_command('hibernate')
+        time.sleep(self.WAIT_FOR_STATE)
+
+        self.check_rdd_status('on', 'Rdd disconnected after EC hibernate')
+
+        logging.info('Checking Rdd can be disconnected in G3.')
+        self.servo.set_dts_mode('off')
+        self.check_rdd_status('off', 'Cr50 did not detect Rdd disconnect in G3')
+        self._try_to_bring_dut_up()
+        if self.rdd_failures:
+            raise error.TestFail('Found Rdd issues: %s' % (self.rdd_failures))