Example #1
0
def RunPackage(output_dir, target, package_path, package_name, package_deps,
               package_args, args):
    """Installs the Fuchsia package at |package_path| on the target,
  executes it with |package_args|, and symbolizes its output.

  output_dir: The path containing the build output files.
  target: The deployment Target object that will run the package.
  package_path: The path to the .far package file.
  package_name: The name of app specified by package metadata.
  package_args: The arguments which will be passed to the Fuchsia process.
  args: Structure of arguments to configure how the package will be run.

  Returns the exit code of the remote package process."""
    target.InstallPackage(package_path, package_name, package_deps)

    if args.install_only:
        logging.info('Installation complete.')
        return

    logging.info('Running application.')
    command = ['run', _GetComponentUri(package_name)] + package_args
    process = target.RunCommandPiped(command,
                                     stdin=open(os.devnull, 'r'),
                                     stdout=subprocess.PIPE,
                                     stderr=subprocess.STDOUT)

    # Run the log data through the symbolizer process.
    build_ids_paths = map(
        lambda package_path: os.path.join(os.path.dirname(
            package_path), 'ids.txt'), [package_path] + package_deps)
    output_stream = SymbolizerFilter(process.stdout, build_ids_paths)

    for next_line in output_stream:
        print(next_line.rstrip())

    process.wait()
    if process.returncode == 0:
        logging.info('Process exited normally with status code 0.')
    else:
        # The test runner returns an error status code if *any* tests fail,
        # so we should proceed anyway.
        logging.warning('Process exited with status code %d.' %
                        process.returncode)

    return process.returncode
Example #2
0
def RunPackage(output_dir, target, package_path, package_name, package_deps,
               package_args, args):
    """Installs the Fuchsia package at |package_path| on the target,
  executes it with |package_args|, and symbolizes its output.

  output_dir: The path containing the build output files.
  target: The deployment Target object that will run the package.
  package_path: The path to the .far package file.
  package_name: The name of app specified by package metadata.
  package_args: The arguments which will be passed to the Fuchsia process.
  args: Structure of arguments to configure how the package will be run.

  Returns the exit code of the remote package process."""

    system_logger = (_AttachKernelLogReader(target)
                     if args.system_logging else None)
    try:
        if system_logger:
            # Spin up a thread to asynchronously dump the system log to stdout
            # for easier diagnoses of early, pre-execution failures.
            log_output_quit_event = multiprocessing.Event()
            log_output_thread = threading.Thread(
                target=lambda: _DrainStreamToStdout(system_logger.stdout,
                                                    log_output_quit_event))
            log_output_thread.daemon = True
            log_output_thread.start()

        target.InstallPackage(package_path, package_name, package_deps)

        if system_logger:
            log_output_quit_event.set()
            log_output_thread.join(timeout=_JOIN_TIMEOUT_SECS)

        if args.install_only:
            logging.info('Installation complete.')
            return

        logging.info('Running application.')
        command = ['run', _GetComponentUri(package_name)] + package_args
        process = target.RunCommandPiped(command,
                                         stdin=open(os.devnull, 'r'),
                                         stdout=subprocess.PIPE,
                                         stderr=subprocess.STDOUT)

        if system_logger:
            output_fd = MergedInputStream(
                [process.stdout, system_logger.stdout]).Start()
        else:
            output_fd = process.stdout.fileno()

        # Run the log data through the symbolizer process.
        build_ids_path = os.path.join(os.path.dirname(package_path), 'ids.txt')
        output_stream = SymbolizerFilter(output_fd, build_ids_path)

        for next_line in output_stream:
            print next_line.rstrip()

        process.wait()
        if process.returncode == 0:
            logging.info('Process exited normally with status code 0.')
        else:
            # The test runner returns an error status code if *any* tests fail,
            # so we should proceed anyway.
            logging.warning('Process exited with status code %d.' %
                            process.returncode)

    finally:
        if system_logger:
            logging.info('Terminating kernel log reader.')
            log_output_quit_event.set()
            log_output_thread.join()
            system_logger.kill()

    return process.returncode
