diff --git a/htmlSanityCheck-core/src/test/groovy/org/aim42/htmlsanitycheck/check/BrokenHttpLinksCheckerSpec.groovy b/htmlSanityCheck-core/src/test/groovy/org/aim42/htmlsanitycheck/check/BrokenHttpLinksCheckerSpec.groovy
index faaf35a6..72f24fe2 100644
--- a/htmlSanityCheck-core/src/test/groovy/org/aim42/htmlsanitycheck/check/BrokenHttpLinksCheckerSpec.groovy
+++ b/htmlSanityCheck-core/src/test/groovy/org/aim42/htmlsanitycheck/check/BrokenHttpLinksCheckerSpec.groovy
@@ -4,8 +4,17 @@ import org.aim42.htmlsanitycheck.Configuration
import org.aim42.htmlsanitycheck.collect.SingleCheckResults
import org.aim42.htmlsanitycheck.html.HtmlConst
import org.aim42.htmlsanitycheck.html.HtmlPage
+import org.aim42.htmlsanitycheck.test.dns.CustomHostNameResolver
import org.wiremock.integrations.testcontainers.WireMockContainer
-import spock.lang.*
+import spock.lang.Ignore
+import spock.lang.IgnoreIf
+import spock.lang.Shared
+import spock.lang.Specification
+import spock.lang.Unroll
+
+import java.lang.reflect.Field
+import java.lang.reflect.Proxy
+
// see end-of-file for license information
class BrokenHttpLinksCheckerSpec extends Specification {
@@ -24,15 +33,14 @@ class BrokenHttpLinksCheckerSpec extends Specification {
.withMappingFromResource("testing.json")
.withExposedPorts(8080)
-
-
-
-
+ @Shared
+ CustomHostNameResolver customHostNameResolver = new CustomHostNameResolver()
/** executed once before all specs are executed **/
def setupSpec() {
wireMockServer.start()
port = wireMockServer.getMappedPort(8080)
+ registerCustomDnsResolver()
}
/** executed once after all specs are executed **/
@@ -40,6 +48,29 @@ class BrokenHttpLinksCheckerSpec extends Specification {
wireMockServer.stop()
}
+ // Custom method to register the DNS resolver
+ private void registerCustomDnsResolver() {
+ try {
+ Field implField = InetAddress.class.getDeclaredField("impl");
+ implField.setAccessible(true);
+ Object currentImpl = implField.get(null);
+
+ Proxy newImpl = (Proxy) Proxy.newProxyInstance(
+ currentImpl.getClass().getClassLoader(),
+ currentImpl.getClass().getInterfaces(),
+ (proxy, method, args) -> {
+ if ("lookupAllHostAddr".equals(method.getName()) && args.length == 1 && args[0] instanceof String) {
+ return customHostNameResolver.resolve((String) args[0]);
+ }
+ return method.invoke(currentImpl, args);
+ }
+ );
+
+ implField.set(null, newImpl);
+ } catch (Exception e) {
+ throw new RuntimeException("Failed to register custom DNS resolver", e);
+ }
+ }
/* executed before every single spec */
@@ -81,7 +112,7 @@ class BrokenHttpLinksCheckerSpec extends Specification {
def "one syntactically correct http URL is ok"() {
given: "an HTML page with a single correct anchor/link"
String HTML = """$HtmlConst.HTML_HEAD
- google
+ google
$HtmlConst.HTML_END """
htmlPage = new HtmlPage(HTML)
@@ -116,9 +147,9 @@ class BrokenHttpLinksCheckerSpec extends Specification {
collector.nrOfProblems() == 0
where:
- goodUrl << ["http://localhost:$port/goodurl1",
- "http://localhost:$port/goodurl2",
- "http://localhost:$port/goodurl3"
+ goodUrl << ["http://${CustomHostNameResolver.WIREMOCK_HOST}:$port/goodurl1",
+ "http://${CustomHostNameResolver.WIREMOCK_HOST}:$port/goodurl2",
+ "http://${CustomHostNameResolver.WIREMOCK_HOST}:$port/goodurl3"
]
}
diff --git a/htmlSanityCheck-core/src/test/java/org/aim42/htmlsanitycheck/test/dns/CustomHostNameResolver.java b/htmlSanityCheck-core/src/test/java/org/aim42/htmlsanitycheck/test/dns/CustomHostNameResolver.java
new file mode 100644
index 00000000..15b5731c
--- /dev/null
+++ b/htmlSanityCheck-core/src/test/java/org/aim42/htmlsanitycheck/test/dns/CustomHostNameResolver.java
@@ -0,0 +1,36 @@
+package org.aim42.htmlsanitycheck.test.dns;
+
+import java.lang.reflect.Field;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+
+public class CustomHostNameResolver {
+
+ public static final String WIREMOCK_HOST = "my.custom.mocked.host";
+ private static Object originalResolver;
+
+ static {
+ try {
+ Field implField = InetAddress.class.getDeclaredField("impl");
+ implField.setAccessible(true);
+ originalResolver = implField.get(null);
+ } catch (Exception e) {
+ throw new RuntimeException("Failed to setup fallback DNS resolver", e);
+ }
+ }
+
+ public InetAddress[] resolve(String hostname) throws UnknownHostException {
+ // Custom DNS resolution logic
+ if (WIREMOCK_HOST.equals(hostname)) {
+ return new InetAddress[]{InetAddress.getByAddress("localhost", new byte[]{127, 0, 0, 1})};
+ }
+ // Fallback to original resolver using reflection
+ try {
+ return (InetAddress[]) originalResolver.getClass()
+ .getMethod("lookupAllHostAddr", String.class)
+ .invoke(originalResolver, hostname);
+ } catch (Exception e) {
+ throw new UnknownHostException("Failed to resolve hostname: " + hostname);
+ }
+ }
+}
\ No newline at end of file