Path: blob/master/test/jdk/java/nio/channels/etc/OpenAndConnect.java
41153 views
/*1* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223import jdk.test.lib.NetworkConfiguration;24import jdk.test.lib.net.IPSupport;25import org.testng.annotations.BeforeTest;26import org.testng.annotations.DataProvider;27import org.testng.annotations.Test;2829import java.io.IOException;30import java.net.*;31import java.nio.channels.*;32import java.util.Arrays;33import java.util.List;34import java.util.LinkedList;3536import static java.lang.System.getProperty;37import static java.lang.System.out;38import static java.net.StandardProtocolFamily.INET;39import static java.net.StandardProtocolFamily.INET6;40import static jdk.test.lib.net.IPSupport.*;4142/*43* @test44* @summary Test SocketChannel, ServerSocketChannel and DatagramChannel45* open() and connect(), taking into consideration combinations of46* protocol families (INET, INET6, default),47* addresses (Inet4Address, Inet6Address).48* @library /test/lib49* @build jdk.test.lib.NetworkConfiguration50* @run testng/othervm OpenAndConnect51*/525354public class OpenAndConnect {55static final Inet4Address IA4ANYLOCAL;56static final Inet6Address IA6ANYLOCAL;57static final Inet4Address IA4LOOPBACK;58static final Inet6Address IA6LOOPBACK;59static Inet4Address IA4LOCAL = null;60static Inet6Address IA6LOCAL = null;61static InetAddress DONT_BIND;6263static {64try {65IA4ANYLOCAL = (Inet4Address) InetAddress.getByName("0.0.0.0");66IA6ANYLOCAL = (Inet6Address) InetAddress.getByName("::0");67IA4LOOPBACK = (Inet4Address) InetAddress.getByName("127.0.0.1");68IA6LOOPBACK = (Inet6Address) InetAddress.getByName("::1");6970// Special value to tell test not to call bind (address is not used)71DONT_BIND = (Inet4Address) InetAddress.getByName("127.0.0.3");7273initAddrs();74} catch (Exception e) {75throw new RuntimeException("Could not initialize addresses", e);76}77}7879@BeforeTest()80public void setup() {81NetworkConfiguration.printSystemConfiguration(out);82IPSupport.printPlatformSupport(out);83throwSkippedExceptionIfNonOperational();8485out.println("IA4LOCAL: " + IA4LOCAL);86out.println("IA6LOCAL: " + IA6LOCAL);87out.println("IA4ANYLOCAL: " + IA4ANYLOCAL);88out.println("IA6ANYLOCAL: " + IA6ANYLOCAL);89out.println("IA4LOOPBACK: " + IA4LOOPBACK);90out.println("IA6LOOPBACK: " + IA6LOOPBACK);91}9293@DataProvider(name = "openConnect")94public Object[][] openConnect() {95LinkedList<Object[]> l = new LinkedList<>();96if (IPSupport.hasIPv4()) {97l.addAll(openConnectV4Tests);98if (IA4LOCAL != null) {99l.addAll(openConnectV4LocalTests);100}101}102if (IPSupport.hasIPv6()) {103l.addAll(openConnectV6Tests);104if (IA6LOCAL != null) {105l.addAll(openConnectV6LocalTests);106}107}108if (IPSupport.hasIPv4() && IPSupport.hasIPv6()) {109l.addAll(openConnectV4AndV6Tests);110if (IA4LOCAL != null) {111l.addAll(openConnectV4LocalAndV6Tests);112}113}114return l.toArray(new Object[][]{});115}116117// +----- sfam is server/first socket family118// |119// | +------ saddr is bind address for server/first socket120// | |121// | | +---- cfam is family for client/second socket122// | | |123// | | | +---- caddr is address client/second124// | | | | socket binds to. When the server125// | | | | has bound to a wildcard address126// | | | | this is address used for connect127// | | | | also.128// | | | |129// | | | |130// | | | |131// | | | |132// + + + +133// { sfam, saddr, cfam, caddr, }134135// Basic tests for when an IPv4 is available136public static List<Object[]> openConnectV4Tests =137Arrays.asList(new Object[][] {138{ INET, IA4LOOPBACK, INET, IA4LOOPBACK },139{ INET, IA4LOOPBACK, null, IA4LOOPBACK },140{ INET, IA4ANYLOCAL, null, IA4LOOPBACK },141{ INET, IA4ANYLOCAL, INET, IA4LOOPBACK },142{ null, IA4LOOPBACK, INET, IA4ANYLOCAL },143{ null, IA4LOOPBACK, INET, IA4LOOPBACK },144{ null, IA4LOOPBACK, INET, null },145{ null, IA4LOOPBACK, null, null }146});147148// Additional tests for when an IPv4 local address is available149public List<Object[]> openConnectV4LocalTests =150Arrays.asList(new Object[][] {151{ INET, IA4LOCAL, INET, IA4LOCAL },152{ INET, IA4LOCAL, null, IA4LOCAL },153{ INET, IA4LOCAL, null, DONT_BIND },154{ INET, IA4ANYLOCAL, INET, IA4LOCAL },155{ INET, IA4ANYLOCAL, null, IA4LOCAL },156{ null, IA4LOCAL, INET, IA4ANYLOCAL },157{ null, IA4LOCAL, INET, IA4LOCAL },158{ null, IA4LOCAL, INET, null },159{ null, IA4LOCAL, null, null }160});161162// Basic tests for when an IPv6 is available163public List<Object[]> openConnectV6Tests =164Arrays.asList(new Object[][] {165{ INET6, IA6ANYLOCAL, null, IA6LOOPBACK },166{ INET6, IA6ANYLOCAL, INET6, IA6LOOPBACK },167{ INET6, IA6LOOPBACK, INET6, IA6LOOPBACK },168{ INET6, IA6LOOPBACK, INET6, IA6LOOPBACK },169{ null, IA6ANYLOCAL, null, IA6LOOPBACK },170{ null, IA6ANYLOCAL, INET6, IA6LOOPBACK },171{ null, IA6LOOPBACK, INET6, IA6LOOPBACK },172{ null, IA6LOOPBACK, INET6, DONT_BIND },173{ null, IA6LOOPBACK, INET6, null },174{ null, IA6LOOPBACK, null, IA6LOOPBACK },175{ null, IA6LOOPBACK, null, null },176{ null, IA6LOOPBACK, INET6, IA6ANYLOCAL },177{ null, IA6LOOPBACK, null, IA6ANYLOCAL }178});179180// Additional tests for when an IPv6 local address is available181public List<Object[]> openConnectV6LocalTests =182Arrays.asList(new Object[][] {183{ INET6, IA6ANYLOCAL, null, IA6LOCAL },184{ INET6, IA6ANYLOCAL, INET6, IA6LOCAL },185{ INET6, IA6LOCAL, INET6, IA6LOCAL },186{ INET6, IA6LOCAL, null, IA6LOCAL },187{ INET6, IA6LOCAL, null, DONT_BIND },188{ INET6, IA6LOCAL, INET6, IA6LOCAL },189{ null, IA6ANYLOCAL, null, IA6LOCAL },190{ null, IA6ANYLOCAL, INET6, IA6LOCAL },191{ null, IA6LOCAL, INET6, IA6LOCAL },192{ null, IA6LOCAL, INET6, IA6ANYLOCAL },193{ null, IA6LOCAL, null, IA6ANYLOCAL },194{ null, IA6LOCAL, null, IA6LOCAL },195{ null, IA6LOCAL, INET6, null },196{ null, IA6LOCAL, null, null }197});198199// Additional tests for when IPv4 and IPv6 are available200public List<Object[]> openConnectV4AndV6Tests =201Arrays.asList(new Object[][] {202{ null, IA4LOOPBACK, INET6, IA6ANYLOCAL },203{ null, IA4LOOPBACK, null, IA6ANYLOCAL },204{ null, IA4LOOPBACK, INET6, DONT_BIND },205{ null, IA4LOOPBACK, INET6, null }206});207208// Additional tests for when IPv4 local address and IPv6 are available209public List<Object[]> openConnectV4LocalAndV6Tests =210Arrays.asList(new Object[][] {211{ null, IA4LOCAL, INET6, IA6ANYLOCAL },212{ null, IA4LOCAL, INET6, null },213{ null, IA4LOCAL, null, IA6ANYLOCAL }214});215216/**217* If the destination address is the wildcard, it is replaced by the alternate218* using the port number from destination. Otherwise destination is returned.219* Only used by dcOpenAndConnect220*/221static InetSocketAddress getDestinationAddress(SocketAddress destination, InetAddress alternate) {222InetSocketAddress isa = (InetSocketAddress)destination;223if (isa.getAddress().isAnyLocalAddress())224return new InetSocketAddress(alternate, isa.getPort());225else226return isa;227}228229@Test(dataProvider = "openConnect")230public void scOpenAndConnect(ProtocolFamily sfam,231InetAddress saddr,232ProtocolFamily cfam,233InetAddress caddr) throws IOException234{235out.printf("scOpenAndConnect: server bind: %s client bind: %s\n", saddr, caddr);236try (ServerSocketChannel ssc = openSSC(sfam)) {237ssc.bind(getSocketAddress(saddr));238InetSocketAddress ssa = (InetSocketAddress)ssc.getLocalAddress();239ssa = getDestinationAddress(ssa, caddr);240out.println(ssa);241try (SocketChannel csc = openSC(cfam)) {242if (caddr != DONT_BIND) {243csc.bind(getSocketAddress(caddr));244}245csc.connect(ssa);246}247}248}249250@Test(dataProvider = "openConnect")251public void dcOpenAndConnect(ProtocolFamily sfam,252InetAddress saddr,253ProtocolFamily cfam,254InetAddress caddr) throws IOException255{256try (DatagramChannel sdc = openDC(sfam)) {257sdc.bind(getSocketAddress(saddr));258SocketAddress ssa = sdc.socket().getLocalSocketAddress();259ssa = getDestinationAddress(ssa, caddr);260out.println(ssa);261try (DatagramChannel dc = openDC(cfam)) {262if (caddr != DONT_BIND) {263dc.bind(getSocketAddress(caddr));264}265dc.connect(ssa);266}267}268}269270// Helper methods271272private static SocketChannel openSC(ProtocolFamily fam) throws IOException {273return fam == null ? SocketChannel.open() : SocketChannel.open(fam);274}275276private static ServerSocketChannel openSSC(ProtocolFamily fam)277throws IOException {278return fam == null ? ServerSocketChannel.open()279: ServerSocketChannel.open(fam);280}281282private static DatagramChannel openDC(ProtocolFamily fam)283throws IOException {284return fam == null ? DatagramChannel.open()285: DatagramChannel.open(fam);286}287288private static SocketAddress getSocketAddress(InetAddress ia) {289return ia == null ? null : new InetSocketAddress(ia, 0);290}291292private static void initAddrs() throws IOException {293294NetworkConfiguration cfg = NetworkConfiguration.probe();295296IA4LOCAL = cfg.ip4Addresses()297.filter(a -> !a.isLoopbackAddress())298.findFirst()299.orElse(null);300301IA6LOCAL = cfg.ip6Addresses()302.filter(a -> !a.isLoopbackAddress())303.findFirst()304.orElse(null);305}306}307308309