예제 #1
0
파일: util.py 프로젝트: tpasternak/pants
def init_subsystems(subsystem_types, options=None):
    """Initialize subsystems for use in tests.

  Does not create an instance.  This function is for setting up subsystems that the code
  under test creates.

  Note that there is some redundancy between this function and BaseTest.context(for_subsystems=...).
  TODO: Fix that.

  :API: public

  :param list subsystem_types: The subclasses of :class:`pants.subsystem.subsystem.Subsystem`
                               to create.
  :param options: dict of scope -> (dict of option name -> value).
                  The scopes may be those of the global instances of the subsystems (i.e.,
                  subsystem_type.options_scope) and/or the scopes of instances of the
                  subsystems they transitively depend on.
  """
    optionables = set()
    for s in subsystem_types:
        if not Subsystem.is_subsystem_type(s):
            raise TypeError('{} is not a subclass of `Subsystem`'.format(s))
        for si in s.known_scope_infos():
            optionables.add(si.optionable_cls)
    if options:
        allowed_scopes = {o.options_scope for o in optionables}
        for scope in options.keys():
            if scope != '' and scope not in allowed_scopes:
                raise ValueError(
                    '`{}` is not the scope of any of these subsystems: {}'.
                    format(scope, optionables))
    # Don't trample existing subsystem options, in case a test has set up some
    # other subsystems in some other way.
    updated_options = dict(
        Subsystem._options.items()) if Subsystem._options else {}
    if options:
        updated_options.update(options)
    Subsystem.set_options(
        create_options_for_optionables(optionables, options=updated_options))
예제 #2
0
  def context(self, for_task_types=None, for_subsystems=None, options=None,
              target_roots=None, console_outstream=None, workspace=None,
              scheduler=None, address_mapper=None, **kwargs):
    """
    :API: public

    :param dict **kwargs: keyword arguments passed in to `create_options_for_optionables`.
    """
    # Many tests use source root functionality via the SourceRootConfig.global_instance().
    # (typically accessed via Target.target_base), so we always set it up, for convenience.
    for_subsystems = set(for_subsystems or ())
    for subsystem in for_subsystems:
      if subsystem.options_scope is None:
        raise TaskError('You must set a scope on your subsystem type before using it in tests.')

    optionables = {SourceRootConfig} | self._build_configuration.optionables() | for_subsystems

    for_task_types = for_task_types or ()
    for task_type in for_task_types:
      scope = task_type.options_scope
      if scope is None:
        raise TaskError('You must set a scope on your task type before using it in tests.')
      optionables.add(task_type)
      # If task is expected to inherit goal-level options, register those directly on the task,
      # by subclassing the goal options registrar and settings its scope to the task scope.
      if issubclass(task_type, GoalOptionsMixin):
        subclass_name = 'test_{}_{}_{}'.format(
          task_type.__name__, task_type.goal_options_registrar_cls.options_scope,
          task_type.options_scope)
        optionables.add(type(subclass_name, (task_type.goal_options_registrar_cls, ),
                             {'options_scope': task_type.options_scope}))

    # Now expand to all deps.
    all_optionables = set()
    for optionable in optionables:
      all_optionables.update(si.optionable_cls for si in optionable.known_scope_infos())

    # Now default the option values and override with any caller-specified values.
    # TODO(benjy): Get rid of the options arg, and require tests to call set_options.
    options = options.copy() if options else {}
    for s, opts in self.options.items():
      scoped_opts = options.setdefault(s, {})
      scoped_opts.update(opts)

    fake_options = create_options_for_optionables(
      all_optionables, options=options, **kwargs)

    Subsystem.reset(reset_options=True)
    Subsystem.set_options(fake_options)

    scheduler = scheduler or self.scheduler

    address_mapper = address_mapper or self.address_mapper

    context = create_context_from_options(fake_options,
                                          target_roots=target_roots,
                                          build_graph=self.build_graph,
                                          build_configuration=self._build_configuration,
                                          address_mapper=address_mapper,
                                          console_outstream=console_outstream,
                                          workspace=workspace,
                                          scheduler=scheduler)
    return context