1 /*
   2  * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 /* @test
  25  * @bug 8081678 8131155
  26  * @summary Tests for stream returning methods
  27  * @library ../../util/stream/bootlib/java.base
  28  * @build java.util.stream.OpTestCase
  29  * @run testng/othervm NetworkInterfaceStreamTest
  30  * @run testng/othervm -Djava.net.preferIPv4Stack=true NetworkInterfaceStreamTest
  31  * @key intermittent
  32  */
  33 
  34 import org.testng.annotations.Test;
  35 
  36 import java.net.InetAddress;
  37 import java.net.NetworkInterface;
  38 import java.net.SocketException;
  39 import java.util.ArrayList;
  40 import java.util.Collection;
  41 import java.util.Collections;
  42 import java.util.function.Supplier;
  43 import java.util.stream.OpTestCase;
  44 import java.util.stream.Stream;
  45 import java.util.stream.TestData;
  46 
  47 public class NetworkInterfaceStreamTest extends OpTestCase {
  48 
  49     private final static boolean IS_WINDOWS = System.getProperty("os.name").startsWith("Windows");
  50 
  51     @Test
  52     public void testNetworkInterfaces() throws SocketException {
  53         Supplier<Stream<NetworkInterface>> ss = () -> {
  54             try {
  55                 return NetworkInterface.networkInterfaces();
  56             }
  57             catch (SocketException e) {
  58                 throw new RuntimeException(e);
  59             }
  60         };
  61 
  62         Collection<NetworkInterface> expected = Collections.list(NetworkInterface.getNetworkInterfaces());
  63         withData(TestData.Factory.ofSupplier("Top-level network interfaces", ss))
  64                 .stream(s -> s)
  65                 .expectedResult(expected)
  66                 .exercise();
  67     }
  68 
  69 
  70     private Collection<NetworkInterface> getAllNetworkInterfaces() throws SocketException {
  71         Collection<NetworkInterface> anis = new ArrayList<>();
  72         for (NetworkInterface ni : Collections.list(NetworkInterface.getNetworkInterfaces())) {
  73             getAllSubNetworkInterfaces(ni, anis);
  74         }
  75         return anis;
  76     }
  77 
  78     private void getAllSubNetworkInterfaces(NetworkInterface ni, Collection<NetworkInterface> result) {
  79         if (isIncluded(ni)) {
  80             result.add(ni);
  81         }
  82 
  83         for (NetworkInterface sni : Collections.list(ni.getSubInterfaces())) {
  84             getAllSubNetworkInterfaces(sni, result);
  85         }
  86     }
  87 
  88     private Stream<NetworkInterface> allNetworkInterfaces() throws SocketException {
  89         return NetworkInterface.networkInterfaces()
  90                 .filter(ni -> isIncluded(ni))
  91                 .flatMap(this::allSubNetworkInterfaces);
  92     }
  93 
  94     private Stream<NetworkInterface> allSubNetworkInterfaces(NetworkInterface ni) {
  95         return Stream.concat(
  96                 Stream.of(ni),
  97                 ni.subInterfaces().filter(sni -> isIncluded(sni)).flatMap(this::allSubNetworkInterfaces));
  98     }
  99 
 100     @Test
 101     public void testSubNetworkInterfaces() throws SocketException {
 102         Supplier<Stream<NetworkInterface>> ss = () -> {
 103             try {
 104                 return allNetworkInterfaces();
 105             }
 106             catch (SocketException e) {
 107                 throw new RuntimeException(e);
 108             }
 109         };
 110 
 111         Collection<NetworkInterface> expected = getAllNetworkInterfaces();
 112         withData(TestData.Factory.ofSupplier("All network interfaces", ss))
 113                 .stream(s -> s)
 114                 .expectedResult(expected)
 115                 .exercise();
 116     }
 117 
 118 
 119     @Test
 120     public void testInetAddresses() throws SocketException {
 121         Supplier<Stream<InetAddress>> ss = () -> {
 122             try {
 123                 return NetworkInterface.networkInterfaces()
 124                         .filter(ni -> isIncluded(ni))
 125                         .flatMap(NetworkInterface::inetAddresses);
 126             }
 127             catch (SocketException e) {
 128                 throw new RuntimeException(e);
 129             }
 130         };
 131 
 132         Collection<NetworkInterface> nis = Collections.list(NetworkInterface.getNetworkInterfaces());
 133         Collection<InetAddress> expected = new ArrayList<>();
 134         for (NetworkInterface ni : nis) {
 135             if (isIncluded(ni)) {
 136                 expected.addAll(Collections.list(ni.getInetAddresses()));
 137             }
 138         }
 139         withData(TestData.Factory.ofSupplier("All inet addresses", ss))
 140                 .stream(s -> s)
 141                 .expectedResult(expected)
 142                 .exercise();
 143     }
 144 
 145     /**
 146      * Check if the input network interface should be included in the test. It is necessary to exclude
 147      * "Teredo Tunneling Pseudo-Interface" whose configuration can be variable during a test run.
 148      *
 149      * @param ni a network interace
 150      * @return false if it is a "Teredo Tunneling Pseudo-Interface", otherwise true.
 151      */
 152     private boolean isIncluded(NetworkInterface ni) {
 153         if (!IS_WINDOWS) {
 154             return true;
 155         }
 156 
 157         String dName = ni.getDisplayName();
 158         return dName == null || !dName.contains("Teredo");
 159     }
 160 
 161 }
 162