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, )
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(), )
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
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
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() )
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