From d3278433a7e2873c471ed1cc188382c6516da9af Mon Sep 17 00:00:00 2001 From: emanueltrandafir1993 Date: Thu, 20 Feb 2025 08:42:53 +0200 Subject: [PATCH 1/3] Add start/stop methods Closes #1025 Signed-off-by: emanueltrandafir1993 --- .../test/unboundid/EmbeddedLdapServer.java | 39 ++++++++++- .../EmbeddedLdapServerFactoryBean.java | 2 +- .../ldap/test/unboundid/LdapTestUtils.java | 2 +- .../unboundid/EmbeddedLdapServerTest.java | 64 +++++++++++++++++++ 4 files changed, 102 insertions(+), 5 deletions(-) create mode 100644 test-support/src/test/java/org/springframework/ldap/test/unboundid/EmbeddedLdapServerTest.java diff --git a/test-support/src/main/java/org/springframework/ldap/test/unboundid/EmbeddedLdapServer.java b/test-support/src/main/java/org/springframework/ldap/test/unboundid/EmbeddedLdapServer.java index 81e5a01c8..4436125fa 100644 --- a/test-support/src/main/java/org/springframework/ldap/test/unboundid/EmbeddedLdapServer.java +++ b/test-support/src/main/java/org/springframework/ldap/test/unboundid/EmbeddedLdapServer.java @@ -21,6 +21,7 @@ import com.unboundid.ldap.listener.InMemoryListenerConfig; import com.unboundid.ldap.sdk.DN; import com.unboundid.ldap.sdk.Entry; +import com.unboundid.ldap.sdk.LDAPException; /** * Helper class for embedded Unboundid ldap server. @@ -28,14 +29,17 @@ * @author Eddu Melendez * @since 2.1.0 */ -public final class EmbeddedLdapServer { +public final class EmbeddedLdapServer implements AutoCloseable { - private InMemoryDirectoryServer directoryServer; + private final InMemoryDirectoryServer directoryServer; private EmbeddedLdapServer(InMemoryDirectoryServer directoryServer) { this.directoryServer = directoryServer; } + /** + * Creates and starts new embedded LDAP server. + */ public static EmbeddedLdapServer newEmbeddedServer(String defaultPartitionName, String defaultPartitionSuffix, int port) throws Exception { InMemoryDirectoryServerConfig config = new InMemoryDirectoryServerConfig(defaultPartitionSuffix); @@ -56,7 +60,36 @@ public static EmbeddedLdapServer newEmbeddedServer(String defaultPartitionName, return new EmbeddedLdapServer(directoryServer); } - public void shutdown() throws Exception { + /** + * Starts the embedded LDAP server. + * + * @since 3.3 + */ + public void start() { + try { + this.directoryServer.startListening(); + } + catch (LDAPException ex) { + throw new RuntimeException(ex); + } + } + + /** + * Closes the embedded LDAP server and releases resource, closing existing + * connections. + * + * @since 3.3 + */ + @Override + public void close() { + this.directoryServer.shutDown(true); + } + + /** + * @deprecated Use {@link #close()} instead. + */ + @Deprecated(since = "3.3") + public void shutdown() { this.directoryServer.shutDown(true); } diff --git a/test-support/src/main/java/org/springframework/ldap/test/unboundid/EmbeddedLdapServerFactoryBean.java b/test-support/src/main/java/org/springframework/ldap/test/unboundid/EmbeddedLdapServerFactoryBean.java index b5f244041..360a68679 100644 --- a/test-support/src/main/java/org/springframework/ldap/test/unboundid/EmbeddedLdapServerFactoryBean.java +++ b/test-support/src/main/java/org/springframework/ldap/test/unboundid/EmbeddedLdapServerFactoryBean.java @@ -53,7 +53,7 @@ protected EmbeddedLdapServer createInstance() throws Exception { @Override protected void destroyInstance(EmbeddedLdapServer instance) throws Exception { - instance.shutdown(); + instance.close(); } } diff --git a/test-support/src/main/java/org/springframework/ldap/test/unboundid/LdapTestUtils.java b/test-support/src/main/java/org/springframework/ldap/test/unboundid/LdapTestUtils.java index 1bfed95b7..9ec82ed37 100644 --- a/test-support/src/main/java/org/springframework/ldap/test/unboundid/LdapTestUtils.java +++ b/test-support/src/main/java/org/springframework/ldap/test/unboundid/LdapTestUtils.java @@ -92,7 +92,7 @@ public static void startEmbeddedServer(int port, String defaultPartitionSuffix, */ public static void shutdownEmbeddedServer() throws Exception { if (embeddedServer != null) { - embeddedServer.shutdown(); + embeddedServer.close(); embeddedServer = null; } } diff --git a/test-support/src/test/java/org/springframework/ldap/test/unboundid/EmbeddedLdapServerTest.java b/test-support/src/test/java/org/springframework/ldap/test/unboundid/EmbeddedLdapServerTest.java new file mode 100644 index 000000000..d2a04f60f --- /dev/null +++ b/test-support/src/test/java/org/springframework/ldap/test/unboundid/EmbeddedLdapServerTest.java @@ -0,0 +1,64 @@ +package org.springframework.ldap.test.unboundid; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.io.IOException; +import java.net.ServerSocket; +import java.net.Socket; + +import org.junit.Test; + +public class EmbeddedLdapServerTest { + + @Test + public void shouldStartAndCloseServer() throws Exception { + int port = getFreePort(); + assertFalse(isPortOpen(port)); + + EmbeddedLdapServer server = EmbeddedLdapServer.newEmbeddedServer("jayway", "dc=jayway,dc=se", port); + assertTrue(isPortOpen(port)); + + server.close(); + assertFalse(isPortOpen(port)); + } + + @Test + public void shouldStartAndAutoCloseServer() throws Exception { + int port = getFreePort(); + assertFalse(isPortOpen(port)); + + try (EmbeddedLdapServer ignored = EmbeddedLdapServer.newEmbeddedServer("jayway", "dc=jayway,dc=se", port)) { + assertTrue(isPortOpen(port)); + } + assertFalse(isPortOpen(port)); + } + + @Test + public void shouldStartAndCloseServerViaLdapTestUtils() throws Exception { + int port = getFreePort(); + assertFalse(isPortOpen(port)); + + LdapTestUtils.startEmbeddedServer(port, "dc=jayway,dc=se", "jayway"); + assertTrue(isPortOpen(port)); + + LdapTestUtils.shutdownEmbeddedServer(); + assertFalse(isPortOpen(port)); + } + + static boolean isPortOpen(int port) { + try (Socket ignored = new Socket("localhost", port)) { + return true; + } + catch (IOException e) { + return false; + } + } + + static int getFreePort() throws IOException { + try (ServerSocket serverSocket = new ServerSocket(0)) { + return serverSocket.getLocalPort(); + } + } + +} \ No newline at end of file From 936112c6b05d383b9c174ce28b4fbb5cdcfe1ad1 Mon Sep 17 00:00:00 2001 From: Josh Cummings <3627351+jzheaux@users.noreply.github.com> Date: Tue, 11 Mar 2025 07:43:31 -0600 Subject: [PATCH 2/3] Fix checkstyle errors Issue gh-1025 --- .../unboundid/EmbeddedLdapServerTest.java | 64 --------------- .../unboundid/EmbeddedLdapServerTests.java | 79 +++++++++++++++++++ 2 files changed, 79 insertions(+), 64 deletions(-) delete mode 100644 test-support/src/test/java/org/springframework/ldap/test/unboundid/EmbeddedLdapServerTest.java create mode 100644 test-support/src/test/java/org/springframework/ldap/test/unboundid/EmbeddedLdapServerTests.java diff --git a/test-support/src/test/java/org/springframework/ldap/test/unboundid/EmbeddedLdapServerTest.java b/test-support/src/test/java/org/springframework/ldap/test/unboundid/EmbeddedLdapServerTest.java deleted file mode 100644 index d2a04f60f..000000000 --- a/test-support/src/test/java/org/springframework/ldap/test/unboundid/EmbeddedLdapServerTest.java +++ /dev/null @@ -1,64 +0,0 @@ -package org.springframework.ldap.test.unboundid; - -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -import java.io.IOException; -import java.net.ServerSocket; -import java.net.Socket; - -import org.junit.Test; - -public class EmbeddedLdapServerTest { - - @Test - public void shouldStartAndCloseServer() throws Exception { - int port = getFreePort(); - assertFalse(isPortOpen(port)); - - EmbeddedLdapServer server = EmbeddedLdapServer.newEmbeddedServer("jayway", "dc=jayway,dc=se", port); - assertTrue(isPortOpen(port)); - - server.close(); - assertFalse(isPortOpen(port)); - } - - @Test - public void shouldStartAndAutoCloseServer() throws Exception { - int port = getFreePort(); - assertFalse(isPortOpen(port)); - - try (EmbeddedLdapServer ignored = EmbeddedLdapServer.newEmbeddedServer("jayway", "dc=jayway,dc=se", port)) { - assertTrue(isPortOpen(port)); - } - assertFalse(isPortOpen(port)); - } - - @Test - public void shouldStartAndCloseServerViaLdapTestUtils() throws Exception { - int port = getFreePort(); - assertFalse(isPortOpen(port)); - - LdapTestUtils.startEmbeddedServer(port, "dc=jayway,dc=se", "jayway"); - assertTrue(isPortOpen(port)); - - LdapTestUtils.shutdownEmbeddedServer(); - assertFalse(isPortOpen(port)); - } - - static boolean isPortOpen(int port) { - try (Socket ignored = new Socket("localhost", port)) { - return true; - } - catch (IOException e) { - return false; - } - } - - static int getFreePort() throws IOException { - try (ServerSocket serverSocket = new ServerSocket(0)) { - return serverSocket.getLocalPort(); - } - } - -} \ No newline at end of file diff --git a/test-support/src/test/java/org/springframework/ldap/test/unboundid/EmbeddedLdapServerTests.java b/test-support/src/test/java/org/springframework/ldap/test/unboundid/EmbeddedLdapServerTests.java new file mode 100644 index 000000000..02d40c559 --- /dev/null +++ b/test-support/src/test/java/org/springframework/ldap/test/unboundid/EmbeddedLdapServerTests.java @@ -0,0 +1,79 @@ +/* + * Copyright 2005-2025 the original author or authors. + * + * 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 + * + * https://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 org.springframework.ldap.test.unboundid; + +import java.io.IOException; +import java.net.ServerSocket; +import java.net.Socket; + +import org.junit.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +public class EmbeddedLdapServerTests { + + @Test + public void shouldStartAndCloseServer() throws Exception { + int port = getFreePort(); + assertThat(isPortOpen(port)).isFalse(); + + EmbeddedLdapServer server = EmbeddedLdapServer.newEmbeddedServer("jayway", "dc=jayway,dc=se", port); + assertThat(isPortOpen(port)).isTrue(); + + server.close(); + assertThat(isPortOpen(port)).isFalse(); + } + + @Test + public void shouldStartAndAutoCloseServer() throws Exception { + int port = getFreePort(); + assertThat(isPortOpen(port)).isFalse(); + + try (EmbeddedLdapServer ignored = EmbeddedLdapServer.newEmbeddedServer("jayway", "dc=jayway,dc=se", port)) { + assertThat(isPortOpen(port)).isTrue(); + } + assertThat(isPortOpen(port)).isFalse(); + } + + @Test + public void shouldStartAndCloseServerViaLdapTestUtils() throws Exception { + int port = getFreePort(); + assertThat(isPortOpen(port)).isFalse(); + + LdapTestUtils.startEmbeddedServer(port, "dc=jayway,dc=se", "jayway"); + assertThat(isPortOpen(port)).isTrue(); + + LdapTestUtils.shutdownEmbeddedServer(); + assertThat(isPortOpen(port)).isFalse(); + } + + static boolean isPortOpen(int port) { + try (Socket ignored = new Socket("localhost", port)) { + return true; + } + catch (IOException ex) { + return false; + } + } + + static int getFreePort() throws IOException { + try (ServerSocket serverSocket = new ServerSocket(0)) { + return serverSocket.getLocalPort(); + } + } + +} From db7ed4cf07a23ac842e4687180383241b350b2b0 Mon Sep 17 00:00:00 2001 From: Josh Cummings <3627351+jzheaux@users.noreply.github.com> Date: Tue, 11 Mar 2025 08:08:34 -0600 Subject: [PATCH 3/3] Error When Starting Twice Issue gh-1025 --- .../test/unboundid/EmbeddedLdapServer.java | 11 +++++- .../unboundid/EmbeddedLdapServerTests.java | 36 +++++++++++++++++++ 2 files changed, 46 insertions(+), 1 deletion(-) diff --git a/test-support/src/main/java/org/springframework/ldap/test/unboundid/EmbeddedLdapServer.java b/test-support/src/main/java/org/springframework/ldap/test/unboundid/EmbeddedLdapServer.java index 4436125fa..b764493ce 100644 --- a/test-support/src/main/java/org/springframework/ldap/test/unboundid/EmbeddedLdapServer.java +++ b/test-support/src/main/java/org/springframework/ldap/test/unboundid/EmbeddedLdapServer.java @@ -23,6 +23,8 @@ import com.unboundid.ldap.sdk.Entry; import com.unboundid.ldap.sdk.LDAPException; +import org.springframework.util.Assert; + /** * Helper class for embedded Unboundid ldap server. * @@ -33,7 +35,13 @@ public final class EmbeddedLdapServer implements AutoCloseable { private final InMemoryDirectoryServer directoryServer; - private EmbeddedLdapServer(InMemoryDirectoryServer directoryServer) { + /** + * Construct an {@link EmbeddedLdapServer} using the provided + * {@link InMemoryDirectoryServer}. + * + * @since 3.3 + */ + public EmbeddedLdapServer(InMemoryDirectoryServer directoryServer) { this.directoryServer = directoryServer; } @@ -66,6 +74,7 @@ public static EmbeddedLdapServer newEmbeddedServer(String defaultPartitionName, * @since 3.3 */ public void start() { + Assert.isTrue(this.directoryServer.getListenPort() == -1, "The server has already been started."); try { this.directoryServer.startListening(); } diff --git a/test-support/src/test/java/org/springframework/ldap/test/unboundid/EmbeddedLdapServerTests.java b/test-support/src/test/java/org/springframework/ldap/test/unboundid/EmbeddedLdapServerTests.java index 02d40c559..22bc987cf 100644 --- a/test-support/src/test/java/org/springframework/ldap/test/unboundid/EmbeddedLdapServerTests.java +++ b/test-support/src/test/java/org/springframework/ldap/test/unboundid/EmbeddedLdapServerTests.java @@ -20,9 +20,13 @@ import java.net.ServerSocket; import java.net.Socket; +import com.unboundid.ldap.listener.InMemoryDirectoryServer; +import com.unboundid.ldap.listener.InMemoryDirectoryServerConfig; +import com.unboundid.ldap.listener.InMemoryListenerConfig; import org.junit.Test; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; public class EmbeddedLdapServerTests { @@ -61,6 +65,38 @@ public void shouldStartAndCloseServerViaLdapTestUtils() throws Exception { assertThat(isPortOpen(port)).isFalse(); } + @Test + public void startWhenNewEmbeddedServerThenException() throws Exception { + int port = getFreePort(); + EmbeddedLdapServer server = EmbeddedLdapServer.newEmbeddedServer("jayway", "dc=jayway,dc=se", port); + assertThatExceptionOfType(IllegalArgumentException.class).isThrownBy(server::start); + } + + @Test + public void startWhenUnstartedThenWorks() throws Exception { + int port = getFreePort(); + InMemoryDirectoryServerConfig config = new InMemoryDirectoryServerConfig("dc=jayway,dc=se"); + config.setListenerConfigs(InMemoryListenerConfig.createLDAPConfig("LDAP", port)); + InMemoryDirectoryServer ds = new InMemoryDirectoryServer(config); + try (EmbeddedLdapServer server = new EmbeddedLdapServer(ds)) { + server.start(); + assertThat(isPortOpen(port)).isTrue(); + } + } + + @Test + public void startWhenAlreadyStartedThenFails() throws Exception { + int port = getFreePort(); + InMemoryDirectoryServerConfig config = new InMemoryDirectoryServerConfig("dc=jayway,dc=se"); + config.setListenerConfigs(InMemoryListenerConfig.createLDAPConfig("LDAP", port)); + InMemoryDirectoryServer ds = new InMemoryDirectoryServer(config); + try (EmbeddedLdapServer server = new EmbeddedLdapServer(ds)) { + server.start(); + assertThat(isPortOpen(port)).isTrue(); + assertThatExceptionOfType(IllegalArgumentException.class).isThrownBy(server::start); + } + } + static boolean isPortOpen(int port) { try (Socket ignored = new Socket("localhost", port)) { return true;