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) {