This is an automated email from the ASF dual-hosted git repository.

robbie pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/qpid-proton-j.git


The following commit(s) were added to refs/heads/master by this push:
     new b95d892  PROTON-2227: restore behaviour around decode errors in 
Flow/Transfer/Disposition types
b95d892 is described below

commit b95d89297de36401fb8cfbb56064f29568abcd49
Author: Robbie Gemmell <rob...@apache.org>
AuthorDate: Fri May 22 17:42:46 2020 +0100

    PROTON-2227: restore behaviour around decode errors in 
Flow/Transfer/Disposition types
---
 .../codec/transport/FastPathDispositionType.java   |  12 +
 .../proton/codec/transport/FastPathFlowType.java   |  12 +
 .../codec/transport/FastPathTransferType.java      |  12 +
 .../qpid/proton/engine/impl/TransportImplTest.java | 375 +++++++++++++++++++++
 4 files changed, 411 insertions(+)

diff --git 
a/proton-j/src/main/java/org/apache/qpid/proton/codec/transport/FastPathDispositionType.java
 
b/proton-j/src/main/java/org/apache/qpid/proton/codec/transport/FastPathDispositionType.java
index 32bed2b..e2ed8d7 100644
--- 
a/proton-j/src/main/java/org/apache/qpid/proton/codec/transport/FastPathDispositionType.java
+++ 
b/proton-j/src/main/java/org/apache/qpid/proton/codec/transport/FastPathDispositionType.java
@@ -116,6 +116,18 @@ public class FastPathDispositionType implements 
AMQPType<Disposition>, FastPathD
                 throw new DecodeException("Incorrect type found in Disposition 
encoding: " + typeCode);
         }
 
