Beispiel #1
0
class State(PClass):
    attrs = pset_field(Attr)
    props = pset_field(Prop)

    def __init__(
        self,
        attrs: Optional[Iterable[Attr]] = None,
        props: Optional[Iterable[Prop]] = None,
    ):
        self.attrs = s() if attrs is None else PSet(attrs)
        self.props = s() if props is None else PSet(props)

    def __or__(self, s: State):
        return State(self.attrs | s.attrs, self.props | s.props)
Beispiel #2
0
class BackendDescription(PClass):
    """
    Represent one kind of storage backend we might be able to use.

    :ivar name: The human-meaningful name of this storage backend.
    :ivar needs_reactor: A flag which indicates whether this backend's API
        factory needs to have a reactor passed to it.
    :ivar needs_cluster_id: A flag which indicates whether this backend's API
        factory needs to have the cluster's unique identifier passed to it.
    :ivar api_factory: An object which can be called with some simple
        configuration data and which returns the API object implementing this
        storage backend.
    :ivar required_config: A set of the dataset configuration keys
        required to initialize this backend.
    :type required_config: ``PSet`` of ``unicode``
    :ivar deployer_type: A constant from ``DeployerType`` indicating which kind
        of ``IDeployer`` the API object returned by ``api_factory`` is usable
        with.
    """
    name = field(type=unicode, mandatory=True)
    needs_reactor = field(type=bool, mandatory=True)
    # XXX Eventually everyone will take cluster_id so we will throw this flag
    # out.
    needs_cluster_id = field(type=bool, mandatory=True)
    # Config "dataset" keys required to initialize this backend.
    required_config = pset_field(unicode)
    api_factory = field(mandatory=True)
    deployer_type = field(
        mandatory=True,
        invariant=lambda value:
        (value in DeployerType.iterconstants(), "Unknown deployer_type"),
    )
Beispiel #3
0
class _FlakyAnnotation(PClass):

    max_runs = field(int,
                     mandatory=True,
                     invariant=lambda x: (x > 0, "must run at least once"))
    min_passes = field(int,
                       mandatory=True,
                       invariant=lambda x: (x > 0, "must pass at least once"))
    jira_keys = pset_field(unicode, optional=False)

    __invariant__ = _flaky_invariants

    def to_dict(self):
        return {
            'max_runs': self.max_runs,
            'min_passes': self.min_passes,
            'jira_keys': set(self.jira_keys),
        }
Beispiel #4
0
class _FlakyAnnotation(PClass):

    max_runs = field(int,
                     mandatory=True,
                     invariant=lambda x: (x > 0, "must run at least once"))
    min_passes = field(int,
                       mandatory=True,
                       invariant=lambda x: (x > 0, "must pass at least once"))
    jira_keys = pset_field(unicode, optional=False)

    __invariant__ = lambda x: (
        (x.max_runs >= x.min_passes, "Can't pass more than we run"),
        (len(x.jira_keys) > 0, "Must provide a jira key"),
    )

    def to_dict(self):
        return {
            'max_runs': self.max_runs,
            'min_passes': self.min_passes,
            'jira_keys': set(self.jira_keys),
        }
Beispiel #5
0
class Task(PClass):
    """
    A tree of actions with the same task UUID.
    """
    _nodes = pmap_field(TaskLevel, (WrittenAction, WrittenMessage))
    _completed = pset_field(TaskLevel)
    _root_level = TaskLevel(level=[])

    def root(self):
        """
        @return: The root L{WrittenAction}.
        """
        return self._nodes[self._root_level]

    def is_complete(self):
        """
        @return bool: True only if all messages in the task tree have been
        added to it.
        """
        return self._root_level in self._completed

    def _insert_action(self, node):
        """
        Add a L{WrittenAction} to the tree.

        Parent actions will be created as necessary.

        @param child: A L{WrittenAction} to add to the tree.

        @return: Updated L{Task}.
        """
        task = self
        if (
            node.end_message and node.start_message and
            (len(node.children) == node.end_message.task_level.level[-1] - 2)):
            # Possibly this action is complete, make sure all sub-actions
            # are complete:
            completed = True
            for child in node.children:
                if (
                    isinstance(child, WrittenAction)
                    and child.task_level not in self._completed):
                    completed = False
                    break
            if completed:
                task = task.transform(["_completed"],
                                      lambda s: s.add(node.task_level))
        task = task.transform(["_nodes", node.task_level], node)
        return task._ensure_node_parents(node)

    def _ensure_node_parents(self, child):
        """
        Ensure the node (WrittenAction/WrittenMessage) is referenced by parent
        nodes.

        Parent actions will be created as necessary.

        @param child: A L{WrittenMessage} or L{WrittenAction} which is
            being added to the tree.

        @return: Updated L{Task}.
        """
        task_level = child.task_level
        if task_level.parent() is None:
            return self

        parent = self._nodes.get(task_level.parent())
        if parent is None:
            parent = WrittenAction(
                task_level=task_level.parent(), task_uuid=child.task_uuid)
        parent = parent._add_child(child)
        return self._insert_action(parent)

    def add(self, message_dict):
        """
        Update the L{Task} with a dictionary containing a serialized Eliot
        message.

        @param message_dict: Dictionary whose task UUID matches this one.

        @return: Updated L{Task}.
        """
        is_action = message_dict.get(ACTION_TYPE_FIELD) is not None
        written_message = WrittenMessage.from_dict(message_dict)
        if is_action:
            action_level = written_message.task_level.parent()
            action = self._nodes.get(action_level)
            if action is None:
                action = WrittenAction(
                    task_level=action_level,
                    task_uuid=message_dict[TASK_UUID_FIELD])
            if message_dict[ACTION_STATUS_FIELD] == STARTED_STATUS:
                # Either newly created MissingAction, or one created by
                # previously added descendant of the action.
                action = action._start(written_message)
            else:
                action = action._end(written_message)
            return self._insert_action(action)
        else:
            # Special case where there is no action:
            if written_message.task_level.level == [1]:
                return self.transform([
                    "_nodes", self._root_level], written_message, [
                        "_completed"], lambda s: s.add(self._root_level))
            else:
                return self._ensure_node_parents(written_message)
