Пример #1
0
    def test_ruleset_with_explicit_type_constraint(self):
        rules = [(Exactly(A), (Select(B), ), noop), (B, (Select(A), ), noop)]
        validator = RulesetValidator(NodeBuilder.create(rules),
                                     goal_to_product=dict(),
                                     root_subject_types=tuple())

        validator.validate()
Пример #2
0
  def test_ruleset_with_selector_only_provided_as_root_subject(self):
    rules = [(A, (Select(B),), noop)]
    validator = RulesetValidator(RuleIndex.create(rules, tuple()),
      goal_to_product={},
      root_subject_fns={k: lambda p: Select(p) for k in (B,)})

    validator.validate()
Пример #3
0
  def test_ruleset_with_selector_only_provided_as_root_subject(self):
    rules = [(A, (Select(B),), noop)]
    validator = RulesetValidator(NodeBuilder.create(rules, tuple()),
      goal_to_product={},
      root_subject_fns={k: lambda p: Select(p) for k in (B,)})

    validator.validate()
Пример #4
0
    def test_ruleset_with_with_selector_only_provided_as_root_subject(self):

        validator = RulesetValidator(
            NodeBuilder.create([(A, (Select(B),), noop)]), goal_to_product=dict(), root_subject_types=(B,)
        )

        validator.validate()
Пример #5
0
    def test_ruleset_with_with_selector_only_provided_as_root_subject(self):

        validator = RulesetValidator(NodeBuilder.create([(A, (Select(B), ),
                                                          noop)]),
                                     goal_to_product=dict(),
                                     root_subject_types=(B, ))

        validator.validate()
Пример #6
0
    def test_ruleset_with_explicit_type_constraint(self):
        rules = [(Exactly(A), (Select(B), ), noop), (B, (Select(A), ), noop)]
        validator = RulesetValidator(
            RuleIndex.create(rules, tuple()),
            goal_to_product={},
            root_subject_fns={k: lambda p: Select(p)
                              for k in (SubA, )})

        validator.validate()
Пример #7
0
  def test_ruleset_with_explicit_type_constraint(self):
    rules = [
      (Exactly(A), (Select(B),), noop),
      (B, (Select(A),), noop)
    ]
    validator = RulesetValidator(RuleIndex.create(rules, tuple()),
      goal_to_product={},
      root_subject_fns={k: lambda p: Select(p) for k in (SubA,)})

    validator.validate()
Пример #8
0
    def test_ruleset_with_goal_not_produced(self):
        rules = [(B, (Select(SubA), ), noop)]

        validator = RulesetValidator(NodeBuilder.create(rules),
                                     goal_to_product={'goal-name': AGoal},
                                     root_subject_types=tuple())
        with self.assertRaises(ValueError) as cm:
            validator.validate()

        self.assertEquals(
            "no task for product used by goal \"goal-name\": <class 'pants_test.engine.test_rules.AGoal'>",
            str(cm.exception))
Пример #9
0
    def test_ruleset_with_goal_not_produced(self):
        rules = [(B, (Select(SubA),), noop)]

        validator = RulesetValidator(
            NodeBuilder.create(rules), goal_to_product={"goal-name": AGoal}, root_subject_types=tuple()
        )
        with self.assertRaises(ValueError) as cm:
            validator.validate()

        self.assertEquals(
            "no task for product used by goal \"goal-name\": <class 'pants_test.engine.test_rules.AGoal'>",
            str(cm.exception),
        )
Пример #10
0
    def test_ruleset_with_missing_product_type(self):
        rules = [(A, (Select(B), ), noop)]
        validator = RulesetValidator(NodeBuilder.create(rules),
                                     goal_to_product=dict(),
                                     root_subject_types=tuple())
        with self.assertRaises(ValueError) as cm:
            validator.validate()

        self.assertEquals(
            dedent("""
                                Found 1 rules with errors:
                                  (A, (Select(B),), noop)
                                    There is no producer of Select(B)
                             """).strip(), str(cm.exception))
