Example #1
0
  def runSerialTests(self, testPath, options, cmdlineArgs = None):
    debuggerInfo = None
    if options.debugger:
      debuggerInfo = mozdebug.get_debugger_info(options.debugger, options.debuggerArgs,
        options.debuggerInteractive);

    profileDir = None
    try:
      reftestlist = self.getManifestPath(testPath)
      if cmdlineArgs == None:
        cmdlineArgs = ['-reftest', reftestlist]
      profile = self.createReftestProfile(options, reftestlist)
      profileDir = profile.profile # name makes more sense

      # browser environment
      browserEnv = self.buildBrowserEnv(options, profileDir)

      log.info("REFTEST INFO | runreftest.py | Running tests: start.\n")
      status = self.runApp(profile,
                           binary=options.app,
                           cmdargs=cmdlineArgs,
                           # give the JS harness 30 seconds to deal with its own timeouts
                           env=browserEnv,
                           timeout=options.timeout + 30.0,
                           symbolsPath=options.symbolsPath,
                           options=options,
                           debuggerInfo=debuggerInfo)
      processLeakLog(self.leakLogFile, options)
      log.info("\nREFTEST INFO | runreftest.py | Running tests: end.")
    finally:
      self.cleanup(profileDir)
    return status
Example #2
0
    def run(self, params, debug=False, debugger=None):
        env = self.build_env()
        env["RUST_BACKTRACE"] = "1"

        args = [path.join("target", "servo")]

        # Borrowed and modified from:
        # http://hg.mozilla.org/mozilla-central/file/c9cfa9b91dea/python/mozbuild/mozbuild/mach_commands.py#l883
        if debug:
            import mozdebug
            if not debugger:
                # No debugger name was provided. Look for the default ones on
                # current OS.
                debugger = mozdebug.get_default_debugger_name(
                    mozdebug.DebuggerSearch.KeepLooking)

            self.debuggerInfo = mozdebug.get_debugger_info(debugger)
            if not self.debuggerInfo:
                print("Could not find a suitable debugger in your PATH.")
                return 1

            # Prepend the debugger args.
            args = ([self.debuggerInfo.path] + self.debuggerInfo.args
                    + args + params)
        else:
            args = args + params

        subprocess.check_call(args, env=env)
Example #3
0
    def runSerialTests(self, manifests, options, cmdlineArgs=None):
        debuggerInfo = None
        if options.debugger:
            debuggerInfo = mozdebug.get_debugger_info(options.debugger, options.debuggerArgs,
                                                      options.debuggerInteractive)

        profileDir = None
        try:
            if cmdlineArgs is None:
                cmdlineArgs = []
            profile = self.createReftestProfile(options, manifests)
            profileDir = profile.profile  # name makes more sense

            # browser environment
            browserEnv = self.buildBrowserEnv(options, profileDir)

            status = self.runApp(profile,
                                 binary=options.app,
                                 cmdargs=cmdlineArgs,
                                 # give the JS harness 30 seconds to deal with
                                 # its own timeouts
                                 env=browserEnv,
                                 timeout=options.timeout + 30.0,
                                 symbolsPath=options.symbolsPath,
                                 options=options,
                                 debuggerInfo=debuggerInfo)
            mozleak.process_leak_log(self.leakLogFile,
                                     leak_thresholds=options.leakThresholds,
                                     stack_fixer=get_stack_fixer_function(options.utilityPath,
                                                                          options.symbolsPath),
            )
        finally:
            self.cleanup(profileDir)
        return status
Example #4
0
    def run(self, params, release=False, dev=False, debug=False, debugger=None):
        env = self.build_env()
        env["RUST_BACKTRACE"] = "1"

        args = [self.get_binary_path(release, dev)]
        # Borrowed and modified from:
        # http://hg.mozilla.org/mozilla-central/file/c9cfa9b91dea/python/mozbuild/mozbuild/mach_commands.py#l883
        if debug:
            import mozdebug

            if not debugger:
                # No debugger name was provided. Look for the default ones on
                # current OS.
                debugger = mozdebug.get_default_debugger_name(mozdebug.DebuggerSearch.KeepLooking)

            self.debuggerInfo = mozdebug.get_debugger_info(debugger)
            if not self.debuggerInfo:
                print("Could not find a suitable debugger in your PATH.")
                return 1

            # Prepend the debugger args.
            args = [self.debuggerInfo.path] + self.debuggerInfo.args + args + params
        else:
            args = args + params

        try:
            subprocess.check_call(args, env=env)
        except subprocess.CalledProcessError as e:
            print("Servo exited with return value %d" % e.returncode)
            return e.returncode
        except OSError as e:
            if e.errno == 2:
                print("Servo Binary can't be found! Run './mach build'" " and try again!")
            else:
                raise e
Example #5
0
    def run(self, params, release=False, dev=False, android=False, debug=False, debugger=None):
        env = self.build_env()
        env["RUST_BACKTRACE"] = "1"

        if android:
            if debug:
                print("Android on-device debugging is not supported by mach yet. See")
                print("https://github.com/servo/servo/wiki/Building-for-Android#debugging-on-device")
                return
            script = [
                "am force-stop com.mozilla.servo",
                "echo servo >/sdcard/servo/android_params"
            ]
            for param in params:
                script += [
                    "echo '%s' >>/sdcard/servo/android_params" % param.replace("'", "\\'")
                ]
            script += [
                "am start com.mozilla.servo/com.mozilla.servo.MainActivity",
                "exit"
            ]
            shell = subprocess.Popen(["adb", "shell"], stdin=subprocess.PIPE)
            shell.communicate("\n".join(script) + "\n")
            return shell.wait()

        args = [self.get_binary_path(release, dev)]

        # Borrowed and modified from:
        # http://hg.mozilla.org/mozilla-central/file/c9cfa9b91dea/python/mozbuild/mozbuild/mach_commands.py#l883
        if debug:
            import mozdebug
            if not debugger:
                # No debugger name was provided. Look for the default ones on
                # current OS.
                debugger = mozdebug.get_default_debugger_name(
                    mozdebug.DebuggerSearch.KeepLooking)

            self.debuggerInfo = mozdebug.get_debugger_info(debugger)
            if not self.debuggerInfo:
                print("Could not find a suitable debugger in your PATH.")
                return 1

            # Prepend the debugger args.
            args = ([self.debuggerInfo.path] + self.debuggerInfo.args +
                    args + params)
        else:
            args = args + params

        try:
            subprocess.check_call(args, env=env)
        except subprocess.CalledProcessError as e:
            print("Servo exited with return value %d" % e.returncode)
            return e.returncode
        except OSError as e:
            if e.errno == 2:
                print("Servo Binary can't be found! Run './mach build'"
                      " and try again!")
            else:
                raise e
Example #6
0
    def debug(self, params, remote, background, debugger, debugparams, slowscript):
        # Parameters come from the CLI. We need to convert them before their use.
        if debugparams:
            import pymake.process
            argv, badchar = pymake.process.clinetoargv(debugparams, os.getcwd())
            if badchar:
                print("The +debugparams you passed require a real shell to parse them.")
                print("(We can't handle the %r character.)" % (badchar,))
                return 1
            debugparams = argv;

        import mozdebug

        if not debugger:
            # No debugger name was provided. Look for the default ones on current OS.
            debugger = mozdebug.get_default_debugger_name(mozdebug.DebuggerSearch.KeepLooking)

        self.debuggerInfo = mozdebug.get_debugger_info(debugger, debugparams)

        # We could not find the information about the desired debugger.
        if not self.debuggerInfo:
            print("Could not find a suitable debugger in your PATH.")
            return 1

        extra_env = { 'MOZ_CRASHREPORTER_DISABLE' : '1' }

        binpath = None

        try:
            binpath = self.get_binary_path('app')
        except Exception as e:
            print("It looks like your program isn't built.",
                "You can run |mach build| to build it.")
            print(e)
            return 1

        # Build the list of arguments to pass to run_process
        args = [self.debuggerInfo.path] + self.debuggerInfo.args
        args.append(binpath)

        if not remote:
            args.append('-no-remote')
        if not background and sys.platform == 'darwin':
            args.append('-foreground')
        if params:
            args.extend(params)
        if '-profile' not in params and '-P' not in params:
            path = os.path.join(self.topobjdir, 'tmp', 'scratch_user')
            if not os.path.isdir(path):
                os.makedirs(path)
            args.append('-profile')
            args.append(path)
        if not slowscript:
            extra_env['JS_DISABLE_SLOW_SCRIPT_SIGNALS'] = '1'
        return self.run_process(args=args, append_env=extra_env,
            ensure_exit_code=False, pass_thru=True)
Example #7
0
    def run(self, binary, params, debug, debugger, debugger_args):
        try:
            binpath = self.get_binary_path("geckodriver")
        except Exception as e:
                print("It looks like geckodriver isn't built. "
                      "Add ac_add_options --enable-geckodrver to your mozconfig ",
                      "and run |mach build| to build it.")
                print(e)
                return 1

        args = [binpath]

        if params:
            args.extend(params)

        if binary is None:
            binary = self.get_binary_path("app")

        args.extend(["--binary", binary])

        if debug or debugger or debugger_args:
            if "INSIDE_EMACS" in os.environ:
                self.log_manager.terminal_handler.setLevel(logging.WARNING)

            import mozdebug
            if not debugger:
                # No debugger name was provided. Look for the default ones on
                # current OS.
                debugger = mozdebug.get_default_debugger_name(mozdebug.DebuggerSearch.KeepLooking)

            if debugger:
                self.debuggerInfo = mozdebug.get_debugger_info(debugger, debugger_args)
                if not self.debuggerInfo:
                    print("Could not find a suitable debugger in your PATH.")
                    return 1

            # Parameters come from the CLI. We need to convert them before
            # their use.
            if debugger_args:
                from mozbuild import shellutil
                try:
                    debugger_args = shellutil.split(debugger_args)
                except shellutil.MetaCharacterException as e:
                    print("The --debugger-args you passed require a real shell to parse them.")
                    print("(We can't handle the %r character.)" % e.char)
                    return 1

            # Prepend the debugger args.
            args = [self.debuggerInfo.path] + self.debuggerInfo.args + args

        return self.run_process(args=args, ensure_exit_code=False,
            pass_thru=True)
Example #8
0
def find_debugger_info(debug, debugger, debugger_args):
    debuggerInfo = None
    if debug or debugger or debugger_args:
        import mozdebug

        if not debugger:
            # No debugger name was provided. Look for the default ones on
            # current OS.
            debugger = mozdebug.get_default_debugger_name(mozdebug.DebuggerSearch.KeepLooking)

        debuggerInfo = None
        if debugger:
            debuggerInfo = mozdebug.get_debugger_info(debugger, debugger_args)

        if debuggerInfo is None:
            raise TalosError('Could not find a suitable debugger in your PATH.')

    return debuggerInfo
Example #9
0
    def prepend_debugger_args(self, args, debugger, debugger_args):
        """
        Given an array with program arguments, prepend arguments to run it under a
        debugger.

        :param args: The executable and arguments used to run the process normally.
        :param debugger: The debugger to use, or empty to use the default debugger.
        :param debugger_args: Any additional parameters to pass to the debugger.
        """

        import mozdebug

        if not debugger:
            # No debugger name was provided. Look for the default ones on
            # current OS.
            debugger = mozdebug.get_default_debugger_name(mozdebug.DebuggerSearch.KeepLooking)

        if debugger:
            debuggerInfo = mozdebug.get_debugger_info(debugger, debugger_args)
            if not debuggerInfo:
                print("Could not find a suitable debugger in your PATH.")
                return 1

        # Parameters come from the CLI. We need to convert them before
        # their use.
        if debugger_args:
            import pymake.process

            argv, badchar = pymake.process.clinetoargv(debugger_args, os.getcwd())
            if badchar:
                print("The --debugger_args you passed require a real shell to parse them.")
                print("(We can't handle the %r character.)" % (badchar,))
                return 1
            debugger_args = argv

        # Prepend the debugger args.
        args = [debuggerInfo.path] + debuggerInfo.args + args
        return args
