def SetupTestServer(target, test_concurrency):
  """Provisions a forwarding test server and configures |target| to use it.

  Returns a Popen object for the test server process."""

  logging.debug('Starting test server.')
  spawning_server = chrome_test_server_spawner.SpawningServer(
      0, SSHPortForwarder(target), test_concurrency)
  forwarded_port = common.ConnectPortForwardingTask(
      target, spawning_server.server_port)
  spawning_server.Start()

  logging.debug('Test server listening for connections (port=%d)' %
                spawning_server.server_port)
  logging.debug('Forwarded port is %d' % forwarded_port)

  config_file = tempfile.NamedTemporaryFile(delete=True)

  # Clean up the config JSON to only pass ports. See https://crbug.com/810209 .
  config_file.write(json.dumps({
    'name': 'testserver',
    'address': '127.0.0.1',
    'spawner_url_base': 'http://localhost:%d' % forwarded_port
  }))

  config_file.flush()
  target.PutFile(config_file.name, '/tmp/net-test-server-config')

  return spawning_server
Beispiel #2
0
def SetupTestServer(target, test_concurrency, for_package, for_realms=[]):
    """Provisions a forwarding test server and configures |target| to use it.

  Returns a Popen object for the test server process."""

    logging.debug('Starting test server.')
    # The TestLauncher can launch more jobs than the limit specified with
    # --test-launcher-jobs so the max number of spawned test servers is set to
    # twice that limit here. See https://crbug.com/913156#c19.
    spawning_server = chrome_test_server_spawner.SpawningServer(
        0, SSHPortForwarder(target), test_concurrency * 2)
    forwarded_port = common.ConnectPortForwardingTask(
        target, spawning_server.server_port)
    spawning_server.Start()

    logging.debug('Test server listening for connections (port=%d)' %
                  spawning_server.server_port)
    logging.debug('Forwarded port is %d' % forwarded_port)

    config_file = tempfile.NamedTemporaryFile(delete=True)

    config_file.write(
        json.dumps(
            {'spawner_url_base': 'http://localhost:%d' % forwarded_port}))

    config_file.flush()
    target.PutFile(config_file.name,
                   '/tmp/net-test-server-config',
                   for_package=for_package,
                   for_realms=for_realms)

    return spawning_server
Beispiel #3
0
    def __init__(self, target):
        AmberRepo.__init__(self, target)
        self._with_count = 0

        self._amber_root = tempfile.mkdtemp()
        pm_tool = common.GetHostToolPathFromPlatform('pm')
        subprocess.check_call([pm_tool, 'newrepo', '-repo', self._amber_root])
        logging.info('Creating and serving temporary Amber root: {}.'.format(
            self._amber_root))

        serve_port = common.GetAvailableTcpPort()
        self._pm_serve_task = subprocess.Popen([
            pm_tool, 'serve', '-d',
            os.path.join(self._amber_root, 'repository'), '-l',
            ':%d' % serve_port, '-q'
        ])

        # Block until "pm serve" starts serving HTTP traffic at |serve_port|.
        timeout = time.time() + _PM_SERVE_LIVENESS_TIMEOUT_SECS
        while True:
            try:
                urllib2.urlopen('http://localhost:%d' % serve_port,
                                timeout=1).read()
                break
            except urllib2.URLError:
                logging.info('Waiting until \'pm serve\' is up...')

            if time.time() >= timeout:
                raise Exception('Timed out while waiting for \'pm serve\'.')

            time.sleep(1)

        remote_port = common.ConnectPortForwardingTask(target, serve_port, 0)
        self._RegisterAmberRepository(self._amber_root, remote_port)
Beispiel #4
0
    def InstallPackage(self, package_path, package_name, package_deps):
        """Installs a package and it's dependencies on the device. If the package is
    already installed then it will be updated to the new version.

    package_path: Path to the .far file to be installed.
    package_name: Package name.
    package_deps: List of .far files with the packages that the main package
                  depends on. These packages are installed or updated as well.
    """
        try:
            tuf_root = tempfile.mkdtemp()
            pm_serve_task = None

            subprocess.check_call([_PM, 'newrepo', '-repo', tuf_root])

            # 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'
            ])

            # Publish all packages to the serving TUF repository under |tuf_root|.
            all_packages = [package_path] + package_deps
            for next_package_path in all_packages:
                _PublishPackage(tuf_root, next_package_path)

            _WaitForPmServeToBeReady(serve_port)

            remote_port = common.ConnectPortForwardingTask(self, serve_port, 0)
            self._RegisterAmberRepository(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 = self.RunCommand(
                    [
                        'amberctl', '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)

        finally:
            self._UnregisterAmberRepository()
            if pm_serve_task:
                pm_serve_task.kill()
            shutil.rmtree(tuf_root)
Beispiel #5
0
    def __init__(self, target):
        super(ManagedPkgRepo, self).__init__()
        self._with_count = 0
        self._target = target

        self._pkg_root = tempfile.mkdtemp()
        pm_tool = common.GetHostToolPathFromPlatform('pm')
        subprocess.check_call([pm_tool, 'newrepo', '-repo', self._pkg_root])
        logging.debug(
            'Creating and serving temporary package root: {}.'.format(
                self._pkg_root))

        with tempfile.NamedTemporaryFile() as pm_port_file:
            # Flags for `pm serve`:
            # https://fuchsia.googlesource.com/fuchsia/+/refs/heads/main/src/sys/pkg/bin/pm/cmd/pm/serve/serve.go
            self._pm_serve_task = subprocess.Popen([
                pm_tool,
                'serve',
                '-d',
                os.path.join(self._pkg_root, 'repository'),
                '-c',
                '2',  # Use config.json format v2, the default for pkgctl.
                '-q',  # Don't log transfer activity.
                '-l',
                ':0',  # Bind to ephemeral port.
                '-f',
                pm_port_file.name  # Publish port number to |pm_port_file|.
            ])

            # Busywait until 'pm serve' starts the server and publishes its port to
            # a temporary file.
            timeout = time.time() + _PM_SERVE_LISTEN_TIMEOUT_SECS
            serve_port = None
            while not serve_port:
                if time.time() > timeout:
                    raise Exception(
                        'Timeout waiting for \'pm serve\' to publish its port.'
                    )

                with open(pm_port_file.name, 'r',
                          encoding='utf8') as serve_port_file:
                    serve_port = serve_port_file.read()

                time.sleep(_PM_SERVE_POLL_INTERVAL)

            serve_port = int(serve_port)
            logging.debug('pm serve is active on port {}.'.format(serve_port))

        remote_port = common.ConnectPortForwardingTask(target, serve_port, 0)
        self._RegisterPkgRepository(self._pkg_root, remote_port)
Beispiel #6
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.
        # TODO(kmarshall): Use -q to suppress pm serve output once blob push
        # is confirmed to be running stably on bots.
        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
            ])
            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:
            task_output = _ReadMergedLines(
                [process.stdout, system_logger.stdout])
        else:
            task_output = process.stdout

        if args.symbolizer_config:
            # Decorate the process output stream with the symbolizer.
            output = FilterStream(task_output, package_name,
                                  args.symbolizer_config, output_dir)
        else:
            logging.warn('Symbolization is DISABLED.')
            output = process.stdout

        for next_line in output:
            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
 def Map(self, port_pairs):
   for p in port_pairs:
     _, host_port = p
     self._port_mapping[host_port] = \
         common.ConnectPortForwardingTask(self._target, host_port)