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_remove(self): # Set up two nodes and run a simulation in which items # are randomly added at specific time intervals sim_reset() alice = QuantumNode("Alice", 1) bob = QuantumNode("Bob", 2) conn = ClassicalFibreConnection(alice, bob, length=.0001) aliceDQ = DistributedQueue(alice, conn) bobDQ = DistributedQueue(bob, conn) aliceProto = TestProtocol(alice, aliceDQ, 1) bobProto = TestProtocol(bob, bobDQ, 1) nodes = [ (alice, [aliceProto]), (bob, [bobProto]), ] conns = [(conn, "dqp_conn", [aliceProto, bobProto])] network = EasyNetwork(name="DistQueueNetwork", nodes=nodes, connections=conns) network.start() sim_run(1000) # Check the Queue contains ordered elements from Alice and Bob queueA = aliceDQ.queueList[0] queueB = bobDQ.queueList[0] qA = queueA.sequence_to_item qB = queueB.sequence_to_item # Make all the items ready for seq in qA: queueA.ack(seq) queueA.ready(seq) for seq in qB: queueB.ack(seq) queueB.ready(seq) # First they should have the same length self.assertGreater(len(qA), 0) self.assertEqual(len(qA), len(qB)) # Check the items are the same and the sequence numbers are ordered count = 0 for k in range(len(qA)): self.assertEqual(qA[k].request, qB[k].request) self.assertEqual(qA[k].seq, qB[k].seq) self.assertEqual(qA[k].seq, count) count = count + 1 # Check that we can remove the items (locally) at both nodes rqid = 0 rqseqs = set([randint(0, len(qA) - 1) for t in range(10)]) for qseq in rqseqs: q_item = aliceDQ.remove_item(rqid, qseq) self.assertIsNotNone(q_item) self.assertFalse(aliceDQ.queueList[rqid].contains(qseq)) # Check that we can pop the remaining items in the correct order remaining = set(range(len(qB))) - rqseqs for qseq in remaining: q_item = aliceDQ.local_pop(rqid) self.assertEqual(q_item.seq, qseq) self.assertIsNotNone(q_item)