示例#1
0
def main():
    parser = optparse.OptionParser()
    parser.add_option('--mobile',
                      action='store_true',
                      dest='mobile',
                      default=False,
                      help='run with mobile settings')
    parser.add_option('--testfile',
                      action='store',
                      type='string',
                      dest='testfile',
                      default='../../services/sync/tests/tps/all_tests.json',
                      help='path to the test file to run [default: %default]')
    parser.add_option('--logfile',
                      action='store',
                      type='string',
                      dest='logfile',
                      default='tps.log',
                      help='path to the log file [default: %default]')
    parser.add_option('--resultfile',
                      action='store',
                      type='string',
                      dest='resultfile',
                      default='tps_result.json',
                      help='path to the result file [default: %default]')
    parser.add_option('--binary',
                      action='store',
                      type='string',
                      dest='binary',
                      default=None,
                      help='path to the Firefox binary, specified either as '
                      'a local file or a url; if omitted, the PATH '
                      'will be searched;')
    parser.add_option('--configfile',
                      action='store',
                      type='string',
                      dest='configfile',
                      default=None,
                      help='path to the config file to use default: %default]')
    parser.add_option('--pulsefile',
                      action='store',
                      type='string',
                      dest='pulsefile',
                      default=None,
                      help='path to file containing a pulse message in '
                      'json format that you want to inject into the monitor')
    parser.add_option(
        '--ignore-unused-engines',
        default=False,
        action='store_true',
        dest='ignore_unused_engines',
        help='If defined, do not load unused engines in individual tests.'
        ' Has no effect for pulse monitor.')
    (options, args) = parser.parse_args()

    configfile = options.configfile
    if configfile is None:
        if os.environ.get('VIRTUAL_ENV'):
            configfile = os.path.join(os.path.dirname(__file__), 'config.json')
        if configfile is None or not os.access(configfile, os.F_OK):
            raise Exception(
                'Unable to find config.json in a VIRTUAL_ENV; you must '
                'specify a config file using the --configfile option')

    # load the config file
    f = open(configfile, 'r')
    configcontent = f.read()
    f.close()
    config = json.loads(configcontent)

    rlock = RLock()

    print 'using result file', options.resultfile

    extensionDir = config.get('extensiondir')
    if not extensionDir or extensionDir == '__EXTENSIONDIR__':
        extensionDir = os.path.join(os.getcwd(), '..', '..', 'services',
                                    'sync', 'tps', 'extensions')
    else:
        if sys.platform == 'win32':
            # replace msys-style paths with proper Windows paths
            m = re.match('^\/\w\/', extensionDir)
            if m:
                extensionDir = '%s:/%s' % (m.group(0)[1:2], extensionDir[3:])
                extensionDir = extensionDir.replace('/', '\\')

    TPS = TPSTestRunner(extensionDir,
                        testfile=options.testfile,
                        logfile=options.logfile,
                        binary=options.binary,
                        config=config,
                        rlock=rlock,
                        mobile=options.mobile,
                        resultfile=options.resultfile,
                        ignore_unused_engines=options.ignore_unused_engines)
    TPS.run_tests()