Example #10
0
    def run(self, params, release=False, dev=False, android=None, debug=False, debugger=None,
            headless=False, software=False, bin=None, emulator=False, usb=False, nightly=None):
        env = self.build_env()
        env["RUST_BACKTRACE"] = "1"

        # Make --debugger imply --debug
        if debugger:
            debug = True

        if android is None:
            android = self.config["build"]["android"]

        if android:
            if debug:
                print("Android on-device debugging is not supported by mach yet. See")
                print("https://github.com/servo/servo/wiki/Building-for-Android#debugging-on-device")
                return
            script = [
                "am force-stop org.mozilla.servo",
            ]
            json_params = shell_quote(json.dumps(params))
            extra = "-e servoargs " + json_params
            rust_log = env.get("RUST_LOG", None)
            if rust_log:
                extra += " -e servolog " + rust_log
            script += [
                "am start " + extra + " org.mozilla.servo/org.mozilla.servo.MainActivity",
                "sleep 0.5",
                "echo Servo PID: $(pidof org.mozilla.servo)",
                "exit"
            ]
            args = [self.android_adb_path(env)]
            if emulator and usb:
                print("Cannot run in both emulator and USB at the same time.")
                return 1
            if emulator:
                args += ["-e"]
            if usb:
                args += ["-d"]
            shell = subprocess.Popen(args + ["shell"], stdin=subprocess.PIPE)
            shell.communicate("\n".join(script) + "\n")
            return shell.wait()

        args = [bin or self.get_nightly_binary_path(nightly) or self.get_binary_path(release, dev)]

        if headless:
            set_osmesa_env(args[0], env)
            args.append('-z')

        if software:
            if not is_linux():
                print("Software rendering is only supported on Linux at the moment.")
                return

            env['LIBGL_ALWAYS_SOFTWARE'] = "1"

        # Borrowed and modified from:
        # http://hg.mozilla.org/mozilla-central/file/c9cfa9b91dea/python/mozbuild/mozbuild/mach_commands.py#l883
        if debug:
            import mozdebug
            if not debugger:
                # No debugger name was provided. Look for the default ones on
                # current OS.
                debugger = mozdebug.get_default_debugger_name(
                    mozdebug.DebuggerSearch.KeepLooking)

            self.debuggerInfo = mozdebug.get_debugger_info(debugger)
            if not self.debuggerInfo:
                print("Could not find a suitable debugger in your PATH.")
                return 1

            command = self.debuggerInfo.path
            if debugger == 'gdb' or debugger == 'lldb':
                rustCommand = 'rust-' + debugger
                try:
                    subprocess.check_call([rustCommand, '--version'], env=env, stdout=open(os.devnull, 'w'))
                except (OSError, subprocess.CalledProcessError):
                    pass
                else:
                    command = rustCommand

            # Prepend the debugger args.
            args = ([command] + self.debuggerInfo.args +
                    args + params)
        else:
            args = args + params

        try:
            check_call(args, env=env)
        except subprocess.CalledProcessError as e:
            print("Servo exited with return value %d" % e.returncode)
            return e.returncode
        except OSError as e:
            if e.errno == 2:
                print("Servo Binary can't be found! Run './mach build'"
                      " and try again!")
            else:
                raise e
Example #11
0
    def run(self, params, release=False, dev=False, android=None, debug=False, debugger=None, browserhtml=False,
            headless=False, software=False):
        env = self.build_env()
        env["RUST_BACKTRACE"] = "1"

        # Make --debugger imply --debug
        if debugger:
            debug = True

        if android is None:
            android = self.config["build"]["android"]

        if android:
            if debug:
                print("Android on-device debugging is not supported by mach yet. See")
                print("https://github.com/servo/servo/wiki/Building-for-Android#debugging-on-device")
                return
            script = [
                "am force-stop com.mozilla.servo",
                "echo servo >/sdcard/servo/android_params"
            ]
            for param in params:
                script += [
                    "echo '%s' >>/sdcard/servo/android_params" % param.replace("'", "\\'")
                ]
            script += [
                "am start com.mozilla.servo/com.mozilla.servo.MainActivity",
                "exit"
            ]
            shell = subprocess.Popen(["adb", "shell"], stdin=subprocess.PIPE)
            shell.communicate("\n".join(script) + "\n")
            return shell.wait()

        args = [self.get_binary_path(release, dev)]

        if browserhtml:
            browserhtml_path = get_browserhtml_path(args[0])
            if is_macosx():
                # Enable borderless on OSX
                args = args + ['-b']
            elif is_windows():
                # Convert to a relative path to avoid mingw -> Windows path conversions
                browserhtml_path = path.relpath(browserhtml_path, os.getcwd())

            args = args + ['--pref', 'dom.mozbrowser.enabled',
                           '--pref', 'dom.forcetouch.enabled',
                           '--pref', 'shell.builtin-key-shortcuts.enabled=false',
                           path.join(browserhtml_path, 'index.html')]

        if headless:
            set_osmesa_env(args[0], env)
            args.append('-z')

        if software:
            if not is_linux():
                print("Software rendering is only supported on Linux at the moment.")
                return

            env['LIBGL_ALWAYS_SOFTWARE'] = "1"

        # Borrowed and modified from:
        # http://hg.mozilla.org/mozilla-central/file/c9cfa9b91dea/python/mozbuild/mozbuild/mach_commands.py#l883
        if debug:
            import mozdebug
            if not debugger:
                # No debugger name was provided. Look for the default ones on
                # current OS.
                debugger = mozdebug.get_default_debugger_name(
                    mozdebug.DebuggerSearch.KeepLooking)

            self.debuggerInfo = mozdebug.get_debugger_info(debugger)
            if not self.debuggerInfo:
                print("Could not find a suitable debugger in your PATH.")
                return 1

            command = self.debuggerInfo.path
            if debugger == 'gdb' or debugger == 'lldb':
                rustCommand = 'rust-' + debugger
                try:
                    subprocess.check_call([rustCommand, '--version'], env=env, stdout=open(os.devnull, 'w'))
                except (OSError, subprocess.CalledProcessError):
                    pass
                else:
                    command = rustCommand

            # Prepend the debugger args.
            args = ([command] + self.debuggerInfo.args +
                    args + params)
        else:
            args = args + params

        try:
            check_call(args, env=env)
        except subprocess.CalledProcessError as e:
            print("Servo exited with return value %d" % e.returncode)
            return e.returncode
        except OSError as e:
            if e.errno == 2:
                print("Servo Binary can't be found! Run './mach build'"
                      " and try again!")
            else:
                raise e
Example #12
0
def check_args(kwargs):
    set_from_config(kwargs)

    if kwargs["product"] is None:
        kwargs["product"] = "firefox"

    if kwargs["manifest_update"] is None:
        kwargs["manifest_update"] = True

    if "sauce" in kwargs["product"]:
        kwargs["pause_after_test"] = False

    if kwargs["test_list"]:
        if kwargs["include"] is not None:
            kwargs["include"].extend(kwargs["test_list"])
        else:
            kwargs["include"] = kwargs["test_list"]

    if kwargs["run_info"] is None:
        kwargs["run_info"] = kwargs["config_path"]

    if kwargs["this_chunk"] > 1:
        require_arg(kwargs, "total_chunks",
                    lambda x: x >= kwargs["this_chunk"])

    if kwargs["chunk_type"] is None:
        if kwargs["total_chunks"] > 1:
            kwargs["chunk_type"] = "dir_hash"
        else:
            kwargs["chunk_type"] = "none"

    if kwargs["processes"] is None:
        kwargs["processes"] = 1

    if kwargs["debugger"] is not None:
        import mozdebug
        if kwargs["debugger"] == "__default__":
            kwargs["debugger"] = mozdebug.get_default_debugger_name()
        debug_info = mozdebug.get_debugger_info(kwargs["debugger"],
                                                kwargs["debugger_args"])
        if debug_info and debug_info.interactive:
            if kwargs["processes"] != 1:
                kwargs["processes"] = 1
            kwargs["no_capture_stdio"] = True
        kwargs["debug_info"] = debug_info
    else:
        kwargs["debug_info"] = None

    if kwargs["binary"] is not None:
        if not os.path.exists(kwargs["binary"]):
            print >> sys.stderr, "Binary path %s does not exist" % kwargs[
                "binary"]
            sys.exit(1)

    if kwargs["ssl_type"] is None:
        if None not in (kwargs["ca_cert_path"], kwargs["host_cert_path"],
                        kwargs["host_key_path"]):
            kwargs["ssl_type"] = "pregenerated"
        elif exe_path(kwargs["openssl_binary"]) is not None:
            kwargs["ssl_type"] = "openssl"
        else:
            kwargs["ssl_type"] = "none"

    if kwargs["ssl_type"] == "pregenerated":
        require_arg(kwargs, "ca_cert_path", lambda x: os.path.exists(x))
        require_arg(kwargs, "host_cert_path", lambda x: os.path.exists(x))
        require_arg(kwargs, "host_key_path", lambda x: os.path.exists(x))

    elif kwargs["ssl_type"] == "openssl":
        path = exe_path(kwargs["openssl_binary"])
        if path is None:
            print >> sys.stderr, "openssl-binary argument missing or not a valid executable"
            sys.exit(1)
        kwargs["openssl_binary"] = path

    if kwargs["ssl_type"] != "none" and kwargs[
            "product"] == "firefox" and kwargs["certutil_binary"]:
        path = exe_path(kwargs["certutil_binary"])
        if path is None:
            print >> sys.stderr, "certutil-binary argument missing or not a valid executable"
            sys.exit(1)
        kwargs["certutil_binary"] = path

    if kwargs['extra_prefs']:
        # If a single pref is passed in as a string, make it a list
        if type(kwargs['extra_prefs']) in (str, unicode):
            kwargs['extra_prefs'] = [kwargs['extra_prefs']]
        missing = any('=' not in prefarg for prefarg in kwargs['extra_prefs'])
        if missing:
            print >> sys.stderr, "Preferences via --setpref must be in key=value format"
            sys.exit(1)
        kwargs['extra_prefs'] = [
            tuple(prefarg.split('=', 1)) for prefarg in kwargs['extra_prefs']
        ]

    if kwargs["reftest_internal"] is None:
        kwargs["reftest_internal"] = True

    return kwargs
Example #13
0
    def run(self,
            params,
            release=False,
            dev=False,
            android=None,
            debug=False,
            debugger=None,
            headless=False,
            software=False,
            bin=None,
            emulator=False,
            usb=False,
            nightly=None):
        env = self.build_env()
        env["RUST_BACKTRACE"] = "1"

        # Make --debugger imply --debug
        if debugger:
            debug = True

        if android is None:
            android = self.config["build"]["android"]

        if android:
            if debug:
                print(
                    "Android on-device debugging is not supported by mach yet. See"
                )
                print(
                    "https://github.com/servo/servo/wiki/Building-for-Android#debugging-on-device"
                )
                return
            script = [
                "am force-stop org.mozilla.servo",
            ]
            json_params = shell_quote(json.dumps(params))
            extra = "-e servoargs " + json_params
            rust_log = env.get("RUST_LOG", None)
            if rust_log:
                extra += " -e servolog " + rust_log
            script += [
                "am start " + extra +
                " org.mozilla.servo/org.mozilla.servo.MainActivity",
                "sleep 0.5", "echo Servo PID: $(pidof org.mozilla.servo)",
                "exit"
            ]
            args = [self.android_adb_path(env)]
            if emulator and usb:
                print("Cannot run in both emulator and USB at the same time.")
                return 1
            if emulator:
                args += ["-e"]
            if usb:
                args += ["-d"]
            shell = subprocess.Popen(args + ["shell"], stdin=subprocess.PIPE)
            shell.communicate("\n".join(script) + "\n")
            return shell.wait()

        args = [
            bin or self.get_nightly_binary_path(nightly)
            or self.get_binary_path(release, dev)
        ]

        if headless:
            set_osmesa_env(args[0], env)
            args.append('-z')

        if software:
            if not is_linux():
                print(
                    "Software rendering is only supported on Linux at the moment."
                )
                return

            env['LIBGL_ALWAYS_SOFTWARE'] = "1"

        # Borrowed and modified from:
        # http://hg.mozilla.org/mozilla-central/file/c9cfa9b91dea/python/mozbuild/mozbuild/mach_commands.py#l883
        if debug:
            import mozdebug
            if not debugger:
                # No debugger name was provided. Look for the default ones on
                # current OS.
                debugger = mozdebug.get_default_debugger_name(
                    mozdebug.DebuggerSearch.KeepLooking)

            self.debuggerInfo = mozdebug.get_debugger_info(debugger)
            if not self.debuggerInfo:
                print("Could not find a suitable debugger in your PATH.")
                return 1

            command = self.debuggerInfo.path
            if debugger == 'gdb' or debugger == 'lldb':
                rustCommand = 'rust-' + debugger
                try:
                    subprocess.check_call([rustCommand, '--version'],
                                          env=env,
                                          stdout=open(os.devnull, 'w'))
                except (OSError, subprocess.CalledProcessError):
                    pass
                else:
                    command = rustCommand

            # Prepend the debugger args.
            args = ([command] + self.debuggerInfo.args + args + params)
        else:
            args = args + params

        try:
            check_call(args, env=env)
        except subprocess.CalledProcessError as e:
            print("Servo exited with return value %d" % e.returncode)
            return e.returncode
        except OSError as e:
            if e.errno == 2:
                print("Servo Binary can't be found! Run './mach build'"
                      " and try again!")
            else:
                raise e
