12f48d9572459c2c90d68e8b017b86eb843fe2a74Christopher Wiley#!/usr/bin/python 22f48d9572459c2c90d68e8b017b86eb843fe2a74Christopher Wiley 3c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu# 4c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu# Copyright (C) 2011 The Android Open Source Project 5c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu# 6c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu# Licensed under the Apache License, Version 2.0 (the "License"); 7c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu# you may not use this file except in compliance with the License. 8c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu# You may obtain a copy of the License at 9c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu# 10c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu# http://www.apache.org/licenses/LICENSE-2.0 11c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu# 12c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu# Unless required by applicable law or agreed to in writing, software 13c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu# distributed under the License is distributed on an "AS IS" BASIS, 14c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu# See the License for the specific language governing permissions and 16c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu# limitations under the License. 17c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu# 182f48d9572459c2c90d68e8b017b86eb843fe2a74Christopher Wiley 192f48d9572459c2c90d68e8b017b86eb843fe2a74Christopher Wiley 202f48d9572459c2c90d68e8b017b86eb843fe2a74Christopher Wileyimport logging 212f48d9572459c2c90d68e8b017b86eb843fe2a74Christopher Wileyimport logging.handlers 222f48d9572459c2c90d68e8b017b86eb843fe2a74Christopher Wileyimport optparse 232f48d9572459c2c90d68e8b017b86eb843fe2a74Christopher Wileyimport sys 242f48d9572459c2c90d68e8b017b86eb843fe2a74Christopher Wileyimport syslog 252f48d9572459c2c90d68e8b017b86eb843fe2a74Christopher Wileyimport time 262f48d9572459c2c90d68e8b017b86eb843fe2a74Christopher Wiley 272f48d9572459c2c90d68e8b017b86eb843fe2a74Christopher Wileyimport dbus 282f48d9572459c2c90d68e8b017b86eb843fe2a74Christopher Wileyimport flimflam 292f48d9572459c2c90d68e8b017b86eb843fe2a74Christopher Wiley 302f48d9572459c2c90d68e8b017b86eb843fe2a74Christopher Wileyoptions = None 312f48d9572459c2c90d68e8b017b86eb843fe2a74Christopher Wiley 322f48d9572459c2c90d68e8b017b86eb843fe2a74Christopher Wiley 332f48d9572459c2c90d68e8b017b86eb843fe2a74Christopher Wileydef SetupSyslog(): 342f48d9572459c2c90d68e8b017b86eb843fe2a74Christopher Wiley syslog_handler = logging.handlers.SysLogHandler(address='/dev/log') 352f48d9572459c2c90d68e8b017b86eb843fe2a74Christopher Wiley formatter = logging.Formatter('%(pathname)s: %(message)s') 362f48d9572459c2c90d68e8b017b86eb843fe2a74Christopher Wiley syslog_handler.setFormatter(formatter) 372f48d9572459c2c90d68e8b017b86eb843fe2a74Christopher Wiley syslog_handler.setLevel(syslog.LOG_WARNING) 382f48d9572459c2c90d68e8b017b86eb843fe2a74Christopher Wiley logging.getLogger().addHandler(syslog_handler) 392f48d9572459c2c90d68e8b017b86eb843fe2a74Christopher Wiley logging.getLogger().addHandler(logging.StreamHandler()) 402f48d9572459c2c90d68e8b017b86eb843fe2a74Christopher Wiley 412f48d9572459c2c90d68e8b017b86eb843fe2a74Christopher Wiley 422f48d9572459c2c90d68e8b017b86eb843fe2a74Christopher Wileydef GetService(service_name): 432f48d9572459c2c90d68e8b017b86eb843fe2a74Christopher Wiley flim = flimflam.FlimFlam(dbus.SystemBus()) 442f48d9572459c2c90d68e8b017b86eb843fe2a74Christopher Wiley service = flim.FindElementByNameSubstring('Service', service_name) 452f48d9572459c2c90d68e8b017b86eb843fe2a74Christopher Wiley if not service: 462f48d9572459c2c90d68e8b017b86eb843fe2a74Christopher Wiley logging.error('Could not find service %s' % service_name) 472f48d9572459c2c90d68e8b017b86eb843fe2a74Christopher Wiley sys.exit(1) 482f48d9572459c2c90d68e8b017b86eb843fe2a74Christopher Wiley return (flim, service) 492f48d9572459c2c90d68e8b017b86eb843fe2a74Christopher Wiley 502f48d9572459c2c90d68e8b017b86eb843fe2a74Christopher Wiley 512f48d9572459c2c90d68e8b017b86eb843fe2a74Christopher Wileydef Cycle(service_name, iteration): 522f48d9572459c2c90d68e8b017b86eb843fe2a74Christopher Wiley try: 532f48d9572459c2c90d68e8b017b86eb843fe2a74Christopher Wiley (flim, service) = GetService(service_name) 542f48d9572459c2c90d68e8b017b86eb843fe2a74Christopher Wiley 552f48d9572459c2c90d68e8b017b86eb843fe2a74Christopher Wiley (connect_success, _) = flim.ConnectService(service=service, 562f48d9572459c2c90d68e8b017b86eb843fe2a74Christopher Wiley retry=False, 572f48d9572459c2c90d68e8b017b86eb843fe2a74Christopher Wiley assoc_timeout=30) 582f48d9572459c2c90d68e8b017b86eb843fe2a74Christopher Wiley time.sleep(options.sleep_after_connect) 592f48d9572459c2c90d68e8b017b86eb843fe2a74Christopher Wiley 602f48d9572459c2c90d68e8b017b86eb843fe2a74Christopher Wiley (disconnect_state, _) = flim.DisconnectService(service) 612f48d9572459c2c90d68e8b017b86eb843fe2a74Christopher Wiley time.sleep(options.sleep_after_disconnect) 622f48d9572459c2c90d68e8b017b86eb843fe2a74Christopher Wiley 632f48d9572459c2c90d68e8b017b86eb843fe2a74Christopher Wiley disconnect_success = (disconnect_state == 'idle') 642f48d9572459c2c90d68e8b017b86eb843fe2a74Christopher Wiley to_return = connect_success and disconnect_success 652f48d9572459c2c90d68e8b017b86eb843fe2a74Christopher Wiley 662f48d9572459c2c90d68e8b017b86eb843fe2a74Christopher Wiley if not to_return: 672f48d9572459c2c90d68e8b017b86eb843fe2a74Christopher Wiley logging.error('Failure at iteration %d: Connect:%-6s ' 682f48d9572459c2c90d68e8b017b86eb843fe2a74Christopher Wiley 'Disconnect:%-6s' % 692f48d9572459c2c90d68e8b017b86eb843fe2a74Christopher Wiley (iteration, connect_success, disconnect_success)) 702f48d9572459c2c90d68e8b017b86eb843fe2a74Christopher Wiley return to_return 712f48d9572459c2c90d68e8b017b86eb843fe2a74Christopher Wiley 722f48d9572459c2c90d68e8b017b86eb843fe2a74Christopher Wiley except dbus.exceptions.DBusException, e: 732f48d9572459c2c90d68e8b017b86eb843fe2a74Christopher Wiley logging.error('Unexpected DBus exception: %s' % e) 742f48d9572459c2c90d68e8b017b86eb843fe2a74Christopher Wiley return False 752f48d9572459c2c90d68e8b017b86eb843fe2a74Christopher Wiley 762f48d9572459c2c90d68e8b017b86eb843fe2a74Christopher Wiley 772f48d9572459c2c90d68e8b017b86eb843fe2a74Christopher Wileydef main(): 782f48d9572459c2c90d68e8b017b86eb843fe2a74Christopher Wiley SetupSyslog() 792f48d9572459c2c90d68e8b017b86eb843fe2a74Christopher Wiley 802f48d9572459c2c90d68e8b017b86eb843fe2a74Christopher Wiley parser = optparse.OptionParser(usage='usage: %prog [options] service-name') 812f48d9572459c2c90d68e8b017b86eb843fe2a74Christopher Wiley parser.set_defaults(keep_going=False) 822f48d9572459c2c90d68e8b017b86eb843fe2a74Christopher Wiley 832f48d9572459c2c90d68e8b017b86eb843fe2a74Christopher Wiley parser.add_option('--continue', action='store_true', dest='keep_going', 842f48d9572459c2c90d68e8b017b86eb843fe2a74Christopher Wiley help='continue after an error') 852f48d9572459c2c90d68e8b017b86eb843fe2a74Christopher Wiley 862f48d9572459c2c90d68e8b017b86eb843fe2a74Christopher Wiley parser.add_option('--sleep_after_connect', default=0.5, type='float', 872f48d9572459c2c90d68e8b017b86eb843fe2a74Christopher Wiley help='Time (in seconds) to sleep after connect') 882f48d9572459c2c90d68e8b017b86eb843fe2a74Christopher Wiley 892f48d9572459c2c90d68e8b017b86eb843fe2a74Christopher Wiley parser.add_option('--sleep_after_disconnect', default=0, type='float', 902f48d9572459c2c90d68e8b017b86eb843fe2a74Christopher Wiley help='Time (in seconds) to sleep after connect') 912f48d9572459c2c90d68e8b017b86eb843fe2a74Christopher Wiley 922f48d9572459c2c90d68e8b017b86eb843fe2a74Christopher Wiley parser.add_option('--limit', default=0, type='int', 932f48d9572459c2c90d68e8b017b86eb843fe2a74Christopher Wiley help='Number of iterations to run (0 for infinite)') 942f48d9572459c2c90d68e8b017b86eb843fe2a74Christopher Wiley 952f48d9572459c2c90d68e8b017b86eb843fe2a74Christopher Wiley 962f48d9572459c2c90d68e8b017b86eb843fe2a74Christopher Wiley global options 972f48d9572459c2c90d68e8b017b86eb843fe2a74Christopher Wiley (options, remaining) = parser.parse_args() 982f48d9572459c2c90d68e8b017b86eb843fe2a74Christopher Wiley 992f48d9572459c2c90d68e8b017b86eb843fe2a74Christopher Wiley if len(remaining) < 1: 1002f48d9572459c2c90d68e8b017b86eb843fe2a74Christopher Wiley parser.error('Must supply a service name') 1012f48d9572459c2c90d68e8b017b86eb843fe2a74Christopher Wiley 1022f48d9572459c2c90d68e8b017b86eb843fe2a74Christopher Wiley (service_name, ) = remaining 1032f48d9572459c2c90d68e8b017b86eb843fe2a74Christopher Wiley 1042f48d9572459c2c90d68e8b017b86eb843fe2a74Christopher Wiley (flim, service) = GetService(service_name) 1052f48d9572459c2c90d68e8b017b86eb843fe2a74Christopher Wiley flim.DisconnectService(service) 1062f48d9572459c2c90d68e8b017b86eb843fe2a74Christopher Wiley 1072f48d9572459c2c90d68e8b017b86eb843fe2a74Christopher Wiley total = 0 1082f48d9572459c2c90d68e8b017b86eb843fe2a74Christopher Wiley success = 0 1092f48d9572459c2c90d68e8b017b86eb843fe2a74Christopher Wiley while options.limit == 0 or total < options.limit: 1102f48d9572459c2c90d68e8b017b86eb843fe2a74Christopher Wiley rc = Cycle(service_name, total) 1112f48d9572459c2c90d68e8b017b86eb843fe2a74Christopher Wiley total += 1 1122f48d9572459c2c90d68e8b017b86eb843fe2a74Christopher Wiley if rc: 1132f48d9572459c2c90d68e8b017b86eb843fe2a74Christopher Wiley success += 1 1142f48d9572459c2c90d68e8b017b86eb843fe2a74Christopher Wiley 1152f48d9572459c2c90d68e8b017b86eb843fe2a74Christopher Wiley message = ( 1162f48d9572459c2c90d68e8b017b86eb843fe2a74Christopher Wiley 'Fail rate %1.3f Pass %-5d Fail %-5d Total %-5d' % 1172f48d9572459c2c90d68e8b017b86eb843fe2a74Christopher Wiley (float(total - success) / total, success, total - success, total)) 1182f48d9572459c2c90d68e8b017b86eb843fe2a74Christopher Wiley 1192f48d9572459c2c90d68e8b017b86eb843fe2a74Christopher Wiley if (total % 10) == 0: 1202f48d9572459c2c90d68e8b017b86eb843fe2a74Christopher Wiley # Not really a warning, but we want to get this into syslog 1212f48d9572459c2c90d68e8b017b86eb843fe2a74Christopher Wiley logging.warning(message) 1222f48d9572459c2c90d68e8b017b86eb843fe2a74Christopher Wiley else: 1232f48d9572459c2c90d68e8b017b86eb843fe2a74Christopher Wiley print message 1242f48d9572459c2c90d68e8b017b86eb843fe2a74Christopher Wiley 1252f48d9572459c2c90d68e8b017b86eb843fe2a74Christopher Wiley if not rc: 1262f48d9572459c2c90d68e8b017b86eb843fe2a74Christopher Wiley if options.keep_going: 1272f48d9572459c2c90d68e8b017b86eb843fe2a74Christopher Wiley # Don't want to run in a tight loop for a persistent failure 1282f48d9572459c2c90d68e8b017b86eb843fe2a74Christopher Wiley sleep_time = 10 1292f48d9572459c2c90d68e8b017b86eb843fe2a74Christopher Wiley logging.warning('Sleeping %d seconds' % sleep_time) 1302f48d9572459c2c90d68e8b017b86eb843fe2a74Christopher Wiley time.sleep(sleep_time) 1312f48d9572459c2c90d68e8b017b86eb843fe2a74Christopher Wiley else: 1322f48d9572459c2c90d68e8b017b86eb843fe2a74Christopher Wiley logging.error('Exiting on failure') 1332f48d9572459c2c90d68e8b017b86eb843fe2a74Christopher Wiley sys.exit(1) 1342f48d9572459c2c90d68e8b017b86eb843fe2a74Christopher Wiley print 'connect-disconnect: Success' 1352f48d9572459c2c90d68e8b017b86eb843fe2a74Christopher Wiley 1362f48d9572459c2c90d68e8b017b86eb843fe2a74Christopher Wiley 1372f48d9572459c2c90d68e8b017b86eb843fe2a74Christopher Wileyif __name__ == '__main__': 1382f48d9572459c2c90d68e8b017b86eb843fe2a74Christopher Wiley try: 1392f48d9572459c2c90d68e8b017b86eb843fe2a74Christopher Wiley main() 1402f48d9572459c2c90d68e8b017b86eb843fe2a74Christopher Wiley except KeyboardInterrupt: 1412f48d9572459c2c90d68e8b017b86eb843fe2a74Christopher Wiley sys.exit(1) 142