Пример #11
0
  def test_ruleset_with_missing_product_type(self):
    rules = [(A, (Select(B),), noop)]
    validator = RulesetValidator(NodeBuilder.create(rules, tuple()),
      goal_to_product={},
      root_subject_fns={k: lambda p: Select(p) for k in (SubA,)})
    with self.assertRaises(ValueError) as cm:
      validator.validate()

    self.assert_equal_with_printing(dedent("""
                     Rules with errors: 1
                       (A, (Select(B),), noop):
                         no matches for Select(B) with subject types: SubA
                     """).strip(),
                                    str(cm.exception))
Пример #12
0
  def test_ruleset_with_missing_product_type(self):
    rules = [(A, (Select(B),), noop)]
    validator = RulesetValidator(RuleIndex.create(rules, tuple()),
                                 goal_to_product={},
                                 root_subject_fns={k: lambda p: Select(p) for k in (SubA,)})
    with self.assertRaises(ValueError) as cm:
      validator.validate()

    self.assert_equal_with_printing(dedent("""
                     Rules with errors: 1
                       (A, (Select(B),), noop):
                         no matches for Select(B) with subject types: SubA
                     """).strip(),
                                    str(cm.exception))
Пример #13
0
  def test_ruleset_with_goal_not_produced(self):
    # The graph is complete, but the goal 'goal-name' requests A,
    # which is not produced by any rule.
    rules = [
      (B, (Select(SubA),), noop)
    ]

    validator = RulesetValidator(NodeBuilder.create(rules, tuple()),
      goal_to_product={'goal-name': AGoal},
      root_subject_fns={k: lambda p: Select(p) for k in (SubA,)})
    with self.assertRaises(ValueError) as cm:
      validator.validate()

    self.assert_equal_with_printing("no task for product used by goal \"goal-name\": AGoal",
                                    str(cm.exception))
Пример #14
0
  def test_ruleset_with_goal_not_produced(self):
    # The graph is complete, but the goal 'goal-name' requests A,
    # which is not produced by any rule.
    rules = [
      (B, (Select(SubA),), noop)
    ]

    validator = RulesetValidator(RuleIndex.create(rules, tuple()),
      goal_to_product={'goal-name': AGoal},
      root_subject_fns={k: lambda p: Select(p) for k in (SubA,)})
    with self.assertRaises(ValueError) as cm:
      validator.validate()

    self.assert_equal_with_printing("no task for product used by goal \"goal-name\": AGoal",
                                    str(cm.exception))
Пример #15
0
    def test_ruleset_with_missing_product_type(self):
        rules = [(A, (Select(B),), noop)]
        validator = RulesetValidator(NodeBuilder.create(rules), goal_to_product=dict(), root_subject_types=tuple())
        with self.assertRaises(ValueError) as cm:
            validator.validate()

        self.assertEquals(
            dedent(
                """
                                Found 1 rules with errors:
                                  (A, (Select(B),), noop)
                                    There is no producer of Select(B)
                             """
            ).strip(),
            str(cm.exception),
        )
Пример #16
0
  def test_initial_select_projection_failure(self):
    rules = [
      (Exactly(A), (SelectProjection(B, D, ('some',), C),), noop),
    ]
    validator = RulesetValidator(RuleIndex.create(rules, tuple()),
      goal_to_product={},
      root_subject_fns=_suba_root_subject_fns)

    with self.assertRaises(ValueError) as cm:
      validator.validate()

    self.assert_equal_with_printing(dedent("""
                      Rules with errors: 1
                        (Exactly(A), (SelectProjection(B, D, (u'some',), C),), noop):
                          no matches for Select(C) when resolving SelectProjection(B, D, (u'some',), C) with subject types: SubA
                      """).strip(),
                                    str(cm.exception))
Пример #17
0
    def test_secondary_select_projection_failure(self):
        rules = [(Exactly(A), (SelectProjection(B, D, ('some', ), C), ), noop),
                 (C, tuple(), noop)]

        validator = RulesetValidator(RuleIndex.create(rules, tuple()),
                                     goal_to_product={},
                                     root_subject_fns=_suba_root_subject_fns)

        with self.assertRaises(ValueError) as cm:
            validator.validate()

        self.assert_equal_with_printing(
            dedent("""
                      Rules with errors: 1
                        (Exactly(A), (SelectProjection(B, D, (u'some',), C),), noop):
                          no matches for Select(B) when resolving SelectProjection(B, D, (u'some',), C) with subject types: D
                      """).strip(), str(cm.exception))
