Path: blob/master/test/jdk/java/net/SocketOption/AfterClose.java
41149 views
/*1* Copyright (c) 2019, 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*/2223/*24* @test25* @bug 822447726* @summary Ensures that IOException is thrown after the socket is closed27* @run testng AfterClose28* @run testng/othervm -Djdk.net.usePlainSocketImpl AfterClose29* @run testng/othervm -Djdk.net.usePlainDatagramSocketImpl AfterClose30*/3132import java.io.IOException;33import java.lang.reflect.Field;34import java.lang.reflect.Method;35import java.net.DatagramSocket;36import java.net.MulticastSocket;37import java.net.NetworkInterface;38import java.net.ServerSocket;39import java.net.Socket;40import java.net.SocketException;41import java.net.SocketOption;42import java.nio.channels.DatagramChannel;43import java.nio.channels.ServerSocketChannel;44import java.nio.channels.SocketChannel;45import java.util.ArrayList;46import java.util.Arrays;47import java.util.HashMap;48import java.util.List;49import java.util.Map;50import java.util.stream.Collectors;5152import org.testng.annotations.DataProvider;53import org.testng.annotations.Test;54import static java.lang.Boolean.*;55import static java.net.StandardSocketOptions.*;56import static org.testng.Assert.expectThrows;5758public class AfterClose {5960static final Class<IOException> IOE = IOException.class;61static final String RO = "READ_ONLY";6263static Map<SocketOption<?>,List<Object>> OPTION_VALUES_MAP = optionValueMap();6465static boolean supportsMulticast(NetworkInterface ni) {66try {67return ni.supportsMulticast();68} catch (SocketException e) {69return false;70}71}7273static List<Object> listNetworkInterfaces() {74try {75return NetworkInterface.networkInterfaces()76.filter(AfterClose::supportsMulticast)77.collect(Collectors.toList());78} catch (Exception e) { }79return List.of();80}8182static Map<SocketOption<?>,List<Object>> optionValueMap() {83Map<SocketOption<?>,List<Object>> map = new HashMap<>();84map.put(IP_MULTICAST_IF, listNetworkInterfaces() );85map.put(IP_MULTICAST_LOOP, listOf(TRUE, FALSE) );86map.put(IP_MULTICAST_TTL, listOf(0, 100, 255) );87map.put(IP_TOS, listOf(0, 101, 255) );88map.put(SO_BROADCAST, listOf(TRUE, FALSE) );89map.put(SO_KEEPALIVE, listOf(TRUE, FALSE) );90map.put(SO_LINGER, listOf(0, 5, 15) );91map.put(SO_RCVBUF, listOf(1, 100, 1000));92map.put(SO_REUSEADDR, listOf(TRUE, FALSE) );93map.put(SO_REUSEPORT, listOf(TRUE, FALSE) );94map.put(SO_SNDBUF, listOf(1, 100, 1000));95map.put(TCP_NODELAY, listOf(TRUE, FALSE) );96// extended options97try {98Class<?> c = Class.forName("jdk.net.ExtendedSocketOptions");99Field field = c.getField("TCP_QUICKACK");100map.put((SocketOption<?>)field.get(null), listOf(TRUE, FALSE));101field = c.getField("TCP_KEEPIDLE");102map.put((SocketOption<?>)field.get(null), listOf(10, 100));103field = c.getField("TCP_KEEPINTERVAL");104map.put((SocketOption<?>)field.get(null), listOf(10, 100));105field = c.getField("TCP_KEEPCOUNT");106map.put((SocketOption<?>)field.get(null), listOf(10, 100));107field = c.getField("SO_INCOMING_NAPI_ID");108map.put((SocketOption<?>)field.get(null), listOf(RO));109} catch (ClassNotFoundException e) {110// ignore, jdk.net module not present111} catch (ReflectiveOperationException e) {112throw new AssertionError(e);113}114return map;115}116117// -- Socket118119@DataProvider(name = "socketOptionValues")120public Object[][] socketOptionValues() throws Exception {121try (Socket s = new Socket()) {122return s.supportedOptions().stream()123.map(so -> new Object[] {so, OPTION_VALUES_MAP.get(so)})124.toArray(Object[][]::new);125}126}127128@Test(dataProvider = "socketOptionValues")129public <T> void closedSocketImplUncreated(SocketOption<T> option, List<T> values)130throws IOException131{132Socket socket = createClosedSocketImplUncreated();133for (int i=0; i<3; i++); {134for (T value : values) {135expectThrows(IOE, () -> socket.setOption(option, value));136expectThrows(IOE, () -> socket.getOption(option));137}138}139}140141@Test(dataProvider = "socketOptionValues")142public <T> void closedSocketImplCreated(SocketOption<T> option, List<T> values)143throws IOException144{145Socket socket = createClosedSocketImplCreated();146for (int i=0; i<3; i++); {147for (T value : values) {148expectThrows(IOE, () -> socket.setOption(option, value));149expectThrows(IOE, () -> socket.getOption(option));150}151}152}153154@Test(dataProvider = "socketOptionValues")155public <T> void closedSocketAdapter(SocketOption<T> option, List<T> values)156throws IOException157{158Socket socket = createClosedSocketFromAdapter();159for (int i=0; i<3; i++); {160for (T value : values) {161if (!RO.equals(value)) expectThrows(IOE, () -> socket.setOption(option, value));162expectThrows(IOE, () -> socket.getOption(option));163}164}165}166167// -- ServerSocket168169@DataProvider(name = "serverSocketOptionValues")170public Object[][] serverSocketOptionValues() throws Exception {171try (ServerSocket ss = new ServerSocket()) {172return ss.supportedOptions().stream()173.map(so -> new Object[] {so, OPTION_VALUES_MAP.get(so)})174.toArray(Object[][]::new);175}176}177178@Test(dataProvider = "serverSocketOptionValues")179public <T> void closedServerSocketImplUncreated(SocketOption<T> option, List<T> values)180throws IOException181{182ServerSocket serverSocket = createClosedServerSocketImplUncreated();183for (int i=0; i<3; i++); {184for (T value : values) {185expectThrows(IOE, () -> serverSocket.setOption(option, value));186expectThrows(IOE, () -> serverSocket.getOption(option));187}188}189}190191@Test(dataProvider = "serverSocketOptionValues")192public <T> void closedServerSocketImplCreated(SocketOption<T> option, List<T> values)193throws IOException194{195ServerSocket serverSocket = createClosedServerSocketImplCreated();196for (int i=0; i<3; i++); {197for (T value : values) {198expectThrows(IOE, () -> serverSocket.setOption(option, value));199expectThrows(IOE, () -> serverSocket.getOption(option));200}201}202}203204@Test(dataProvider = "serverSocketOptionValues")205public <T> void closedServerSocketAdapter(SocketOption<T> option, List<T> values)206throws IOException207{208if (option == IP_TOS)209return; // SSC does not support IP_TOS210211ServerSocket serverSocket = createClosedServerSocketFromAdapter();212for (int i=0; i<3; i++); {213for (T value : values) {214if (!RO.equals(value)) expectThrows(IOE, () -> serverSocket.setOption(option, value));215expectThrows(IOE, () -> serverSocket.getOption(option));216}217}218}219220// -- DatagramSocket221222@DataProvider(name = "datagramSocketOptionValues")223public Object[][] datagramSocketOptionValues() throws Exception {224try (DatagramSocket ds = new DatagramSocket()) {225return ds.supportedOptions().stream()226.map(so -> new Object[] {so, OPTION_VALUES_MAP.get(so)})227.toArray(Object[][]::new);228}229}230231@Test(dataProvider = "datagramSocketOptionValues")232public <T> void closedUnboundDatagramSocket(SocketOption<T> option, List<T> values)233throws IOException234{235DatagramSocket datagramSocket = createClosedUnboundDatagramSocket();236for (int i=0; i<3; i++); {237for (T value : values) {238if (!RO.equals(value)) expectThrows(IOE, () -> datagramSocket.setOption(option, value));239expectThrows(IOE, () -> datagramSocket.getOption(option));240}241}242}243244@Test(dataProvider = "datagramSocketOptionValues")245public <T> void closedBoundDatagramSocket(SocketOption<T> option, List<T> values)246throws IOException247{248DatagramSocket datagramSocket = createClosedBoundDatagramSocket();249for (int i=0; i<3; i++); {250for (T value : values) {251if (!RO.equals(value)) expectThrows(IOE, () -> datagramSocket.setOption(option, value));252expectThrows(IOE, () -> datagramSocket.getOption(option));253}254}255}256257@Test(dataProvider = "datagramSocketOptionValues")258public <T> void closedDatagramAdapter(SocketOption<T> option, List<T> values)259throws IOException260{261DatagramSocket datagramSocket = createClosedBoundDatagramSocket();262for (int i=0; i<3; i++); {263for (T value : values) {264if (!RO.equals(value)) expectThrows(IOE, () -> datagramSocket.setOption(option, value));265expectThrows(IOE, () -> datagramSocket.getOption(option));266}267}268}269270// -- MulticastSocket271272@DataProvider(name = "multicastSocketOptionValues")273public Object[][] multicastSocketOptionValues() throws Exception {274try (MulticastSocket ms = new MulticastSocket()) {275return ms.supportedOptions().stream()276.map(so -> new Object[] {so, OPTION_VALUES_MAP.get(so)})277.toArray(Object[][]::new);278}279}280281@Test(dataProvider = "multicastSocketOptionValues")282public <T> void closedUnboundMulticastSocket(SocketOption<T> option, List<T> values)283throws IOException284{285MulticastSocket multicastSocket = createClosedUnboundMulticastSocket();286for (int i=0; i<3; i++); {287for (T value : values) {288if (!RO.equals(value)) expectThrows(IOE, () -> multicastSocket.setOption(option, value));289expectThrows(IOE, () -> multicastSocket.getOption(option));290}291}292}293294@Test(dataProvider = "multicastSocketOptionValues")295public <T> void closedBoundMulticastSocket(SocketOption<T> option, List<T> values)296throws IOException297{298MulticastSocket multicastSocket = createClosedBoundMulticastSocket();299for (int i=0; i<3; i++); {300for (T value : values) {301if (!RO.equals(value)) expectThrows(IOE, () -> multicastSocket.setOption(option, value));302expectThrows(IOE, () -> multicastSocket.getOption(option));303}304}305}306307// --308309static List<Object> listOf(Object... objs) {310List<Object> l = new ArrayList<>();311Arrays.stream(objs).forEachOrdered(l::add);312return l;313}314315// Returns a closed Socket that has an impl whose `create` method has NOT been invoked.316static Socket createClosedSocketImplUncreated() throws IOException {317Socket s = new Socket();318s.close();319return s;320}321322// Returns a closed Socket that has an impl whose `create` method has been invoked.323static Socket createClosedSocketImplCreated() throws IOException {324Socket s = new Socket();325s.bind(null); // binding causes impl::create to be invoked326s.close();327return s;328}329330// Returns a closed Socket created from a SocketChannel's adapter.331static Socket createClosedSocketFromAdapter() throws IOException {332SocketChannel sc = SocketChannel.open();333sc.close();334return sc.socket();335}336337// Returns a closed ServerSocket that has an impl whose `create` method has NOT been invoked.338static ServerSocket createClosedServerSocketImplUncreated() throws IOException {339ServerSocket ss = new ServerSocket();340ss.close();341return ss;342}343344// Returns a closed ServerSocket that has an impl whose `create` method has been invoked.345static ServerSocket createClosedServerSocketImplCreated() throws IOException {346ServerSocket ss = new ServerSocket();347ss.bind(null); // binding causes impl::create to be invoked348ss.close();349return ss;350}351352// Returns a closed ServerSocket created from a ServerSocketChannel's adapter.353static ServerSocket createClosedServerSocketFromAdapter() throws IOException {354ServerSocketChannel ssc = ServerSocketChannel.open();355ssc.close();356return ssc.socket();357}358359// Returns a closed unbound DatagramSocket.360static DatagramSocket createClosedUnboundDatagramSocket() throws IOException {361DatagramSocket ds = new DatagramSocket(null);362assert ds.isBound() == false;363ds.close();364return ds;365}366367// Returns a closed bound DatagramSocket.368static DatagramSocket createClosedBoundDatagramSocket() throws IOException {369DatagramSocket ds = new DatagramSocket();370assert ds.isBound() == true;371ds.close();372return ds;373}374375// Returns a closed DatagramSocket that created from a DatagramChannel's adapter.376static DatagramSocket createClosedDatagramSocketFromAdapter() throws IOException {377DatagramChannel dc = DatagramChannel.open();378dc.close();379return dc.socket();380}381382// Returns a closed unbound MulticastSocket.383static MulticastSocket createClosedUnboundMulticastSocket() throws IOException {384MulticastSocket ms = new MulticastSocket(null);385assert ms.isBound() == false;386ms.close();387return ms;388}389390// Returns a closed bound MulticastSocket.391static MulticastSocket createClosedBoundMulticastSocket() throws IOException {392MulticastSocket ms = new MulticastSocket();393assert ms.isBound() == true;394ms.close();395return ms;396}397}398399400