PROTON-2005: fix pn_delivery_abort() for multiframe and session outgoing bytes
diff --git a/c/src/core/engine.c b/c/src/core/engine.c
index 4187cad..c3a82ad 100644
--- a/c/src/core/engine.c
+++ b/c/src/core/engine.c
@@ -2062,6 +2062,8 @@
if (!delivery->local.settled) { /* Can't abort a settled delivery */
delivery->aborted = true;
pn_delivery_settle(delivery);
+ delivery->link->session->outgoing_bytes -= pn_buffer_size(delivery->bytes);
+ pn_buffer_clear(delivery->bytes);
}
}
diff --git a/c/tests/connection_driver_test.cpp b/c/tests/connection_driver_test.cpp
index 62b60ff..f8e3345 100644
--- a/c/tests/connection_driver_test.cpp
+++ b/c/tests/connection_driver_test.cpp
@@ -302,6 +302,7 @@
/* Aborted delivery consumes no credit */
CHECK(1 == pn_link_credit(rcv));
CHECK(1 == pn_link_credit(snd));
+ CHECK(0 == pn_session_outgoing_bytes(pn_link_session(snd)));
}
void send_receive_message(const std::string &tag, pn_test::driver_pair &d) {
diff --git a/python/tests/proton_tests/engine.py b/python/tests/proton_tests/engine.py
index 3f07c9f..5f9543f 100644
--- a/python/tests/proton_tests/engine.py
+++ b/python/tests/proton_tests/engine.py
@@ -895,6 +895,35 @@
binary = self.rcv.recv(1024)
assert binary is None
+ def test_multiframe_abort(self):
+ self.rcv.flow(1)
+ sd = self.snd.delivery("tag")
+ msg = b"this is a test"
+ n = self.snd.send(msg)
+ assert n == len(msg)
+
+ self.pump()
+
+ binary = self.rcv.recv(1024)
+ assert binary == msg, (binary, msg)
+
+ msg = b"this is more. Error if not discarded."
+ n = self.snd.send(msg)
+ assert n == len(msg)
+ sd.abort()
+ assert sd.aborted
+
+ # Confirm abort discards the sender's buffered content, i.e. no data in generated transfer frame.
+ # We want:
+ # @transfer(20) [handle=0, delivery-id=0, delivery-tag=b"tag", message-format=0, settled=true, aborted=true]
+ wanted = b"\x00\x00\x00%\x02\x00\x00\x00\x00S\x14\xd0\x00\x00\x00\x15\x00\x00\x00\nR\x00R\x00\xa0\x03tagR\x00A@@@@A"
+ t = self.snd.transport
+ wire_bytes = t.peek(1024)
+ assert wanted == wire_bytes
+
+ self.pump()
+ assert self.rcv.current.aborted
+
def test_disposition(self):
self.rcv.flow(1)