This is an automated email from the ASF dual-hosted git repository. tabish pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/qpid-protonj2.git
The following commit(s) were added to refs/heads/main by this push: new b2c3e94b PROTON-2739 Add some extra API for Open and Attach responses b2c3e94b is described below commit b2c3e94bb5af22189ae612a83b49658bf158b2a0 Author: Timothy Bish <tabish...@gmail.com> AuthorDate: Fri May 26 17:26:27 2023 -0400 PROTON-2739 Add some extra API for Open and Attach responses Add simple API to script attach and open responses should mirror back desired capabilities as offered. --- .../driver/expectations/AttachExpectation.java | 41 +++++++++++++ .../test/driver/expectations/OpenExpectation.java | 39 +++++++++++++ .../protonj2/test/driver/ProtonTestClientTest.java | 28 +++++++++ .../protonj2/test/driver/ReceiverHandlingTest.java | 67 ++++++++++++++++++++++ 4 files changed, 175 insertions(+) diff --git a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/expectations/AttachExpectation.java b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/expectations/AttachExpectation.java index 7c7fbbd9..da77ea75 100644 --- a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/expectations/AttachExpectation.java +++ b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/expectations/AttachExpectation.java @@ -23,6 +23,7 @@ import static org.hamcrest.CoreMatchers.nullValue; import static org.hamcrest.collection.ArrayMatching.hasItemInArray; import java.nio.ByteBuffer; +import java.util.Arrays; import java.util.Map; import java.util.UUID; @@ -65,6 +66,7 @@ public class AttachExpectation extends AbstractExpectation<Attach> { private AttachInjectAction response; private boolean rejecting; + private boolean inKindResponse; public AttachExpectation(AMQPTestDriver driver) { super(driver); @@ -81,12 +83,40 @@ public class AttachExpectation extends AbstractExpectation<Attach> { return this; } + /** + * Creates a sufficient response for a simple {@link Attach} request for + * simple test scripts. This response does not offer capabilities to the + * remote which means that the scripting code may need to add any that it + * wants to or validate errors on the remote if desired capabilities are + * absent. + * + * @return the {@link Attach} injection action that will be used to respond. + */ public AttachInjectAction respond() { response = new AttachInjectAction(driver); driver.addScriptedElement(response); return response; } + /** + * More complete auto response than normal where the response attempts to match + * all requested capabilities etc in the Attach response so that the script writer + * can assume that the response to the attach request is a valid and complete + * response without need to complete the offered capabilities in response to the + * remote's desired capabilities etc. + * <p> + * Use this with a bit of care as it will overwrite any script defined response + * values in favor of an in-kind version. + * + * @return the {@link Attach} injection action that will be used to respond. + */ + public AttachInjectAction respondInKind() { + response = new AttachInjectAction(driver); + inKindResponse = true; + driver.addScriptedElement(response); + return response; + } + public DetachInjectAction reject(boolean close, String condition, String description) { return reject(close, Symbol.valueOf(condition), description); } @@ -181,6 +211,17 @@ public class AttachExpectation extends AbstractExpectation<Attach> { } } + if (inKindResponse) { + final Symbol[] desired = attach.getDesiredCapabilities(); + if (desired != null && desired.length > 0) { + response.withOfferedCapabilities(Arrays.copyOf(desired, desired.length)); + } + + if (attach.getMaxMessageSize() != null) { + response.withMaxMessageSize(attach.getMaxMessageSize()); + } + } + // Other fields are left not set for now unless test script configured } } diff --git a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/expectations/OpenExpectation.java b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/expectations/OpenExpectation.java index ee888d5a..87275b55 100644 --- a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/expectations/OpenExpectation.java +++ b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/expectations/OpenExpectation.java @@ -21,6 +21,7 @@ import static org.hamcrest.CoreMatchers.notNullValue; import static org.hamcrest.collection.ArrayMatching.hasItemInArray; import java.nio.ByteBuffer; +import java.util.Arrays; import java.util.Map; import org.apache.qpid.protonj2.test.driver.AMQPTestDriver; @@ -45,6 +46,7 @@ public class OpenExpectation extends AbstractExpectation<Open> { private OpenInjectAction response; private boolean explicitlyNullContainerId; + private boolean inKindResponse; public OpenExpectation(AMQPTestDriver driver) { super(driver); @@ -55,12 +57,40 @@ public class OpenExpectation extends AbstractExpectation<Open> { onChannel(0); // Open must used channel zero. } + /** + * Creates a sufficient response for a simple {@link Open} request for + * simple test scripts. This response does not offer capabilities to the + * remote which means that the scripting code may need to add any that it + * wants to or validate errors on the remote if desired capabilities are + * absent. + * + * @return the {@link Open} injection action that will be used to respond. + */ public OpenInjectAction respond() { response = new OpenInjectAction(driver); driver.addScriptedElement(response); return response; } + /** + * More complete auto response than normal where the response attempts to match + * all requested capabilities etc in the {@link Open} response so that the script + * writer can assume that the response to the open request is a valid and complete + * response without need to complete the offered capabilities in response to the + * remote's desired capabilities etc. + * <p> + * Use this with a bit of care as it will overwrite any script defined response + * values in favor of an in-kind version. + * + * @return the {@link Open} injection action that will be used to respond. + */ + public OpenInjectAction respondInKind() { + response = new OpenInjectAction(driver); + driver.addScriptedElement(response); + inKindResponse = true; + return response; + } + public CloseInjectAction reject() { response = new OpenInjectAction(driver); driver.addScriptedElement(response); @@ -109,6 +139,15 @@ public class OpenExpectation extends AbstractExpectation<Open> { if (response.onChannel() == BeginInjectAction.CHANNEL_UNSET) { response.onChannel(channel); } + + if (inKindResponse) { + final Symbol[] desired = open.getDesiredCapabilities(); + if (desired != null && desired.length > 0) { + response.withOfferedCapabilities(Arrays.copyOf(desired, desired.length)); + } + + response.withMaxFrameSize(open.getMaxFrameSize()); + } } } diff --git a/protonj2-test-driver/src/test/java/org/apache/qpid/protonj2/test/driver/ProtonTestClientTest.java b/protonj2-test-driver/src/test/java/org/apache/qpid/protonj2/test/driver/ProtonTestClientTest.java index c671b594..42fcf83c 100644 --- a/protonj2-test-driver/src/test/java/org/apache/qpid/protonj2/test/driver/ProtonTestClientTest.java +++ b/protonj2-test-driver/src/test/java/org/apache/qpid/protonj2/test/driver/ProtonTestClientTest.java @@ -222,6 +222,34 @@ class ProtonTestClientTest extends TestPeerTestsBase { } } + @Test + public void testOpenInKindResponseCarriesDesiredCapabilities() throws Exception { + try (ProtonTestServer peer = new ProtonTestServer()) { + peer.expectAMQPHeader().respondWithAMQPHeader(); + peer.expectOpen().respondInKind(); + peer.expectClose().respond(); + peer.start(); + + URI remoteURI = peer.getServerURI(); + + ProtonTestClient client = new ProtonTestClient(); + + client.connect(remoteURI.getHost(), remoteURI.getPort()); + client.expectAMQPHeader(); + client.expectOpen().withOfferedCapability("test"); + client.expectClose(); + client.remoteHeader(AMQPHeader.getAMQPHeader()).now(); + client.remoteOpen().withDesiredCapabilities("test").now(); + client.remoteClose().now(); + client.waitForScriptToComplete(5, TimeUnit.SECONDS); + client.close(); + + LOG.info("Test started, peer listening on: {}", remoteURI); + + peer.waitForScriptToComplete(5, TimeUnit.SECONDS); + } + } + @Test public void testClientFailsTestIfFrameSizeExpectationNotMet() throws Exception { try (ProtonTestServer peer = new ProtonTestServer()) { diff --git a/protonj2-test-driver/src/test/java/org/apache/qpid/protonj2/test/driver/ReceiverHandlingTest.java b/protonj2-test-driver/src/test/java/org/apache/qpid/protonj2/test/driver/ReceiverHandlingTest.java index b1aaaefd..ae1b9432 100644 --- a/protonj2-test-driver/src/test/java/org/apache/qpid/protonj2/test/driver/ReceiverHandlingTest.java +++ b/protonj2-test-driver/src/test/java/org/apache/qpid/protonj2/test/driver/ReceiverHandlingTest.java @@ -24,6 +24,7 @@ import java.util.concurrent.TimeUnit; import org.apache.qpid.protonj2.test.driver.codec.transport.AMQPHeader; import org.apache.qpid.protonj2.test.driver.utils.TestPeerTestsBase; +import org.hamcrest.Matchers; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Timeout; import org.slf4j.Logger; @@ -343,4 +344,70 @@ class ReceiverHandlingTest extends TestPeerTestsBase { assertThrows(AssertionError.class, () -> peer.waitForScriptToComplete(5, TimeUnit.SECONDS)); } } + + @Test + public void testNonInKindAttachResponseOffersCapabilitiesAreOmitted() throws Exception { + try (ProtonTestServer peer = new ProtonTestServer(); + ProtonTestClient client = new ProtonTestClient()) { + + peer.expectAMQPHeader().respondWithAMQPHeader(); + peer.expectOpen().respond(); + peer.expectBegin().respond(); + peer.expectAttach().ofSender().respondInKind(); + peer.expectEnd().respond(); + peer.start(); + + URI remoteURI = peer.getServerURI(); + + LOG.info("Test started, peer listening on: {}", remoteURI); + + client.connect(remoteURI.getHost(), remoteURI.getPort()); + client.expectAMQPHeader(); + client.expectOpen(); + client.expectBegin(); + client.expectAttach().ofReceiver().withOfferedCapability("test"); + client.expectEnd(); + client.remoteAMQPHeader().now(); + client.remoteOpen().now(); + client.remoteBegin().now(); + client.remoteAttach().ofSender().withDesiredCapabilities("test").now(); + client.remoteEnd().now(); + + client.waitForScriptToComplete(5, TimeUnit.SECONDS); + peer.waitForScriptToComplete(5, TimeUnit.SECONDS); + } + } + + @Test + public void testInKindAttachResponseOffersCapabilitiesDesired() throws Exception { + try (ProtonTestServer peer = new ProtonTestServer(); + ProtonTestClient client = new ProtonTestClient()) { + + peer.expectAMQPHeader().respondWithAMQPHeader(); + peer.expectOpen().respond(); + peer.expectBegin().respond(); + peer.expectAttach().ofSender().respond(); + peer.expectEnd().respond(); + peer.start(); + + URI remoteURI = peer.getServerURI(); + + LOG.info("Test started, peer listening on: {}", remoteURI); + + client.connect(remoteURI.getHost(), remoteURI.getPort()); + client.expectAMQPHeader(); + client.expectOpen(); + client.expectBegin(); + client.expectAttach().ofReceiver().withOfferedCapabilities(Matchers.nullValue()); + client.expectEnd(); + client.remoteAMQPHeader().now(); + client.remoteOpen().now(); + client.remoteBegin().now(); + client.remoteAttach().ofSender().withDesiredCapabilities("test").now(); + client.remoteEnd().now(); + + client.waitForScriptToComplete(5, TimeUnit.SECONDS); + peer.waitForScriptToComplete(5, TimeUnit.SECONDS); + } + } } --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@qpid.apache.org For additional commands, e-mail: commits-h...@qpid.apache.org