示例#2
0
def main():
    parser = optparse.OptionParser()
    parser.add_option('--binary',
                      action='store',
                      type='string',
                      dest='binary',
                      default=None,
                      help='path to the Firefox binary, specified either as '
                           'a local file or a url; if omitted, the PATH '
                           'will be searched;')
    parser.add_option('--configfile',
                      action='store',
                      type='string',
                      dest='configfile',
                      default=None,
                      help='path to the config file to use default: %default]')
    parser.add_option('--debug',
                      action='store_true',
                      dest='debug',
                      default=False,
                      help='run in debug mode')
    parser.add_option('--ignore-unused-engines',
                       default=False,
                       action='store_true',
                       dest='ignore_unused_engines',
                       help='If defined, do not load unused engines in individual tests.'
                            ' Has no effect for pulse monitor.')
    parser.add_option('--logfile',
                      action='store',
                      type='string',
                      dest='logfile',
                      default='tps.log',
                      help='path to the log file [default: %default]')
    parser.add_option('--mobile',
                      action='store_true',
                      dest='mobile',
                      default=False,
                      help='run with mobile settings')
    parser.add_option('--pulsefile',
                      action='store',
                      type='string',
                      dest='pulsefile',
                      default=None,
                      help='path to file containing a pulse message in '
                           'json format that you want to inject into the monitor')
    parser.add_option('--resultfile',
                      action='store',
                      type='string',
                      dest='resultfile',
                      default='tps_result.json',
                      help='path to the result file [default: %default]')
    parser.add_option('--testfile',
                      action='store',
                      type='string',
                      dest='testfile',
                      default='all_tests.json',
                      help='path to the test file to run [default: %default]')
    (options, args) = parser.parse_args()

    configfile = options.configfile
    if configfile is None:
        virtual_env = os.environ.get('VIRTUAL_ENV')
        if virtual_env:
            configfile = os.path.join(virtual_env, 'config.json')
        if configfile is None or not os.access(configfile, os.F_OK):
            raise Exception('Unable to find config.json in a VIRTUAL_ENV; you must '
                            'specify a config file using the --configfile option')

    # load the config file
    f = open(configfile, 'r')
    configcontent = f.read()
    f.close()
    config = json.loads(configcontent)
    testfile = os.path.join(config.get('testdir', ''), options.testfile)

    rlock = RLock()

    print 'using result file', options.resultfile

    extensionDir = config.get('extensiondir')
    if not extensionDir or extensionDir == '__EXTENSIONDIR__':
        extensionDir = os.path.join(os.getcwd(), '..', '..',
                                    'services', 'sync', 'tps', 'extensions')
    else:
        if sys.platform == 'win32':
            # replace msys-style paths with proper Windows paths
            m = re.match('^\/\w\/', extensionDir)
            if m:
                extensionDir = '%s:/%s' % (m.group(0)[1:2], extensionDir[3:])
                extensionDir = extensionDir.replace('/', '\\')

    TPS = TPSTestRunner(extensionDir,
                        binary=options.binary,
                        config=config,
                        debug=options.debug,
                        ignore_unused_engines=options.ignore_unused_engines,
                        logfile=options.logfile,
                        mobile=options.mobile,
                        resultfile=options.resultfile,
                        rlock=rlock,
                        testfile=testfile,
                      )
    TPS.run_tests()

    if TPS.numfailed > 0 or TPS.numpassed == 0:
        sys.exit(1)