Example #14
0
    def runSerialTests(self, manifests, options, cmdargs=None):
        debuggerInfo = None
        if options.debugger:
            debuggerInfo = mozdebug.get_debugger_info(options.debugger, options.debuggerArgs,
                                                      options.debuggerInteractive)

        profileDir = None
        startAfter = None  # When the previous run crashed, we skip the tests we ran before
        prevStartAfter = None
        for i in itertools.count():
            try:
                if cmdargs is None:
                    cmdargs = []

                if self.use_marionette:
                    cmdargs.append('-marionette')

                profile = self.createReftestProfile(options,
                                                    manifests,
                                                    startAfter=startAfter)
                profileDir = profile.profile  # name makes more sense

                # browser environment
                browserEnv = self.buildBrowserEnv(options, profileDir)

                self.log.info("Running with e10s: {}".format(options.e10s))
                status, startAfter = self.runApp(profile,
                                                 binary=options.app,
                                                 cmdargs=cmdargs,
                                                 env=browserEnv,
                                                 # We generally want the JS harness or marionette
                                                 # to handle timeouts if they can.
                                                 # The default JS harness timeout is currently
                                                 # 300 seconds (default options.timeout).
                                                 # The default Marionette socket timeout is
                                                 # currently 360 seconds.
                                                 # Give the JS harness extra time to deal with
                                                 # its own timeouts and try to usually exceed
                                                 # the 360 second marionette socket timeout.
                                                 # See bug 479518 and bug 1414063.
                                                 timeout=options.timeout + 70.0,
                                                 symbolsPath=options.symbolsPath,
                                                 options=options,
                                                 debuggerInfo=debuggerInfo)
                self.log.info("Process mode: {}".format('e10s' if options.e10s else 'non-e10s'))
                mozleak.process_leak_log(self.leakLogFile,
                                         leak_thresholds=options.leakThresholds,
                                         stack_fixer=get_stack_fixer_function(options.utilityPath,
                                                                              options.symbolsPath))
                if status == 0:
                    break

                if startAfter == self.TEST_SEEN_FINAL:
                    self.log.info("Finished running all tests, skipping resume "
                                  "despite non-zero status code: %s" % status)
                    break

                if startAfter is not None and options.shuffle:
                    self.log.error("Can not resume from a crash with --shuffle "
                                   "enabled. Please consider disabling --shuffle")
                    break
                if startAfter is not None and options.maxRetries <= i:
                    self.log.error("Hit maximum number of allowed retries ({}) "
                                   "in the test run".format(options.maxRetries))
                    break
                if startAfter == prevStartAfter:
                    # If the test stuck on the same test, or there the crashed
                    # test appeared more then once, stop
                    self.log.error("Force stop because we keep running into "
                                   "test \"{}\"".format(startAfter))
                    break
                prevStartAfter = startAfter
                # TODO: we need to emit an SUITE-END log if it crashed
            finally:
                self.cleanup(profileDir)
        return status
Example #15
0
def check_args(kwargs):
    set_from_config(kwargs)

    for test_paths in kwargs["test_paths"].itervalues():
        if not ("tests_path" in test_paths and "metadata_path" in test_paths):
            print "Fatal: must specify both a test path and metadata path"
            sys.exit(1)
        for key, path in test_paths.iteritems():
            name = key.split("_", 1)[0]

            if not os.path.exists(path):
                print "Fatal: %s path %s does not exist" % (name, path)
                sys.exit(1)

            if not os.path.isdir(path):
                print "Fatal: %s path %s is not a directory" % (name, path)
                sys.exit(1)

    if kwargs["product"] is None:
        kwargs["product"] = "firefox"

    if "sauce" in kwargs["product"]:
        kwargs["pause_after_test"] = False

    if kwargs["test_list"]:
        if kwargs["include"] is not None:
            kwargs["include"].extend(kwargs["test_list"])
        else:
            kwargs["include"] = kwargs["test_list"]

    if kwargs["run_info"] is None:
        kwargs["run_info"] = kwargs["config_path"]

    if kwargs["this_chunk"] > 1:
        require_arg(kwargs, "total_chunks",
                    lambda x: x >= kwargs["this_chunk"])

    if kwargs["chunk_type"] is None:
        if kwargs["total_chunks"] > 1:
            kwargs["chunk_type"] = "dir_hash"
        else:
            kwargs["chunk_type"] = "none"

    if kwargs["processes"] is None:
        kwargs["processes"] = 1

    if kwargs["debugger"] is not None:
        import mozdebug
        if kwargs["debugger"] == "__default__":
            kwargs["debugger"] = mozdebug.get_default_debugger_name()
        debug_info = mozdebug.get_debugger_info(kwargs["debugger"],
                                                kwargs["debugger_args"])
        if debug_info and debug_info.interactive:
            if kwargs["processes"] != 1:
                kwargs["processes"] = 1
            kwargs["no_capture_stdio"] = True
        kwargs["debug_info"] = debug_info
    else:
        kwargs["debug_info"] = None

    if kwargs["binary"] is not None:
        if not os.path.exists(kwargs["binary"]):
            print >> sys.stderr, "Binary path %s does not exist" % kwargs[
                "binary"]
            sys.exit(1)

    if kwargs["ssl_type"] is None:
        if None not in (kwargs["ca_cert_path"], kwargs["host_cert_path"],
                        kwargs["host_key_path"]):
            kwargs["ssl_type"] = "pregenerated"
        elif exe_path(kwargs["openssl_binary"]) is not None:
            kwargs["ssl_type"] = "openssl"
        else:
            kwargs["ssl_type"] = "none"

    if kwargs["ssl_type"] == "pregenerated":
        require_arg(kwargs, "ca_cert_path", lambda x: os.path.exists(x))
        require_arg(kwargs, "host_cert_path", lambda x: os.path.exists(x))
        require_arg(kwargs, "host_key_path", lambda x: os.path.exists(x))

    elif kwargs["ssl_type"] == "openssl":
        path = exe_path(kwargs["openssl_binary"])
        if path is None:
            print >> sys.stderr, "openssl-binary argument missing or not a valid executable"
            sys.exit(1)
        kwargs["openssl_binary"] = path

    if kwargs["ssl_type"] != "none" and kwargs[
            "product"] == "firefox" and kwargs["certutil_binary"]:
        path = exe_path(kwargs["certutil_binary"])
        if path is None:
            print >> sys.stderr, "certutil-binary argument missing or not a valid executable"
            sys.exit(1)
        kwargs["certutil_binary"] = path

    if kwargs['extra_prefs']:
        missing = any('=' not in prefarg for prefarg in kwargs['extra_prefs'])
        if missing:
            print >> sys.stderr, "Preferences via --setpref must be in key=value format"
            sys.exit(1)
        kwargs['extra_prefs'] = [
            tuple(prefarg.split('=', 1)) for prefarg in kwargs['extra_prefs']
        ]

    if kwargs["reftest_internal"] is None:
        # Default to the internal reftest implementation on Linux and OSX
        kwargs["reftest_internal"] = sys.platform.startswith(
            "linux") or sys.platform.startswith("darwin")

    return kwargs
Example #16
0
    def run(self, params, release=False, dev=False, android=None, debug=False, debugger=None, browserhtml=False,
            headless=False, software=False):
        env = self.build_env()
        env["RUST_BACKTRACE"] = "1"

        # Make --debugger imply --debug
        if debugger:
            debug = True

        if android is None:
            android = self.config["build"]["android"]

        if android:
            if debug:
                print("Android on-device debugging is not supported by mach yet. See")
                print("https://github.com/servo/servo/wiki/Building-for-Android#debugging-on-device")
                return
            script = [
                "am force-stop com.mozilla.servo",
                "echo servo >/sdcard/Android/data/com.mozilla.servo/files/android_params"
            ]
            for param in params:
                script += [
                    "echo '%s' >>/sdcard/Android/data/com.mozilla.servo/files/android_params"
                    % param.replace("'", "\\'")
                ]
            script += [
                "am start com.mozilla.servo/com.mozilla.servo.MainActivity",
                "exit"
            ]
            shell = subprocess.Popen(["adb", "shell"], stdin=subprocess.PIPE)
            shell.communicate("\n".join(script) + "\n")
            return shell.wait()

        args = [self.get_binary_path(release, dev)]

        if browserhtml:
            browserhtml_path = get_browserhtml_path(args[0])
            if is_macosx():
                # Enable borderless on OSX
                args = args + ['-b']
            elif is_windows():
                # Convert to a relative path to avoid mingw -> Windows path conversions
                browserhtml_path = path.relpath(browserhtml_path, os.getcwd())

            args = args + ['--pref', 'dom.mozbrowser.enabled',
                           '--pref', 'dom.forcetouch.enabled',
                           '--pref', 'shell.builtin-key-shortcuts.enabled=false',
                           path.join(browserhtml_path, 'index.html')]

        if headless:
            set_osmesa_env(args[0], env)
            args.append('-z')

        if software:
            if not is_linux():
                print("Software rendering is only supported on Linux at the moment.")
                return

            env['LIBGL_ALWAYS_SOFTWARE'] = "1"

        # Borrowed and modified from:
        # http://hg.mozilla.org/mozilla-central/file/c9cfa9b91dea/python/mozbuild/mozbuild/mach_commands.py#l883
        if debug:
            import mozdebug
            if not debugger:
                # No debugger name was provided. Look for the default ones on
                # current OS.
                debugger = mozdebug.get_default_debugger_name(
                    mozdebug.DebuggerSearch.KeepLooking)

            self.debuggerInfo = mozdebug.get_debugger_info(debugger)
            if not self.debuggerInfo:
                print("Could not find a suitable debugger in your PATH.")
                return 1

            command = self.debuggerInfo.path
            if debugger == 'gdb' or debugger == 'lldb':
                rustCommand = 'rust-' + debugger
                try:
                    subprocess.check_call([rustCommand, '--version'], env=env, stdout=open(os.devnull, 'w'))
                except (OSError, subprocess.CalledProcessError):
                    pass
                else:
                    command = rustCommand

            # Prepend the debugger args.
            args = ([command] + self.debuggerInfo.args +
                    args + params)
        else:
            args = args + params

        try:
            check_call(args, env=env)
        except subprocess.CalledProcessError as e:
            print("Servo exited with return value %d" % e.returncode)
            return e.returncode
        except OSError as e:
            if e.errno == 2:
                print("Servo Binary can't be found! Run './mach build'"
                      " and try again!")
            else:
                raise e
