[java-plugin-shibd] branch main updated: Add storage flow tests, more workarounds for Spring mock bugs.
Scott Cantor
cantor.2 at osu.edu
Wed Jul 3 20:28:14 UTC 2024
This is an automated email from the git hooks/post-receive script.
scantor pushed a commit to branch main
in repository java-plugin-shibd.
View the commit online:
http://git.shibboleth.net/view/?p=java-plugin-shibd.git;a=commit;h=bb0c21e0715cade6ea343e0259c02feda9e3442d
The following commit(s) were added to refs/heads/main by this push:
new bb0c21e Add storage flow tests, more workarounds for Spring mock bugs.
bb0c21e is described below
commit bb0c21e0715cade6ea343e0259c02feda9e3442d
Author: Scott Cantor <cantor.2 at osu.edu>
AuthorDate: Wed Jul 3 16:28:11 2024 -0400
Add storage flow tests, more workarounds for Spring mock bugs.
---
.../shibboleth/sp/flows/AbstractSPFlowTest.java | 21 +-
.../java/net/shibboleth/sp/flows/PingFlowTest.java | 2 +-
.../net/shibboleth/sp/flows/SealerFlowTest.java | 8 +-
.../net/shibboleth/sp/flows/StorageFlowTest.java | 395 +++++++++++++++++++++
4 files changed, 413 insertions(+), 13 deletions(-)
diff --git a/sp-conf-impl/src/test/java/net/shibboleth/sp/flows/AbstractSPFlowTest.java b/sp-conf-impl/src/test/java/net/shibboleth/sp/flows/AbstractSPFlowTest.java
index 0241495..1ab60e2 100644
--- a/sp-conf-impl/src/test/java/net/shibboleth/sp/flows/AbstractSPFlowTest.java
+++ b/sp-conf-impl/src/test/java/net/shibboleth/sp/flows/AbstractSPFlowTest.java
@@ -120,10 +120,10 @@ public abstract class AbstractSPFlowTest extends AbstractFlowTest {
setBasicAuth(AGENT_ID, "foo");
}
- protected void setRequest(final String method, final DDF body, final String contentType) throws IOException {
+ protected void setRequest(final String method, final DDF body) throws IOException {
try (final ByteArrayOutputStream out = new ByteArrayOutputStream()) {
body.serialize(out);
- setRequest(request, method, out.toString(Charset.forName("UTF-8")) , contentType);
+ setRequest(request, method, out.toString(Charset.forName("UTF-8")) , "text/plain");
}
}
@@ -162,15 +162,20 @@ public abstract class AbstractSPFlowTest extends AbstractFlowTest {
Assert.assertEquals(response.getContentType(), "text/plain");
- try (final InputStream in = new ByteArrayInputStream(response.getContentAsByteArray())) {
- final DDF body = DDF.deserialize(in);
+ final byte[] body = response.getContentAsByteArray();
+ if (body == null || body.length == 0) {
+ return null;
+ }
+
+ try (final InputStream in = new ByteArrayInputStream(body)) {
+ final DDF obj = DDF.deserialize(in);
if (eventId != null) {
- Assert.assertTrue(body.isstruct());
- Assert.assertEquals(body.getmember(EVENT_MEMBER_NAME).string(), eventId);
+ Assert.assertTrue(obj.isstruct());
+ Assert.assertEquals(obj.getmember(EVENT_MEMBER_NAME).string(), eventId);
} else {
- Assert.assertTrue(!body.isstruct() || body.getmember(EVENT_MEMBER_NAME).isnull());
+ Assert.assertTrue(!obj.isstruct() || obj.getmember(EVENT_MEMBER_NAME).isnull());
}
- return body;
+ return obj;
} catch (final IOException e) {
Assert.fail("DDF deserialization threw", e);
return null;
diff --git a/sp-conf-impl/src/test/java/net/shibboleth/sp/flows/PingFlowTest.java b/sp-conf-impl/src/test/java/net/shibboleth/sp/flows/PingFlowTest.java
index 0d2e2f5..0a5627d 100644
--- a/sp-conf-impl/src/test/java/net/shibboleth/sp/flows/PingFlowTest.java
+++ b/sp-conf-impl/src/test/java/net/shibboleth/sp/flows/PingFlowTest.java
@@ -80,7 +80,7 @@ public class PingFlowTest extends AbstractSPFlowTest {
@Test
public void testSuccess() throws IOException {
setDefaultAuth();
- setRequest("GET", new DDF(null), "text/plain");
+ setRequest("GET", new DDF(null));
final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
assertFlowExecutionResult(result, FLOW_ID);
assertFlowExecutionOutcome(result.getOutcome());
diff --git a/sp-conf-impl/src/test/java/net/shibboleth/sp/flows/SealerFlowTest.java b/sp-conf-impl/src/test/java/net/shibboleth/sp/flows/SealerFlowTest.java
index 7d73956..abd7078 100644
--- a/sp-conf-impl/src/test/java/net/shibboleth/sp/flows/SealerFlowTest.java
+++ b/sp-conf-impl/src/test/java/net/shibboleth/sp/flows/SealerFlowTest.java
@@ -83,7 +83,7 @@ public class SealerFlowTest extends AbstractSPFlowTest {
final DDF input = new DDF().structure();
input.addmember(DoSealerOperation.VALUE).string(TEST_VALUE);
input.addmember(DoSealerOperation.EXP).longinteger(Instant.now().minusSeconds(3600).toEpochMilli() / 1000);
- setRequest("POST", input, "text/plain");
+ setRequest("POST", input);
final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
assertFlowExecutionResult(result, FLOW_ID);
@@ -113,7 +113,7 @@ public class SealerFlowTest extends AbstractSPFlowTest {
final DDF input = new DDF().structure();
input.addmember(DoSealerOperation.VALUE).string(TEST_VALUE);
- setRequest("POST", input, "text/plain");
+ setRequest("POST", input);
final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
assertFlowExecutionResult(result, FLOW_ID);
@@ -153,7 +153,7 @@ public class SealerFlowTest extends AbstractSPFlowTest {
final DDF input = new DDF().structure();
input.addmember(DoSealerOperation.VALUE).string(wrapped);
- setRequest("GET", input, "text/plain");
+ setRequest("GET", input);
final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
assertFlowExecutionResult(result, FLOW_ID);
@@ -175,7 +175,7 @@ public class SealerFlowTest extends AbstractSPFlowTest {
final DDF input = new DDF().structure();
input.addmember(DoSealerOperation.VALUE).string(wrapped);
- setRequest("GET", input, "text/plain");
+ setRequest("GET", input);
final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
assertFlowExecutionResult(result, FLOW_ID);
diff --git a/sp-conf-impl/src/test/java/net/shibboleth/sp/flows/StorageFlowTest.java b/sp-conf-impl/src/test/java/net/shibboleth/sp/flows/StorageFlowTest.java
new file mode 100644
index 0000000..24938b1
--- /dev/null
+++ b/sp-conf-impl/src/test/java/net/shibboleth/sp/flows/StorageFlowTest.java
@@ -0,0 +1,395 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.shibboleth.sp.flows;
+
+import java.io.IOException;
+import java.time.Instant;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.opensaml.profile.action.EventIds;
+import org.opensaml.storage.StorageRecord;
+import org.opensaml.storage.StorageService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.webflow.executor.FlowExecutionResult;
+import org.testng.Assert;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.Test;
+
+import net.shibboleth.shared.annotation.constraint.NotEmpty;
+import net.shibboleth.sp.ddf.DDF;
+import net.shibboleth.sp.profile.impl.DoStorageOperation;
+
+/**
+ * Unit test for the SP sealer flow.
+ */
+public class StorageFlowTest extends AbstractSPFlowTest {
+
+ /** Flow ID. */
+ @Nonnull public static final String FLOW_ID = "sp/storage";
+
+ /** Test data. */
+ @Nonnull public static final String TEST_CONTEXT = "org.example.context";
+
+ /** Test context. */
+ @Nonnull @NotEmpty private final static String AGENT_CONTEXT = AGENT_ID + '!' + TEST_CONTEXT;
+
+ /** Test key. */
+ @Nonnull public static final String TEST_KEY = "foo";
+
+ /** Test data. */
+ @Nonnull public static final String TEST_VALUE = "testValue";
+
+ @Autowired
+ @Qualifier("shibboleth.StorageService")
+ @Nullable StorageService storageService;
+
+ protected StorageFlowTest() {
+ super(FLOW_ID);
+ }
+
+ /**
+ * Get the auto-wired storage service.
+ *
+ * @return storage service
+ */
+ @Nonnull public StorageService getStorageService() {
+ assert storageService != null;
+ return storageService;
+ }
+
+ /**
+ * Clear the storage service between tests.
+ *
+ * @throws IOException
+ */
+ @AfterMethod
+ public void clearStorage() throws IOException {
+ getStorageService().deleteContext(AGENT_CONTEXT);
+ }
+
+ /**
+ * Test invalid method.
+ *
+ * @throws IOException
+ */
+ @Test
+ public void invalidMethod() throws IOException {
+ setDefaultAuth();
+ setRequest("FOO", new DDF(null));
+ final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
+ assertFlowExecutionResult(result, FLOW_ID);
+ assertFlowExecutionOutcome(result.getOutcome());
+ assertOutputMessageEvent(result, EventIds.INVALID_MESSAGE);
+ }
+
+ /**
+ * Test wrap operation with no input.
+ * @throws IOException
+ */
+ @Test
+ public void testMissingRead() throws IOException {
+ setDefaultAuth();
+
+ final DDF input = new DDF().structure();
+ input.addmember(DoStorageOperation.CONTEXT).string(TEST_CONTEXT);
+ input.addmember(DoStorageOperation.KEY).string(TEST_KEY);
+ setRequest("GET", input);
+
+ final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
+ assertFlowExecutionResult(result, FLOW_ID);
+ assertFlowExecutionOutcome(result.getOutcome());
+ assertOutputMessageEvent(result, DoStorageOperation.RECORD_NOT_FOUND);
+ }
+
+ /**
+ * Test successful get.
+ *
+ * @throws IOException
+ */
+ @Test
+ public void successRead() throws IOException {
+ setDefaultAuth();
+
+ final long exp = Instant.now().plusSeconds(900).toEpochMilli();
+
+ getStorageService().create(AGENT_CONTEXT, TEST_KEY, TEST_VALUE, exp);
+
+ final DDF input = new DDF().structure();
+ input.addmember(DoStorageOperation.CONTEXT).string(TEST_CONTEXT);
+ input.addmember(DoStorageOperation.KEY).string(TEST_KEY);
+ setRequest("GET", input);
+
+ final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
+ assertFlowExecutionResult(result, FLOW_ID);
+ assertFlowExecutionOutcome(result.getOutcome());
+ final DDF output = assertOutputMessageEvent(result, null);
+ assert output != null;
+
+ Assert.assertEquals(output.getmember(DoStorageOperation.VALUE).string(), TEST_VALUE);
+ Assert.assertEquals(output.getmember(DoStorageOperation.VERSION).longinteger(), 1);
+ Assert.assertEquals(output.getmember(DoStorageOperation.EXP).longinteger(), exp / 1000);
+ }
+
+ /**
+ * Test missing delete.
+ *
+ * @throws IOException
+ */
+ @Test
+ public void missingDelete() throws IOException {
+ setDefaultAuth();
+
+ getStorageService().create(AGENT_CONTEXT, TEST_KEY, TEST_VALUE, null);
+
+ final DDF input = new DDF().structure();
+ input.addmember(DoStorageOperation.CONTEXT).string(TEST_CONTEXT);
+ input.addmember(DoStorageOperation.KEY).string(TEST_KEY + "2");
+ setRequest("DELETE", input);
+
+ final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
+ assertFlowExecutionResult(result, FLOW_ID);
+ assertFlowExecutionOutcome(result.getOutcome());
+
+ assertOutputMessageEvent(result, DoStorageOperation.RECORD_NOT_FOUND);
+
+ Assert.assertNotNull(getStorageService().read(AGENT_CONTEXT, TEST_KEY));
+ }
+
+ /**
+ * Test successful delete.
+ *
+ * @throws IOException
+ */
+ @Test
+ public void successDelete() throws IOException {
+ setDefaultAuth();
+
+ getStorageService().create(AGENT_CONTEXT, TEST_KEY, TEST_VALUE, null);
+
+ final DDF input = new DDF().structure();
+ input.addmember(DoStorageOperation.CONTEXT).string(TEST_CONTEXT);
+ input.addmember(DoStorageOperation.KEY).string(TEST_KEY);
+ setRequest("DELETE", input);
+
+ final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
+ assertFlowExecutionResult(result, FLOW_ID);
+ assertFlowExecutionOutcome(result.getOutcome());
+
+ final DDF output = assertOutputMessageEvent(result, null);
+ Assert.assertNull(output);
+
+ Assert.assertNull(getStorageService().read(AGENT_CONTEXT, TEST_KEY));
+ }
+
+ /**
+ * Test successful create.
+ *
+ * @throws IOException
+ */
+ @Test
+ public void successCreate() throws IOException {
+ setDefaultAuth();
+
+ final DDF input = new DDF().structure();
+ input.addmember(DoStorageOperation.CONTEXT).string(TEST_CONTEXT);
+ input.addmember(DoStorageOperation.KEY).string(TEST_KEY);
+ input.addmember(DoStorageOperation.VALUE).string(TEST_VALUE);
+ setRequest("PUT", input);
+
+ final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
+ assertFlowExecutionResult(result, FLOW_ID);
+ assertFlowExecutionOutcome(result.getOutcome());
+
+ final DDF output = assertOutputMessageEvent(result, null);
+ Assert.assertNull(output);
+
+ final StorageRecord<?> record = getStorageService().read(AGENT_CONTEXT, TEST_KEY);
+ assert record != null;
+ Assert.assertEquals(record.getVersion(), 1);
+ Assert.assertEquals(record.getValue(), TEST_VALUE);
+ }
+
+ /**
+ * Test duplicate create.
+ *
+ * @throws IOException
+ */
+ @Test
+ public void duplicateCreate() throws IOException {
+ setDefaultAuth();
+
+ getStorageService().create(AGENT_CONTEXT, TEST_KEY, TEST_VALUE, null);
+
+ final DDF input = new DDF().structure();
+ input.addmember(DoStorageOperation.CONTEXT).string(TEST_CONTEXT);
+ input.addmember(DoStorageOperation.KEY).string(TEST_KEY);
+ input.addmember(DoStorageOperation.VALUE).string(TEST_VALUE);
+ setRequest("PUT", input);
+
+ final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
+ assertFlowExecutionResult(result, FLOW_ID);
+ assertFlowExecutionOutcome(result.getOutcome());
+ assertOutputMessageEvent(result, DoStorageOperation.DUPLICATE_RECORD);
+ }
+
+ /**
+ * Test successful update.
+ *
+ * @throws IOException
+ */
+ @Test
+ public void successUpdate() throws IOException {
+ setDefaultAuth();
+
+ getStorageService().create(AGENT_CONTEXT, TEST_KEY, TEST_VALUE, null);
+
+ final DDF input = new DDF().structure();
+ input.addmember(DoStorageOperation.CONTEXT).string(TEST_CONTEXT);
+ input.addmember(DoStorageOperation.KEY).string(TEST_KEY);
+ input.addmember(DoStorageOperation.VALUE).string("changed");
+ setRequest("POST", input);
+
+ final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
+ assertFlowExecutionResult(result, FLOW_ID);
+ assertFlowExecutionOutcome(result.getOutcome());
+
+ final DDF output = assertOutputMessageEvent(result, null);
+ Assert.assertNull(output);
+
+ final StorageRecord<?> record = getStorageService().read(AGENT_CONTEXT, TEST_KEY);
+ assert record != null;
+ Assert.assertEquals(record.getVersion(), 2);
+ Assert.assertEquals(record.getValue(), "changed");
+ }
+
+ /**
+ * Test successful update as a create.
+ *
+ * @throws IOException
+ */
+ @Test
+ public void successUpdateAsCreate() throws IOException {
+ setDefaultAuth();
+
+ final DDF input = new DDF().structure();
+ input.addmember(DoStorageOperation.CONTEXT).string(TEST_CONTEXT);
+ input.addmember(DoStorageOperation.KEY).string(TEST_KEY);
+ input.addmember(DoStorageOperation.VALUE).string(TEST_VALUE);
+ setRequest("POST", input);
+
+ final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
+ assertFlowExecutionResult(result, FLOW_ID);
+ assertFlowExecutionOutcome(result.getOutcome());
+
+ final DDF output = assertOutputMessageEvent(result, null);
+ Assert.assertNull(output);
+
+ final StorageRecord<?> record = getStorageService().read(AGENT_CONTEXT, TEST_KEY);
+ assert record != null;
+ Assert.assertEquals(record.getVersion(), 1);
+ Assert.assertEquals(record.getValue(), TEST_VALUE);
+ }
+
+ /**
+ * Test successful update with a version.
+ *
+ * @throws IOException
+ */
+ @Test
+ public void successUpdateWithVersion() throws IOException {
+ setDefaultAuth();
+
+ getStorageService().create(AGENT_CONTEXT, TEST_KEY, TEST_VALUE, null);
+
+ final DDF input = new DDF().structure();
+ input.addmember(DoStorageOperation.CONTEXT).string(TEST_CONTEXT);
+ input.addmember(DoStorageOperation.KEY).string(TEST_KEY);
+ input.addmember(DoStorageOperation.VALUE).string("changed");
+ input.addmember(DoStorageOperation.VERSION).longinteger(1);
+ setRequest("POST", input);
+
+ final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
+ assertFlowExecutionResult(result, FLOW_ID);
+ assertFlowExecutionOutcome(result.getOutcome());
+
+ final DDF output = assertOutputMessageEvent(result, null);
+ assert output != null;
+ Assert.assertEquals(output.getmember(DoStorageOperation.VERSION).longinteger(), 2);
+
+ final StorageRecord<?> record = getStorageService().read(AGENT_CONTEXT, TEST_KEY);
+ assert record != null;
+ Assert.assertEquals(record.getVersion(), 2);
+ Assert.assertEquals(record.getValue(), "changed");
+ }
+
+ /**
+ * Test failed update with a version.
+ *
+ * @throws IOException
+ */
+ @Test
+ public void failedUpdateWithVersion() throws IOException {
+ setDefaultAuth();
+
+ getStorageService().create(AGENT_CONTEXT, TEST_KEY, TEST_VALUE, null);
+
+ final DDF input = new DDF().structure();
+ input.addmember(DoStorageOperation.CONTEXT).string(TEST_CONTEXT);
+ input.addmember(DoStorageOperation.KEY).string(TEST_KEY);
+ input.addmember(DoStorageOperation.VALUE).string("changed");
+ input.addmember(DoStorageOperation.VERSION).longinteger(2);
+ setRequest("POST", input);
+
+ final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
+ assertFlowExecutionResult(result, FLOW_ID);
+ assertFlowExecutionOutcome(result.getOutcome());
+
+ assertOutputMessageEvent(result, DoStorageOperation.VERSION_MISMATCH);
+
+ final StorageRecord<?> record = getStorageService().read(AGENT_CONTEXT, TEST_KEY);
+ assert record != null;
+ Assert.assertEquals(record.getVersion(), 1);
+ Assert.assertEquals(record.getValue(), TEST_VALUE);
+ }
+
+ /**
+ * Test failed update with a version when record missing.
+ *
+ * @throws IOException
+ */
+ @Test
+ public void missingUpdateWithVersion() throws IOException {
+ setDefaultAuth();
+
+ final DDF input = new DDF().structure();
+ input.addmember(DoStorageOperation.CONTEXT).string(TEST_CONTEXT);
+ input.addmember(DoStorageOperation.KEY).string(TEST_KEY);
+ input.addmember(DoStorageOperation.VALUE).string("changed");
+ input.addmember(DoStorageOperation.VERSION).longinteger(2);
+ setRequest("POST", input);
+
+ final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
+ assertFlowExecutionResult(result, FLOW_ID);
+ assertFlowExecutionOutcome(result.getOutcome());
+
+ assertOutputMessageEvent(result, DoStorageOperation.RECORD_NOT_FOUND);
+
+ Assert.assertNull(getStorageService().read(AGENT_CONTEXT, TEST_KEY));
+ }
+
+}
\ No newline at end of file
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
More information about the commits
mailing list