def test_sending_references_preserves_eq(self): calls = [] class Object(cap.PlashObject): def cap_invoke(self, args): calls.append(args) loop = self.make_event_loop() sock1, sock2 = self.socketpair() got = self._read_to_list(loop, sock1) [imported] = self.make_connection(loop, sock2, [], 1) writer = plash.comms.stream.FDBufferedWriter(loop, sock1) object1 = Object() object2 = Object() imported.cap_invoke(("body", (object1, object1, object2), ())) loop.run_awhile() decoded = [cap.decode_pocp_message(data) for data in got] self.assertEquals( decoded, [("invoke", cap.encode_wire_id(cap.NAMESPACE_RECEIVER, 0), [cap.encode_wire_id(cap.NAMESPACE_SENDER, 0), cap.encode_wire_id(cap.NAMESPACE_SENDER, 0), cap.encode_wire_id(cap.NAMESPACE_SENDER, 1)], "body")]) # Now check that we can invoke the resulting object and drop # it twice for unused in range(2): writer.write(plash.comms.simple.make_message( cap.make_invoke_message( cap.encode_wire_id(cap.NAMESPACE_RECEIVER, 0), [], "body"))) writer.write(plash.comms.simple.make_message( cap.make_drop_message( cap.encode_wire_id(cap.NAMESPACE_RECEIVER, 0)))) loop.run_awhile()
def test_dropping_all_exported_references(self): loop = self.make_event_loop() sock1, sock2 = self.socketpair() self.make_connection(loop, sock1, [cap.PlashObject() for index in range(100)]) del sock1 writer = plash.comms.stream.FDBufferedWriter(loop, sock2) for index in range(100): writer.write(plash.comms.simple.make_message(cap.make_drop_message( cap.encode_wire_id(cap.NAMESPACE_RECEIVER, index)))) loop.run_awhile() self.assertTrue(self._connection_dropped(sock2))
def test_dropping_exported_references(self): deleted = [] class Object(cap.PlashObject): def __init__(self, index): self._index = index def __del__(self): deleted.append(self._index) loop = self.make_event_loop() sock1, sock2 = self.socketpair() self.make_connection(loop, sock1, [Object(index) for index in range(100)]) writer = plash.comms.stream.FDBufferedWriter(loop, sock2) # Should work for any sequence of indexes indexes = [5, 10, 56, 1, 0] for index in indexes: writer.write(plash.comms.simple.make_message(cap.make_drop_message( cap.encode_wire_id(cap.NAMESPACE_RECEIVER, index)))) loop.run_awhile() self.assertEquals(deleted, indexes)
def test_receiving_and_invoking_single_use_reference(self): calls = [] class Object(cap.PlashObject): def cap_invoke(self, args): calls.append(args) loop = self.make_event_loop() sock1, sock2 = self.socketpair() exported = Object() self.make_connection(loop, sock1, [exported]) del sock1 received = self._read_to_list(loop, sock2) writer = plash.comms.stream.FDBufferedWriter(loop, sock2) writer.write(plash.comms.simple.make_message(cap.make_invoke_message( cap.encode_wire_id(cap.NAMESPACE_RECEIVER, 0), [cap.encode_wire_id(cap.NAMESPACE_SENDER_SINGLE_USE, 1234)], "body data"))) # Drop the exported object so that the imported single use # object is the only one left. writer.write(plash.comms.simple.make_message(cap.make_drop_message( cap.encode_wire_id(cap.NAMESPACE_RECEIVER, 0)))) loop.run_awhile() self.assertEquals(len(calls), 1) data, caps, fds = calls[0] [received_obj] = caps assert isinstance(received_obj, self.base_class), received_obj self.check_remote_object(received_obj, object_id=1234, single_use=True) self.check_object_used_up(received_obj, used_up=False) received_obj.cap_invoke(("some return message", (), ())) self.check_object_used_up(received_obj, used_up=True) # This tests sending a message and immediately disconnecting. # The message should be queued, not dropped. The message # should be sent before the connection is dropped. loop.run_awhile() decoded = [cap.decode_pocp_message(data) for data in received] self.assertEquals( decoded, [("invoke", cap.encode_wire_id(cap.NAMESPACE_RECEIVER, 1234), [], "some return message")]) self.assertTrue(self._connection_dropped(sock2))
def test_drop_encoding(self): self.assertEquals( cap.decode_pocp_message(cap.make_drop_message(789)), ("drop", 789))