1 #!/usr/bin/python 2 3 # 4 # Copyright (C) 2011 The Android Open Source Project 5 # 6 # Licensed under the Apache License, Version 2.0 (the "License"); 7 # you may not use this file except in compliance with the License. 8 # You may obtain a copy of the License at 9 # 10 # http://www.apache.org/licenses/LICENSE-2.0 11 # 12 # Unless required by applicable law or agreed to in writing, software 13 # distributed under the License is distributed on an "AS IS" BASIS, 14 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 # See the License for the specific language governing permissions and 16 # limitations under the License. 17 # 18 19 20 import logging 21 import logging.handlers 22 import optparse 23 import sys 24 import syslog 25 import time 26 27 import dbus 28 import flimflam 29 30 options = None 31 32 33 def SetupSyslog(): 34 syslog_handler = logging.handlers.SysLogHandler(address='/dev/log') 35 formatter = logging.Formatter('%(pathname)s: %(message)s') 36 syslog_handler.setFormatter(formatter) 37 syslog_handler.setLevel(syslog.LOG_WARNING) 38 logging.getLogger().addHandler(syslog_handler) 39 logging.getLogger().addHandler(logging.StreamHandler()) 40 41 42 def GetService(service_name): 43 flim = flimflam.FlimFlam(dbus.SystemBus()) 44 service = flim.FindElementByNameSubstring('Service', service_name) 45 if not service: 46 logging.error('Could not find service %s' % service_name) 47 sys.exit(1) 48 return (flim, service) 49 50 51 def Cycle(service_name, iteration): 52 try: 53 (flim, service) = GetService(service_name) 54 55 (connect_success, _) = flim.ConnectService(service=service, 56 retry=False, 57 assoc_timeout=30) 58 time.sleep(options.sleep_after_connect) 59 60 (disconnect_state, _) = flim.DisconnectService(service) 61 time.sleep(options.sleep_after_disconnect) 62 63 disconnect_success = (disconnect_state == 'idle') 64 to_return = connect_success and disconnect_success 65 66 if not to_return: 67 logging.error('Failure at iteration %d: Connect:%-6s ' 68 'Disconnect:%-6s' % 69 (iteration, connect_success, disconnect_success)) 70 return to_return 71 72 except dbus.exceptions.DBusException, e: 73 logging.error('Unexpected DBus exception: %s' % e) 74 return False 75 76 77 def main(): 78 SetupSyslog() 79 80 parser = optparse.OptionParser(usage='usage: %prog [options] service-name') 81 parser.set_defaults(keep_going=False) 82 83 parser.add_option('--continue', action='store_true', dest='keep_going', 84 help='continue after an error') 85 86 parser.add_option('--sleep_after_connect', default=0.5, type='float', 87 help='Time (in seconds) to sleep after connect') 88 89 parser.add_option('--sleep_after_disconnect', default=0, type='float', 90 help='Time (in seconds) to sleep after connect') 91 92 parser.add_option('--limit', default=0, type='int', 93 help='Number of iterations to run (0 for infinite)') 94 95 96 global options 97 (options, remaining) = parser.parse_args() 98 99 if len(remaining) < 1: 100 parser.error('Must supply a service name') 101 102 (service_name, ) = remaining 103 104 (flim, service) = GetService(service_name) 105 flim.DisconnectService(service) 106 107 total = 0 108 success = 0 109 while options.limit == 0 or total < options.limit: 110 rc = Cycle(service_name, total) 111 total += 1 112 if rc: 113 success += 1 114 115 message = ( 116 'Fail rate %1.3f Pass %-5d Fail %-5d Total %-5d' % 117 (float(total - success) / total, success, total - success, total)) 118 119 if (total % 10) == 0: 120 # Not really a warning, but we want to get this into syslog 121 logging.warning(message) 122 else: 123 print message 124 125 if not rc: 126 if options.keep_going: 127 # Don't want to run in a tight loop for a persistent failure 128 sleep_time = 10 129 logging.warning('Sleeping %d seconds' % sleep_time) 130 time.sleep(sleep_time) 131 else: 132 logging.error('Exiting on failure') 133 sys.exit(1) 134 print 'connect-disconnect: Success' 135 136 137 if __name__ == '__main__': 138 try: 139 main() 140 except KeyboardInterrupt: 141 sys.exit(1) 142