Пример #1
0
 def setUpClass(cls) -> None:
     super().setUpClass()
     # NB: We must set this up at the class level, rather than per-test level, because
     # `init_rust_logging` must never be called more than once. The Rust logger is global and static,
     # and initializing it twice in the same test class results in a SIGABRT.
     init_native().init_rust_logging(
         # We set the level to the least verbose possible, as individual tests will increase the
         # verbosity as necessary.
         level=LogLevel.ERROR.level,
         log_show_rust_3rdparty=False,
     )
Пример #2
0
    def _init_engine(self, local_store_dir: Optional[str] = None) -> None:
        if self._scheduler is not None:
            return

        options_bootstrapper = OptionsBootstrapper.create(
            args=["--pants-config-files=[]"])
        local_store_dir = (local_store_dir
                           or options_bootstrapper.bootstrap_options.
                           for_global_scope().local_store_dir)

        # NB: This uses the long form of initialization because it needs to directly specify
        # `cls.alias_groups` rather than having them be provided by bootstrap options.
        graph_session = EngineInitializer.setup_legacy_graph_extended(
            pants_ignore_patterns=[],
            local_store_dir=local_store_dir,
            build_file_imports_behavior=BuildFileImportsBehavior.error,
            native=init_native(),
            options_bootstrapper=options_bootstrapper,
            build_root=self.build_root,
            build_configuration=self.build_config(),
            build_ignore_patterns=None,
        ).new_session(zipkin_trace_v2=False, build_id="buildid_for_test")
        self._scheduler = graph_session.scheduler_session
        self._build_graph, self._address_mapper = graph_session.create_build_graph(
            Specs(address_specs=AddressSpecs([]),
                  filesystem_specs=FilesystemSpecs([])),
            self._build_root(),
        )
Пример #3
0
    def _init_engine(self, local_store_dir: Optional[str] = None) -> None:
        if self._scheduler is not None:
            return

        options_bootstrapper = OptionsBootstrapper.create(
            env={}, args=["--pants-config-files=[]", *self.additional_options], allow_pantsrc=False
        )
        global_options = options_bootstrapper.bootstrap_options.for_global_scope()
        local_store_dir = local_store_dir or global_options.local_store_dir
        local_execution_root_dir = global_options.local_execution_root_dir
        named_caches_dir = global_options.named_caches_dir

        # NB: This uses the long form of initialization because it needs to directly specify
        # `cls.alias_groups` rather than having them be provided by bootstrap options.
        graph_session = EngineInitializer.setup_legacy_graph_extended(
            pants_ignore_patterns=[],
            use_gitignore=False,
            local_store_dir=local_store_dir,
            local_execution_root_dir=local_execution_root_dir,
            named_caches_dir=named_caches_dir,
            build_file_prelude_globs=(),
            glob_match_error_behavior=GlobMatchErrorBehavior.error,
            native=init_native(),
            options_bootstrapper=options_bootstrapper,
            build_root=self.build_root,
            build_configuration=self.build_config(),
            execution_options=ExecutionOptions.from_bootstrap_options(global_options),
        ).new_session(build_id="buildid_for_test", should_report_workunits=True)
        self._scheduler = graph_session.scheduler_session
Пример #4
0
    def _init_engine(self, local_store_dir: Optional[str] = None) -> None:
        if self._scheduler is not None:
            return

        options_bootstrapper = OptionsBootstrapper.create(
            env={},
            args=["--pants-config-files=[]", *self.additional_options],
            allow_pantsrc=False)
        global_options = options_bootstrapper.bootstrap_options.for_global_scope(
        )
        local_store_dir = local_store_dir or global_options.local_store_dir
        local_execution_root_dir = global_options.local_execution_root_dir
        named_caches_dir = global_options.named_caches_dir

        graph_session = EngineInitializer.setup_graph_extended(
            pants_ignore_patterns=[],
            use_gitignore=False,
            local_store_dir=local_store_dir,
            local_execution_root_dir=local_execution_root_dir,
            named_caches_dir=named_caches_dir,
            native=init_native(),
            options_bootstrapper=options_bootstrapper,
            build_root=self.build_root,
            build_configuration=self.build_config(),
            execution_options=ExecutionOptions.from_bootstrap_options(
                global_options),
        ).new_session(build_id="buildid_for_test",
                      should_report_workunits=True)
        self._scheduler = graph_session.scheduler_session