示例#3
0
def main():
    parser = optparse.OptionParser()
    parser.add_option("--email-results",
                      action="store_true",
                      dest="emailresults",
                      default=False,
                      help="email the test results to the recipients defined "
                      "in the config file")
    parser.add_option("--mobile",
                      action="store_true",
                      dest="mobile",
                      default=False,
                      help="run with mobile settings")
    parser.add_option("--autolog",
                      action="store_true",
                      dest="autolog",
                      default=False,
                      help="post results to Autolog")
    parser.add_option("--testfile",
                      action="store",
                      type="string",
                      dest="testfile",
                      default='../../services/sync/tests/tps/test_sync.js',
                      help="path to the test file to run "
                      "[default: %default]")
    parser.add_option("--logfile",
                      action="store",
                      type="string",
                      dest="logfile",
                      default='tps.log',
                      help="path to the log file [default: %default]")
    parser.add_option("--binary",
                      action="store",
                      type="string",
                      dest="binary",
                      default=None,
                      help="path to the Firefox binary, specified either as "
                      "a local file or a url; if omitted, the PATH "
                      "will be searched;")
    parser.add_option("--configfile",
                      action="store",
                      type="string",
                      dest="configfile",
                      default=None,
                      help="path to the config file to use "
                      "[default: %default]")
    parser.add_option("--pulsefile",
                      action="store",
                      type="string",
                      dest="pulsefile",
                      default=None,
                      help="path to file containing a pulse message in "
                      "json format that you want to inject into the monitor")
    parser.add_option(
        "--ignore-unused-engines",
        default=False,
        action="store_true",
        dest="ignore_unused_engines",
        help="If defined, don't load unused engines in individual tests."
        " Has no effect for pulse monitor.")
    (options, args) = parser.parse_args()

    configfile = options.configfile
    if configfile is None:
        if os.environ.get('VIRTUAL_ENV'):
            configfile = os.path.join(os.path.dirname(__file__), 'config.json')
        if configfile is None or not os.access(configfile, os.F_OK):
            raise Exception(
                "Unable to find config.json in a VIRTUAL_ENV; you must "
                "specify a config file using the --configfile option")

    # load the config file
    f = open(configfile, 'r')
    configcontent = f.read()
    f.close()
    config = json.loads(configcontent)

    rlock = RLock()

    extensionDir = config.get("extensiondir")
    if not extensionDir or extensionDir == '__EXTENSIONDIR__':
        extensionDir = os.path.join(os.getcwd(), "..", "..", "services",
                                    "sync", "tps")
    else:
        if sys.platform == 'win32':
            # replace msys-style paths with proper Windows paths
            import re
            m = re.match('^\/\w\/', extensionDir)
            if m:
                extensionDir = "%s:/%s" % (m.group(0)[1:2], extensionDir[3:])
                extensionDir = extensionDir.replace("/", "\\")

    if options.binary is None:
        while True:
            try:
                # If no binary is specified, start the pulse build monitor, and wait
                # until we receive build notifications before running tests.
                monitor = TPSPulseMonitor(extensionDir,
                                          config=config,
                                          autolog=options.autolog,
                                          emailresults=options.emailresults,
                                          testfile=options.testfile,
                                          logfile=options.logfile,
                                          rlock=rlock)
                print "waiting for pulse build notifications"

                if options.pulsefile:
                    # For testing purposes, inject a pulse message directly into
                    # the monitor.
                    builddata = json.loads(open(options.pulsefile, 'r').read())
                    monitor.onBuildComplete(builddata)

                monitor.listen()
            except KeyboardInterrupt:
                sys.exit()
            except:
                traceback.print_exc()
                print 'sleeping 5 minutes'
                time.sleep(300)

    TPS = TPSTestRunner(extensionDir,
                        emailresults=options.emailresults,
                        testfile=options.testfile,
                        logfile=options.logfile,
                        binary=options.binary,
                        config=config,
                        rlock=rlock,
                        mobile=options.mobile,
                        autolog=options.autolog,
                        ignore_unused_engines=options.ignore_unused_engines)
    TPS.run_tests()