Example #17
0
    def debug(self, params, remote, background, debugger, debugparams,
              slowscript):
        # Parameters come from the CLI. We need to convert them before their use.
        if debugparams:
            import pymake.process
            argv, badchar = pymake.process.clinetoargv(debugparams,
                                                       os.getcwd())
            if badchar:
                print(
                    "The +debugparams you passed require a real shell to parse them."
                )
                print("(We can't handle the %r character.)" % (badchar, ))
                return 1
            debugparams = argv

        import mozdebug

        if not debugger:
            # No debugger name was provided. Look for the default ones on current OS.
            debugger = mozdebug.get_default_debugger_name(
                mozdebug.DebuggerSearch.KeepLooking)

        self.debuggerInfo = mozdebug.get_debugger_info(debugger, debugparams)

        # We could not find the information about the desired debugger.
        if not self.debuggerInfo:
            print("Could not find a suitable debugger in your PATH.")
            return 1

        extra_env = {'MOZ_CRASHREPORTER_DISABLE': '1'}

        binpath = None

        try:
            binpath = self.get_binary_path('app')
        except Exception as e:
            print("It looks like your program isn't built.",
                  "You can run |mach build| to build it.")
            print(e)
            return 1

        # Build the list of arguments to pass to run_process
        args = [self.debuggerInfo.path] + self.debuggerInfo.args
        args.append(binpath)

        if not remote:
            args.append('-no-remote')
        if not background and sys.platform == 'darwin':
            args.append('-foreground')
        if params:
            args.extend(params)
        if '-profile' not in params and '-P' not in params:
            path = os.path.join(self.topobjdir, 'tmp', 'scratch_user')
            if not os.path.isdir(path):
                os.makedirs(path)
            args.append('-profile')
            args.append(path)
        if not slowscript:
            extra_env['JS_DISABLE_SLOW_SCRIPT_SIGNALS'] = '1'
        return self.run_process(args=args,
                                append_env=extra_env,
                                ensure_exit_code=False,
                                pass_thru=True)
def check_args(kwargs):
    set_from_config(kwargs)

    if kwargs["product"] is None:
        kwargs["product"] = "firefox"

    if kwargs["manifest_update"] is None:
        kwargs["manifest_update"] = True

    if "sauce" in kwargs["product"]:
        kwargs["pause_after_test"] = False

    if kwargs["test_list"]:
        if kwargs["include"] is not None:
            kwargs["include"].extend(kwargs["test_list"])
        else:
            kwargs["include"] = kwargs["test_list"]

    if kwargs["run_info"] is None:
        kwargs["run_info"] = kwargs["config_path"]

    if kwargs["this_chunk"] > 1:
        require_arg(kwargs, "total_chunks", lambda x: x >= kwargs["this_chunk"])

    if kwargs["chunk_type"] is None:
        if kwargs["total_chunks"] > 1:
            kwargs["chunk_type"] = "dir_hash"
        else:
            kwargs["chunk_type"] = "none"

    if kwargs["processes"] is None:
        kwargs["processes"] = 1

    if kwargs["debugger"] is not None:
        import mozdebug
        if kwargs["debugger"] == "__default__":
            kwargs["debugger"] = mozdebug.get_default_debugger_name()
        debug_info = mozdebug.get_debugger_info(kwargs["debugger"],
                                                kwargs["debugger_args"])
        if debug_info and debug_info.interactive:
            if kwargs["processes"] != 1:
                kwargs["processes"] = 1
            kwargs["no_capture_stdio"] = True
        kwargs["debug_info"] = debug_info
    else:
        kwargs["debug_info"] = None

    if kwargs["binary"] is not None:
        if not os.path.exists(kwargs["binary"]):
            print("Binary path %s does not exist" % kwargs["binary"], file=sys.stderr)
            sys.exit(1)

    if kwargs["ssl_type"] is None:
        if None not in (kwargs["ca_cert_path"], kwargs["host_cert_path"], kwargs["host_key_path"]):
            kwargs["ssl_type"] = "pregenerated"
        elif exe_path(kwargs["openssl_binary"]) is not None:
            kwargs["ssl_type"] = "openssl"
        else:
            kwargs["ssl_type"] = "none"

    if kwargs["ssl_type"] == "pregenerated":
        require_arg(kwargs, "ca_cert_path", lambda x:os.path.exists(x))
        require_arg(kwargs, "host_cert_path", lambda x:os.path.exists(x))
        require_arg(kwargs, "host_key_path", lambda x:os.path.exists(x))

    elif kwargs["ssl_type"] == "openssl":
        path = exe_path(kwargs["openssl_binary"])
        if path is None:
            print("openssl-binary argument missing or not a valid executable", file=sys.stderr)
            sys.exit(1)
        kwargs["openssl_binary"] = path

    if kwargs["ssl_type"] != "none" and kwargs["product"] == "firefox" and kwargs["certutil_binary"]:
        path = exe_path(kwargs["certutil_binary"])
        if path is None:
            print("certutil-binary argument missing or not a valid executable", file=sys.stderr)
            sys.exit(1)
        kwargs["certutil_binary"] = path

    if kwargs['extra_prefs']:
        # If a single pref is passed in as a string, make it a list
        if type(kwargs['extra_prefs']) in (str, unicode):
            kwargs['extra_prefs'] = [kwargs['extra_prefs']]
        missing = any('=' not in prefarg for prefarg in kwargs['extra_prefs'])
        if missing:
            print("Preferences via --setpref must be in key=value format", file=sys.stderr)
            sys.exit(1)
        kwargs['extra_prefs'] = [tuple(prefarg.split('=', 1)) for prefarg in
                                 kwargs['extra_prefs']]

    if kwargs["reftest_internal"] is None:
        kwargs["reftest_internal"] = True

    if kwargs["lsan_dir"] is None:
        kwargs["lsan_dir"] = kwargs["prefs_root"]

    if kwargs["reftest_screenshot"] is None:
        kwargs["reftest_screenshot"] = "unexpected"

    return kwargs
Example #19
0
    def run(self, params, remote, background, noprofile, debug, debugger,
        debugparams, slowscript, dmd, mode, sample_below, max_frames,
        show_dump_stats):

        try:
            binpath = self.get_binary_path('app')
        except Exception as e:
            print("It looks like your program isn't built.",
                "You can run |mach build| to build it.")
            print(e)
            return 1

        args = [binpath]

        if params:
            args.extend(params)

        if not remote:
            args.append('-no-remote')

        if not background and sys.platform == 'darwin':
            args.append('-foreground')

        no_profile_option_given = \
            all(p not in params for p in ['-profile', '--profile', '-P'])
        if no_profile_option_given and not noprofile:
            path = os.path.join(self.topobjdir, 'tmp', 'scratch_user')
            if not os.path.isdir(path):
                os.makedirs(path)
            args.append('-profile')
            args.append(path)

        extra_env = {}

        if debug or debugger or debugparams:
            import mozdebug
            if not debugger:
                # No debugger name was provided. Look for the default ones on
                # current OS.
                debugger = mozdebug.get_default_debugger_name(mozdebug.DebuggerSearch.KeepLooking)

            if debugger:
                self.debuggerInfo = mozdebug.get_debugger_info(debugger, debugparams)
                if not self.debuggerInfo:
                    print("Could not find a suitable debugger in your PATH.")
                    return 1

            # Parameters come from the CLI. We need to convert them before
            # their use.
            if debugparams:
                import pymake.process
                argv, badchar = pymake.process.clinetoargv(debugparams, os.getcwd())
                if badchar:
                    print("The --debugparams you passed require a real shell to parse them.")
                    print("(We can't handle the %r character.)" % (badchar,))
                    return 1
                debugparams = argv;

            if not slowscript:
                extra_env['JS_DISABLE_SLOW_SCRIPT_SIGNALS'] = '1'

            extra_env['MOZ_CRASHREPORTER_DISABLE'] = '1'

            # Prepend the debugger args.
            args = [self.debuggerInfo.path] + self.debuggerInfo.args + args

        if dmd:
            dmd_params = []

            if mode:
                dmd_params.append('--mode=' + mode)
            if sample_below:
                dmd_params.append('--sample-below=' + sample_below)
            if max_frames:
                dmd_params.append('--max-frames=' + max_frames)
            if show_dump_stats:
                dmd_params.append('--show-dump-stats=yes')

            bin_dir = os.path.dirname(binpath)
            lib_name = self.substs['DLL_PREFIX'] + 'dmd' + self.substs['DLL_SUFFIX']
            dmd_lib = os.path.join(bin_dir, lib_name)
            if not os.path.exists(dmd_lib):
                print("Please build with |--enable-dmd| to use DMD.")
                return 1

            env_vars = {
                "Darwin": {
                    "DYLD_INSERT_LIBRARIES": dmd_lib,
                    "LD_LIBRARY_PATH": bin_dir,
                },
                "Linux": {
                    "LD_PRELOAD": dmd_lib,
                    "LD_LIBRARY_PATH": bin_dir,
                },
                "WINNT": {
                    "MOZ_REPLACE_MALLOC_LIB": dmd_lib,
                },
            }

            arch = self.substs['OS_ARCH']

            if dmd_params:
                env_vars[arch]["DMD"] = " ".join(dmd_params)

            extra_env.update(env_vars.get(arch, {}))

        return self.run_process(args=args, ensure_exit_code=False,
            pass_thru=True, append_env=extra_env)