Пример #18
0
    def test_ruleset_with_superclass_of_selected_type_produced_fails(self):
        rules = [(A, (Select(B), ), noop), (B, (Select(SubA), ), noop)]
        validator = RulesetValidator(
            RuleIndex.create(rules, tuple()),
            goal_to_product={},
            root_subject_fns={k: lambda p: Select(p)
                              for k in (C, )})

        with self.assertRaises(ValueError) as cm:
            validator.validate()
        self.assert_equal_with_printing(
            dedent("""
                                      Rules with errors: 2
                                        (A, (Select(B),), noop):
                                          depends on unfulfillable (B, (Select(SubA),), noop) of C with subject types: C
                                        (B, (Select(SubA),), noop):
                                          no matches for Select(SubA) with subject types: C
                                      """).strip(), str(cm.exception))
Пример #19
0
    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)
Пример #20
0
  def test_ruleset_with_superclass_of_selected_type_produced_fails(self):
    rules = [
      (A, (Select(B),), noop),
      (B, (Select(SubA),), noop)
    ]
    validator = RulesetValidator(RuleIndex.create(rules, tuple()),
      goal_to_product={},
      root_subject_fns={k: lambda p: Select(p) for k in (C,)})

    with self.assertRaises(ValueError) as cm:
      validator.validate()
    self.assert_equal_with_printing(dedent("""
                                      Rules with errors: 2
                                        (A, (Select(B),), noop):
                                          depends on unfulfillable (B, (Select(SubA),), noop) of C with subject types: C
                                        (B, (Select(SubA),), noop):
                                          no matches for Select(SubA) with subject types: C
                                      """).strip(),
                                    str(cm.exception))
Пример #21
0
  def test_ruleset_unreachable_due_to_product_of_select_dependencies(self):
    rules = [
      (A, (SelectDependencies(B, SubA, field_types=(D,)),), noop),
    ]
    intrinsics = [
      (B, C, noop),
    ]
    validator = RulesetValidator(RuleIndex.create(rules, intrinsics),
      goal_to_product={},
      root_subject_fns={k: lambda p: Select(p) for k in (A,)})

    with self.assertRaises(ValueError) as cm:
      validator.validate()

    self.assert_equal_with_printing(dedent("""
                             Rules with errors: 1
                               (A, (SelectDependencies(B, SubA, field_types=(D,)),), noop):
                                 Unreachable with subject types: Any
                             """).strip(),
                                    str(cm.exception))
Пример #22
0
 def test_fails_if_root_subject_types_empty(self):
   rules = [
     (A, (Select(B),), noop),
   ]
   with self.assertRaises(ValueError) as cm:
     RulesetValidator(NodeBuilder.create(rules, tuple()),
     goal_to_product={},
     root_subject_fns={})
   self.assertEquals(dedent("""
                               root_subject_fns must not be empty
                            """).strip(), str(cm.exception))
Пример #23
0
  def test_ruleset_unreachable_due_to_product_of_select_dependencies(self):
    rules = [
      (A, (SelectDependencies(B, SubA, field_types=(D,)),), noop),
    ]
    intrinsics = [
      (B, C, noop),
    ]
    validator = RulesetValidator(NodeBuilder.create(rules, intrinsics),
      goal_to_product={},
      root_subject_fns={k: lambda p: Select(p) for k in (A,)})

    with self.assertRaises(ValueError) as cm:
      validator.validate()

    self.assert_equal_with_printing(dedent("""
                             Rules with errors: 1
                               (A, (SelectDependencies(B, SubA, u'dependencies', field_types=(D,)),), noop):
                                 Unreachable with subject types: Any
                             """).strip(),
                                    str(cm.exception))
Пример #24
0
  def test_ruleset_with_failure_due_to_incompatible_subject_for_intrinsic(self):
    rules = [
      (D, (Select(C),), noop)
    ]
    intrinsics = [
      (B, C, noop),
    ]
    validator = RulesetValidator(NodeBuilder.create(rules, intrinsics),
      goal_to_product={},
      root_subject_fns={k: lambda p: Select(p) for k in (A,)})

    with self.assertRaises(ValueError) as cm:
      validator.validate()

    self.assert_equal_with_printing(dedent("""
                                      Rules with errors: 1
                                        (D, (Select(C),), noop):
                                          no matches for Select(C) with subject types: A
                                      """).strip(),
                                    str(cm.exception))
