diff --git a/Jenkinsfile b/Jenkinsfile
index dbb74f72..fac3e806 100644
--- a/Jenkinsfile
+++ b/Jenkinsfile
@@ -3,19 +3,3 @@ buildPlugin(useContainerAgent: false, configurations: [
[platform: 'linux', jdk: 11],
[platform: 'windows', jdk: 17],
])
-
-/* TODO rewrite tests to use Testcontainers (and select Linux VM nodes above)
-node('docker') {
- stage('checkout') {
- checkout scm
- }
-
- stage('maven') {
- sh 'docker build -t fixture src/test/resources/fixture && docker run --add-host=samdom.example.com:127.0.0.1 -v /var/lib/docker --privileged --dns=127.0.0.1 --dns=8.8.8.8 -v $WORKSPACE:/project fixture clean install -P onlyITs'
- }
-
- stage('surefire-report') {
- junit 'target/surefire-reports/*.xml'
- }
-}
-*/
diff --git a/pom.xml b/pom.xml
index cfdb9c8c..356d5b92 100644
--- a/pom.xml
+++ b/pom.xml
@@ -129,6 +129,13 @@
1.19.0
test
+
+
+ org.burningwave
+ tools
+ 0.26.1
+ test
+
@@ -156,6 +163,7 @@
onlyITs
+
@@ -165,13 +173,20 @@
**/*IT.java
+
+ **/Windows*IT.java
+
+
ITs
+
+ true
+
@@ -187,6 +202,9 @@
**/*IT.java
+
+ **/Windows*IT.java
+
@@ -194,6 +212,49 @@
+
+
+ onlyWindowsITs
+
+
+
+ maven-surefire-plugin
+
+ 1
+
+ **/Windows*IT.java
+
+
+
+
+
+
+
+
+ WindowsITs
+
+
+
+ maven-surefire-plugin
+
+
+ WindowsITs
+
+ test
+
+
+ 1
+
+ **/Windows*IT.java
+
+
+
+
+
+
+
+
+
diff --git a/src/test/java/hudson/plugins/active_directory/WindowsAdsiModeUserCacheDisabledIT.java b/src/test/java/hudson/plugins/active_directory/WindowsAdsiModeUserCacheDisabledIT.java
index d1fe261c..47ac79c1 100644
--- a/src/test/java/hudson/plugins/active_directory/WindowsAdsiModeUserCacheDisabledIT.java
+++ b/src/test/java/hudson/plugins/active_directory/WindowsAdsiModeUserCacheDisabledIT.java
@@ -20,7 +20,7 @@
/**
* This tests requires a very specific windows environment to run, the windows machine
* needs to be joined to a function domain that has the user fred with the password ia4uV1EeKait.
- * It is enabled in the ITs profile, but will skip on I as that profile is enabled only on the special Linux environment.
+ * It is enabled in the WindowsITs profile, but will skip on I as that profile is enabled only on the special Linux environment.
*/
public class WindowsAdsiModeUserCacheDisabledIT {
diff --git a/src/test/java/hudson/plugins/active_directory/WindowsAdsiModeUserCacheEnabledIT.java b/src/test/java/hudson/plugins/active_directory/WindowsAdsiModeUserCacheEnabledIT.java
index 5009b954..445a1ade 100644
--- a/src/test/java/hudson/plugins/active_directory/WindowsAdsiModeUserCacheEnabledIT.java
+++ b/src/test/java/hudson/plugins/active_directory/WindowsAdsiModeUserCacheEnabledIT.java
@@ -22,7 +22,7 @@
/**
* This tests requires a very specific windows environment to run, the windows machine
* needs to be joined to a function domain that has the user fred with the password ia4uV1EeKait.
- * It is enabled in the ITs profile, but will skip on I as that profile is enabled only on the special Linux environment.
+ * It is enabled in the windowsITs profile, but will skip on I as that profile is enabled only on the special Linux environment.
*/
public class WindowsAdsiModeUserCacheEnabledIT {
diff --git a/src/test/java/hudson/plugins/active_directory/docker/ActiveDirectoryGenericContainer.java b/src/test/java/hudson/plugins/active_directory/docker/ActiveDirectoryGenericContainer.java
index 720e5bcd..b5125596 100644
--- a/src/test/java/hudson/plugins/active_directory/docker/ActiveDirectoryGenericContainer.java
+++ b/src/test/java/hudson/plugins/active_directory/docker/ActiveDirectoryGenericContainer.java
@@ -3,6 +3,8 @@
import java.io.IOException;
import org.testcontainers.containers.GenericContainer;
import org.testcontainers.containers.InternetProtocol;
+import org.testcontainers.containers.wait.strategy.LogMessageWaitStrategy;
+import org.testcontainers.containers.wait.strategy.WaitStrategy;
import org.testcontainers.images.builder.ImageFromDockerfile;
import com.github.dockerjava.api.DockerClient;
import com.github.dockerjava.api.command.CreateContainerCmd;
@@ -25,7 +27,8 @@ public ActiveDirectoryGenericContainer() {
.withFileFromClasspath("named.conf.options", "hudson/plugins/active_directory/docker/TheFlintstonesTest/TheFlintstones/named.conf.options")
.withFileFromClasspath("sssd.conf", "hudson/plugins/active_directory/docker/TheFlintstonesTest/TheFlintstones/sssd.conf")
.withFileFromClasspath("supervisord.conf", "hudson/plugins/active_directory/docker/TheFlintstonesTest/TheFlintstones/supervisord.conf"));
- setWaitStrategy(null);
+ // wait for the custom.sh script to complete successfully
+ setWaitStrategy(new LogMessageWaitStrategy().withRegEx(".*\\Qexited: custom (exit status 0; expected)\\E.*"));
}
/*
@@ -35,8 +38,8 @@ public ActiveDirectoryGenericContainer() {
public ActiveDirectoryGenericContainer withStaticPorts() {
addFixedExposedPort(3268, 3268); // global catalog
addFixedExposedPort(3269, 3269); // global catalog over tls
- addFixedExposedPort(53, 53, InternetProtocol.TCP); // DNS over TCP
- addFixedExposedPort(53, 53, InternetProtocol.UDP); // DNS over UDP
+ addFixedExposedPort(553, 53, InternetProtocol.TCP); // DNS over TCP
+ addFixedExposedPort(553, 53, InternetProtocol.UDP); // DNS over UDP
return this;
}
diff --git a/src/test/java/hudson/plugins/active_directory/docker/EntoEndUserCacheLookupDisabledTest.java b/src/test/java/hudson/plugins/active_directory/docker/EntoEndUserCacheLookupDisabledTest.java
index 40fdc3ac..d8abe3ae 100644
--- a/src/test/java/hudson/plugins/active_directory/docker/EntoEndUserCacheLookupDisabledTest.java
+++ b/src/test/java/hudson/plugins/active_directory/docker/EntoEndUserCacheLookupDisabledTest.java
@@ -59,9 +59,6 @@ public void customSingleADSetup(ActiveDirectoryDomain activeDirectoryDomain, Str
ActiveDirectorySecurityRealm activeDirectorySecurityRealm = new ActiveDirectorySecurityRealm(null, domains, site, bindName, bindPassword, null, groupLookupStrategy, removeIrrelevantGroups, customDomain, cache, startTls, internalUsersDatabase, false);
j.getInstance().setSecurityRealm(activeDirectorySecurityRealm);
- while(!docker.getLogs().contains("custom (exit status 0; expected)")) {
- Thread.sleep(1000);
- }
UserDetails userDetails = null;
int i = 0;
while (i < MAX_RETRIES && userDetails == null) {
diff --git a/src/test/java/hudson/plugins/active_directory/docker/EntoEndUserCacheLookupEnabledTest.java b/src/test/java/hudson/plugins/active_directory/docker/EntoEndUserCacheLookupEnabledTest.java
index 55fc773e..a9e1ae87 100644
--- a/src/test/java/hudson/plugins/active_directory/docker/EntoEndUserCacheLookupEnabledTest.java
+++ b/src/test/java/hudson/plugins/active_directory/docker/EntoEndUserCacheLookupEnabledTest.java
@@ -80,9 +80,6 @@ public void customSingleADSetup(ActiveDirectoryDomain activeDirectoryDomain, Str
ActiveDirectorySecurityRealm activeDirectorySecurityRealm = new ActiveDirectorySecurityRealm(null, domains, site, bindName, bindPassword, null, groupLookupStrategy, removeIrrelevantGroups, customDomain, cache, startTls, internalUsersDatabase, false);
j.getInstance().setSecurityRealm(activeDirectorySecurityRealm);
- while(!docker.getLogs().contains("custom (exit status 0; expected)")) {
- Thread.sleep(1000);
- }
UserDetails userDetails = null;
int i = 0;
while (i < MAX_RETRIES && userDetails == null) {
diff --git a/src/test/java/hudson/plugins/active_directory/docker/TheFlintstonesIT.java b/src/test/java/hudson/plugins/active_directory/docker/TheFlintstonesIT.java
index bfe4f966..64e7ebc8 100644
--- a/src/test/java/hudson/plugins/active_directory/docker/TheFlintstonesIT.java
+++ b/src/test/java/hudson/plugins/active_directory/docker/TheFlintstonesIT.java
@@ -25,15 +25,28 @@
package hudson.plugins.active_directory.docker;
import static org.junit.Assert.assertEquals;
+
import java.io.IOException;
+import java.net.Inet6Address;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
import java.util.ArrayList;
+import java.util.LinkedHashMap;
import java.util.List;
+import java.util.Map;
+
import javax.naming.NamingException;
import javax.servlet.ServletException;
import hudson.plugins.active_directory.TlsConfiguration;
import org.acegisecurity.AuthenticationServiceException;
import org.acegisecurity.userdetails.UserDetails;
+import org.burningwave.tools.net.DNSClientHostResolver;
+import org.burningwave.tools.net.DefaultHostResolver;
+import org.burningwave.tools.net.HostResolutionRequestInterceptor;
+import org.burningwave.tools.net.MappedHostResolver;
+import org.junit.After;
+import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.jvnet.hudson.test.Issue;
@@ -41,13 +54,15 @@
import org.jvnet.hudson.test.LoggerRule;
import hudson.plugins.active_directory.ActiveDirectoryDomain;
import hudson.plugins.active_directory.ActiveDirectorySecurityRealm;
+import hudson.plugins.active_directory.DNSUtils;
import hudson.plugins.active_directory.GroupLookupStrategy;
/**
- * Integration tests with Docker and requiring custom DNS in the target env with fixed ports.
+ * Integration tests with Docker and using samba as a DNS server
*/
public class TheFlintstonesIT {
+
@Rule(order = 0)
public RequireDockerRule rdr = new RequireDockerRule();
@@ -60,6 +75,41 @@ public class TheFlintstonesIT {
@Rule
public LoggerRule l = new LoggerRule();
+ @Before
+ public void overrideDNSServers() throws UnknownHostException {
+ // we need to pint the JVMs DNS resolver at the AD (samba) server
+ // for AD to work correctly it needs to be able to resolve hosts and do SRV lookups on the domain
+
+ // whilst the `getHost()` is supposed to return an IPAddress in some cases it will return "localhost"
+ // we need a resolved address to configure the resolver do a lookup before we change the DNS.
+ InetAddress hostInetAddr = InetAddress.getByName(docker.getHost());
+ String hostIP = hostInetAddr.getHostAddress();
+
+ // but additionally we need to use the locally bound ports for the catalog and not what AD returns for name resolution
+ Map hostAliases = new LinkedHashMap<>();
+ hostAliases.put("dc1.samdom.example.com", hostIP);
+ // this adds the A entry for the PDC, but will leave the discovery of this to the SRV lookup
+
+ HostResolutionRequestInterceptor.INSTANCE.install(
+ new MappedHostResolver(hostAliases),
+ new DNSClientHostResolver(hostIP, 553),
+ DefaultHostResolver.INSTANCE);
+
+ // we also need to set the JNDI default
+ // see hudson.plugins.active_directory.ActiveDirectoryDomain.createDNSLookupContext()
+ if (hostInetAddr instanceof Inet6Address) {
+ System.setProperty(DNSUtils.OVERRIDE_DNS_PROPERTY, "dns://["+hostIP+"]:553");
+ } else {
+ System.setProperty(DNSUtils.OVERRIDE_DNS_PROPERTY, "dns://"+hostIP+":553");
+ }
+ }
+
+ @After
+ public void restoreDNS() {
+ HostResolutionRequestInterceptor.INSTANCE.install(DefaultHostResolver.INSTANCE);
+ System.clearProperty(DNSUtils.OVERRIDE_DNS_PROPERTY);
+ }
+
public final static String AD_DOMAIN = "samdom.example.com";
public final static String AD_MANAGER_DN = "CN=Administrator,CN=Users,DC=SAMDOM,DC=EXAMPLE,DC=COM";
public final static String AD_MANAGER_DN_PASSWORD = "ia4uV1EeKait";
@@ -74,16 +124,13 @@ public void dynamicSetUp() throws Exception {
}
public void dynamicSetUp(boolean requireTLS) throws Exception {
- dockerIp = requireTLS ? docker.getHost() : "dc1.samdom.example.com";
+ dockerIp = "dc1.samdom.example.com";
dockerPort = docker.getMappedPort(requireTLS ? GLOBAL_CATALOG_TLS : GLOBAL_CATALOG_PLAIN_TEXT);
ActiveDirectoryDomain activeDirectoryDomain = new ActiveDirectoryDomain(AD_DOMAIN, dockerIp + ":" + dockerPort , null, AD_MANAGER_DN, AD_MANAGER_DN_PASSWORD);
List domains = new ArrayList<>(1);
domains.add(activeDirectoryDomain);
ActiveDirectorySecurityRealm activeDirectorySecurityRealm = new ActiveDirectorySecurityRealm(null, domains, null, null, null, null, GroupLookupStrategy.RECURSIVE, false, true, null, false, null, requireTLS);
j.getInstance().setSecurityRealm(activeDirectorySecurityRealm);
- while(!docker.getLogs().contains("custom (exit status 0; expected)")) {
- Thread.sleep(1000);
- }
UserDetails userDetails = null;
int i = 0;
while (i < MAX_RETRIES && userDetails == null) {
diff --git a/src/test/java/hudson/plugins/active_directory/docker/TheFlintstonesTest.java b/src/test/java/hudson/plugins/active_directory/docker/TheFlintstonesTest.java
index f5abb8a3..e6909e1f 100644
--- a/src/test/java/hudson/plugins/active_directory/docker/TheFlintstonesTest.java
+++ b/src/test/java/hudson/plugins/active_directory/docker/TheFlintstonesTest.java
@@ -117,9 +117,6 @@ public void dynamicSetUp() throws Exception {
domains.add(activeDirectoryDomain);
ActiveDirectorySecurityRealm activeDirectorySecurityRealm = new ActiveDirectorySecurityRealm(null, domains, null, null, null, null, GroupLookupStrategy.RECURSIVE, false, true, null, false, null, false);
j.getInstance().setSecurityRealm(activeDirectorySecurityRealm);
- while(!docker.getLogs().contains("custom (exit status 0; expected)")) {
- Thread.sleep(1000);
- }
UserDetails userDetails = null;
int i = 0;
while (i < MAX_RETRIES && userDetails == null) {