Example #20
0
def check_args(kwargs):
    set_from_config(kwargs)

    for test_paths in kwargs["test_paths"].itervalues():
        if not ("tests_path" in test_paths and "metadata_path" in test_paths):
            print "Fatal: must specify both a test path and metadata path"
            sys.exit(1)
        for key, path in test_paths.iteritems():
            name = key.split("_", 1)[0]

            if not os.path.exists(path):
                print "Fatal: %s path %s does not exist" % (name, path)
                sys.exit(1)

            if not os.path.isdir(path):
                print "Fatal: %s path %s is not a directory" % (name, path)
                sys.exit(1)

    if kwargs["product"] is None:
        kwargs["product"] = "firefox"

    if kwargs["test_list"]:
        if kwargs["include"] is not None:
            kwargs["include"].extend(kwargs["test_list"])
        else:
            kwargs["include"] = kwargs["test_list"]

    if kwargs["run_info"] is None:
        kwargs["run_info"] = kwargs["config_path"]

    if kwargs["this_chunk"] > 1:
        require_arg(kwargs, "total_chunks",
                    lambda x: x >= kwargs["this_chunk"])

    if kwargs["chunk_type"] is None:
        if kwargs["total_chunks"] > 1:
            kwargs["chunk_type"] = "dir_hash"
        else:
            kwargs["chunk_type"] = "none"

    if kwargs["processes"] is None:
        kwargs["processes"] = 1

    if kwargs["debugger"] is not None:
        import mozdebug
        if kwargs["debugger"] == "__default__":
            kwargs["debugger"] = mozdebug.get_default_debugger_name()
        debug_info = mozdebug.get_debugger_info(kwargs["debugger"],
                                                kwargs["debugger_args"])
        if debug_info and debug_info.interactive:
            if kwargs["processes"] != 1:
                kwargs["processes"] = 1
            kwargs["no_capture_stdio"] = True
        kwargs["debug_info"] = debug_info
    else:
        kwargs["debug_info"] = None

    if kwargs["binary"] is not None:
        if not os.path.exists(kwargs["binary"]):
            print >> sys.stderr, "Binary path %s does not exist" % kwargs[
                "binary"]
            sys.exit(1)

    if kwargs["ssl_type"] is None:
        if None not in (kwargs["ca_cert_path"], kwargs["host_cert_path"],
                        kwargs["host_key_path"]):
            kwargs["ssl_type"] = "pregenerated"
        elif exe_path(kwargs["openssl_binary"]) is not None:
            kwargs["ssl_type"] = "openssl"
        else:
            kwargs["ssl_type"] = "none"

    if kwargs["ssl_type"] == "pregenerated":
        require_arg(kwargs, "ca_cert_path", lambda x: os.path.exists(x))
        require_arg(kwargs, "host_cert_path", lambda x: os.path.exists(x))
        require_arg(kwargs, "host_key_path", lambda x: os.path.exists(x))

    elif kwargs["ssl_type"] == "openssl":
        path = exe_path(kwargs["openssl_binary"])
        if path is None:
            print >> sys.stderr, "openssl-binary argument missing or not a valid executable"
            sys.exit(1)
        kwargs["openssl_binary"] = path

    if kwargs["ssl_type"] != "none" and kwargs["product"] == "firefox":
        path = exe_path(kwargs["certutil_binary"])
        if path is None:
            print >> sys.stderr, "certutil-binary argument missing or not a valid executable"
            sys.exit(1)
        kwargs["certutil_binary"] = path

    return kwargs
    def run_mochitest_general(self, flavor=None, test_objects=None, resolve_tests=True, **kwargs):
        from mochitest_options import ALL_FLAVORS
        from mozlog.commandline import setup_logging
        from mozlog.handlers import StreamHandler
        from moztest.resolve import get_suite_definition

        # TODO: This is only strictly necessary while mochitest is using Python
        # 2 and can be removed once the command is migrated to Python 3.
        self.activate_virtualenv()

        buildapp = None
        for app in SUPPORTED_APPS:
            if conditions.is_buildapp_in(self, apps=[app]):
                buildapp = app
                break

        flavors = None
        if flavor:
            for fname, fobj in ALL_FLAVORS.iteritems():
                if flavor in fobj['aliases']:
                    if buildapp not in fobj['enabled_apps']:
                        continue
                    flavors = [fname]
                    break
        else:
            flavors = [f for f, v in ALL_FLAVORS.iteritems() if buildapp in v['enabled_apps']]

        from mozbuild.controller.building import BuildDriver
        self._ensure_state_subdir_exists('.')

        test_paths = kwargs['test_paths']
        kwargs['test_paths'] = []

        if kwargs.get('debugger', None):
            import mozdebug
            if not mozdebug.get_debugger_info(kwargs.get('debugger')):
                sys.exit(1)

        mochitest = self._spawn(MochitestRunner)
        tests = []
        if resolve_tests:
            tests = mochitest.resolve_tests(test_paths, test_objects, cwd=self._mach_context.cwd)

        if not kwargs.get('log'):
            # Create shared logger
            format_args = {'level': self._mach_context.settings['test']['level']}
            if len(tests) == 1:
                format_args['verbose'] = True
                format_args['compact'] = False

            default_format = self._mach_context.settings['test']['format']
            kwargs['log'] = setup_logging('mach-mochitest', kwargs, {default_format: sys.stdout},
                                          format_args)
            for handler in kwargs['log'].handlers:
                if isinstance(handler, StreamHandler):
                    handler.formatter.inner.summary_on_shutdown = True

        driver = self._spawn(BuildDriver)
        driver.install_tests()

        subsuite = kwargs.get('subsuite')
        if subsuite == 'default':
            kwargs['subsuite'] = None

        suites = defaultdict(list)
        unsupported = set()
        for test in tests:
            # Filter out non-mochitests and unsupported flavors.
            if test['flavor'] not in ALL_FLAVORS:
                continue

            key = (test['flavor'], test.get('subsuite', ''))
            if test['flavor'] not in flavors:
                unsupported.add(key)
                continue

            if subsuite == 'default':
                # "--subsuite default" means only run tests that don't have a subsuite
                if test.get('subsuite'):
                    unsupported.add(key)
                    continue
            elif subsuite and test.get('subsuite', '') != subsuite:
                unsupported.add(key)
                continue

            suites[key].append(test)

        if ('mochitest', 'media') in suites:
            req = os.path.join('testing', 'tools', 'websocketprocessbridge',
                               'websocketprocessbridge_requirements.txt')
            self.virtualenv_manager.activate()
            self.virtualenv_manager.install_pip_requirements(req, require_hashes=False)

            # sys.executable is used to start the websocketprocessbridge, though for some
            # reason it doesn't get set when calling `activate_this.py` in the virtualenv.
            sys.executable = self.virtualenv_manager.python_path

        # This is a hack to introduce an option in mach to not send
        # filtered tests to the mochitest harness. Mochitest harness will read
        # the master manifest in that case.
        if not resolve_tests:
            for flavor in flavors:
                key = (flavor, kwargs.get('subsuite'))
                suites[key] = []

        if not suites:
            # Make it very clear why no tests were found
            if not unsupported:
                print(TESTS_NOT_FOUND.format('\n'.join(
                    sorted(list(test_paths or test_objects)))))
                return 1

            msg = []
            for f, s in unsupported:
                fobj = ALL_FLAVORS[f]
                apps = fobj['enabled_apps']
                name = fobj['aliases'][0]
                if s:
                    name = '{} --subsuite {}'.format(name, s)

                if buildapp not in apps:
                    reason = 'requires {}'.format(' or '.join(apps))
                else:
                    reason = 'excluded by the command line'
                msg.append('    mochitest -f {} ({})'.format(name, reason))
            print(SUPPORTED_TESTS_NOT_FOUND.format(
                buildapp, '\n'.join(sorted(msg))))
            return 1

        if buildapp == 'android':
            from mozrunner.devices.android_device import (verify_android_device, InstallIntent)
            app = kwargs.get('app')
            if not app:
                app = "org.mozilla.geckoview.test"
            device_serial = kwargs.get('deviceSerial')
            install = InstallIntent.NO if kwargs.get('no_install') else InstallIntent.YES

            # verify installation
            verify_android_device(self, install=install, xre=False, network=True,
                                  app=app, device_serial=device_serial)
            run_mochitest = mochitest.run_android_test
        else:
            run_mochitest = mochitest.run_desktop_test

        overall = None
        for (flavor, subsuite), tests in sorted(suites.items()):
            suite_name, suite = get_suite_definition(flavor, subsuite)
            if 'test_paths' in suite['kwargs']:
                del suite['kwargs']['test_paths']

            harness_args = kwargs.copy()
            harness_args.update(suite['kwargs'])
            # Pass in the full suite name as defined in moztest/resolve.py in case
            # chunk-by-runtime is called, in which case runtime information for
            # specific mochitest suite has to be loaded. See Bug 1637463.
            harness_args.update({'suite_name': suite_name})

            result = run_mochitest(
                self._mach_context,
                tests=tests,
                **harness_args)

            if result:
                overall = result

            # Halt tests on keyboard interrupt
            if result == -1:
                break

        # Only shutdown the logger if we created it
        if kwargs['log'].name == 'mach-mochitest':
            kwargs['log'].shutdown()

        return overall
Example #22
0
def test(command_context, what, extra_args, **log_args):
    """Run tests from names or paths.

    mach test accepts arguments specifying which tests to run. Each argument
    can be:

    * The path to a test file
    * A directory containing tests
    * A test suite name
    * An alias to a test suite name (codes used on TreeHerder)

    When paths or directories are given, they are first resolved to test
    files known to the build system.

    If resolved tests belong to more than one test type/flavor/harness,
    the harness for each relevant type/flavor will be invoked. e.g. if
    you specify a directory with xpcshell and browser chrome mochitests,
    both harnesses will be invoked.

    Warning: `mach test` does not automatically re-build.
    Please remember to run `mach build` when necessary.

    EXAMPLES

    Run all test files in the devtools/client/shared/redux/middleware/xpcshell/
    directory:

    `./mach test devtools/client/shared/redux/middleware/xpcshell/`

    The below command prints a short summary of results instead of
    the default more verbose output.
    Do not forget the - (minus sign) after --log-grouped!

    `./mach test --log-grouped - devtools/client/shared/redux/middleware/xpcshell/`
    """
    from mozlog.commandline import setup_logging
    from mozlog.handlers import StreamHandler
    from moztest.resolve import get_suite_definition, TestResolver, TEST_SUITES

    resolver = command_context._spawn(TestResolver)
    run_suites, run_tests = resolver.resolve_metadata(what)

    if not run_suites and not run_tests:
        print(UNKNOWN_TEST)
        return 1

    if log_args.get("debugger", None):
        import mozdebug

        if not mozdebug.get_debugger_info(log_args.get("debugger")):
            sys.exit(1)
        extra_args_debugger_notation = "=".join(
            ["--debugger", log_args.get("debugger")])
        if extra_args:
            extra_args.append(extra_args_debugger_notation)
        else:
            extra_args = [extra_args_debugger_notation]

    # Create shared logger
    format_args = {
        "level": command_context._mach_context.settings["test"]["level"]
    }
    if not run_suites and len(run_tests) == 1:
        format_args["verbose"] = True
        format_args["compact"] = False

    default_format = command_context._mach_context.settings["test"]["format"]
    log = setup_logging("mach-test", log_args, {default_format: sys.stdout},
                        format_args)
    for handler in log.handlers:
        if isinstance(handler, StreamHandler):
            handler.formatter.inner.summary_on_shutdown = True

    status = None
    for suite_name in run_suites:
        suite = TEST_SUITES[suite_name]
        kwargs = suite["kwargs"]
        kwargs["log"] = log
        kwargs.setdefault("subsuite", None)

        if "mach_command" in suite:
            res = command_context._mach_context.commands.dispatch(
                suite["mach_command"],
                command_context._mach_context,
                argv=extra_args,
                **kwargs,
            )
            if res:
                status = res

    buckets = {}
    for test in run_tests:
        key = (test["flavor"], test.get("subsuite", ""))
        buckets.setdefault(key, []).append(test)

    for (flavor, subsuite), tests in sorted(buckets.items()):
        _, m = get_suite_definition(flavor, subsuite)
        if "mach_command" not in m:
            substr = "-{}".format(subsuite) if subsuite else ""
            print(UNKNOWN_FLAVOR % (flavor, substr))
            status = 1
            continue

        kwargs = dict(m["kwargs"])
        kwargs["log"] = log
        kwargs.setdefault("subsuite", None)

        res = command_context._mach_context.commands.dispatch(
            m["mach_command"],
            command_context._mach_context,
            argv=extra_args,
            test_objects=tests,
            **kwargs,
        )
        if res:
            status = res

    log.shutdown()
    return status
Example #23
0
def run(command_context, binary, params, debug, debugger, debugger_args):
    try:
        binpath = command_context.get_binary_path("geckodriver")
    except BinaryNotFoundException as e:
        command_context.log(logging.ERROR, "geckodriver", {"error": str(e)},
                            "ERROR: {error}")
        command_context.log(
            logging.INFO,
            "geckodriver",
            {},
            "It looks like geckodriver isn't built. "
            "Add ac_add_options --enable-geckodriver to your "
            "mozconfig "
            "and run |./mach build| to build it.",
        )
        return 1

    args = [binpath]

    if params:
        args.extend(params)

    if binary is None:
        try:
            binary = command_context.get_binary_path("app")
        except BinaryNotFoundException as e:
            command_context.log(logging.ERROR, "geckodriver",
                                {"error": str(e)}, "ERROR: {error}")
            command_context.log(logging.INFO, "geckodriver",
                                {"help": e.help()}, "{help}")
            return 1

    args.extend(["--binary", binary])

    if debug or debugger or debugger_args:
        if "INSIDE_EMACS" in os.environ:
            command_context.log_manager.terminal_handler.setLevel(
                logging.WARNING)

        import mozdebug

        if not debugger:
            # No debugger name was provided. Look for the default ones on
            # current OS.
            debugger = mozdebug.get_default_debugger_name(
                mozdebug.DebuggerSearch.KeepLooking)

        if debugger:
            debuggerInfo = mozdebug.get_debugger_info(debugger, debugger_args)
            if not debuggerInfo:
                print("Could not find a suitable debugger in your PATH.")
                return 1

        # Parameters come from the CLI. We need to convert them before
        # their use.
        if debugger_args:
            from mozbuild import shellutil

            try:
                debugger_args = shellutil.split(debugger_args)
            except shellutil.MetaCharacterException as e:
                print(
                    "The --debugger-args you passed require a real shell to parse them."
                )
                print("(We can't handle the %r character.)" % e.char)
                return 1

        # Prepend the debugger args.
        args = [debuggerInfo.path] + debuggerInfo.args + args

    return command_context.run_process(args=args,
                                       ensure_exit_code=False,
                                       pass_thru=True)
