[autotest] Check servod process's status in verify_software
We've seen servo verification took very long time when servod is actually not
running. This adds a lot of overhead to the test. The timeout can be as long
as 2 minutes and servo verification is done 3 times in each test.
This CL add a check of actual servod process in servo_host.verify_software.
If servod is not running, servo host object will fail to be verified without
waiting for actual servo call to timeout in servo.initialize_dut, e.g.,
self.set('dut_hub_pwren', 'on')
Also add a timeout around servo.initialize_dut for 30 seconds.
BUG=chromium:404209
TEST=local servo setup and test_that
Change-Id: I46d2d10cd188db57c73b749c688d3d788a6df305
Reviewed-on: https://chromium-review.googlesource.com/213671
Tested-by: Dan Shi <dshi@chromium.org>
Reviewed-by: Richard Barnette <jrbarnette@chromium.org>
Commit-Queue: Richard Barnette <jrbarnette@chromium.org>
diff --git a/server/hosts/servo_host.py b/server/hosts/servo_host.py
index 9b9dbaf..2aa8b5b 100644
--- a/server/hosts/servo_host.py
+++ b/server/hosts/servo_host.py
@@ -79,6 +79,8 @@
REBOOT_DELAY_SECS = 20
# Servod process name.
SERVOD_PROCESS = 'servod'
+ # Timeout for initializing servo signals.
+ INITIALIZE_SERVO_TIMEOUT_SECS = 30
_MAX_POWER_CYCLE_ATTEMPTS = 3
_timer = stats.Timer('servo_host')
@@ -357,6 +359,32 @@
(self.hostname, e))
+ def _check_servod_status(self):
+ """Check if servod process is running.
+
+ If servod is not running, there is no need to verify if servo is
+ working. Check the process before making any servod call can avoid
+ long timeout that eventually fail any servod call.
+ If the servo host is set to localhost, failure of servod status check
+ will be ignored, as servo call may use ssh tunnel.
+
+ @raises ServoHostVerifyFailure if servod process does not exist.
+
+ """
+ try:
+ pid = int(self.run('pgrep servod').stdout.strip())
+ logging.info('servod is running, PID=%d', pid)
+ except (error.AutoservRunError, error.AutoservSSHTimeout) as e:
+ if self._is_localhost:
+ logging.info('Ignoring servod status check failure. servo host '
+ 'is set to localhost, servo call may use ssh '
+ 'tunnel to go through.')
+ else:
+ raise ServoHostVerifyFailure(
+ 'Servod status check failed for %s: %s' %
+ (self.hostname, e))
+
+
@_timer.decorate
def _update_image(self):
"""Update the image on the servo host, if needed.
@@ -475,6 +503,9 @@
logging.info('Verifying if servo config file exists.')
self._check_servo_config()
+ logging.info('Verifying if servod is running.')
+ self._check_servod_status()
+
logging.info('Verifying servo host %s with sanity checks.',
self.hostname)
self._check_servo_host_usb()
@@ -485,7 +516,11 @@
self._check_servod()
else:
self._servo = servo.Servo(servo_host=self)
- self._servo.initialize_dut()
+ timeout, _ = retry.timeout(
+ self._servo.initialize_dut,
+ timeout_sec=self.INITIALIZE_SERVO_TIMEOUT_SECS)
+ if timeout:
+ raise ServoHostVerifyFailure('Servo initialize timed out.')
logging.info('Sanity checks pass on servo host %s', self.hostname)