def test_full_graph_for_planner_example(self): symbol_table_cls = TargetTable address_mapper = AddressMapper(symbol_table_cls, JsonParser, '*.BUILD.json') tasks = create_graph_tasks(address_mapper, symbol_table_cls) + create_fs_tasks() intrinsics = create_fs_intrinsics('Let us pretend that this is a ProjectTree!') rule_index = RuleIndex.create(tasks, intrinsics) graphmaker = GraphMaker(rule_index, root_subject_fns={k: lambda p: Select(p) for k in (Address, # TODO, use the actual fns. PathGlobs, SingleAddress, SiblingAddresses, DescendantAddresses, AscendantAddresses )}) fullgraph = graphmaker.full_graph() print('---diagnostic------') print(fullgraph.error_message()) print('/---diagnostic------') print(fullgraph) # Assert that all of the rules specified the various task fns are present declared_rules = rule_index.all_rules() rules_remaining_in_graph_strs = set(str(r.rule) for r in fullgraph.rule_dependencies.keys()) declared_rule_strings = set(str(r) for r in declared_rules) self.assertEquals(declared_rule_strings, rules_remaining_in_graph_strs ) # statically assert that the number of dependency keys is fixed self.assertEquals(41, len(fullgraph.rule_dependencies))
def test_full_graph_for_planner_example(self): symbol_table_cls = TargetTable address_mapper = AddressMapper(symbol_table_cls, JsonParser, '*.BUILD.json') tasks = create_graph_tasks(address_mapper, symbol_table_cls) + create_fs_tasks() intrinsics = create_fs_intrinsics('Let us pretend that this is a ProjectTree!') rule_index = NodeBuilder.create(tasks, intrinsics) graphmaker = GraphMaker(rule_index, root_subject_fns={k: lambda p: Select(p) for k in (Address, # TODO, use the actual fns. PathGlobs, SingleAddress, SiblingAddresses, DescendantAddresses, AscendantAddresses )}) fullgraph = graphmaker.full_graph() print('---diagnostic------') print(fullgraph.error_message()) print('/---diagnostic------') print(fullgraph) # Assert that all of the rules specified the various task fns are present declared_rules = rule_index.all_rules() rules_remaining_in_graph_strs = set(str(r.rule) for r in fullgraph.rule_dependencies.keys()) declared_rule_strings = set(str(r) for r in declared_rules) self.assertEquals(declared_rule_strings, rules_remaining_in_graph_strs )
def __init__(self, goals, tasks, project_tree, native, graph_lock=None): """ :param goals: A dict from a goal name to a product type. A goal is just an alias for a particular (possibly synthetic) product. :param tasks: A set of (output, input selection clause, task function) triples which is used to compute values in the product graph. :param project_tree: An instance of ProjectTree for the current build root. :param native: An instance of engine.subsystem.native.Native. :param graph_lock: A re-entrant lock to use for guarding access to the internal product Graph instance. Defaults to creating a new threading.RLock(). """ self._products_by_goal = goals self._project_tree = project_tree self._native = native self._product_graph_lock = graph_lock or threading.RLock() self._run_count = 0 # Create a handle for the ExternContext (which must be kept alive as long as this object), and # the native Scheduler. self._context = ExternContext() self._context_handle = native.new_handle(self._context) # TODO: The only (?) case where we use inheritance rather than exact type unions. has_products_constraint = TypeConstraint( self._to_id(SubclassesOf(HasProducts))) scheduler = native.lib.scheduler_create( self._context_handle, extern_key_for, extern_id_to_str, extern_val_to_str, extern_satisfied_by, extern_store_list, extern_project, extern_project_multi, self._to_key('name'), self._to_key('products'), self._to_key('default'), self._to_constraint(Address), has_products_constraint, self._to_constraint(Variants)) self._scheduler = native.gc(scheduler, native.lib.scheduler_destroy) self._execution_request = None # Validate and register all provided and intrinsic tasks. select_product = lambda product: Select(product) # TODO: This bounding of input Subject types allows for closed-world validation, but is not # strictly necessary for execution. We might eventually be able to remove it by only executing # validation below the execution roots (and thus not considering paths that aren't in use). root_selector_fns = { Address: select_product, AscendantAddresses: select_product, DescendantAddresses: select_product, PathGlobs: select_product, SiblingAddresses: select_product, SingleAddress: select_product, } intrinsics = create_fs_intrinsics( project_tree) + create_snapshot_intrinsics(project_tree) singletons = create_snapshot_singletons(project_tree) node_builder = NodeBuilder.create(tasks, intrinsics, singletons) RulesetValidator(node_builder, goals, root_selector_fns).validate() self._register_tasks(node_builder.tasks) self._register_intrinsics(node_builder.intrinsics) self._register_singletons(node_builder.singletons)
def __init__(self, goals, tasks, project_tree, native, graph_lock=None): """ :param goals: A dict from a goal name to a product type. A goal is just an alias for a particular (possibly synthetic) product. :param tasks: A set of (output, input selection clause, task function) triples which is used to compute values in the product graph. :param project_tree: An instance of ProjectTree for the current build root. :param native: An instance of engine.subsystem.native.Native. :param graph_lock: A re-entrant lock to use for guarding access to the internal product Graph instance. Defaults to creating a new threading.RLock(). """ self._products_by_goal = goals self._project_tree = project_tree self._native = native self._product_graph_lock = graph_lock or threading.RLock() self._run_count = 0 # TODO: The only (?) case where we use inheritance rather than exact type unions. has_products_constraint = SubclassesOf(HasProducts) # Create the ExternContext, and the native Scheduler. self._scheduler = native.new_scheduler(has_products_constraint, constraint_for(Address), constraint_for(Variants)) self._execution_request = None # Validate and register all provided and intrinsic tasks. # TODO: This bounding of input Subject types allows for closed-world validation, but is not # strictly necessary for execution. We might eventually be able to remove it by only executing # validation below the execution roots (and thus not considering paths that aren't in use). select_product = lambda product: Select(product) root_selector_fns = { Address: select_product, AscendantAddresses: select_product, DescendantAddresses: select_product, PathGlobs: select_product, SiblingAddresses: select_product, SingleAddress: select_product, } intrinsics = create_fs_intrinsics(project_tree) + create_snapshot_intrinsics(project_tree) singletons = create_snapshot_singletons(project_tree) rule_index = RuleIndex.create(tasks, intrinsics, singletons) RulesetValidator(rule_index, goals, root_selector_fns).validate() self._register_tasks(rule_index.tasks) self._register_intrinsics(rule_index.intrinsics) self._register_singletons(rule_index.singletons)
def __init__(self, goals, tasks, project_tree, native, graph_lock=None): """ :param goals: A dict from a goal name to a product type. A goal is just an alias for a particular (possibly synthetic) product. :param tasks: A set of (output, input selection clause, task function) triples which is used to compute values in the product graph. :param project_tree: An instance of ProjectTree for the current build root. :param native: An instance of engine.subsystem.native.Native. :param graph_lock: A re-entrant lock to use for guarding access to the internal product Graph instance. Defaults to creating a new threading.RLock(). """ self._products_by_goal = goals self._project_tree = project_tree self._native = native self._product_graph_lock = graph_lock or threading.RLock() self._run_count = 0 # TODO: The only (?) case where we use inheritance rather than exact type unions. has_products_constraint = SubclassesOf(HasProducts) # Create the ExternContext, and the native Scheduler. self._scheduler = native.new_scheduler( has_products_constraint, constraint_for(Address), constraint_for(Variants) ) self._execution_request = None # Validate and register all provided and intrinsic tasks. # TODO: This bounding of input Subject types allows for closed-world validation, but is not # strictly necessary for execution. We might eventually be able to remove it by only executing # validation below the execution roots (and thus not considering paths that aren't in use). select_product = lambda product: Select(product) root_selector_fns = { Address: select_product, AscendantAddresses: select_product, DescendantAddresses: select_product, PathGlobs: select_product, SiblingAddresses: select_product, SingleAddress: select_product, } intrinsics = create_fs_intrinsics(project_tree) + create_snapshot_intrinsics(project_tree) singletons = create_snapshot_singletons(project_tree) rule_index = RuleIndex.create(tasks, intrinsics, singletons) RulesetValidator(rule_index, goals, root_selector_fns).validate() self._register_tasks(rule_index.tasks) self._register_intrinsics(rule_index.intrinsics) self._register_singletons(rule_index.singletons)
def __init__(self, goals, tasks, project_tree, native, graph_lock=None): """ :param goals: A dict from a goal name to a product type. A goal is just an alias for a particular (possibly synthetic) product. :param tasks: A set of (output, input selection clause, task function) triples which is used to compute values in the product graph. :param project_tree: An instance of ProjectTree for the current build root. :param native: An instance of engine.subsystem.native.Native. :param graph_lock: A re-entrant lock to use for guarding access to the internal product Graph instance. Defaults to creating a new threading.RLock(). """ self._products_by_goal = goals self._project_tree = project_tree self._native = native self._product_graph_lock = graph_lock or threading.RLock() self._run_count = 0 # Create a handle for the ExternContext (which must be kept alive as long as this object), and # the native Scheduler. self._context = ExternContext() self._context_handle = native.new_handle(self._context) # TODO: The only (?) case where we use inheritance rather than exact type unions. has_products_constraint = TypeConstraint(self._to_id(SubclassesOf(HasProducts))) scheduler = native.lib.scheduler_create(self._context_handle, extern_key_for, extern_id_to_str, extern_val_to_str, extern_satisfied_by, extern_store_list, extern_project, extern_project_multi, extern_create_exception, self._to_key('name'), self._to_key('products'), self._to_key('default'), self._to_constraint(Address), has_products_constraint, self._to_constraint(Variants)) self._scheduler = native.gc(scheduler, native.lib.scheduler_destroy) self._execution_request = None # Validate and register all provided and intrinsic tasks. select_product = lambda product: Select(product) # TODO: This bounding of input Subject types allows for closed-world validation, but is not # strictly necessary for execution. We might eventually be able to remove it by only executing # validation below the execution roots (and thus not considering paths that aren't in use). root_selector_fns = { Address: select_product, AscendantAddresses: select_product, DescendantAddresses: select_product, PathGlobs: select_product, SiblingAddresses: select_product, SingleAddress: select_product, } intrinsics = create_fs_intrinsics(project_tree) + create_snapshot_intrinsics(project_tree) singletons = create_snapshot_singletons(project_tree) node_builder = NodeBuilder.create(tasks, intrinsics, singletons) RulesetValidator(node_builder, goals, root_selector_fns).validate() self._register_tasks(node_builder.tasks) self._register_intrinsics(node_builder.intrinsics) self._register_singletons(node_builder.singletons)