Example #24
0
    def run_mochitest_general(self,
                              flavor=None,
                              test_objects=None,
                              resolve_tests=True,
                              **kwargs):
        from mochitest_options import ALL_FLAVORS
        from mozlog.commandline import setup_logging
        from mozlog.handlers import StreamHandler
        from moztest.resolve import get_suite_definition

        # TODO: This is only strictly necessary while mochitest is using Python
        # 2 and can be removed once the command is migrated to Python 3.
        self.activate_virtualenv()

        buildapp = None
        for app in SUPPORTED_APPS:
            if conditions.is_buildapp_in(self, apps=[app]):
                buildapp = app
                break

        flavors = None
        if flavor:
            for fname, fobj in six.iteritems(ALL_FLAVORS):
                if flavor in fobj["aliases"]:
                    if buildapp not in fobj["enabled_apps"]:
                        continue
                    flavors = [fname]
                    break
        else:
            flavors = [
                f for f, v in six.iteritems(ALL_FLAVORS)
                if buildapp in v["enabled_apps"]
            ]

        from mozbuild.controller.building import BuildDriver

        self._ensure_state_subdir_exists(".")

        test_paths = kwargs["test_paths"]
        kwargs["test_paths"] = []

        if kwargs.get("debugger", None):
            import mozdebug

            if not mozdebug.get_debugger_info(kwargs.get("debugger")):
                sys.exit(1)

        mochitest = self._spawn(MochitestRunner)
        tests = []
        if resolve_tests:
            tests = mochitest.resolve_tests(test_paths,
                                            test_objects,
                                            cwd=self._mach_context.cwd)

        if not kwargs.get("log"):
            # Create shared logger
            format_args = {
                "level": self._mach_context.settings["test"]["level"]
            }
            if len(tests) == 1:
                format_args["verbose"] = True
                format_args["compact"] = False

            default_format = self._mach_context.settings["test"]["format"]
            kwargs["log"] = setup_logging("mach-mochitest", kwargs,
                                          {default_format: sys.stdout},
                                          format_args)
            for handler in kwargs["log"].handlers:
                if isinstance(handler, StreamHandler):
                    handler.formatter.inner.summary_on_shutdown = True

        driver = self._spawn(BuildDriver)
        driver.install_tests()

        subsuite = kwargs.get("subsuite")
        if subsuite == "default":
            kwargs["subsuite"] = None

        suites = defaultdict(list)
        is_webrtc_tag_present = False
        unsupported = set()
        for test in tests:
            # Check if we're running a webrtc test so we can enable webrtc
            # specific test logic later if needed.
            if "webrtc" in test.get("tags", ""):
                is_webrtc_tag_present = True

            # Filter out non-mochitests and unsupported flavors.
            if test["flavor"] not in ALL_FLAVORS:
                continue

            key = (test["flavor"], test.get("subsuite", ""))
            if test["flavor"] not in flavors:
                unsupported.add(key)
                continue

            if subsuite == "default":
                # "--subsuite default" means only run tests that don't have a subsuite
                if test.get("subsuite"):
                    unsupported.add(key)
                    continue
            elif subsuite and test.get("subsuite", "") != subsuite:
                unsupported.add(key)
                continue

            suites[key].append(test)

        # Only webrtc mochitests in the media suite need the websocketprocessbridge.
        if ("mochitest", "media") in suites and is_webrtc_tag_present:
            req = os.path.join(
                "testing",
                "tools",
                "websocketprocessbridge",
                "websocketprocessbridge_requirements_3.txt",
            )
            self.virtualenv_manager.activate()
            self.virtualenv_manager.install_pip_requirements(
                req, require_hashes=False)

            # sys.executable is used to start the websocketprocessbridge, though for some
            # reason it doesn't get set when calling `activate_this.py` in the virtualenv.
            sys.executable = self.virtualenv_manager.python_path

        # This is a hack to introduce an option in mach to not send
        # filtered tests to the mochitest harness. Mochitest harness will read
        # the master manifest in that case.
        if not resolve_tests:
            for flavor in flavors:
                key = (flavor, kwargs.get("subsuite"))
                suites[key] = []

        if not suites:
            # Make it very clear why no tests were found
            if not unsupported:
                print(
                    TESTS_NOT_FOUND.format("\n".join(
                        sorted(list(test_paths or test_objects)))))
                return 1

            msg = []
            for f, s in unsupported:
                fobj = ALL_FLAVORS[f]
                apps = fobj["enabled_apps"]
                name = fobj["aliases"][0]
                if s:
                    name = "{} --subsuite {}".format(name, s)

                if buildapp not in apps:
                    reason = "requires {}".format(" or ".join(apps))
                else:
                    reason = "excluded by the command line"
                msg.append("    mochitest -f {} ({})".format(name, reason))
            print(
                SUPPORTED_TESTS_NOT_FOUND.format(buildapp,
                                                 "\n".join(sorted(msg))))
            return 1

        if buildapp == "android":
            from mozrunner.devices.android_device import (
                verify_android_device,
                InstallIntent,
            )

            app = kwargs.get("app")
            if not app:
                app = "org.mozilla.geckoview.test"
            device_serial = kwargs.get("deviceSerial")
            install = (InstallIntent.NO
                       if kwargs.get("no_install") else InstallIntent.YES)

            # verify installation
            verify_android_device(
                self,
                install=install,
                xre=False,
                network=True,
                app=app,
                device_serial=device_serial,
            )
            run_mochitest = mochitest.run_android_test
        else:
            run_mochitest = mochitest.run_desktop_test

        overall = None
        for (flavor, subsuite), tests in sorted(suites.items()):
            suite_name, suite = get_suite_definition(flavor, subsuite)
            if "test_paths" in suite["kwargs"]:
                del suite["kwargs"]["test_paths"]

            harness_args = kwargs.copy()
            harness_args.update(suite["kwargs"])
            # Pass in the full suite name as defined in moztest/resolve.py in case
            # chunk-by-runtime is called, in which case runtime information for
            # specific mochitest suite has to be loaded. See Bug 1637463.
            harness_args.update({"suite_name": suite_name})

            result = run_mochitest(self._mach_context,
                                   tests=tests,
                                   **harness_args)

            if result:
                overall = result

            # Halt tests on keyboard interrupt
            if result == -1:
                break

        # Only shutdown the logger if we created it
        if kwargs["log"].name == "mach-mochitest":
            kwargs["log"].shutdown()

        return overall
Example #25
0
    def test(self, what, extra_args, **log_args):
        """Run tests from names or paths.

        mach test accepts arguments specifying which tests to run. Each argument
        can be:

        * The path to a test file
        * A directory containing tests
        * A test suite name
        * An alias to a test suite name (codes used on TreeHerder)

        If no input is provided, tests will be run based on files changed in
        the local tree. Relevant tests, tags, or flavors are determined by
        IMPACTED_TESTS annotations in moz.build files relevant to the
        changed files.

        When paths or directories are given, they are first resolved to test
        files known to the build system.

        If resolved tests belong to more than one test type/flavor/harness,
        the harness for each relevant type/flavor will be invoked. e.g. if
        you specify a directory with xpcshell and browser chrome mochitests,
        both harnesses will be invoked.
        """
        from mozlog.commandline import setup_logging
        from mozlog.handlers import StreamHandler
        from moztest.resolve import get_suite_definition, TestResolver, TEST_SUITES

        resolver = self._spawn(TestResolver)
        run_suites, run_tests = resolver.resolve_metadata(what)

        if not run_suites and not run_tests:
            print(UNKNOWN_TEST)
            return 1

        if log_args.get('debugger', None):
            import mozdebug
            if not mozdebug.get_debugger_info(log_args.get('debugger')):
                sys.exit(1)
            extra_args_debugger_notation = '='.join(
                ['--debugger', log_args.get('debugger')]).encode('ascii')
            if extra_args:
                extra_args.append(extra_args_debugger_notation)
            else:
                extra_args = [extra_args_debugger_notation]

        # Create shared logger
        format_args = {'level': self._mach_context.settings['test']['level']}
        if not run_suites and len(run_tests) == 1:
            format_args['verbose'] = True
            format_args['compact'] = False

        default_format = self._mach_context.settings['test']['format']
        log = setup_logging('mach-test', log_args,
                            {default_format: sys.stdout}, format_args)
        for handler in log.handlers:
            if isinstance(handler, StreamHandler):
                handler.formatter.inner.summary_on_shutdown = True

        status = None
        for suite_name in run_suites:
            suite = TEST_SUITES[suite_name]
            kwargs = suite['kwargs']
            kwargs['log'] = log

            if 'mach_command' in suite:
                res = self._mach_context.commands.dispatch(
                    suite['mach_command'],
                    self._mach_context,
                    argv=extra_args,
                    **kwargs)
                if res:
                    status = res

        buckets = {}
        for test in run_tests:
            key = (test['flavor'], test.get('subsuite', ''))
            buckets.setdefault(key, []).append(test)

        for (flavor, subsuite), tests in sorted(buckets.items()):
            _, m = get_suite_definition(flavor, subsuite)
            if 'mach_command' not in m:
                substr = '-{}'.format(subsuite) if subsuite else ''
                print(UNKNOWN_FLAVOR % (flavor, substr))
                status = 1
                continue

            kwargs = dict(m['kwargs'])
            kwargs['log'] = log

            res = self._mach_context.commands.dispatch(m['mach_command'],
                                                       self._mach_context,
                                                       argv=extra_args,
                                                       test_objects=tests,
                                                       **kwargs)
            if res:
                status = res

        log.shutdown()
        return status
Example #26
0
def check_args(kwargs):
    set_from_config(kwargs)

    if kwargs["product"] is None:
        kwargs["product"] = "firefox"

    if kwargs["manifest_update"] is None:
        kwargs["manifest_update"] = True

    if "sauce" in kwargs["product"]:
        kwargs["pause_after_test"] = False

    if kwargs["test_list"]:
        if kwargs["include"] is not None:
            kwargs["include"].extend(kwargs["test_list"])
        else:
            kwargs["include"] = kwargs["test_list"]

    if kwargs["run_info"] is None:
        kwargs["run_info"] = kwargs["config_path"]

    if kwargs["this_chunk"] > 1:
        require_arg(kwargs, "total_chunks",
                    lambda x: x >= kwargs["this_chunk"])

    if kwargs["chunk_type"] is None:
        if kwargs["total_chunks"] > 1:
            kwargs["chunk_type"] = "dir_hash"
        else:
            kwargs["chunk_type"] = "none"

    if kwargs["test_groups_file"] is not None:
        if kwargs["run_by_dir"] is not False:
            print("Can't pass --test-groups and --run-by-dir")
            sys.exit(1)
        if not os.path.exists(kwargs["test_groups_file"]):
            print("--test-groups file %s not found" %
                  kwargs["test_groups_file"])
            sys.exit(1)

    if kwargs["processes"] is None:
        kwargs["processes"] = 1

    if kwargs["debugger"] is not None:
        import mozdebug
        if kwargs["debugger"] == "__default__":
            kwargs["debugger"] = mozdebug.get_default_debugger_name()
        debug_info = mozdebug.get_debugger_info(kwargs["debugger"],
                                                kwargs["debugger_args"])
        if debug_info and debug_info.interactive:
            if kwargs["processes"] != 1:
                kwargs["processes"] = 1
            kwargs["no_capture_stdio"] = True
        kwargs["debug_info"] = debug_info
    else:
        kwargs["debug_info"] = None

    if kwargs["binary"] is not None:
        if not os.path.exists(kwargs["binary"]):
            print("Binary path %s does not exist" % kwargs["binary"],
                  file=sys.stderr)
            sys.exit(1)

    if kwargs["ssl_type"] is None:
        if None not in (kwargs["ca_cert_path"], kwargs["host_cert_path"],
                        kwargs["host_key_path"]):
            kwargs["ssl_type"] = "pregenerated"
        elif exe_path(kwargs["openssl_binary"]) is not None:
            kwargs["ssl_type"] = "openssl"
        else:
            kwargs["ssl_type"] = "none"

    if kwargs["ssl_type"] == "pregenerated":
        require_arg(kwargs, "ca_cert_path", lambda x: os.path.exists(x))
        require_arg(kwargs, "host_cert_path", lambda x: os.path.exists(x))
        require_arg(kwargs, "host_key_path", lambda x: os.path.exists(x))

    elif kwargs["ssl_type"] == "openssl":
        path = exe_path(kwargs["openssl_binary"])
        if path is None:
            print("openssl-binary argument missing or not a valid executable",
                  file=sys.stderr)
            sys.exit(1)
        kwargs["openssl_binary"] = path

    if kwargs["ssl_type"] != "none" and kwargs[
            "product"] == "firefox" and kwargs["certutil_binary"]:
        path = exe_path(kwargs["certutil_binary"])
        if path is None:
            print("certutil-binary argument missing or not a valid executable",
                  file=sys.stderr)
            sys.exit(1)
        kwargs["certutil_binary"] = path

    if kwargs['extra_prefs']:
        missing = any('=' not in prefarg for prefarg in kwargs['extra_prefs'])
        if missing:
            print("Preferences via --setpref must be in key=value format",
                  file=sys.stderr)
            sys.exit(1)
        kwargs['extra_prefs'] = [
            tuple(prefarg.split('=', 1)) for prefarg in kwargs['extra_prefs']
        ]

    if kwargs["reftest_internal"] is None:
        kwargs["reftest_internal"] = True

    if kwargs["reftest_screenshot"] is None:
        kwargs["reftest_screenshot"] = "unexpected" if not kwargs[
            "debug_test"] else "always"

    if kwargs["enable_webrender"] is None:
        kwargs["enable_webrender"] = False

    if kwargs["preload_browser"] is None:
        # Default to preloading a gecko instance if we're only running a single process
        kwargs["preload_browser"] = kwargs["processes"] == 1

    return kwargs
