I am trying to use Spring LDAP in one of my Spring Boot projects but I am getting an 'Address already in use' error when running multiple tests.
I have cloned locally the sample project here: https://spring.io/guides/gs/authenticating-ldap/
...and just added the boilerplate test normally created by Spring Boot to verify that the Application Context loads correctly:
@RunWith(SpringRunner.class)
@SpringBootTest
public class MyApplicationTests {
@Test
public void contextLoads() {
}
}
If run alone, this test passes. As soon as LdapAuthenticationTests and MyApplicationTests are run together, I get the error above for the latter.
After debugging a bit, I've found out that this happens because the system tries to spawn a second instance of the embedded server.
I am sure I am missing something very stupid in the configuration. How can I fix this problem?
I had a similar problem, and it looks like you had a static port configured (as was in my case).
According to this article:
Spring Boot starts an embedded LDAP server for each application context. Logically, that means, it starts an embedded LDAP server for each test class. Practically, this is not always true since Spring Boot caches and reuses application contexts. However, you should always expect that there is more than one LDAP server running while executing your tests. For this reason, you may not declare a port for your LDAP server. In this way, it will automatically uses a free port. Otherwise, your tests will fail with “Address already in use”
Thus it might be a better idea not to define spring.ldap.embedded.port
at all.
I addressed the same issue. I solved it with an additional TestExecutionListener since you can get the InMemoryDirectoryServer bean.
/**
* @author slemoine
*/
public class LdapExecutionListener implements TestExecutionListener {
@Override
public void afterTestClass(TestContext testContext) {
InMemoryDirectoryServer ldapServer = testContext.getApplicationContext().getBean(InMemoryDirectoryServer.class);
ldapServer.shutDown(true);
}
}
And on each SpringBootTest (or only once in an abstract super class)
@RunWith(SpringRunner.class)
@SpringBootTest
@TestExecutionListeners(listeners = LdapExecutionListener.class,
mergeMode = TestExecutionListeners.MergeMode.MERGE_WITH_DEFAULTS)
public class MyTestClass {
...
}
also do not forget
mergeMode = TestExecutionListeners.MergeMode.MERGE_WITH_DEFAULTS
to avoid disabling the whole @SpringBootTest auto configuration.
Okay, I think I found a solution by adding a @DirtiesContext
annotation to my test classes:
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)
If you are using spring embedded ldap, try to comment or remove port value from config file as below :
spring :
ldap:
embedded:
base-dn: dc=example,dc=org
credential:
username: cn=admin,dc=example,dc=org
password: admin
ldif: classpath:test-schema.ldif
# port: 12345
validation:
enabled: false
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With