Example #3
0
def RunTestPackage(output_dir, target, package_paths, package_name,
                   package_args, args):
    """Installs the Fuchsia package at |package_path| on the target,
  executes it with |package_args|, and symbolizes its output.

  output_dir: The path containing the build output files.
  target: The deployment Target object that will run the package.
  package_paths: The paths to the .far packages to be installed.
  package_name: The name of the primary package to run.
  package_args: The arguments which will be passed to the Fuchsia process.
  args: RunTestPackageArgs instance configuring how the package will be run.

  Returns the exit code of the remote package process."""

    system_logger = (_AttachKernelLogReader(target)
                     if args.system_logging else None)
    try:
        if system_logger:
            # Spin up a thread to asynchronously dump the system log to stdout
            # for easier diagnoses of early, pre-execution failures.
            log_output_quit_event = multiprocessing.Event()
            log_output_thread = threading.Thread(
                target=lambda: _DrainStreamToStdout(system_logger.stdout,
                                                    log_output_quit_event))
            log_output_thread.daemon = True
            log_output_thread.start()

        with target.GetAmberRepo():
            target.InstallPackage(package_paths)

            if system_logger:
                log_output_quit_event.set()
                log_output_thread.join(timeout=_JOIN_TIMEOUT_SECS)

            logging.info('Running application.')
            if args.use_run_test_component:
                command = ['run-test-component']
                if args.test_realm_label:
                    command += ['--realm-label=%s' % args.test_realm_label]
            # TODO(crbug.com/1156768): Deprecate runtests.
            elif args.code_coverage:
                # runtests requires specifying an output directory.
                command = ['runtests', '-o', '/tmp']
            else:
                command = ['run']
            command += [_GetComponentUri(package_name)] + package_args

            process = target.RunCommandPiped(command,
                                             stdin=open(os.devnull, 'r'),
                                             stdout=subprocess.PIPE,
                                             stderr=subprocess.STDOUT)

            if system_logger:
                output_stream = MergedInputStream(
                    [process.stdout, system_logger.stdout]).Start()
            else:
                output_stream = process.stdout

            # Run the log data through the symbolizer process.
            output_stream = SymbolizerFilter(output_stream,
                                             BuildIdsPaths(package_paths))

            for next_line in output_stream:
                print(next_line.rstrip())

            process.wait()
            if process.returncode == 0:
                logging.info('Process exited normally with status code 0.')
            else:
                # The test runner returns an error status code if *any* tests fail,
                # so we should proceed anyway.
                logging.warning('Process exited with status code %d.' %
                                process.returncode)

    finally:
        if system_logger:
            logging.info('Terminating kernel log reader.')
            log_output_quit_event.set()
            log_output_thread.join()
            system_logger.kill()

    return process.returncode