Пример #25
0
  def test_not_fulfillable_duplicated_dependency(self):
    # If a rule depends on another rule+subject in two ways, and one of them is unfulfillable
    # Only the unfulfillable one should be in the errors.
    rules = [
      (B, (Select(D),), noop),
      (D, (Select(A), SelectDependencies(A, SubA, field_types=(C,))), noop),
      (A, (Select(SubA),), noop)
    ]
    validator = RulesetValidator(RuleIndex.create(rules, tuple()),
      goal_to_product={},
      root_subject_fns=_suba_root_subject_fns)

    with self.assertRaises(ValueError) as cm:
      validator.validate()

    self.assert_equal_with_printing(dedent("""
                      Rules with errors: 2
                        (B, (Select(D),), noop):
                          depends on unfulfillable (D, (Select(A), SelectDependencies(A, SubA, field_types=(C,))), noop) of SubA with subject types: SubA
                        (D, (Select(A), SelectDependencies(A, SubA, field_types=(C,))), noop):
                          depends on unfulfillable (A, (Select(SubA),), noop) of C with subject types: SubA""").strip(),
        str(cm.exception))
Пример #26
0
    def test_not_fulfillable_duplicated_dependency(self):
        # If a rule depends on another rule+subject in two ways, and one of them is unfulfillable
        # Only the unfulfillable one should be in the errors.
        rules = [(B, (Select(D), ), noop),
                 (D, (Select(A), SelectDependencies(A, SubA,
                                                    field_types=(C, ))), noop),
                 (A, (Select(SubA), ), noop)]
        validator = RulesetValidator(RuleIndex.create(rules, tuple()),
                                     goal_to_product={},
                                     root_subject_fns=_suba_root_subject_fns)

        with self.assertRaises(ValueError) as cm:
            validator.validate()

        self.assert_equal_with_printing(
            dedent("""
                      Rules with errors: 2
                        (B, (Select(D),), noop):
                          depends on unfulfillable (D, (Select(A), SelectDependencies(A, SubA, field_types=(C,))), noop) of SubA with subject types: SubA
                        (D, (Select(A), SelectDependencies(A, SubA, field_types=(C,))), noop):
                          depends on unfulfillable (A, (Select(SubA),), noop) of C with subject types: SubA"""
                   ).strip(), str(cm.exception))
Пример #27
0
  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)
Пример #28
0
    def __init__(self,
                 goals,
                 tasks,
                 project_tree,
                 graph_lock=None,
                 inline_nodes=True,
                 graph_validator=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 graph_lock: A re-entrant lock to use for guarding access to the internal ProductGraph
                       instance. Defaults to creating a new threading.RLock().
    :param inline_nodes: Whether to inline execution of `inlineable` Nodes. This improves
                         performance, but can make debugging more difficult because the entire
                         execution history is not recorded in the ProductGraph.
    :param graph_validator: A validator that runs over the entire graph after every scheduling
                            attempt. Very expensive, very experimental.
    """
        self._products_by_goal = goals
        self._project_tree = project_tree
        self._node_builder = NodeBuilder.create(tasks)

        self._graph_validator = graph_validator
        self._product_graph = ProductGraph()
        self._product_graph_lock = graph_lock or threading.RLock()
        self._inline_nodes = inline_nodes

        select_product = lambda product: Select(product)
        select_dep_addrs = lambda product: SelectDependencies(
            product, Addresses, field_types=(Address, ))
        self._root_selector_fns = {
            Address: select_product,
            PathGlobs: select_product,
            SingleAddress: select_dep_addrs,
            SiblingAddresses: select_dep_addrs,
            AscendantAddresses: select_dep_addrs,
            DescendantAddresses: select_dep_addrs,
        }

        RulesetValidator(self._node_builder, goals,
                         self._root_selector_fns.keys()).validate()
Пример #29
0
    def test_ruleset_with_explicit_type_constraint(self):
        rules = [(Exactly(A), (Select(B),), noop), (B, (Select(A),), noop)]
        validator = RulesetValidator(NodeBuilder.create(rules), goal_to_product=dict(), root_subject_types=tuple())

        validator.validate()