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 9import logging, re 10 11# http://docs.python.org/2/library/errno.html 12import errno 13 14from autotest_lib.client.common_lib import error 15from autotest_lib.server import test 16 17 18class 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