Example #4
0
def RunPackage(output_dir, target, package_path, package_name, package_deps,
               package_args, args):
    """Copies the Fuchsia package at |package_path| to the target,
  executes it with |package_args|, and symbolizes its output.

  output_dir: The path containing the build output files.
  target: The deployment Target object that will run the package.
  package_path: The path to the .far package file.
  package_name: The name of app specified by package metadata.
  package_args: The arguments which will be passed to the Fuchsia process.
  args: Structure of arguments to configure how the package will be run.

  Returns the exit code of the remote package process."""

    system_logger = (_AttachKernelLogReader(target)
                     if args.system_logging else None)
    try:
        if system_logger:
            # Spin up a thread to asynchronously dump the system log to stdout
            # for easier diagnoses of early, pre-execution failures.
            log_output_quit_event = multiprocessing.Event()
            log_output_thread = threading.Thread(
                target=lambda: _DrainStreamToStdout(system_logger.stdout,
                                                    log_output_quit_event))
            log_output_thread.daemon = True
            log_output_thread.start()

        tuf_root = tempfile.mkdtemp()
        pm_serve_task = None

        # Publish all packages to the serving TUF repository under |tuf_root|.
        subprocess.check_call([PM, 'newrepo', '-repo', tuf_root])
        all_packages = [package_path] + package_deps
        for next_package_path in all_packages:
            PublishPackage(tuf_root, next_package_path)

        # Serve the |tuf_root| using 'pm serve' and configure the target to pull
        # from it.
        serve_port = common.GetAvailableTcpPort()
        pm_serve_task = subprocess.Popen([
            PM, 'serve', '-d',
            os.path.join(tuf_root, 'repository'), '-l',
            ':%d' % serve_port, '-q'
        ])
        remote_port = common.ConnectPortForwardingTask(target, serve_port, 0)
        _RegisterAmberRepository(target, tuf_root, remote_port)

        # Install all packages.
        for next_package_path in all_packages:
            install_package_name, package_version = GetPackageInfo(
                next_package_path)
            logging.info('Installing %s version %s.' %
                         (install_package_name, package_version))
            return_code = target.RunCommand([
                'amber_ctl', 'get_up', '-n', install_package_name, '-v',
                package_version
            ],
                                            timeout_secs=_INSTALL_TIMEOUT_SECS)
            if return_code != 0:
                raise Exception('Error while installing %s.' %
                                install_package_name)

        if system_logger:
            log_output_quit_event.set()
            log_output_thread.join(timeout=_JOIN_TIMEOUT_SECS)

        if args.install_only:
            logging.info('Installation complete.')
            return

        logging.info('Running application.')
        command = ['run', _GetComponentUri(package_name)] + package_args
        process = target.RunCommandPiped(command,
                                         stdin=open(os.devnull, 'r'),
                                         stdout=subprocess.PIPE,
                                         stderr=subprocess.STDOUT)

        if system_logger:
            output_fd = MergedInputStream(
                [process.stdout, system_logger.stdout]).Start()
        else:
            output_fd = process.stdout.fileno()

        # Run the log data through the symbolizer process.
        build_ids_path = os.path.join(os.path.dirname(package_path), 'ids.txt')
        output_stream = SymbolizerFilter(output_fd, build_ids_path)

        for next_line in output_stream:
            print next_line.rstrip()

        process.wait()
        if process.returncode == 0:
            logging.info('Process exited normally with status code 0.')
        else:
            # The test runner returns an error status code if *any* tests fail,
            # so we should proceed anyway.
            logging.warning('Process exited with status code %d.' %
                            process.returncode)

    finally:
        if system_logger:
            logging.info('Terminating kernel log reader.')
            log_output_quit_event.set()
            log_output_thread.join()
            system_logger.kill()

        _UnregisterAmberRepository(target)
        if pm_serve_task:
            pm_serve_task.kill()
        shutil.rmtree(tuf_root)

    return process.returncode
Example #5
0
def RunTestPackage(output_dir, target, package_paths, package_name,
                   package_args, args):
    """Installs the Fuchsia package at |package_path| on the target,
  executes it with |package_args|, and symbolizes its output.

  output_dir: The path containing the build output files.
  target: The deployment Target object that will run the package.
  package_paths: The paths to the .far packages to be installed.
  package_name: The name of the primary package to run.
  package_args: The arguments which will be passed to the Fuchsia process.
  args: RunTestPackageArgs instance configuring how the package will be run.

  Returns the exit code of the remote package process."""

    with target.GetPkgRepo():
        start_time = time.time()
        target.InstallPackage(package_paths)
        logging.info('Test installed in {:.2f} seconds.'.format(time.time() -
                                                                start_time))

        # TODO(crbug.com/1156768): Deprecate runtests.
        if args.code_coverage:
            # runtests requires specifying an output directory and a double dash
            # before the argument list.
            command = [
                'runtests', '-o', '/tmp',
                _GetComponentUri(package_name)
            ]
            if args.test_realm_label:
                command += ['--realm-label', args.test_realm_label]
            command += ['--']
        elif args.use_run_test_component:
            command = ['run-test-component']
            if args.test_realm_label:
                command += ['--realm-label=%s' % args.test_realm_label]
            command.append(_GetComponentUri(package_name))
            command.append('--')
        else:
            command = ['run', _GetComponentUri(package_name)]

        command.extend(package_args)

        process = target.RunCommandPiped(command,
                                         stdin=open(os.devnull, 'r'),
                                         stdout=subprocess.PIPE,
                                         stderr=subprocess.STDOUT,
                                         text=True)

        # Print the test process' symbolized standard output.
        for next_line in SymbolizerFilter(process.stdout,
                                          BuildIdsPaths(package_paths)):
            print(next_line.rstrip())

        process.wait()
        if process.returncode == 0:
            logging.info('Process exited normally with status code 0.')
        else:
            # The test runner returns an error status code if *any* tests fail,
            # so we should proceed anyway.
            logging.warning('Process exited with status code %d.' %
                            process.returncode)

    return process.returncode