+        if (count < 2) {
+            throw new DecodeException("The 'first' field cannot be omitted");
+        }
+
+        try {
+            return readFields(decoder, count);
+        } catch (NullPointerException npe) {
+            throw new DecodeException("Unexpected null value - mandatory field 
not set? (" + npe.getMessage() + ")", npe);
+        }
+    }
+
+    private final Disposition readFields(DecoderImpl decoder, int count) {
         Disposition disposition = new Disposition();
 
         for (int index = 0; index < count; ++index) {
diff --git 
a/proton-j/src/main/java/org/apache/qpid/proton/codec/transport/FastPathFlowType.java
 
b/proton-j/src/main/java/org/apache/qpid/proton/codec/transport/FastPathFlowType.java
index 534ab0c..4d17f2e 100644
--- 
a/proton-j/src/main/java/org/apache/qpid/proton/codec/transport/FastPathFlowType.java
+++ 
b/proton-j/src/main/java/org/apache/qpid/proton/codec/transport/FastPathFlowType.java
@@ -104,6 +104,18 @@ public class FastPathFlowType implements AMQPType<Flow>, 
FastPathDescribedTypeCo
                 throw new DecodeException("Incorrect type found in Flow 
encoding: " + typeCode);
         }
 
+        if (count < 4) {
+            throw new DecodeException("The outgoing-window field cannot be 
omitted");
+        }
+
+        try {
+            return readFields(decoder, count);
+        } catch (NullPointerException npe) {
+            throw new DecodeException("Unexpected null value - mandatory field 
not set? (" + npe.getMessage() + ")", npe);
+        }
+    }
+
+    private final Flow readFields(DecoderImpl decoder, int count) {
         Flow flow = new Flow();
 
         for (int index = 0; index < count; ++index) {
diff --git 
a/proton-j/src/main/java/org/apache/qpid/proton/codec/transport/FastPathTransferType.java
 
b/proton-j/src/main/java/org/apache/qpid/proton/codec/transport/FastPathTransferType.java
index b37c5b6..b540885 100644
--- 
a/proton-j/src/main/java/org/apache/qpid/proton/codec/transport/FastPathTransferType.java
+++ 
b/proton-j/src/main/java/org/apache/qpid/proton/codec/transport/FastPathTransferType.java
@@ -85,6 +85,18 @@ public class FastPathTransferType implements 
AMQPType<Transfer>, FastPathDescrib
                 throw new DecodeException("Incorrect type found in Transfer 
encoding: " + typeCode);
         }
 
+        if (count < 1) {
+            throw new DecodeException("The handle field cannot be omitted");
+        }
+
+        try {
+            return readFields(decoder, count);
+        } catch (NullPointerException npe) {
+            throw new DecodeException("Unexpected null value - mandatory field 
not set? (" + npe.getMessage() + ")", npe);
+        }
+    }
+
+    private final Transfer readFields(DecoderImpl decoder, int count) {
         Transfer transfer = new Transfer();
 
         for (int index = 0; index < count; ++index) {
diff --git 
a/proton-j/src/test/java/org/apache/qpid/proton/engine/impl/TransportImplTest.java
 
b/proton-j/src/test/java/org/apache/qpid/proton/engine/impl/TransportImplTest.java
index bd7e569..1f89075 100644
--- 
a/proton-j/src/test/java/org/apache/qpid/proton/engine/impl/TransportImplTest.java
+++ 
b/proton-j/src/test/java/org/apache/qpid/proton/engine/impl/TransportImplTest.java
@@ -3801,6 +3801,381 @@ public class TransportImplTest
         assertEquals("Unexpected condition", expectedCondition, ((Close) 
frameBody).getError());
     }
 
+    @Test
+    public void testEmptyBeginProvokesDecodeError() {
+        // Provide the bytes for Begin, but omit any fields to provoke a 
decode error.
+        byte[] bytes = new byte[] {  0x00, 0x00, 0x00, 0x0C, // Frame size = 
12 bytes.
+                0x02, 0x00, 0x00, 0x00, // DOFF, TYPE, 2x CHANNEL
+                0x00, 0x53, 0x11, 0x45};// Described-type, ulong type, Begin 
descriptor, list0.
+
+        doInvalidBeginProvokesDecodeErrorTestImpl(bytes, "The outgoing-window 
field cannot be omitted");
+    }
+
+    @Test
+    public void testTruncatedBeginProvokesDecodeError1() {
+        // Provide the bytes for Begin, but only give a null (i-e not-present) 
for the remote-channel.
+        byte[] bytes = new byte[] {  0x00, 0x00, 0x00, 0x0F, // Frame size = 
15 bytes.
+                0x02, 0x00, 0x00, 0x00, // DOFF, TYPE, 2x CHANNEL
+                0x00, 0x53, 0x11, (byte) 0xC0, // Described-type, ulong type, 
Begin descriptor, list8.
+                0x03, 0x01, 0x40 }; // size (3), count (1), remote-channel 
(null).
+
+        doInvalidBeginProvokesDecodeErrorTestImpl(bytes, "The outgoing-window 
field cannot be omitted");
+    }
+
+    @Test
+    public void testTruncatedBeginProvokesDecodeError2() {
+        // Provide the bytes for Begin, but only give a [not-present 
remote-channel +] next-outgoing-id and incoming-window. Provokes a decode error 
as there must be 4 fields.
+        byte[] bytes = new byte[] {  0x00, 0x00, 0x00, 0x11, // Frame size = 
17 bytes.
+                0x02, 0x00, 0x00, 0x00, // DOFF, TYPE, 2x CHANNEL
+                0x00, 0x53, 0x11, (byte) 0xC0, // Described-type, ulong type, 
Begin descriptor, list8.
+                0x05, 0x03, 0x40, 0x43, 0x43 }; // size (5), count (3), 
remote-channel (null), next-outgoing-id (uint0), incoming-window (uint0).
+
+        doInvalidBeginProvokesDecodeErrorTestImpl(bytes, "The outgoing-window 
field cannot be omitted");
+    }
+
+    @Test
+    public void testTruncatedBeginProvokesDecodeError3() {
+        // Provide the bytes for Begin, but only give a [not-present 
remote-channel +] next-outgoing-id and incoming-window, and send 
not-present/null for outgoing-window. Provokes a decode error as must be 
present.
+        byte[] bytes = new byte[] {  0x00, 0x00, 0x00, 0x12, // Frame size = 
18 bytes.
+                0x02, 0x00, 0x00, 0x00, // DOFF, TYPE, 2x CHANNEL
+                0x00, 0x53, 0x11, (byte) 0xC0, // Described-type, ulong type, 
Begin descriptor, list8.
+                0x06, 0x04, 0x40, 0x43, 0x43, 0x40 }; // size (5), count (4), 
remote-channel (null), next-outgoing-id (uint0), incoming-window (uint0), 
outgoing-window (null).
+
+        doInvalidBeginProvokesDecodeErrorTestImpl(bytes, "Unexpected null 
value - mandatory field not set? (the outgoing-window field is mandatory)");
+    }
+
+    private void doInvalidBeginProvokesDecodeErrorTestImpl(byte[] bytes, 
String description) {
+        MockTransportImpl transport = new MockTransportImpl();
+        Connection connection = Proton.connection();
+
+        Collector collector = Collector.Factory.create();
+        connection.collect(collector);
+
+        transport.bind(connection);
+        connection.open();
+
+        pumpMockTransport(transport);
+
+        assertEquals("Unexpected frames written: " + 
getFrameTypesWritten(transport), 1, transport.writes.size());
+        assertTrue("Unexpected frame type", transport.writes.get(0) instanceof 
Open);
+
+        // Provide the response bytes for the header
+        transport.tail().put(AmqpHeader.HEADER);
+        transport.process();
+
+        // Send the necessary response to open
+        transport.handleFrame(new TransportFrame(0, new Open(), null));
+
+        int capacity = transport.capacity();
+        assertTrue("Unexpected transport capacity: " + capacity, capacity > 
bytes.length);
+
+        transport.tail().put(bytes);
+        transport.process();
+
+        pumpMockTransport(transport);
+
+        assertEquals("Unexpected frames written: " + 
getFrameTypesWritten(transport), 2, transport.writes.size());
+        FrameBody frameBody = transport.writes.get(1);
+        assertTrue("Unexpected frame type", frameBody instanceof Close);
+
+        // Expect the close frame generated to contain a decode error 
condition referencing the missing container-id.
+        ErrorCondition expectedCondition = new ErrorCondition();
+        expectedCondition.setCondition(AmqpError.DECODE_ERROR);
+        expectedCondition.setDescription(description);
+
+        assertEquals("Unexpected condition", expectedCondition, ((Close) 
frameBody).getError());
+    }
+
+    @Test
+    public void testEmptyFlowProvokesDecodeError() {
+        // Provide the bytes for Flow, but omit any fields to provoke a decode 
error.
+        byte[] bytes = new byte[] {  0x00, 0x00, 0x00, 0x0C, // Frame size = 
12 bytes.
+                0x02, 0x00, 0x00, 0x00, // DOFF, TYPE, 2x CHANNEL
+                0x00, 0x53, 0x13, 0x45};// Described-type, ulong type, Flow 
descriptor, list0.
+
+        doInvalidFlowProvokesDecodeErrorTestImpl(bytes, "The outgoing-window 
field cannot be omitted");
+    }
+
+    @Test
+    public void testTruncatedFlowProvokesDecodeError1() {
+        // Provide the bytes for Flow, but only give a 0 for the 
next-incoming-id. Provokes a decode error as there must be 4 fields.
+        byte[] bytes = new byte[] {  0x00, 0x00, 0x00, 0x0F, // Frame size = 
15 bytes.
+                0x02, 0x00, 0x00, 0x00, // DOFF, TYPE, 2x CHANNEL
+                0x00, 0x53, 0x13, (byte) 0xC0, // Described-type, ulong type, 
Flow descriptor, list8.
+                0x03, 0x01, 0x43 }; // size (3), count (1), next-incoming-id 
(uint0).
+
+        doInvalidFlowProvokesDecodeErrorTestImpl(bytes, "The outgoing-window 
field cannot be omitted");
+    }
+
+    @Test
+    public void testTruncatedFlowProvokesDecodeError2() {
+        // Provide the bytes for Flow, but only give a next-incoming-id and 
incoming-window and next-outgoing-id. Provokes a decode error as there must be 
4 fields.
+        byte[] bytes = new byte[] {  0x00, 0x00, 0x00, 0x11, // Frame size = 
17 bytes.
+                0x02, 0x00, 0x00, 0x00, // DOFF, TYPE, 2x CHANNEL
+                0x00, 0x53, 0x13, (byte) 0xC0, // Described-type, ulong type, 
Flow descriptor, list8.
+                0x05, 0x03, 0x43, 0x43, 0x43 }; // size (5), count (3), 
next-incoming-id (0), incoming-window (uint0), next-outgoing-id (uint0).
+
+        doInvalidFlowProvokesDecodeErrorTestImpl(bytes, "The outgoing-window 
field cannot be omitted");
+    }
+
+    @Test
+    public void testTruncatedFlowProvokesDecodeError3() {
+        // Provide the bytes for Flow, but only give a next-incoming-id and 
incoming-window and next-outgoing-id, and send not-present/null for 
outgoing-window. Provokes a decode error as must be present.
+        byte[] bytes = new byte[] {  0x00, 0x00, 0x00, 0x12, // Frame size = 
18 bytes.
+                0x02, 0x00, 0x00, 0x00, // DOFF, TYPE, 2x CHANNEL
+                0x00, 0x53, 0x13, (byte) 0xC0, // Described-type, ulong type, 
Flow descriptor, list8.
+                0x06, 0x04, 0x43, 0x43, 0x43, 0x40 }; // size (5), count (4), 
next-incoming-id (0), incoming-window (uint0), next-outgoing-id (uint0), 
outgoing-window (null).
+
+        doInvalidFlowProvokesDecodeErrorTestImpl(bytes, "Unexpected null value 
- mandatory field not set? (the outgoing-window field is mandatory)");
+    }
+
+    private void doInvalidFlowProvokesDecodeErrorTestImpl(byte[] bytes, String 
description) {
+        MockTransportImpl transport = new MockTransportImpl();
+        Connection connection = Proton.connection();
+
+        Collector collector = Collector.Factory.create();
+        connection.collect(collector);
+
+        transport.bind(connection);
+        connection.open();
+
+        Session session = connection.session();
+        session.open();
+
+        pumpMockTransport(transport);
+
+        assertEquals("Unexpected frames written: " + 
getFrameTypesWritten(transport), 2, transport.writes.size());
+        assertTrue("Unexpected frame type", transport.writes.get(0) instanceof 
Open);
+        assertTrue("Unexpected frame type", transport.writes.get(1) instanceof 
Begin);
+
+        // Provide the response bytes for the header
+        transport.tail().put(AmqpHeader.HEADER);
+        transport.process();
+
+
+        // Send the necessary response to Open/Begin
+        transport.handleFrame(new TransportFrame(0, new Open(), null));
+
+        Begin begin = new Begin();
+        begin.setRemoteChannel(UnsignedShort.valueOf((short) 0));
+        begin.setNextOutgoingId(UnsignedInteger.ONE);
+        begin.setIncomingWindow(UnsignedInteger.valueOf(1024));
+        begin.setOutgoingWindow(UnsignedInteger.valueOf(1024));
+        transport.handleFrame(new TransportFrame(0, begin, null));
+
+        int capacity = transport.capacity();
+        assertTrue("Unexpected transport capacity: " + capacity, capacity > 
bytes.length);
+
+        transport.tail().put(bytes);
+        transport.process();
+
+        pumpMockTransport(transport);
+
+        assertEquals("Unexpected frames written: " + 
getFrameTypesWritten(transport), 3, transport.writes.size());
+        FrameBody frameBody = transport.writes.get(2);
+        assertTrue("Unexpected frame type", frameBody instanceof Close);
+
+        // Expect the close frame generated to contain a decode error 
condition referencing the missing container-id.
+        ErrorCondition expectedCondition = new ErrorCondition();
+        expectedCondition.setCondition(AmqpError.DECODE_ERROR);
+        expectedCondition.setDescription(description);
+
+        assertEquals("Unexpected condition", expectedCondition, ((Close) 
frameBody).getError());
+    }
+
+    @Test
+    public void testEmptyTransferProvokesDecodeError() {
+        // Provide the bytes for Transfer, but omit any fields to provoke a 
decode error.
+        byte[] bytes = new byte[] {  0x00, 0x00, 0x00, 0x0C, // Frame size = 
12 bytes.
+                0x02, 0x00, 0x00, 0x00, // DOFF, TYPE, 2x CHANNEL
+                0x00, 0x53, 0x14, 0x45};// Described-type, ulong type, 
Transfer descriptor, list0.
+
+        doInvalidTransferProvokesDecodeErrorTestImpl(bytes, "The handle field 
cannot be omitted");
+    }
+
+    @Test
+    public void testTruncatedTransferProvokesDecodeError() {
+        // Provide the bytes for Transfer, but only give a null for the 
not-present handle. Provokes a decode error as there must be a handle.
+        byte[] bytes = new byte[] {  0x00, 0x00, 0x00, 0x0F, // Frame size = 
15 bytes.
+                0x02, 0x00, 0x00, 0x00, // DOFF, TYPE, 2x CHANNEL
+                0x00, 0x53, 0x14, (byte) 0xC0, // Described-type, ulong type, 
Transfer descriptor, list8.
+                0x03, 0x01, 0x40 }; // size (3), count (1), handle (null / 
not-present).
+
+        doInvalidTransferProvokesDecodeErrorTestImpl(bytes, "Unexpected null 
value - mandatory field not set? (the handle field is mandatory)");
+    }
+
+    private void doInvalidTransferProvokesDecodeErrorTestImpl(byte[] bytes, 
String description) {
+        MockTransportImpl transport = new MockTransportImpl();
+        Connection connection = Proton.connection();
+
+        Collector collector = Collector.Factory.create();
+        connection.collect(collector);
+
+        transport.bind(connection);
+        connection.open();
+
+        Session session = connection.session();
+        session.open();
+
+        String linkName = "myReceiver";
+        Receiver receiver = session.receiver(linkName);
+        receiver.flow(5);
+        receiver.open();
+
+        pumpMockTransport(transport);
+
+        assertEquals("Unexpected frames written: " + 
getFrameTypesWritten(transport), 4, transport.writes.size());
+        assertTrue("Unexpected frame type", transport.writes.get(0) instanceof 
Open);
+        assertTrue("Unexpected frame type", transport.writes.get(1) instanceof 
Begin);
+        assertTrue("Unexpected frame type", transport.writes.get(2) instanceof 
Attach);
+        assertTrue("Unexpected frame type", transport.writes.get(3) instanceof 
Flow);
+
+        // Provide the response bytes for the header
+        transport.tail().put(AmqpHeader.HEADER);
+        transport.process();
+
+        // Send the necessary response to Open/Begin/Attach
+        transport.handleFrame(new TransportFrame(0, new Open(), null));
+
+        Begin begin = new Begin();
+        begin.setRemoteChannel(UnsignedShort.valueOf((short) 0));
+        begin.setNextOutgoingId(UnsignedInteger.ONE);
+        begin.setIncomingWindow(UnsignedInteger.valueOf(1024));
+        begin.setOutgoingWindow(UnsignedInteger.valueOf(1024));
+        transport.handleFrame(new TransportFrame(0, begin, null));
+
+        Attach attach = new Attach();
+        attach.setHandle(UnsignedInteger.ZERO);
+        attach.setRole(Role.SENDER);
+        attach.setName(linkName);
+        attach.setInitialDeliveryCount(UnsignedInteger.ZERO);
+        transport.handleFrame(new TransportFrame(0, attach, null));
+
+        int capacity = transport.capacity();
+        assertTrue("Unexpected transport capacity: " + capacity, capacity > 
bytes.length);
+
+        transport.tail().put(bytes);
+        transport.process();
+
+        pumpMockTransport(transport);
+
+        assertEquals("Unexpected frames written: " + 
getFrameTypesWritten(transport), 5, transport.writes.size());
+        FrameBody frameBody = transport.writes.get(4);
+        assertTrue("Unexpected frame type", frameBody instanceof Close);
+
+        // Expect the close frame generated to contain a decode error 
condition referencing the missing container-id.
+        ErrorCondition expectedCondition = new ErrorCondition();
+        expectedCondition.setCondition(AmqpError.DECODE_ERROR);
+        expectedCondition.setDescription(description);
+
+        assertEquals("Unexpected condition", expectedCondition, ((Close) 
frameBody).getError());
+    }
+
+    @Test
+    public void testEmptyDispositionProvokesDecodeError() {
+        // Provide the bytes for Disposition, but omit any fields to provoke a 
decode error.
+        byte[] bytes = new byte[] {  0x00, 0x00, 0x00, 0x0C, // Frame size = 
12 bytes.
+                0x02, 0x00, 0x00, 0x00, // DOFF, TYPE, 2x CHANNEL
+                0x00, 0x53, 0x15, 0x45};// Described-type, ulong type, 
Disposition descriptor, list0.
+
+        doInvalidDispositionProvokesDecodeErrorTestImpl(bytes, "The 'first' 
field cannot be omitted");
+    }
+
+    @Test
+    public void testTruncatedDispositionProvokesDecodeError() {
+        // Provide the bytes for Disposition, but only give a null/not-present 
for the 'first' field. Provokes a decode error as there must be a role and 
'first'.
+        byte[] bytes = new byte[] {  0x00, 0x00, 0x00, 0x10, // Frame size = 
16 bytes.
+                0x02, 0x00, 0x00, 0x00, // DOFF, TYPE, 2x CHANNEL
+                0x00, 0x53, 0x15, (byte) 0xC0, // Described-type, ulong type, 
Disposition descriptor, list8.
+                0x04, 0x02, 0x41, 0x40 }; // size (4), count (2), role 
(receiver - the peers perspective), first ( null / not-present)
+
+        doInvalidDispositionProvokesDecodeErrorTestImpl(bytes, "Unexpected 
null value - mandatory field not set? (the first field is mandatory)");
+    }
+
+    private void doInvalidDispositionProvokesDecodeErrorTestImpl(byte[] bytes, 
String description) {
+        MockTransportImpl transport = new MockTransportImpl();
+        Connection connection = Proton.connection();
+
+        Collector collector = Collector.Factory.create();
+        connection.collect(collector);
+
+        transport.bind(connection);
+        connection.open();
+
+        Session session = connection.session();
+        session.open();
+
+        String linkName = "mySender";
+        Sender sender = session.sender(linkName);
+        sender.open();
+
+        pumpMockTransport(transport);
+
+        assertEquals("Unexpected frames written: " + 
getFrameTypesWritten(transport), 3, transport.writes.size());
+        assertTrue("Unexpected frame type", transport.writes.get(0) instanceof 
Open);
+        assertTrue("Unexpected frame type", transport.writes.get(1) instanceof 
Begin);
+        assertTrue("Unexpected frame type", transport.writes.get(2) instanceof 
Attach);
+
+        // Provide the response bytes for the header
+        transport.tail().put(AmqpHeader.HEADER);
+        transport.process();
+
+        // Send the necessary response to Open/Begin/Attach plus some credit
+        transport.handleFrame(new TransportFrame(0, new Open(), null));
+
+        Begin begin = new Begin();
+        begin.setRemoteChannel(UnsignedShort.valueOf((short) 0));
+        begin.setNextOutgoingId(UnsignedInteger.ONE);
+        begin.setIncomingWindow(UnsignedInteger.valueOf(1024));
+        begin.setOutgoingWindow(UnsignedInteger.valueOf(1024));
+        transport.handleFrame(new TransportFrame(0, begin, null));
+
+        Attach attach = new Attach();
+        attach.setHandle(UnsignedInteger.ZERO);
+        attach.setRole(Role.SENDER);
+        attach.setName(linkName);
+        attach.setInitialDeliveryCount(UnsignedInteger.ZERO);
+        transport.handleFrame(new TransportFrame(0, attach, null));
+
+        int credit = 1;
+        Flow flow = new Flow();
+        flow.setHandle(UnsignedInteger.ZERO);
+        flow.setDeliveryCount(UnsignedInteger.ZERO);
+        flow.setNextIncomingId(UnsignedInteger.ONE);
+        flow.setNextOutgoingId(UnsignedInteger.ZERO);
+        flow.setIncomingWindow(UnsignedInteger.valueOf(1024));
+        flow.setOutgoingWindow(UnsignedInteger.valueOf(1024));
+        flow.setDrain(true);
+        flow.setLinkCredit(UnsignedInteger.valueOf(credit));
+        transport.handleFrame(new TransportFrame(0, flow, null));
+
+        sendMessage(sender, "tag1", "content1");
+
+        pumpMockTransport(transport);
+
+        assertEquals("Unexpected frames written: " + 
getFrameTypesWritten(transport), 4, transport.writes.size());
+        assertTrue("Unexpected frame type", transport.writes.get(3) instanceof 
Transfer);
+
+        int capacity = transport.capacity();
+        assertTrue("Unexpected transport capacity: " + capacity, capacity > 
bytes.length);
+
+        transport.tail().put(bytes);
+        transport.process();
+
+        pumpMockTransport(transport);
+
+        assertEquals("Unexpected frames written: " + 
getFrameTypesWritten(transport), 5, transport.writes.size());
+        FrameBody frameBody = transport.writes.get(4);
+        assertTrue("Unexpected frame type", frameBody instanceof Close);
+
+        // Expect the close frame generated to contain a decode error 
condition referencing the missing container-id.
+        ErrorCondition expectedCondition = new ErrorCondition();
+        expectedCondition.setCondition(AmqpError.DECODE_ERROR);
+        expectedCondition.setDescription(description);
+
+        assertEquals("Unexpected condition", expectedCondition, ((Close) 
frameBody).getError());
+    }
+
     private void prepareAndOpenConnection(MockTransportImpl transport, 
Connection connection) {
         transport.bind(connection);
         connection.open();


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscr...@qpid.apache.org
For additional commands, e-mail: commits-h...@qpid.apache.org

Reply via email to