You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by ta...@apache.org on 2023/05/26 21:26:43 UTC

[qpid-protonj2] branch main updated: PROTON-2739 Add some extra API for Open and Attach responses

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 <ta...@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-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org