示例#4
0
def main():
  parser = optparse.OptionParser()
  parser.add_option("--email-results",
                    action = "store_true", dest = "emailresults",
                    default = False,
                    help = "email the test results to the recipients defined "
                           "in the config file")
  parser.add_option("--mobile",
                    action = "store_true", dest = "mobile",
                    default = False,
                    help = "run with mobile settings")
  parser.add_option("--autolog",
                    action = "store_true", dest = "autolog",
                    default = False,
                    help = "post results to Autolog")
  parser.add_option("--testfile",
                    action = "store", type = "string", dest = "testfile",
                    default = '../../services/sync/tests/tps/test_sync.js',
                    help = "path to the test file to run "
                           "[default: %default]")
  parser.add_option("--logfile",
                    action = "store", type = "string", dest = "logfile",
                    default = 'tps.log',
                    help = "path to the log file [default: %default]")
  parser.add_option("--binary",
                    action = "store", type = "string", dest = "binary",
                    default = None,
                    help = "path to the Firefox binary, specified either as "
                           "a local file or a url; if omitted, the PATH "
                           "will be searched;")
  parser.add_option("--configfile",
                    action = "store", type = "string", dest = "configfile",
                    default = None,
                    help = "path to the config file to use "
                           "[default: %default]")
  parser.add_option("--pulsefile",
                    action = "store", type = "string", dest = "pulsefile",
                    default = None,
                    help = "path to file containing a pulse message in "
                           "json format that you want to inject into the monitor")
  parser.add_option("--ignore-unused-engines",
                     default=False,
                     action="store_true",
                     dest="ignore_unused_engines",
                     help="If defined, don't load unused engines in individual tests."
                           " Has no effect for pulse monitor.")
  (options, args) = parser.parse_args()

  configfile = options.configfile
  if configfile is None:
    if os.environ.get('VIRTUAL_ENV'):
      configfile = os.path.join(os.path.dirname(__file__), 'config.json')
    if configfile is None or not os.access(configfile, os.F_OK):
      raise Exception("Unable to find config.json in a VIRTUAL_ENV; you must "
                      "specify a config file using the --configfile option")

  # load the config file
  f = open(configfile, 'r')
  configcontent = f.read()
  f.close()
  config = json.loads(configcontent)

  rlock = RLock()
 
  extensionDir = config.get("extensiondir")
  if not extensionDir or extensionDir == '__EXTENSIONDIR__':
    extensionDir = os.path.join(os.getcwd(), "..", "..", "services", "sync", "tps")
  else:
    if sys.platform == 'win32':
      # replace msys-style paths with proper Windows paths
      import re
      m = re.match('^\/\w\/', extensionDir)
      if m:
        extensionDir = "%s:/%s" % (m.group(0)[1:2], extensionDir[3:])
        extensionDir = extensionDir.replace("/", "\\")

  if options.binary is None:
    while True:
      try:
        # If no binary is specified, start the pulse build monitor, and wait
        # until we receive build notifications before running tests.
        monitor = TPSPulseMonitor(extensionDir,
                                  config=config,
                                  autolog=options.autolog,
                                  emailresults=options.emailresults,
                                  testfile=options.testfile,
                                  logfile=options.logfile,
                                  rlock=rlock)
        print "waiting for pulse build notifications"

        if options.pulsefile:
          # For testing purposes, inject a pulse message directly into
          # the monitor.
          builddata = json.loads(open(options.pulsefile, 'r').read())
          monitor.onBuildComplete(builddata)

        monitor.listen()
      except KeyboardInterrupt:
        sys.exit()
      except:
        traceback.print_exc()
        print 'sleeping 5 minutes'
        time.sleep(300)

  TPS = TPSTestRunner(extensionDir,
                      emailresults=options.emailresults,
                      testfile=options.testfile,
                      logfile=options.logfile,
                      binary=options.binary,
                      config=config,
                      rlock=rlock,
                      mobile=options.mobile,
                      autolog=options.autolog,
                      ignore_unused_engines=options.ignore_unused_engines)
  TPS.run_tests()
示例#5
0
def main():
    parser = optparse.OptionParser()
    parser.add_option("--mobile",
                      action="store_true",
                      dest="mobile",
                      default=False,
                      help="run with mobile settings")
    parser.add_option("--testfile",
                      action="store",
                      type="string",
                      dest="testfile",
                      default='../../services/sync/tests/tps/test_sync.js',
                      help="path to the test file to run "
                      "[default: %default]")
    parser.add_option("--logfile",
                      action="store",
                      type="string",
                      dest="logfile",
                      default='tps.log',
                      help="path to the log file [default: %default]")
    parser.add_option("--resultfile",
                      action="store",
                      type="string",
                      dest="resultfile",
                      default='tps_result.json',
                      help="path to the result file [default: %default]")
    parser.add_option("--binary",
                      action="store",
                      type="string",
                      dest="binary",
                      default=None,
                      help="path to the Firefox binary, specified either as "
                      "a local file or a url; if omitted, the PATH "
                      "will be searched;")
    parser.add_option("--configfile",
                      action="store",
                      type="string",
                      dest="configfile",
                      default=None,
                      help="path to the config file to use "
                      "[default: %default]")
    parser.add_option("--pulsefile",
                      action="store",
                      type="string",
                      dest="pulsefile",
                      default=None,
                      help="path to file containing a pulse message in "
                      "json format that you want to inject into the monitor")
    parser.add_option(
        "--ignore-unused-engines",
        default=False,
        action="store_true",
        dest="ignore_unused_engines",
        help="If defined, don't load unused engines in individual tests."
        " Has no effect for pulse monitor.")
    (options, args) = parser.parse_args()

    configfile = options.configfile
    if configfile is None:
        if os.environ.get('VIRTUAL_ENV'):
            configfile = os.path.join(os.path.dirname(__file__), 'config.json')
        if configfile is None or not os.access(configfile, os.F_OK):
            raise Exception(
                "Unable to find config.json in a VIRTUAL_ENV; you must "
                "specify a config file using the --configfile option")

    # load the config file
    f = open(configfile, 'r')
    configcontent = f.read()
    f.close()
    config = json.loads(configcontent)

    rlock = RLock()

    print 'using result file', options.resultfile

    extensionDir = config.get("extensiondir")
    if not extensionDir or extensionDir == '__EXTENSIONDIR__':
        extensionDir = os.path.join(os.getcwd(), "..", "..", "services",
                                    "sync", "tps", "extensions")
    else:
        if sys.platform == 'win32':
            # replace msys-style paths with proper Windows paths
            import re
            m = re.match('^\/\w\/', extensionDir)
            if m:
                extensionDir = "%s:/%s" % (m.group(0)[1:2], extensionDir[3:])
                extensionDir = extensionDir.replace("/", "\\")

    TPS = TPSTestRunner(extensionDir,
                        testfile=options.testfile,
                        logfile=options.logfile,
                        binary=options.binary,
                        config=config,
                        rlock=rlock,
                        mobile=options.mobile,
                        resultfile=options.resultfile,
                        ignore_unused_engines=options.ignore_unused_engines)
    TPS.run_tests()
