Ejemplo n.º 1
0
    def apply(self):
        try:
            if self.agent_id != self._replay.agent_id:
                raise ReplayError(
                    "Tried to apply the entry belonging to the "
                    "agent id: %r, but the Replay instance "
                    "belogs to: %r" % (self.agent_id, self._replay.agent_id)
                )

            self._replay.set_current_time(self._timestamp)

            if self.journal_id == "agency":
                self._replay.replay_agency_entry(self)
                return self

            self._replay._log_entry(self)

            self._replay.require_agent()
            instance = self._replay.registry.get(self.journal_id, None)
            if instance is None:
                raise ReplayError(
                    "Instance for journal_id %r not found "
                    "in the registry when replaying %r" % (self.journal_id, self.function_id)
                )

            result = instance.replay(self)

            if self._next_effect < len(self._side_effects):
                remaining = self._side_effects[self._next_effect]
                side_effect = self.restore_side_effect(remaining, parse_args=True)
                function_id, args, kwargs, _effects, _result = side_effect
                se_desc = side_effect_as_string(function_id, args, kwargs)
                raise ReplayError("Function %s did not consume side-effect %s" % (self.function_id, se_desc))

            frozen_result = self._replay.serializer.freeze(result)
            unfrozen_result = self._replay.unserializer.convert(frozen_result)
            expected = self._replay.unserializer.convert(self.frozen_result)

            if unfrozen_result != expected:
                res = pformat(unfrozen_result)
                exp = pformat(expected)

                diffs = text_helper.format_diff(exp, res, "\n               ")
                raise ReplayError(
                    "Function %r replay result "
                    "does not match recorded one.\n"
                    "  RESULT:      %s\n"
                    "  EXPECTED:    %s\n"
                    "  DIFFERENCES: %s\n" % (self.function_id, res, exp, diffs)
                )

            self._replay.log("State after the entry: %r", self._replay.agent._get_state())

            return self
        except Exception as e:
            error.handle_exception(
                "replay", e, "Failed trying to apply instance %r entry %r: ", self.journal_id, self.function_id
            )
            raise
Ejemplo n.º 2
0
    def _validate_replay_on_agent(self, history, entries):
        aid = history.agent_id
        agent = yield self.driver.find_agent(aid)
        if agent is None:
            self.warning(
                'Agent with id %r not found. '
                'This usually means it was terminated, during the test.', aid)
            return
        if agent._instance_id != history.instance_id:
            self.warning(
                'Agent instance id is %s, the journal entries are for '
                'instance_id %s. This history will not get validated, as '
                'now we dont have the real instance to compare the result '
                'with.', agent._instance_id, history.instance_id)
            return

        self.log("Validating replay of %r with id: %s",
                 agent.agent.__class__.__name__, aid)

        self.log("Found %d entries of this agent.", len(entries))
        r = replay.Replay(iter(entries), aid)
        for entry in r:
            entry.apply()

        agent_snapshot, protocols = agent.snapshot_agent()
        self.log("Replay complete. Comparing state of the agent and his "
                 "%d protocols.", len(protocols))
        if agent_snapshot._get_state() != r.agent._get_state():
            s1 = r.agent._get_state()
            s2 = agent_snapshot._get_state()
            comp = self.deep_compare(s1, s2)
            info = "  INFO:        %s: %s\n" % comp if comp else ""
            res = repr(pytree.serialize(agent_snapshot._get_state()))
            exp = repr(pytree.serialize(r.agent._get_state()))
            diffs = text_helper.format_diff(exp, res, "\n               ")
            self.fail("Agent snapshot different after replay:\n%s"
                      "  SNAPSHOT:    %s\n"
                      "  EXPECTED:    %s\n"
                      "  DIFFERENCES: %s\n"
                      % (info, res, exp, diffs))

        self.assertEqual(agent_snapshot._get_state(), r.agent._get_state())

        self.assertEqual(len(r.protocols), len(protocols),
                         "Protocols of agent: %s from replay doesn't much "
                         "the test result. \nReplay: %s,\nResult: %s" %
                         (aid,
                          pformat(r.protocols),
                          pformat(protocols)))

        def sort(recorders):
            # at some point the protocols are stored as the dictionary values,
            # for this reason they come in snapshot in random order and need
            # to be sorted before comparing
            return sorted(recorders, key=operator.attrgetter('journal_id'))

        for from_snapshot, from_replay in zip(sort(protocols),
                                              sort(r.protocols)):
            self.assertEqual(from_snapshot._get_state(),
                             from_replay._get_state(),
                             "Failed comparing state of protocols. \nA=%s "
                             "\B=%s." % (pformat(from_snapshot),
                                         pformat(from_replay)))