Skip to content

Commit

Permalink
ThroughputTest: Move JEP380 code into Java16+ code without reflection
Browse files Browse the repository at this point in the history
Previously, we were using reflection to check for the presence of
UnixDomainSocketAddress.

Now that we can build Java16+ code, this is no longer necessary.

Move JEP380 related code into a ThroughputTestShim class, which is
populated with corresponding test code only when Java 16 or newer is
being used.
  • Loading branch information
kohlschuetter committed Jul 15, 2023
1 parent e9c31ea commit 7a8f86a
Show file tree
Hide file tree
Showing 4 changed files with 133 additions and 53 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,12 @@

import org.newsclub.net.unix.AFSocketCapability;
import org.newsclub.net.unix.AFSocketCapabilityRequirement;
import org.newsclub.net.unix.AFUNIXSocketAddress;

import com.kohlschutter.annotations.compiletime.SuppressFBWarnings;

@AFSocketCapabilityRequirement(AFSocketCapability.CAPABILITY_UNIX_DOMAIN)
@SuppressFBWarnings("NM_SAME_SIMPLE_NAME_AS_SUPERCLASS")
public final class ThroughputTest extends
org.newsclub.net.unix.ThroughputTest<AFUNIXSocketAddress> {
public final class ThroughputTest extends ThroughputTestShim {

public ThroughputTest() {
super(AFUNIXAddressSpecifics.INSTANCE);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/*
* junixsocket
*
* Copyright 2009-2023 Christian Kohlschütter
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.newsclub.net.unix.domain;

import java.net.StandardProtocolFamily;
import java.net.UnixDomainSocketAddress;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.nio.file.Files;
import java.nio.file.Path;

import org.junit.jupiter.api.Test;
import org.newsclub.net.unix.AFUNIXSocketAddress;
import org.newsclub.net.unix.AddressSpecifics;

import com.kohlschutter.testutil.AvailabilityRequirement;

/**
* Shim class to allow for some tests that test code that is only available in newer Java versions,
* particularly JEP 380-related code (UnixDomainSocketAddress).
*
* @author Christian Kohlschütter
*/
abstract class ThroughputTestShim extends
org.newsclub.net.unix.ThroughputTest<AFUNIXSocketAddress> {

protected ThroughputTestShim(AddressSpecifics<AFUNIXSocketAddress> asp) {
super(asp);
}

@Test
@AvailabilityRequirement(classes = "java.net.UnixDomainSocketAddress", //
message = "This test requires Java 16 or later")
public void testJEP380() throws Exception {
testJEP380(false);
}

@Test
@AvailabilityRequirement(classes = "java.net.UnixDomainSocketAddress", //
message = "This test requires Java 16 or later")
public void testJEP380direct() throws Exception {
testJEP380(true);
}

private void testJEP380(boolean direct) throws Exception {
Path p = newTempFile().toPath();
try {
UnixDomainSocketAddress usa = UnixDomainSocketAddress.of(p);

ServerSocketChannel ssc = ServerSocketChannel.open(StandardProtocolFamily.UNIX);

runTestSocketChannel("JEP380 SocketChannel", usa, ssc, () -> {
SocketChannel sc = SocketChannel.open(StandardProtocolFamily.UNIX);
connectSocket(sc, ssc.getLocalAddress());
return sc;
}, direct);
} finally {
Files.delete(p);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,9 @@
import static org.junit.jupiter.api.Assertions.assertNotEquals;
import static org.junit.jupiter.api.Assumptions.assumeTrue;

import java.lang.reflect.InvocationTargetException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.ProtocolFamily;
import java.net.SocketAddress;
import java.net.StandardProtocolFamily;
import java.nio.channels.DatagramChannel;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
Expand All @@ -34,7 +31,6 @@
import org.junit.jupiter.api.Test;

import com.kohlschutter.annotations.compiletime.SuppressFBWarnings;
import com.kohlschutter.testutil.AvailabilityRequirement;
import com.kohlschutter.testutil.SystemPropertyRequirement;

@SuppressFBWarnings({
Expand All @@ -47,52 +43,6 @@ public ThroughputTest() {
super(JavaAddressSpecifics.INSTANCE);
}

@Test
@AvailabilityRequirement(classes = {"java.net.UnixDomainSocketAddress"}, //
message = "This test requires Java 16 or later")
public void testJEP380() throws Exception {
assumeTrue(ENABLED > 0, "Throughput tests are disabled");
assumeTrue(PAYLOAD_SIZE > 0, "Payload must be positive");
runTestJEP380(false);
}

@Test
@AvailabilityRequirement(classes = {"java.net.UnixDomainSocketAddress"}, //
message = "This test requires Java 16 or later")
public void testJEP380directBuffer() throws Exception {
assumeTrue(ENABLED > 0, "Throughput tests are disabled");
assumeTrue(PAYLOAD_SIZE > 0, "Payload must be positive");
runTestJEP380(true);
}

private static SocketAddress jep380SocketAddress(String path) throws IllegalAccessException,
IllegalArgumentException, InvocationTargetException, SecurityException {
try {
// We use reflection so we can compile on older Java versions
Class<?> klazz = Class.forName("java.net.UnixDomainSocketAddress");
return (SocketAddress) klazz.getMethod("of", String.class).invoke(null, path);
} catch (NoSuchMethodException | ClassNotFoundException e) {
assumeTrue(false, "java.net.UnixDomainSocketAddress (JEP 380) not supported by JVM");
return null;
}
}

private void runTestJEP380(boolean direct) throws Exception {
SocketAddress sa = jep380SocketAddress(socketFile().getPath());

ServerSocketChannel ssc;
// We use reflection so we can compile on older Java versions
try {
ssc = (ServerSocketChannel) ServerSocketChannel.class.getMethod("open", ProtocolFamily.class)
.invoke(null, StandardProtocolFamily.valueOf("UNIX"));
} catch (Exception e) {
throw new IllegalStateException(e);
}

runTestSocketChannel("JEP380 SocketChannel", sa, ssc, () -> SocketChannel.open(ssc
.getLocalAddress()), direct);
}

@Test
@SystemPropertyRequirement(property = "org.newsclub.net.unix.throughput-test.ip.enabled", //
value = "1", message = "Loopback TCP/IP testing is disabled")
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/*
* junixsocket
*
* Copyright 2009-2023 Christian Kohlschütter
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.newsclub.net.unix.domain;

import static org.junit.jupiter.api.Assertions.fail;

import java.io.File;

import org.junit.jupiter.api.Test;
import org.newsclub.net.unix.AFUNIXSocketAddress;
import org.newsclub.net.unix.AddressSpecifics;

import com.kohlschutter.testutil.AvailabilityRequirement;

/**
* Shim class to allow for some tests that test code that is only available in newer Java versions,
* particularly JEP 380-related code (UnixDomainSocketAddress).
*
* @author Christian Kohlschütter
*/
abstract class ThroughputTestShim extends
org.newsclub.net.unix.ThroughputTest<AFUNIXSocketAddress> {

protected ThroughputTestShim(AddressSpecifics<AFUNIXSocketAddress> asp) {
super(asp);
}

@Test
@AvailabilityRequirement(classes = "java.net.UnixDomainSocketAddress", //
message = "This test requires Java 16 or later")
public void testJEP380() throws Exception {
fail("Should not be reached");
}

@Test
@AvailabilityRequirement(classes = "java.net.UnixDomainSocketAddress", //
message = "This test requires Java 16 or later")
public void testJEP380direct() throws Exception {
fail("Should not be reached");
}
}

0 comments on commit 7a8f86a

Please sign in to comment.