Merge "Merge "Add additional checks to multicast tests" into oreo-cts-dev am: d7ab0877dc" into oreo-mr1-cts-dev
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/MulticastSocketTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/MulticastSocketTest.java
index a24a67b..57c79d3 100644
--- a/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/MulticastSocketTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/MulticastSocketTest.java
@@ -17,6 +17,7 @@
 
 package org.apache.harmony.tests.java.net;
 
+import java.io.FileDescriptor;
 import java.io.IOException;
 import java.net.BindException;
 import java.net.DatagramPacket;
@@ -32,11 +33,19 @@
 import java.util.ArrayList;
 import java.util.Enumeration;
 import java.util.List;
+import libcore.io.IoUtils;
+import libcore.io.Libcore;
 import libcore.junit.junit3.TestCaseWithRules;
 import libcore.junit.util.ResourceLeakageDetector;
 import org.junit.Rule;
 import org.junit.rules.TestRule;
 
+import android.system.ErrnoException;
+
+import static android.system.OsConstants.AF_INET;
+import static android.system.OsConstants.IFF_RUNNING;
+import static android.system.OsConstants.SOCK_DGRAM;
+
 public class MulticastSocketTest extends TestCaseWithRules {
     @Rule
     public TestRule guardRule = ResourceLeakageDetector.getRule();
@@ -927,6 +936,9 @@
 
     private static boolean willWorkForMulticast(NetworkInterface iface) throws IOException {
         return iface.isUp()
+                // On Oreo+ NetworkInterface.isUp() doesn't check the IFF_RUNNING flag so we do
+                // so here. http://b/71977275
+                && ((getOsFlags(iface) & IFF_RUNNING) != 0)
                 // Typically loopback interfaces do not support multicast, but we rule them out
                 // explicitly anyway.
                 && !iface.isLoopback()
@@ -936,6 +948,20 @@
                 && iface.getInetAddresses().hasMoreElements();
     }
 
+    private static int getOsFlags(NetworkInterface iface) throws IOException {
+        FileDescriptor fd = null;
+        try {
+            fd = Libcore.rawOs.socket(AF_INET, SOCK_DGRAM, 0);
+            return Libcore.rawOs.ioctlFlags(fd, iface.getName());
+        } catch (ErrnoException e) {
+            throw e.rethrowAsSocketException();
+        } catch (Exception ex) {
+            throw new SocketException(ex);
+        } finally {
+            IoUtils.closeQuietly(fd);
+        }
+    }
+
     private static MulticastSocket createReceivingSocket(int aPort) throws IOException {
         MulticastSocket ms = new MulticastSocket(aPort);
         ms.setSoTimeout(2000);
diff --git a/luni/src/test/java/libcore/java/nio/channels/DatagramChannelMulticastTest.java b/luni/src/test/java/libcore/java/nio/channels/DatagramChannelMulticastTest.java
index 5013114..38babc0 100644
--- a/luni/src/test/java/libcore/java/nio/channels/DatagramChannelMulticastTest.java
+++ b/luni/src/test/java/libcore/java/nio/channels/DatagramChannelMulticastTest.java
@@ -18,6 +18,10 @@
 
 import junit.framework.AssertionFailedError;
 import junit.framework.TestCase;
+
+import android.system.ErrnoException;
+
+import java.io.FileDescriptor;
 import java.io.IOException;
 import java.net.Inet4Address;
 import java.net.Inet6Address;
@@ -37,8 +41,13 @@
 import java.util.Enumeration;
 
 import libcore.io.IoBridge;
+import libcore.io.IoUtils;
+import libcore.io.Libcore;
 
+import static android.system.OsConstants.AF_INET;
+import static android.system.OsConstants.IFF_RUNNING;
 import static android.system.OsConstants.POLLIN;
+import static android.system.OsConstants.SOCK_DGRAM;
 
 /**
  * Tests associated with multicast behavior of DatagramChannel.
@@ -1223,12 +1232,32 @@
 
     private static boolean willWorkForMulticast(NetworkInterface iface) throws IOException {
         return iface.isUp()
-                // Typically loopback interfaces do not support multicast, but they are ruled out
-                // explicitly here anyway.
-                && !iface.isLoopback() && iface.supportsMulticast()
+                // On Oreo+ NetworkInterface.isUp() doesn't check the IFF_RUNNING flag so we do
+                // so here. http://b/71977275
+                && ((getOsFlags(iface) & IFF_RUNNING) != 0)
+                // Typically loopback interfaces do not support multicast, but we rule them out
+                // explicitly anyway.
+                && !iface.isLoopback()
+                // Point-to-point interfaces are known to cause problems. http://b/23279677
+                && !iface.isPointToPoint()
+                && iface.supportsMulticast()
                 && iface.getInetAddresses().hasMoreElements();
     }
 
+    private static int getOsFlags(NetworkInterface iface) throws IOException {
+        FileDescriptor fd = null;
+        try {
+            fd = Libcore.rawOs.socket(AF_INET, SOCK_DGRAM, 0);
+            return Libcore.rawOs.ioctlFlags(fd, iface.getName());
+        } catch (ErrnoException e) {
+            throw e.rethrowAsSocketException();
+        } catch (Exception ex) {
+            throw new SocketException(ex);
+        } finally {
+            IoUtils.closeQuietly(fd);
+        }
+    }
+
     private static void createChannelAndSendMulticastMessage(
             InetAddress group, int port, String msg, NetworkInterface sendingInterface)
             throws IOException {