def main():
    parser = get_parser()
    (options, _) = parser.parse_args()

    level = logging.DEBUG if options.verbose else logging.INFO
    logging.basicConfig(
        format=u'%(asctime)s %(levelname)s %(name)s %(message)s',
        level=level)

    # Lower the warning levels of a number of loggers
    for logger_name in ['paramiko.transport', 'paramiko.transport.sftp',
                        'requests.packages.urllib3.connectionpool',
                        'swiftclient']:
        logging.getLogger(logger_name).setLevel(logging.WARNING)

    database = db.DB(Configuration().DATABASE_URL)

    queue = JobQueue(
        database=database,
        nodepool=NodePool(Configuration().NODEPOOL_IMAGE),
        filesystem=filesystem_services.RealFilesystem(),
        uploader=swift_upload.SwiftUploader(),
        executor=utils.execute_command)
    
    if options.flush:
        queue.flush()
        return

    if options.change_ref:
        change_num, patchset = options.change_ref.split('/')[-2:]
        patch_details = utils.get_patchset_details(change_num, patchset)
        # Verify we got the right patch back
        queue.addJob(patch_details['ref'], patch_details['project'], patch_details['revision'])
        return

    if options.run_job:
        queue.triggerJob(options.run_job)
        return

    if options.recheck:
        for jobnum in options.recheck:
            queue.recheckJob(jobnum)
        return

    queue.startCleanupThreads()

    try:
        while True:
            try:
                queue.postResults()
                queue.processResults()
                queue.triggerJobs()
                Configuration().check_reload()
            except Exception, e:
                logging.exception(e)
                # Ignore exception and try again; keeps the app polling
            time.sleep(Configuration().get_int('POLL'))
    except KeyboardInterrupt:
        logging.info("Terminated by user")
 def test_get_patchset_details(self, mock_json):
     db = mock.Mock()
     ret_json='{"project":"openstack-infra/tripleo-ci",'+\
               '"id":"I15431d8ede45a4fde51d0e6baa9e3cdf50c03920",'+\
               '"number":"68139","patchSets":[{"number":"1",'+\
               '"revision":"b678325a816c60ad3b0141c6cc6890c7c156f649"},'+\
               '{"number":"2",'+\
               '"revision":"430973f7d8499be075569624d0501e549a2208f2"}]}'
     mock_json.return_value = json.loads(ret_json)
     details = utils.get_patchset_details('68139', '2')
     self.assertEqual(details['project'], 'openstack-infra/tripleo-ci')
     self.assertEqual(details['number'], '2')
     self.assertEqual(details['revision'], '430973f7d8499be075569624d0501e549a2208f2')
 def test_get_patchset_details(self, mock_json):
     db = mock.Mock()
     ret_json='{"project":"openstack-infra/tripleo-ci",'+\
               '"id":"I15431d8ede45a4fde51d0e6baa9e3cdf50c03920",'+\
               '"number":"68139","patchSets":[{"number":"1",'+\
               '"revision":"b678325a816c60ad3b0141c6cc6890c7c156f649"},'+\
               '{"number":"2",'+\
               '"revision":"430973f7d8499be075569624d0501e549a2208f2"}]}'
     mock_json.return_value = json.loads(ret_json)
     details = utils.get_patchset_details('68139', '2')
     self.assertEqual(details['project'], 'openstack-infra/tripleo-ci')
     self.assertEqual(details['number'], '2')
     self.assertEqual(details['revision'],
                      '430973f7d8499be075569624d0501e549a2208f2')