Beispiel #6
0
 class Record(PRecord):
     value = pset_field((Something, int))
Beispiel #7
0
 class Record(PRecord):
     value = pset_field(Something)
     value2 = pset_field(int)
Beispiel #8
0
 class Record(PRecord):
     value = pset_field(int, optional=True)
Beispiel #9
0
 class Record(PRecord):
     value = pset_field(int)
Beispiel #10
0
 class Record(PRecord):
     value = pset_field((int, str))
Beispiel #11
0
class RecordContainingContainers(PRecord):
    map = pmap_field(str, str)
    vec = pvector_field(str)
    set = pset_field(str)
Beispiel #12
0
class TypedContainerObj(PClass):
    map = pmap_field(str, str)
    set = pset_field(str)
    vec = pvector_field(str)
class Columns(PRecord):
    all_columns = pvector_field(str)
    current_set = pset_field(str)
Beispiel #14
0
 class Record(PRecord):
     value = pset_field(("record_test.Something", "record_test.Another"))
Beispiel #15
0
 class Record(PRecord):
     value = pset_field("record_test.Something")
Beispiel #16
0
class Game(PClass):
    black_positions = pset_field(Position)
    white_positions = pset_field(Position)
Beispiel #17
0
 class Record(PRecord):
     value = pset_field(int, initial=(1, 2))
Beispiel #18
0
class Ranker(PClass):
    _greater_than = pmap_field(str, PSet)
    _remaining_pairs = pset_field(PSet)
    _all_items = field(initial=pset())

    @classmethod
    def new(cls, items):
        remaining = pset({pset(x) for x in combinations(items, 2)})
        return cls(_remaining_pairs=remaining)

    def is_complete(self):
        return len(self._remaining_pairs) == 0

    def add_ranking(self, larger, smaller):
        """ Decide that 'larger' is greater than 'smaller' """
        key = pset([larger, smaller])

        slf = self

        if slf.cmp_items(smaller, larger) > 0:
            raise ValueError(f"{smaller} is already greater than {larger}")

        if key not in slf._remaining_pairs:
            return slf

        # Set larger as being greater than smaller
        slf = slf.set(_remaining_pairs=slf._remaining_pairs.remove(key))
        if larger not in slf._greater_than:
            slf = slf.set(_greater_than=slf._greater_than.set(larger, pset()))

        slf = slf.set(
            _greater_than=slf._greater_than.set(
                larger, slf._greater_than[larger].add(smaller)),
            _all_items=slf._all_items.add(larger).add(smaller),
        )

        # Set larger as being greater than everything which smaller is greater than
        for item in slf.everying_less_than(larger):
            slf = slf.add_ranking(larger, item)

        return slf

    def sample(self):
        for item in self._remaining_pairs:
            return item

    def everying_less_than(self, item):
        return self._greater_than[item]

    def has_item(self, item):
        return item in self._all_items

    def sorted_items(self, *args, **kwargs):
        return self.sorted(self._all_items, *args, **kwargs)

    def sorted(self, items, *args, **kwargs):
        kwargs["key"] = self.key_func
        return sorted(items, *args, **kwargs)

    @property
    def key_func(self):
        return cmp_to_key(self.cmp_items)

    def cmp_items(self, a, b):
        if b in self._greater_than.get(a, {}):
            return 1

        if a in self._greater_than.get(b, {}):
            return -1

        return 0