Source code for msgtransfer.imp_0.checker
import argparse
[docs]class Checker():
"""
Maintain the global state of a distributed system of msgtransfer.imp_0
nodes and check some assertions. Created by msgtransfer.servicetester
when testing the distributed system. Maintains the following variables:
- servicetester: the servicetester object that started this checker object
- n: number of (msgtransfer.imp0) nodes
- sent: sent state maintained by servicetester.serviceparts object
- transit_counts: map indexed by node pairs of lists of ints.
transit_counts[(j,k)] is a list of (k-j)%n+1 ints, where list entry p
is the number of packets of flow (j,k) that have passed by node (j+p)%n.
Function ``handle_event(e)``:
- RPC-called by an node to report an event ``e`` at the node.
Here ``e`` is a ``(p,j,k,msg)`` tuple indicating the generation or
arrival at node ``p`` of a packet with srcid ``j``, dstid ``k``,
and data equal to serialized ``msg``.
- Update the global state according to ``e`` and check if following
assertion still holds:
for every event (p, j, k, msg):
sent[(j,k)][transit_counts[(j,k)][(j+k)%n]] == msg
"""
def __init__(self, servicetester, argv):
self.servicetester = servicetester
parser = argparse.ArgumentParser()
parser.add_argument("num_nodes", type=int, help="number of nodes")
args = parser.parse_args(argv[1:])
self.num_nodes = args.num_nodes
self.sent = servicetester.serviceparts.sent
self.transit_counts = {(j,k):[0 for p in range((k-j)%self.num_nodes + 1)]
for k in range(self.num_nodes)
for j in range(self.num_nodes) if k != j}
if self.servicetester.eventlog:
self.servicetester.eventlog.append(('checker', 'init', [str(self.num_nodes)]))
def handle_event(self, event):
"""
events:
- ('checker', 'linkup'|'linkdown', j, k): j-k link initiated by j.
- ('checker', 'sent'|'fwd'|'rcvd', j, dst, msg): event occurs at node j,
msg[0] is source node of msg.
"""
print("handle_event called:", event, flush=True)
event = event[1:]
if event[0] in ('sent', 'fwd', 'rcvd'):
event = event[1:]
# event: (j, dst, msg)
j, dst, msg = event
src = msg[0]
sent_src_dst = self.sent[(src,dst)]
count_src_dst = self.transit_counts[(src,dst)]
src2j_hops = (j - src) % self.num_nodes
# check msgtransfer.imp0 assertion
if sent_src_dst[count_src_dst[src2j_hops]] != msg:
print("Node", j, "event invalid", flush=True)
else:
print("Node", j, "event valid", flush=True)
count_src_dst[src2j_hops] += 1
# nothing to check for 'linkup' and 'linkdown' events
###### END class Checker of module msgtransfer.imp0.checker ############