示例#6
0
文件: cli.py 项目: edmoz/tps-dev
def main():
    parser = optparse.OptionParser()
    parser.add_option("--mobile",
                      action = "store_true", dest = "mobile",
                      default = False,
                      help = "run with mobile settings")
    parser.add_option("--testfile",
                      action = "store", type = "string", dest = "testfile",
                      default = '../../services/sync/tests/tps/test_sync.js',
                      help = "path to the test file to run "
                             "[default: %default]")
    parser.add_option("--logfile",
                      action = "store", type = "string", dest = "logfile",
                      default = 'tps.log',
                      help = "path to the log file [default: %default]")
    parser.add_option("--resultfile",
                      action = "store", type = "string", dest = "resultfile",
                      default = 'tps_result.json',
                      help = "path to the result file [default: %default]")
    parser.add_option("--binary",
                      action = "store", type = "string", dest = "binary",
                      default = None,
                      help = "path to the Firefox binary, specified either as "
                             "a local file or a url; if omitted, the PATH "
                             "will be searched;")
    parser.add_option("--configfile",
                      action = "store", type = "string", dest = "configfile",
                      default = None,
                      help = "path to the config file to use "
                             "[default: %default]")
    parser.add_option("--pulsefile",
                      action = "store", type = "string", dest = "pulsefile",
                      default = None,
                      help = "path to file containing a pulse message in "
                             "json format that you want to inject into the monitor")
    parser.add_option("--ignore-unused-engines",
                       default=False,
                       action="store_true",
                       dest="ignore_unused_engines",
                       help="If defined, don't load unused engines in individual tests."
                             " Has no effect for pulse monitor.")
    parser.add_option("--sync_ts_uri",
                       default=None,
                       action="store",
                       dest="sync_ts_uri",
                       help="If defined, sets the token server cluster url")
    (options, args) = parser.parse_args()

    configfile = options.configfile
    if configfile is None:
        if os.environ.get('VIRTUAL_ENV'):
            configfile = os.path.join(os.path.dirname(__file__), 'config.json')
        if configfile is None or not os.access(configfile, os.F_OK):
            raise Exception("Unable to find config.json in a VIRTUAL_ENV; you must "
                            "specify a config file using the --configfile option")

    # load the config file
    f = open(configfile, 'r')
    configcontent = f.read()
    f.close()
    config = json.loads(configcontent)

    rlock = RLock()

    print 'using result file', options.resultfile

    extensionDir = config.get("extensiondir")
    if not extensionDir or extensionDir == '__EXTENSIONDIR__':
        extensionDir = os.path.join(os.getcwd(), "..", "..", "services", "sync", "tps", "extensions")
    else:
        if sys.platform == 'win32':
            # replace msys-style paths with proper Windows paths
            import re
            m = re.match('^\/\w\/', extensionDir)
            if m:
                extensionDir = "%s:/%s" % (m.group(0)[1:2], extensionDir[3:])
                extensionDir = extensionDir.replace("/", "\\")

    TPS = TPSTestRunner(extensionDir,
                        testfile=options.testfile,
                        logfile=options.logfile,
                        binary=options.binary,
                        config=config,
                        rlock=rlock,
                        mobile=options.mobile,
                        resultfile=options.resultfile,
                        ignore_unused_engines=options.ignore_unused_engines,
                        sync_ts_uri=options.sync_ts_uri)
    TPS.run_tests()
