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