def test_comm_timeout(self): self.callback_storage = [] def add_callback(result): self.callback_storage.append(result) sim_reset() alice = QuantumNode("Alice", 1) bob = QuantumNode("Bob", 2) conn = ClassicalFibreConnection(alice, bob, length=0.01) aliceDQ = DistributedQueue(alice, conn) aliceDQ.add_callback = add_callback num_adds = 100 aliceProto = TestProtocol(alice, aliceDQ, 1, maxNum=num_adds) nodes = [alice, bob] conns = [(conn, "dqp_conn", [aliceProto])] network = EasyNetwork(name="DistQueueNetwork", nodes=nodes, connections=conns) network.start() sim_run(5000) expected_qid = 0 expected_results = [(aliceDQ.DQ_TIMEOUT, expected_qid, qseq % aliceDQ.myWsize, [alice.name, qseq]) for qseq in range(num_adds)] # Check that all attempted add's timed out self.assertEqual(self.callback_storage, expected_results) # Check that alice's distributed queue has no outstanding add acks self.assertEqual(aliceDQ.waitAddAcks, {}) # Check that all of the local queues are empty for local_queue in aliceDQ.queueList: self.assertEqual(local_queue.queue, []) self.assertEqual(local_queue.sequence_to_item, {}) # Check that we incremented the comms_seq self.assertEqual(aliceDQ.comms_seq, num_adds)
def test_resend_acks(self): sim_reset() node = QuantumNode("TestNode 1", 1) node2 = QuantumNode("TestNode 2", 2) conn = ClassicalFibreConnection(node, node2, length=25) dq = DistributedQueue(node, conn, numQueues=3, throw_local_queue_events=True) dq2 = DistributedQueue(node2, conn, numQueues=3, throw_local_queue_events=True) dq.connect_to_peer_protocol(dq2, conn) storage1 = [] storage2 = [] def callback1(result): storage1.append(result) def callback2(result): storage2.append(result) nodes = [ (node, [dq]), (node2, [dq2]), ] conns = [(conn, "dq_conn", [dq, dq2])] network = EasyNetwork(name="DistQueueNetwork", nodes=nodes, connections=conns) network.start() dq.add_callback = callback1 dq2.add_callback = callback2 # Add one request create_id = 0 request = SchedulerRequest(0, 0, 0, 0, create_id, 0, 0, True, False, False, True) dq2.add(request=request, qid=0) run_time = dq.comm_delay * dq.timeout_factor sim_run(run_time) # Set way to short timeout (to force resend) dq2.timeout_factor = 1 / 2 # Add one request (slave) create_id = 1 request = SchedulerRequest(0, 0, 0, 0, create_id, 0, 0, True, False, False, True) dq2.add(request=request, qid=0) run_time += (dq.comm_delay + 1) * 4 sim_run(run_time) # Set to correct factor again dq2.timeout_factor = 2 create_id = 2 request = SchedulerRequest(0, 0, 0, 0, create_id, 0, 0, True, False, False, True) dq.add(request=request, qid=0) dq2.add(request=request, qid=0) run_time += dq.comm_delay * dq.timeout_factor sim_run(run_time) self.assertEqual(len(storage1), 4) self.assertEqual(len(storage2), 4) q_seqs1 = [res[2] for res in storage1] q_seqs2 = [res[2] for res in storage2] for qseq in range(4): for q_seqs in [q_seqs1, q_seqs2]: # TODO do we care about the ordering? self.assertIn(qseq, q_seqs)
def test_unordered_subsequent_acks(self): sim_reset() node = QuantumNode("TestNode 1", 1) node2 = QuantumNode("TestNode 2", 2) conn = ClassicalFibreConnection(node, node2, length=25) dq = DistributedQueue(node, conn, numQueues=3, throw_local_queue_events=True) dq2 = DistributedQueue(node2, conn, numQueues=3, throw_local_queue_events=True) dq.connect_to_peer_protocol(dq2, conn) storage1 = [] storage2 = [] def callback1(result): storage1.append(result) def callback2(result): storage2.append(result) nodes = [ (node, [dq]), (node2, [dq2]), ] conns = [(conn, "dq_conn", [dq, dq2])] network = EasyNetwork(name="DistQueueNetwork", nodes=nodes, connections=conns) network.start() # Add three requests (master) dq.add_callback = callback1 dq2.add_callback = callback2 for create_id in range(3): request = SchedulerRequest(0, 0, 0, 0, create_id, 0, 0, True, False, False, True) dq.add(request=request, qid=0) run_time = dq.comm_delay * dq.timeout_factor sim_run(run_time) self.assertEqual(len(storage1), 3) self.assertEqual(len(storage2), 3) q_seqs1 = [res[2] for res in storage1] q_seqs2 = [res[2] for res in storage2] self.assertEqual(q_seqs1, [0, 1, 2]) self.assertEqual(q_seqs2, [0, 1, 2]) # Remove one request (such that next queue seq will be 0 again) dq.remove_item(0, 1) dq2.remove_item(0, 1) storage1 = [] storage2 = [] # Add requests from master and slave create_id = 3 request = SchedulerRequest(0, 0, 0, 0, create_id, 0, 0, True, False, False, True) dq.add(request=request, qid=0) request = SchedulerRequest(0, 0, 0, 0, create_id, 0, 0, True, False, False, True) dq2.add(request=request, qid=0) run_time += dq.comm_delay * dq.timeout_factor sim_run(run_time) self.assertEqual(len(storage1), 2) self.assertEqual(len(storage2), 2) q_seqs1 = [res[2] for res in storage1] q_seqs2 = [res[2] for res in storage2] self.assertIn(1, q_seqs1) self.assertIn(3, q_seqs1) self.assertIn(1, q_seqs2) self.assertIn(3, q_seqs2)
def test_full_queue(self): sim_reset() node = QuantumNode("TestNode 1", 1) node2 = QuantumNode("TestNode 2", 2) conn = ClassicalFibreConnection(node, node2, length=0.0001) dq = DistributedQueue(node, conn, numQueues=3) dq2 = DistributedQueue(node2, conn, numQueues=3) dq.connect_to_peer_protocol(dq2, conn) storage = [] def callback(result): storage.append(result) nodes = [ (node, [dq]), (node2, [dq2]), ] conns = [(conn, "dq_conn", [dq, dq2])] network = EasyNetwork(name="DistQueueNetwork", nodes=nodes, connections=conns) network.start() for j in range(dq.maxSeq): dq.add(request=j + 1, qid=0) sim_run(1000) with self.assertRaises(LinkLayerException): dq.add(request=0, qid=0) dq2.add_callback = callback for j in range(dq2.maxSeq): dq2.add(request=j + 1, qid=1) sim_run(2000) with self.assertRaises(LinkLayerException): dq2.add(request=dq2.maxSeq + 1, qid=1) self.assertEqual(len(storage), 257) self.assertEqual(storage[-1], (dq2.DQ_ERR, 1, None, dq2.maxSeq + 1)) storage = [] for j in range(dq.maxSeq): if j % 2: dq.add(request=j + 1, qid=2) else: dq2.add(request=j + 1, qid=2) dq2.add(request=dq.maxSeq + 1, qid=2) sim_run(3000) with self.assertRaises(LinkLayerException): dq.add(request=0, qid=2) self.assertEqual(len(storage), 257) self.assertEqual(storage[-1], (dq2.DQ_REJECT, 2, 0, dq2.maxSeq + 1))