示例#7
0
def main():
    parser = optparse.OptionParser()
    parser.add_option('--binary',
                      action='store',
                      type='string',
                      dest='binary',
                      default=None,
                      help='path to the Firefox binary, specified either as '
                      'a local file or a url; if omitted, the PATH '
                      'will be searched;')
    parser.add_option('--configfile',
                      action='store',
                      type='string',
                      dest='configfile',
                      default=None,
                      help='path to the config file to use default: %default]')
    parser.add_option('--debug',
                      action='store_true',
                      dest='debug',
                      default=False,
                      help='run in debug mode')
    parser.add_option(
        '--ignore-unused-engines',
        default=False,
        action='store_true',
        dest='ignore_unused_engines',
        help='If defined, do not load unused engines in individual tests.'
        ' Has no effect for pulse monitor.')
    parser.add_option('--logfile',
                      action='store',
                      type='string',
                      dest='logfile',
                      default='tps.log',
                      help='path to the log file [default: %default]')
    parser.add_option('--mobile',
                      action='store_true',
                      dest='mobile',
                      default=False,
                      help='run with mobile settings')
    parser.add_option('--pulsefile',
                      action='store',
                      type='string',
                      dest='pulsefile',
                      default=None,
                      help='path to file containing a pulse message in '
                      'json format that you want to inject into the monitor')
    parser.add_option('--resultfile',
                      action='store',
                      type='string',
                      dest='resultfile',
                      default='tps_result.json',
                      help='path to the result file [default: %default]')
    parser.add_option('--testfile',
                      action='store',
                      type='string',
                      dest='testfile',
                      default='all_tests.json',
                      help='path to the test file to run [default: %default]')
    parser.add_option('--stop-on-error',
                      action='store_true',
                      dest='stop_on_error',
                      help='stop running tests after the first failure')
    (options, args) = parser.parse_args()

    configfile = options.configfile
    if configfile is None:
        virtual_env = os.environ.get('VIRTUAL_ENV')
        if virtual_env:
            configfile = os.path.join(virtual_env, 'config.json')
        if configfile is None or not os.access(configfile, os.F_OK):
            raise Exception(
                'Unable to find config.json in a VIRTUAL_ENV; you must '
                'specify a config file using the --configfile option')

    # load the config file
    f = open(configfile, 'r')
    configcontent = f.read()
    f.close()
    config = json.loads(configcontent)
    testfile = os.path.join(config.get('testdir', ''), options.testfile)

    rlock = RLock()

    print('using result file', options.resultfile)

    extensionDir = config.get('extensiondir')
    if not extensionDir or extensionDir == '__EXTENSIONDIR__':
        extensionDir = os.path.join(os.getcwd(), '..', '..', 'services',
                                    'sync', 'tps', 'extensions')
    else:
        if sys.platform == 'win32':
            # replace msys-style paths with proper Windows paths
            m = re.match('^\/\w\/', extensionDir)
            if m:
                extensionDir = '%s:/%s' % (m.group(0)[1:2], extensionDir[3:])
                extensionDir = extensionDir.replace('/', '\\')
    if sys.platform == 'darwin':
        # Needed to avoid tab crashes on mac due to level 3 sandboxing
        sourceRoot = os.path.join(extensionDir, '..', '..', '..', '..')
        os.environ['MOZ_DEVELOPER_REPO_DIR'] = os.path.abspath(sourceRoot)

    TPS = TPSTestRunner(
        extensionDir,
        binary=options.binary,
        config=config,
        debug=options.debug,
        ignore_unused_engines=options.ignore_unused_engines,
        logfile=options.logfile,
        mobile=options.mobile,
        resultfile=options.resultfile,
        rlock=rlock,
        testfile=testfile,
        stop_on_error=options.stop_on_error,
    )
    TPS.run_tests()

    if TPS.numfailed > 0 or TPS.numpassed == 0:
        sys.exit(1)
