Skip to content

Commit 7388dee

Browse files
committed
test: Fix tests on Java 21 or newer; add new InetAddress mocking code
Some unit tests work with fake ("mocked") InetAddress objects, which are currently assembled via mockito. With Java 21 and newer, this is no longer possible. Replace the mocking code with a new "InetAddressMockery" class that can provide real Inet4Address objects by means of Java object deserialization. Fixes #144 Signed-off-by: Christian Kohlschütter <[email protected]>
1 parent 24b0922 commit 7388dee

File tree

3 files changed

+111
-12
lines changed

3 files changed

+111
-12
lines changed

core/src/test/java/org/dcache/nfs/InetAddressMatcherTest.java

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import java.net.InetAddress;
2828
import java.net.UnknownHostException;
2929

30+
import org.dcache.testutils.InetAddressMockery;
3031
import org.junit.Ignore;
3132
import org.junit.Test;
3233

@@ -164,11 +165,6 @@ public void testDomainNoMatch() throws UnknownHostException {
164165
}
165166

166167
private InetAddress mockInetAddress(String dnsName, String... ips) throws UnknownHostException {
167-
168-
InetAddress mockedAddress = mock(InetAddress.class);
169-
given(mockedAddress.getHostName()).willReturn(dnsName);
170-
given(mockedAddress.getCanonicalHostName()).willReturn(dnsName);
171-
172-
return mockedAddress;
168+
return InetAddressMockery.mockedResolvedIPv4Address(dnsName, ips[0]);
173169
}
174170
}

core/src/test/java/org/dcache/testutils/InetAddressBuilder.java

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@
22

33
import java.net.InetAddress;
44

5-
import org.mockito.Mockito;
6-
75
public class InetAddressBuilder {
86
private String ipAddress;
97
private String hostName;
@@ -19,9 +17,6 @@ public InetAddressBuilder hostName(String hostName) {
1917
}
2018

2119
public InetAddress build() {
22-
InetAddress address = Mockito.mock(InetAddress.class);
23-
Mockito.when(address.getHostAddress()).thenReturn(ipAddress);
24-
Mockito.when(address.getHostName()).thenReturn(hostName);
25-
return address;
20+
return InetAddressMockery.mockedResolvedIPv4Address(hostName, ipAddress);
2621
}
2722
}
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
package org.dcache.testutils;
2+
3+
import java.io.ByteArrayInputStream;
4+
import java.io.IOException;
5+
import java.io.ObjectInputStream;
6+
import java.io.ObjectStreamConstants;
7+
import java.net.Inet4Address;
8+
import java.net.InetAddress;
9+
import java.net.UnknownHostException;
10+
import java.nio.ByteBuffer;
11+
import java.nio.charset.StandardCharsets;
12+
13+
/**
14+
* Creates InetAddress objects that contain arbitrary hostname/address combinations.
15+
*
16+
* @author Christian Kohlschütter
17+
*/
18+
public final class InetAddressMockery {
19+
private InetAddressMockery() {
20+
throw new IllegalStateException("No instances");
21+
}
22+
23+
/**
24+
* Returns a "resolved" Inet4Address using the given hostname and IPv4 address.
25+
*
26+
* @param hostname The hostname.
27+
* @param ip4Address The IPv4 address (e.g. "1.2.3.4").
28+
* @return The Inet4Address object.
29+
* @throws IllegalStateException on internal error.
30+
*/
31+
public static InetAddress mockedResolvedIPv4Address(String hostname, String ip4Address) {
32+
byte[] addr;
33+
try {
34+
addr = ((Inet4Address) InetAddress.getByName(ip4Address)).getAddress();
35+
} catch (UnknownHostException e) {
36+
throw new IllegalStateException(e);
37+
}
38+
int ipv4Addr = ((addr[0]) << 24 & 0xFF000000) | (addr[1] << 16 & 0xFF0000)
39+
| (addr[2] << 8 & 0xFF00) | (addr[3] & 0xFF);
40+
return mockedResolvedIPv4Address(hostname, ipv4Addr);
41+
}
42+
43+
/**
44+
* Returns a "resolved" Inet4Address using the given hostname and IPv4 address.
45+
*
46+
* @param hostname The hostname.
47+
* @param ip4Address The IPv4 address (e.g. {@code 0x01020304})
48+
* @return The Inet4Address object.
49+
* @throws IllegalStateException on internal error.
50+
*/
51+
public static InetAddress mockedResolvedIPv4Address(String hostname, int ip4Address) {
52+
try (ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(serializeIp4(hostname,
53+
ip4Address)))) {
54+
return (InetAddress) in.readObject();
55+
} catch (ClassNotFoundException | IOException e) {
56+
throw new IllegalStateException(e);
57+
}
58+
}
59+
60+
private static byte[] serializeIp4(String hostname, int address) {
61+
ByteBuffer bb = ByteBuffer.allocate(512);
62+
bb.putShort(ObjectStreamConstants.STREAM_MAGIC); // STREAM_MAGIC
63+
bb.putShort((short) 5); // STREAM_VERSION (hard-coded)
64+
bb.put(ObjectStreamConstants.TC_OBJECT);
65+
bb.put(ObjectStreamConstants.TC_CLASSDESC);
66+
67+
putShortLengthUtf8(bb, InetAddress.class.getName());
68+
bb.putLong(3286316764910316507L); // InetAddress serialVersionUID
69+
bb.put((byte) 0x03); // class type descriptor
70+
bb.putShort((short) 3); // 3 fields
71+
72+
bb.put((byte) 0x49);
73+
putShortLengthUtf8(bb, "address");
74+
75+
bb.put((byte) 0x49);
76+
putShortLengthUtf8(bb, "family");
77+
78+
bb.put((byte) 0x4c);
79+
putShortLengthUtf8(bb, "hostName");
80+
81+
bb.put(ObjectStreamConstants.TC_STRING);
82+
putShortLengthEncodedClassName(bb, String.class);
83+
bb.put(ObjectStreamConstants.TC_ENDBLOCKDATA);
84+
85+
bb.put(ObjectStreamConstants.TC_BASE);
86+
bb.putInt(address);
87+
bb.putInt(0x00000001); // IPv4
88+
bb.put(ObjectStreamConstants.TC_STRING);
89+
putShortLengthUtf8(bb, hostname);
90+
91+
bb.put(ObjectStreamConstants.TC_ENDBLOCKDATA);
92+
bb.flip();
93+
94+
byte[] buf = new byte[bb.remaining()];
95+
bb.get(buf);
96+
return buf;
97+
}
98+
99+
private static void putShortLengthEncodedClassName(ByteBuffer bb, Class<?> klazz) {
100+
putShortLengthUtf8(bb, "L" + klazz.getName().replace('.', '/') + ";");
101+
}
102+
103+
private static void putShortLengthUtf8(ByteBuffer bb, String s) {
104+
byte[] utf8 = s.getBytes(StandardCharsets.UTF_8);
105+
bb.putShort((short) utf8.length);
106+
bb.put(utf8);
107+
}
108+
}

0 commit comments

Comments
 (0)