Example #27
0
    def runSerialTests(self, manifests, options, cmdargs=None):
        debuggerInfo = None
        if options.debugger:
            debuggerInfo = mozdebug.get_debugger_info(options.debugger, options.debuggerArgs,
                                                      options.debuggerInteractive)

        tests = None
        if self.parse_manifest:
            tests = self.getActiveTests(manifests, options)

            ids = [t['identifier'] for t in tests]
            self.log.suite_start(ids, name=options.suite)

        startAfter = None  # When the previous run crashed, we skip the tests we ran before
        prevStartAfter = None
        for i in itertools.count():
            status, startAfter, results = self.runApp(
                options,
                tests=tests,
                manifests=manifests,
                cmdargs=cmdargs,
                # We generally want the JS harness or marionette
                # to handle timeouts if they can.
                # The default JS harness timeout is currently
                # 300 seconds (default options.timeout).
                # The default Marionette socket timeout is
                # currently 360 seconds.
                # Give the JS harness extra time to deal with
                # its own timeouts and try to usually exceed
                # the 360 second marionette socket timeout.
                # See bug 479518 and bug 1414063.
                timeout=options.timeout + 70.0,
                symbolsPath=options.symbolsPath,
                debuggerInfo=debuggerInfo
            )
            mozleak.process_leak_log(self.leakLogFile,
                                     leak_thresholds=options.leakThresholds,
                                     stack_fixer=get_stack_fixer_function(options.utilityPath,
                                                                          options.symbolsPath))

            if status == 0:
                break

            if startAfter == self.TEST_SEEN_FINAL:
                self.log.info("Finished running all tests, skipping resume "
                              "despite non-zero status code: %s" % status)
                break

            if startAfter is not None and options.shuffle:
                self.log.error("Can not resume from a crash with --shuffle "
                               "enabled. Please consider disabling --shuffle")
                break
            if startAfter is not None and options.maxRetries <= i:
                self.log.error("Hit maximum number of allowed retries ({}) "
                               "in the test run".format(options.maxRetries))
                break
            if startAfter == prevStartAfter:
                # If the test stuck on the same test, or there the crashed
                # test appeared more then once, stop
                self.log.error("Force stop because we keep running into "
                               "test \"{}\"".format(startAfter))
                break
            prevStartAfter = startAfter
            # TODO: we need to emit an SUITE-END log if it crashed

        if self.parse_manifest:
            self.log.suite_end(extra={'results': results})
        return status
def check_args(kwargs):
    set_from_config(kwargs)

    if kwargs["product"] is None:
        kwargs["product"] = "firefox"

    if "sauce" in kwargs["product"]:
        kwargs["pause_after_test"] = False

    if kwargs["test_list"]:
        if kwargs["include"] is not None:
            kwargs["include"].extend(kwargs["test_list"])
        else:
            kwargs["include"] = kwargs["test_list"]

    if kwargs["run_info"] is None:
        kwargs["run_info"] = kwargs["config_path"]

    if kwargs["this_chunk"] > 1:
        require_arg(kwargs, "total_chunks", lambda x: x >= kwargs["this_chunk"])

    if kwargs["chunk_type"] is None:
        if kwargs["total_chunks"] > 1:
            kwargs["chunk_type"] = "dir_hash"
        else:
            kwargs["chunk_type"] = "none"

    if kwargs["processes"] is None:
        kwargs["processes"] = 1

    if kwargs["debugger"] is not None:
        import mozdebug
        if kwargs["debugger"] == "__default__":
            kwargs["debugger"] = mozdebug.get_default_debugger_name()
        debug_info = mozdebug.get_debugger_info(kwargs["debugger"],
                                                kwargs["debugger_args"])
        if debug_info and debug_info.interactive:
            if kwargs["processes"] != 1:
                kwargs["processes"] = 1
            kwargs["no_capture_stdio"] = True
        kwargs["debug_info"] = debug_info
    else:
        kwargs["debug_info"] = None

    if kwargs["binary"] is not None:
        if not os.path.exists(kwargs["binary"]):
            print >> sys.stderr, "Binary path %s does not exist" % kwargs["binary"]
            sys.exit(1)

    if kwargs["ssl_type"] is None:
        if None not in (kwargs["ca_cert_path"], kwargs["host_cert_path"], kwargs["host_key_path"]):
            kwargs["ssl_type"] = "pregenerated"
        elif exe_path(kwargs["openssl_binary"]) is not None:
            kwargs["ssl_type"] = "openssl"
        else:
            kwargs["ssl_type"] = "none"

    if kwargs["ssl_type"] == "pregenerated":
        require_arg(kwargs, "ca_cert_path", lambda x:os.path.exists(x))
        require_arg(kwargs, "host_cert_path", lambda x:os.path.exists(x))
        require_arg(kwargs, "host_key_path", lambda x:os.path.exists(x))

    elif kwargs["ssl_type"] == "openssl":
        path = exe_path(kwargs["openssl_binary"])
        if path is None:
            print >> sys.stderr, "openssl-binary argument missing or not a valid executable"
            sys.exit(1)
        kwargs["openssl_binary"] = path

    if kwargs["ssl_type"] != "none" and kwargs["product"] == "firefox" and kwargs["certutil_binary"]:
        path = exe_path(kwargs["certutil_binary"])
        if path is None:
            print >> sys.stderr, "certutil-binary argument missing or not a valid executable"
            sys.exit(1)
        kwargs["certutil_binary"] = path

    if kwargs['extra_prefs']:
        missing = any('=' not in prefarg for prefarg in kwargs['extra_prefs'])
        if missing:
            print >> sys.stderr, "Preferences via --setpref must be in key=value format"
            sys.exit(1)
        kwargs['extra_prefs'] = [tuple(prefarg.split('=', 1)) for prefarg in
                                 kwargs['extra_prefs']]

    if kwargs["reftest_internal"] is None:
        # Default to the internal reftest implementation on Linux and OSX
        kwargs["reftest_internal"] = sys.platform.startswith("linux") or sys.platform.startswith("darwin")

    return kwargs
Example #29
0
    def run(self, params, release=False, dev=False, android=None, debug=False, debugger=None, browserhtml=False):
        env = self.build_env()
        env["RUST_BACKTRACE"] = "1"

        if android is None:
            android = self.config["build"]["android"]

        if android:
            if debug:
                print("Android on-device debugging is not supported by mach yet. See")
                print("https://github.com/servo/servo/wiki/Building-for-Android#debugging-on-device")
                return
            script = [
                "am force-stop com.mozilla.servo",
                "echo servo >/sdcard/servo/android_params"
            ]
            for param in params:
                script += [
                    "echo '%s' >>/sdcard/servo/android_params" % param.replace("'", "\\'")
                ]
            script += [
                "am start com.mozilla.servo/com.mozilla.servo.MainActivity",
                "exit"
            ]
            shell = subprocess.Popen(["adb", "shell"], stdin=subprocess.PIPE)
            shell.communicate("\n".join(script) + "\n")
            return shell.wait()

        args = [self.get_binary_path(release, dev)]

        # Borrowed and modified from:
        # http://hg.mozilla.org/mozilla-central/file/c9cfa9b91dea/python/mozbuild/mozbuild/mach_commands.py#l883
        if debug:
            import mozdebug
            if not debugger:
                # No debugger name was provided. Look for the default ones on
                # current OS.
                debugger = mozdebug.get_default_debugger_name(
                    mozdebug.DebuggerSearch.KeepLooking)

            self.debuggerInfo = mozdebug.get_debugger_info(debugger)
            if not self.debuggerInfo:
                print("Could not find a suitable debugger in your PATH.")
                return 1

            command = self.debuggerInfo.path
            if debugger == 'gdb' or debugger == 'lldb':
                rustCommand = 'rust-' + debugger
                try:
                    subprocess.check_call([rustCommand, '--version'], env=env, stdout=open(os.devnull, 'w'))
                except (OSError, subprocess.CalledProcessError):
                    pass
                else:
                    command = rustCommand

            # Prepend the debugger args.
            args = ([command] + self.debuggerInfo.args +
                    args + params)
        elif browserhtml:
            browserhtml_path = find_dep_path_newest('browserhtml', args[0])
            if browserhtml_path is None:
                print("Could not find browserhtml package; perhaps you haven't built Servo.")
                return 1
            args = args + ['-w', '-b', '--pref', 'dom.mozbrowser.enabled',
                           path.join(browserhtml_path, 'out', 'index.html')]
            args = args + params
        else:
            args = args + params

        try:
            check_call(args, env=env)
        except subprocess.CalledProcessError as e:
            print("Servo exited with return value %d" % e.returncode)
            return e.returncode
        except OSError as e:
            if e.errno == 2:
                print("Servo Binary can't be found! Run './mach build'"
                      " and try again!")
            else:
                raise e
Example #30
0
    def run(self, params, release=False, dev=False, android=None, debug=False, debugger=None, browserhtml=False):
        env = self.build_env()
        env["RUST_BACKTRACE"] = "1"

        if android is None:
            android = self.config["build"]["android"]

        if android:
            if debug:
                print("Android on-device debugging is not supported by mach yet. See")
                print("https://github.com/servo/servo/wiki/Building-for-Android#debugging-on-device")
                return
            script = [
                "am force-stop com.mozilla.servo",
                "echo servo >/sdcard/servo/android_params"
            ]
            for param in params:
                script += [
                    "echo '%s' >>/sdcard/servo/android_params" % param.replace("'", "\\'")
                ]
            script += [
                "am start com.mozilla.servo/com.mozilla.servo.MainActivity",
                "exit"
            ]
            shell = subprocess.Popen(["adb", "shell"], stdin=subprocess.PIPE)
            shell.communicate("\n".join(script) + "\n")
            return shell.wait()

        args = [self.get_binary_path(release, dev)]

        # Borrowed and modified from:
        # http://hg.mozilla.org/mozilla-central/file/c9cfa9b91dea/python/mozbuild/mozbuild/mach_commands.py#l883
        if debug:
            import mozdebug
            if not debugger:
                # No debugger name was provided. Look for the default ones on
                # current OS.
                debugger = mozdebug.get_default_debugger_name(
                    mozdebug.DebuggerSearch.KeepLooking)

            self.debuggerInfo = mozdebug.get_debugger_info(debugger)
            if not self.debuggerInfo:
                print("Could not find a suitable debugger in your PATH.")
                return 1

            command = self.debuggerInfo.path
            if debugger == 'gdb' or debugger == 'lldb':
                rustCommand = 'rust-' + debugger
                try:
                    subprocess.check_call([rustCommand, '--version'], env=env, stdout=open(os.devnull, 'w'))
                    command = rustCommand
                except (OSError, subprocess.CalledProcessError):
                    pass

            # Prepend the debugger args.
            args = ([command] + self.debuggerInfo.args +
                    args + params)
        elif browserhtml:
            browserhtml_path = find_dep_path_newest('browserhtml', args[0])
            if browserhtml_path is None:
                print("Could not find browserhtml package; perhaps you haven't built Servo.")
                return 1
            args = args + ['-w', '-b', '--pref', 'dom.mozbrowser.enabled',
                           path.join(browserhtml_path, 'out', 'index.html')]
            args = args + params
        else:
            args = args + params

        try:
            check_call(args, env=env)
        except subprocess.CalledProcessError as e:
            print("Servo exited with return value %d" % e.returncode)
            return e.returncode
        except OSError as e:
            if e.errno == 2:
                print("Servo Binary can't be found! Run './mach build'"
                      " and try again!")
            else:
                raise e