示例#8
0
文件: cli.py 项目: Floflis/gecko-b2g
def main():
    parser = optparse.OptionParser()
    parser.add_option(
        "--binary",
        action="store",
        type="string",
        dest="binary",
        default=None,
        help="path to the Firefox binary, specified either as "
        "a local file or a url; if omitted, the PATH "
        "will be searched;",
    )
    parser.add_option(
        "--configfile",
        action="store",
        type="string",
        dest="configfile",
        default=None,
        help="path to the config file to use default: %default]",
    )
    parser.add_option(
        "--debug",
        action="store_true",
        dest="debug",
        default=False,
        help="run in debug mode",
    )
    parser.add_option(
        "--ignore-unused-engines",
        default=False,
        action="store_true",
        dest="ignore_unused_engines",
        help="If defined, do not load unused engines in individual tests."
        " Has no effect for pulse monitor.",
    )
    parser.add_option(
        "--logfile",
        action="store",
        type="string",
        dest="logfile",
        default="tps.log",
        help="path to the log file [default: %default]",
    )
    parser.add_option(
        "--mobile",
        action="store_true",
        dest="mobile",
        default=False,
        help="run with mobile settings",
    )
    parser.add_option(
        "--pulsefile",
        action="store",
        type="string",
        dest="pulsefile",
        default=None,
        help="path to file containing a pulse message in "
        "json format that you want to inject into the monitor",
    )
    parser.add_option(
        "--resultfile",
        action="store",
        type="string",
        dest="resultfile",
        default="tps_result.json",
        help="path to the result file [default: %default]",
    )
    parser.add_option(
        "--testfile",
        action="store",
        type="string",
        dest="testfile",
        default="all_tests.json",
        help="path to the test file to run [default: %default]",
    )
    parser.add_option(
        "--stop-on-error",
        action="store_true",
        dest="stop_on_error",
        help="stop running tests after the first failure",
    )
    (options, args) = parser.parse_args()

    configfile = options.configfile
    if configfile is None:
        virtual_env = os.environ.get("VIRTUAL_ENV")
        if virtual_env:
            configfile = os.path.join(virtual_env, "config.json")
        if configfile is None or not os.access(configfile, os.F_OK):
            raise Exception(
                "Unable to find config.json in a VIRTUAL_ENV; you must "
                "specify a config file using the --configfile option")

    # load the config file
    f = open(configfile, "r")
    configcontent = f.read()
    f.close()
    config = json.loads(configcontent)
    testfile = os.path.join(config.get("testdir", ""), options.testfile)

    rlock = RLock()

    print("using result file", options.resultfile)

    extensionDir = config.get("extensiondir")
    if not extensionDir or extensionDir == "__EXTENSIONDIR__":
        extensionDir = os.path.join(os.getcwd(), "..", "..", "services",
                                    "sync", "tps", "extensions")
    else:
        if sys.platform == "win32":
            # replace msys-style paths with proper Windows paths
            m = re.match("^\/\w\/", extensionDir)
            if m:
                extensionDir = "%s:/%s" % (m.group(0)[1:2], extensionDir[3:])
                extensionDir = extensionDir.replace("/", "\\")
    if sys.platform == "darwin":
        # Needed to avoid tab crashes on mac due to level 3 sandboxing
        sourceRoot = os.path.join(extensionDir, "..", "..", "..", "..")
        os.environ["MOZ_DEVELOPER_REPO_DIR"] = os.path.abspath(sourceRoot)

    TPS = TPSTestRunner(
        extensionDir,
        binary=options.binary,
        config=config,
        debug=options.debug,
        ignore_unused_engines=options.ignore_unused_engines,
        logfile=options.logfile,
        mobile=options.mobile,
        resultfile=options.resultfile,
        rlock=rlock,
        testfile=testfile,
        stop_on_error=options.stop_on_error,
    )
    TPS.run_tests()

    if TPS.numfailed > 0 or TPS.numpassed == 0:
        sys.exit(1)