FAFT: Support sending multiple controls in one connection to servod
Originally, servod accepts one control per connection. For exmaple, a power
button press is composed of two connections, one for press and one for release.
We found that this kind of time-sensitive behaviors failed under a congested
network environment. For example, a 0.1s power button press to power on DUT
actaully took 1s to be done, which shut the DUT down again.
A patch on servod accepts multiple controls per one connection, see:
https://gerrit.chromium.org/gerrit/46309
This CL fixes FAFT to support sending multiple controls to servod.
It falls back to the original one control per connection when it sees
servod is too old.
BUG=chrome-os-partner:18047,chromeos-os-partner:18048
TEST=manual
Using the original servod, only one control per connection supported,
run firmware_FAFTSetup and firmware_ConsecutiveBoot passed.
Using the new servod, multiple controls per connection supported,
run firmware_FAFTSetup and firmware_ConsecutiveBoot passed.
The tests firmware_FAFTSetup and firmware_ConsecutiveBoot cover the following
behaviors this CL changed:
- cold reset,
- warm reset,
- power button press.
Change-Id: Icfa2439cc8128be7e6648d0ab89ccbba70d53006
Reviewed-on: https://gerrit.chromium.org/gerrit/46509
Reviewed-by: Vic Yang <victoryang@chromium.org>
Commit-Queue: Tom Wai-Hong Tam <waihong@chromium.org>
Tested-by: Tom Wai-Hong Tam <waihong@chromium.org>
diff --git a/server/cros/servo/servo.py b/server/cros/servo/servo.py
index 430c82e..a565449 100644
--- a/server/cros/servo/servo.py
+++ b/server/cros/servo/servo.py
@@ -221,9 +221,9 @@
Args:
secs: Time in seconds to simulate the keypress.
"""
- self.set_nocheck('pwr_button', 'press')
- time.sleep(secs)
- self.set_nocheck('pwr_button', 'release')
+ self.set_get_all(['pwr_button:press',
+ 'sleep:%.4f' % secs,
+ 'pwr_button:release'])
# TODO(tbroch) Different systems have different release times on the
# power button that this loop addresses. Longer term we may want to
# make this delay platform specific.
@@ -376,11 +376,11 @@
This has the side effect of shutting off the device. The
device is guaranteed to be off at the end of this call.
"""
+ self.set_get_all(['cold_reset:on',
+ 'sleep:%.4f' % self._DUT_RESET_DELAY,
+ 'cold_reset:off'])
# After the reset, give the EC the time it needs to
# re-initialize.
- self.set('cold_reset', 'on')
- time.sleep(self._DUT_RESET_DELAY)
- self.set('cold_reset', 'off')
time.sleep(self._EC_RESET_DELAY)
@@ -389,9 +389,9 @@
Has the side effect of restarting the device.
"""
- self.set('warm_reset', 'on')
- time.sleep(self._DUT_RESET_DELAY)
- self.set('warm_reset', 'off')
+ self.set_get_all(['warm_reset:on',
+ 'sleep:%.4f' % self._DUT_RESET_DELAY,
+ 'warm_reset:off'])
def _get_xmlrpclib_exception(self, xmlexc):
@@ -452,6 +452,39 @@
raise error.TestFail(err_msg)
+ def set_get_all(self, controls):
+ """Set &| get one or more control values.
+
+ @param controls: list of strings, controls to set &| get.
+
+ @raise: error.TestError in case error occurs setting/getting values.
+ """
+ rv = []
+ try:
+ rv = self._server.set_get_all(controls)
+ except xmlrpclib.Fault as e:
+ # TODO(waihong): Remove the following backward compatibility when
+ # the new versions of hdctools are deployed.
+ if 'not supported' in str(e):
+ logging.warning('The servod is too old that set_get_all '
+ 'not supported. Use set and get instead.')
+ for control in controls:
+ if ':' in control:
+ (name, value) = control.split(':')
+ if name == 'sleep':
+ time.sleep(float(value))
+ else:
+ self.set_nocheck(name, value)
+ rv.append(True)
+ else:
+ rv.append(self.get(name))
+ else:
+ err_msg = "Problem with '%s' :: %s" % \
+ (controls, self._get_xmlrpclib_exception(e))
+ raise error.TestFail(err_msg)
+ return rv
+
+
# TODO(waihong) It may fail if multiple servo's are connected to the same
# host. Should look for a better way, like the USB serial name, to identify
# the USB device.