Example #31
0
    def runSerialTests(self, manifests, options, cmdargs=None):
        debuggerInfo = None
        if options.debugger:
            debuggerInfo = mozdebug.get_debugger_info(options.debugger, options.debuggerArgs,
                                                      options.debuggerInteractive)

        profileDir = None
        startAfter = None  # When the previous run crashed, we skip the tests we ran before
        prevStartAfter = None
        for i in itertools.count():
            try:
                if cmdargs is None:
                    cmdargs = []

                if self.use_marionette:
                    cmdargs.append('-marionette')

                profile = self.createReftestProfile(options,
                                                    manifests,
                                                    startAfter=startAfter)
                profileDir = profile.profile  # name makes more sense

                # browser environment
                browserEnv = self.buildBrowserEnv(options, profileDir)

                self.log.info("Running with e10s: {}".format(options.e10s))
                status, startAfter = self.runApp(profile,
                                                 binary=options.app,
                                                 cmdargs=cmdargs,
                                                 # give the JS harness 30 seconds to deal with
                                                 # its own timeouts
                                                 env=browserEnv,
                                                 timeout=options.timeout + 30.0,
                                                 symbolsPath=options.symbolsPath,
                                                 options=options,
                                                 debuggerInfo=debuggerInfo)
                self.log.info("Process mode: {}".format('e10s' if options.e10s else 'non-e10s'))
                mozleak.process_leak_log(self.leakLogFile,
                                         leak_thresholds=options.leakThresholds,
                                         stack_fixer=get_stack_fixer_function(options.utilityPath,
                                                                              options.symbolsPath))
                if status == 0:
                    break

                if startAfter == self.TEST_SEEN_FINAL:
                    self.log.info("Finished running all tests, skipping resume "
                                  "despite non-zero status code: %s" % status)
                    break

                if startAfter is not None and options.shuffle:
                    self.log.error("Can not resume from a crash with --shuffle "
                                   "enabled. Please consider disabling --shuffle")
                    break
                if startAfter is not None and options.maxRetries <= i:
                    self.log.error("Hit maximum number of allowed retries ({}) "
                                   "in the test run".format(options.maxRetries))
                    break
                if startAfter == prevStartAfter:
                    # If the test stuck on the same test, or there the crashed
                    # test appeared more then once, stop
                    self.log.error("Force stop because we keep running into "
                                   "test \"{}\"".format(startAfter))
                    break
                prevStartAfter = startAfter
                # TODO: we need to emit an SUITE-END log if it crashed
            finally:
                self.cleanup(profileDir)
        return status
Example #32
0
    def run(self, params, remote, background, noprofile, debug, debugger,
            debugparams, slowscript, dmd, sample_below, max_frames,
            show_dump_stats, mode):

        try:
            binpath = self.get_binary_path('app')
        except Exception as e:
            print("It looks like your program isn't built.",
                  "You can run |mach build| to build it.")
            print(e)
            return 1

        args = [binpath]

        if params:
            args.extend(params)

        if not remote:
            args.append('-no-remote')

        if not background and sys.platform == 'darwin':
            args.append('-foreground')

        if '-profile' not in params and '-P' not in params and not noprofile:
            path = os.path.join(self.topobjdir, 'tmp', 'scratch_user')
            if not os.path.isdir(path):
                os.makedirs(path)
            args.append('-profile')
            args.append(path)

        extra_env = {}

        if debug:
            import mozdebug
            if not debugger:
                # No debugger name was provided. Look for the default ones on
                # current OS.
                debugger = mozdebug.get_default_debugger_name(
                    mozdebug.DebuggerSearch.KeepLooking)

            self.debuggerInfo = mozdebug.get_debugger_info(
                debugger, debugparams)
            if not self.debuggerInfo:
                print("Could not find a suitable debugger in your PATH.")
                return 1

            # Parameters come from the CLI. We need to convert them before
            # their use.
            if debugparams:
                import pymake.process
                argv, badchar = pymake.process.clinetoargv(
                    debugparams, os.getcwd())
                if badchar:
                    print(
                        "The --debugparams you passed require a real shell to parse them."
                    )
                    print("(We can't handle the %r character.)" % (badchar, ))
                    return 1
                debugparams = argv

            if not slowscript:
                extra_env['JS_DISABLE_SLOW_SCRIPT_SIGNALS'] = '1'

            extra_env['MOZ_CRASHREPORTER_DISABLE'] = '1'

            # Prepend the debugger args.
            args = [self.debuggerInfo.path] + self.debuggerInfo.args + args

        if dmd:
            dmd_params = []

            if sample_below:
                dmd_params.append('--sample-below=' + sample_below)
            if max_frames:
                dmd_params.append('--max-frames=' + max_frames)
            if show_dump_stats:
                dmd_params.append('--show-dump-stats=yes')
            if mode:
                dmd_params.append('--mode=' + mode)

            if dmd_params:
                dmd_env_var = " ".join(dmd_params)
            else:
                dmd_env_var = "1"

            bin_dir = os.path.dirname(binpath)
            lib_name = self.substs['DLL_PREFIX'] + 'dmd' + self.substs[
                'DLL_SUFFIX']
            dmd_lib = os.path.join(bin_dir, lib_name)
            if not os.path.exists(dmd_lib):
                print("Please build with |--enable-dmd| to use DMD.")
                return 1

            env_vars = {
                "Darwin": {
                    "DYLD_INSERT_LIBRARIES": dmd_lib,
                    "LD_LIBRARY_PATH": bin_dir,
                    "DMD": dmd_env_var,
                },
                "Linux": {
                    "LD_PRELOAD": dmd_lib,
                    "LD_LIBRARY_PATH": bin_dir,
                    "DMD": dmd_env_var,
                },
                "WINNT": {
                    "MOZ_REPLACE_MALLOC_LIB": dmd_lib,
                    "DMD": dmd_env_var,
                },
            }
            extra_env.update(env_vars.get(self.substs['OS_ARCH'], {}))

        return self.run_process(args=args,
                                ensure_exit_code=False,
                                pass_thru=True,
                                append_env=extra_env)
Example #33
0
def check_args(kwargs):
    set_from_config(kwargs)

    for test_paths in kwargs["test_paths"].itervalues():
        if not ("tests_path" in test_paths and
                "metadata_path" in test_paths):
            print "Fatal: must specify both a test path and metadata path"
            sys.exit(1)
        for key, path in test_paths.iteritems():
            name = key.split("_", 1)[0]

            if not os.path.exists(path):
                print "Fatal: %s path %s does not exist" % (name, path)
                sys.exit(1)

            if not os.path.isdir(path):
                print "Fatal: %s path %s is not a directory" % (name, path)
                sys.exit(1)

    if kwargs["product"] is None:
        kwargs["product"] = "firefox"

    if kwargs["test_list"]:
        if kwargs["include"] is not None:
            kwargs["include"].extend(kwargs["test_list"])
        else:
            kwargs["include"] = kwargs["test_list"]

    if kwargs["run_info"] is None:
        kwargs["run_info"] = kwargs["config_path"]

    if kwargs["this_chunk"] > 1:
        require_arg(kwargs, "total_chunks", lambda x: x >= kwargs["this_chunk"])

    if kwargs["chunk_type"] is None:
        if kwargs["total_chunks"] > 1:
            kwargs["chunk_type"] = "equal_time"
        else:
            kwargs["chunk_type"] = "none"

    if kwargs["processes"] is None:
        kwargs["processes"] = 1

    if kwargs["debugger"] is not None:
        import mozdebug
        if kwargs["debugger"] == "__default__":
            kwargs["debugger"] = mozdebug.get_default_debugger_name()
        debug_info = mozdebug.get_debugger_info(kwargs["debugger"],
                                                kwargs["debugger_args"])
        if debug_info and debug_info.interactive:
            if kwargs["processes"] != 1:
                kwargs["processes"] = 1
            kwargs["no_capture_stdio"] = True
        kwargs["debug_info"] = debug_info
    else:
        kwargs["debug_info"] = None

    if kwargs["binary"] is not None:
        if not os.path.exists(kwargs["binary"]):
            print >> sys.stderr, "Binary path %s does not exist" % kwargs["binary"]
            sys.exit(1)

    if kwargs["ssl_type"] is None:
        if None not in (kwargs["ca_cert_path"], kwargs["host_cert_path"], kwargs["host_key_path"]):
            kwargs["ssl_type"] = "pregenerated"
        elif exe_path(kwargs["openssl_binary"]) is not None:
            kwargs["ssl_type"] = "openssl"
        else:
            kwargs["ssl_type"] = "none"

    if kwargs["ssl_type"] == "pregenerated":
        require_arg(kwargs, "ca_cert_path", lambda x:os.path.exists(x))
        require_arg(kwargs, "host_cert_path", lambda x:os.path.exists(x))
        require_arg(kwargs, "host_key_path", lambda x:os.path.exists(x))

    elif kwargs["ssl_type"] == "openssl":
        path = exe_path(kwargs["openssl_binary"])
        if path is None:
            print >> sys.stderr, "openssl-binary argument missing or not a valid executable"
            sys.exit(1)
        kwargs["openssl_binary"] = path

    if kwargs["ssl_type"] != "none" and kwargs["product"] == "firefox":
        path = exe_path(kwargs["certutil_binary"])
        if path is None:
            print >> sys.stderr, "certutil-binary argument missing or not a valid executable"
            sys.exit(1)
        kwargs["certutil_binary"] = path

    return kwargs
Example #34
0
    def runSerialTests(self, manifests, options, cmdargs=None):
        debuggerInfo = None
        if options.debugger:
            debuggerInfo = mozdebug.get_debugger_info(
                options.debugger, options.debuggerArgs,
                options.debuggerInteractive)

        def run(**kwargs):
            if kwargs.get("tests"):
                self.lastTest = kwargs["tests"][-1]["identifier"]
                if not isinstance(self.lastTest, string_types):
                    self.lastTest = " ".join(self.lastTest)

            status = self.runApp(
                options,
                manifests=manifests,
                cmdargs=cmdargs,
                # We generally want the JS harness or marionette
                # to handle timeouts if they can.
                # The default JS harness timeout is currently
                # 300 seconds (default options.timeout).
                # The default Marionette socket timeout is
                # currently 360 seconds.
                # Give the JS harness extra time to deal with
                # its own timeouts and try to usually exceed
                # the 360 second marionette socket timeout.
                # See bug 479518 and bug 1414063.
                timeout=options.timeout + 70.0,
                debuggerInfo=debuggerInfo,
                symbolsPath=options.symbolsPath,
                **kwargs)

            mozleak.process_leak_log(
                self.leakLogFile,
                leak_thresholds=options.leakThresholds,
                stack_fixer=get_stack_fixer_function(options.utilityPath,
                                                     options.symbolsPath),
            )
            return status

        if not self.run_by_manifest:
            return run()

        tests = self.getActiveTests(manifests, options)
        tests_by_manifest = defaultdict(list)
        ids_by_manifest = defaultdict(list)
        for t in tests:
            tests_by_manifest[t["manifest"]].append(t)
            test_id = t["identifier"]
            if not isinstance(test_id, string_types):
                test_id = " ".join(test_id)
            ids_by_manifest[t["manifestID"]].append(test_id)

        self.log.suite_start(ids_by_manifest, name=options.suite)

        overall = 0
        for manifest, tests in tests_by_manifest.items():
            self.log.info("Running tests in {}".format(manifest))
            status = run(tests=tests)
            overall = overall or status

        self.log.suite_end(extra={"results": self.outputHandler.results})
        return overall