Home | History | Annotate | Download | only in platform_HWwatchdog
      1 # Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
      2 # Use of this source code is governed by a BSD-style license that can be
      3 # found in the LICENSE file.
      4 
      5 # This test isn't really HW specific. It's testing /dev/watchdog API
      6 # to make sure it works as expected. The most robust implementations is
      7 # based on real HW but it doesn't have to be.
      8 
      9 import logging, re
     10 
     11 # http://docs.python.org/2/library/errno.html
     12 import errno
     13 
     14 from autotest_lib.client.common_lib import error
     15 from autotest_lib.server import test
     16 
     17 
     18 class platform_HWwatchdog(test.test):
     19     """Test to make sure that /dev/watchdog will reboot the system."""
     20 
     21     version = 1
     22 
     23     def _stop_watchdog(self, wd_dev):
     24         # HW watchdog is open and closed "properly".
     25         try:
     26             self.client.run('echo "V" > %s' % wd_dev);
     27         except error.AutoservRunError, e:
     28             raise error.TestError('write to %s failed (%s)' %
     29                                   (wd_dev, errno.errorcode[e.errno]))
     30 
     31     def _trig_watchdog(self, wd_dev):
     32         # Test the machine will reboot if HW watchdog is open but NOT pet.
     33         try:
     34             self.client.run('echo "z" > %s' % wd_dev);
     35         except error.AutoservRunError, e:
     36             raise error.TestError('write to %s failed (%s)' %
     37                                   (wd_dev, errno.errorcode[e.errno]))
     38 
     39         logging.info("KernelHWpath: tickled watchdog on %s (%ds to reboot)",
     40                      self.client.hostname, self._hw_interval)
     41 
     42         # machine should became unpingable after lockup
     43         # ...give 5 seconds slack...
     44         wait_down = self._hw_interval + 5
     45         if not self.client.wait_down(timeout=wait_down):
     46             raise error.TestError('machine should be unpingable '
     47                                   'within %d seconds' % wait_down)
     48 
     49         # make sure the machine comes back,
     50         # DHCP can take up to 45 seconds in odd cases.
     51         if not self.client.wait_up(timeout=60):
     52             raise error.TestError('machine did not reboot/ping within '
     53                                   '60 seconds of HW reset')
     54 
     55     def _exists_on_client(self, wd_dev):
     56         return self.client.run('test -c "%s"' % wd_dev,
     57                                ignore_status=True).exit_status == 0
     58 
     59     # If daisydog is running, stop it so we can use /dev/watchdog
     60     def _stop_daemon(self):
     61         """If running, stop daisydog so we can use /dev/watchdog."""
     62         self.client.run('stop daisydog', ignore_status=True)
     63 
     64     def _start_daemon(self):
     65         self.client.run('start daisydog', ignore_status=True)
     66 
     67     def _query_hw_interval(self):
     68         """Check how long the hardware interval is."""
     69         output = self.client.run('daisydog -c').stdout
     70         secs = re.findall(r'HW watchdog interval is (\d*) seconds', output)[0]
     71         return int(secs)
     72 
     73     def run_once(self, host=None):
     74         self.client = host
     75         wd_dev = '/dev/watchdog'
     76 
     77         # If watchdog not present, just skip this test
     78         if not self._exists_on_client(wd_dev):
     79             logging.info("INFO: %s not present. Skipping test.", wd_dev)
     80             return
     81 
     82         self._stop_daemon()
     83         self._hw_interval = self._query_hw_interval()
     84         self._stop_watchdog(wd_dev)
     85         self._trig_watchdog(wd_dev)
     86         self._start_daemon()
     87