Пример #5
0
  def _init_engine(self):
    if self._scheduler is not None:
      return

    self._local_store_dir = os.path.realpath(safe_mkdtemp())
    safe_mkdir(self._local_store_dir)

    # NB: This uses the long form of initialization because it needs to directly specify
    # `cls.alias_groups` rather than having them be provided by bootstrap options.
    graph_session = EngineInitializer.setup_legacy_graph_extended(
      pants_ignore_patterns=None,
      local_store_dir=self._local_store_dir,
      build_file_imports_behavior='allow',
      native=init_native(),
      options_bootstrapper=OptionsBootstrapper.create(args=['--pants-config-files=[]']),
      build_configuration=self.build_config(),
      build_ignore_patterns=None,
    ).new_session(zipkin_trace_v2=False, build_id="buildid_for_test")
    self._scheduler = graph_session.scheduler_session
    self._build_graph, self._address_mapper = graph_session.create_build_graph(
        TargetRoots([]), self._build_root()
      )
Пример #6
0
class SchedulerTestBase:
    """A mixin for classes (tests, presumably) which need to create temporary schedulers.

  TODO: In the medium term, this should be part of pants_test.test_base.TestBase.
  """

    _native = init_native()

    def _create_work_dir(self):
        work_dir = safe_mkdtemp()
        self.addCleanup(safe_rmtree, work_dir)
        return work_dir

    def mk_fs_tree(self,
                   build_root_src=None,
                   ignore_patterns=None,
                   work_dir=None):
        """Create a temporary FilesystemProjectTree.

    :param build_root_src: Optional directory to pre-populate from; otherwise, empty.
    :returns: A FilesystemProjectTree.
    """
        work_dir = work_dir or self._create_work_dir()
        build_root = os.path.join(work_dir, 'build_root')
        if build_root_src is not None:
            shutil.copytree(build_root_src, build_root, symlinks=True)
        else:
            os.makedirs(build_root)
        return FileSystemProjectTree(build_root,
                                     ignore_patterns=ignore_patterns)

    def mk_scheduler(
        self,
        rules=None,
        union_rules=None,
        project_tree=None,
        work_dir=None,
        include_trace_on_error=True,
        should_report_workunits=False,
    ):
        """Creates a SchedulerSession for a Scheduler with the given Rules installed."""
        rules = rules or []
        work_dir = work_dir or self._create_work_dir()
        project_tree = project_tree or self.mk_fs_tree(work_dir=work_dir)
        local_store_dir = os.path.realpath(safe_mkdtemp())
        scheduler = Scheduler(self._native,
                              project_tree,
                              local_store_dir,
                              rules,
                              union_rules,
                              DEFAULT_EXECUTION_OPTIONS,
                              include_trace_on_error=include_trace_on_error)
        return scheduler.new_session(
            zipkin_trace_v2=False,
            build_id="buildid_for_test",
            should_report_workunits=should_report_workunits)

    def context_with_scheduler(self, scheduler, *args, **kwargs):
        return self.context(*args, scheduler=scheduler, **kwargs)

    def execute(self, scheduler, product, *subjects):
        """Runs an ExecutionRequest for the given product and subjects, and returns the result value."""
        request = scheduler.execution_request([product], subjects)
        return self.execute_literal(scheduler, request)

    def execute_literal(self, scheduler, execution_request):
        returns, throws = scheduler.execute(execution_request)
        if throws:
            with temporary_file_path(cleanup=False, suffix='.dot') as dot_file:
                scheduler.visualize_graph_to_file(dot_file)
                raise ValueError(
                    f'At least one root failed: {throws}. Visualized as {dot_file}'
                )
        return list(state.value for _, state in returns)

    def execute_expecting_one_result(self, scheduler, product, subject):
        request = scheduler.execution_request([product], [subject])
        returns, throws = scheduler.execute(request)

        if throws:
            _, state = throws[0]
            raise state.exc

        self.assertEqual(len(returns), 1)

        _, state = returns[0]
        return state

    def execute_raising_throw(self, scheduler, product, subject):
        resulting_value = self.execute_expecting_one_result(
            scheduler, product, subject)
        self.assertTrue(type(resulting_value) is Throw)

        raise resulting_value.exc