blob: 8c3e7f381e16b86a144cfc624ce7be1d21b4cbaa [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 tests.api.java.net;
import dalvik.annotation.KnownFailure;
import dalvik.annotation.TestTargetClass;
import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetNew;
import java.io.IOException;
import java.net.BindException;
import java.net.DatagramPacket;
import java.net.Inet4Address;
import java.net.Inet6Address;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.MulticastSocket;
import java.net.NetworkInterface;
import java.net.SocketAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.security.Permission;
import java.util.Enumeration;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.TimeUnit;
import tests.support.Support_NetworkInterface;
import tests.support.Support_PortManager;
@TestTargetClass(MulticastSocket.class)
public class MulticastSocketTest extends SocketTestCase {
Thread t;
MulticastSocket mss;
MulticastServer server;
// private member variables used for tests
boolean atLeastOneInterface = false;
boolean atLeastTwoInterfaces = false;
private NetworkInterface networkInterface1 = null;
private NetworkInterface networkInterface2 = null;
private NetworkInterface IPV6networkInterface1 = null;
static class MulticastServer extends Thread {
public MulticastSocket ms;
volatile boolean running = true;
private final BlockingQueue<DatagramPacket> queue
= new ArrayBlockingQueue<DatagramPacket>(1);
public void run() {
try {
while (running) {
try {
byte[] rbuf = new byte[512];
rbuf[0] = -1;
DatagramPacket rdp = new DatagramPacket(rbuf, rbuf.length);
ms.receive(rdp);
queue.put(rdp);
} catch (java.io.InterruptedIOException e) {
} catch (InterruptedException e) {
}
}
} catch (java.io.IOException e) {
System.out.println("Multicast server failed: " + e);
} finally {
ms.close();
}
}
public synchronized void leaveGroup(InetAddress aGroup)
throws java.io.IOException {
ms.leaveGroup(aGroup);
}
public MulticastServer(InetAddress anAddress, int aPort)
throws java.io.IOException {
ms = new MulticastSocket(aPort);
ms.setSoTimeout(2000);
ms.joinGroup(anAddress);
}
public MulticastServer(SocketAddress anAddress, int aPort,
NetworkInterface netInterface) throws java.io.IOException {
ms = new MulticastSocket(aPort);
ms.setSoTimeout(2000);
ms.joinGroup(anAddress, netInterface);
}
public DatagramPacket receive() throws InterruptedException {
return queue.poll(1000, TimeUnit.MILLISECONDS);
}
public void stopServer() throws InterruptedException {
running = false;
interrupt();
join();
}
}
/**
* @tests java.net.MulticastSocket#MulticastSocket()
*/
@TestTargetNew(
level = TestLevel.SUFFICIENT,
notes = "IOException exception checking missed.",
method = "MulticastSocket",
args = {}
)
public void test_Constructor() throws IOException {
// regression test for 497
MulticastSocket s = new MulticastSocket();
// regression test for Harmony-1162
assertTrue(s.getReuseAddress());
SecurityManager sm = new SecurityManager() {
public void checkPermission(Permission perm) {
}
public void checkListen(int port) {
throw new SecurityException();
}
};
SecurityManager oldSm = System.getSecurityManager();
System.setSecurityManager(sm);
try {
new MulticastSocket();
fail("SecurityException should be thrown.");
} catch (SecurityException e) {
// expected
} catch (SocketException e) {
fail("SocketException was thrown.");
} catch (IOException e) {
fail("IOException was thrown.");
e.printStackTrace();
} finally {
System.setSecurityManager(oldSm);
}
}
/**
* @tests java.net.MulticastSocket#MulticastSocket(int)
*/
@TestTargetNew(
level = TestLevel.SUFFICIENT,
notes = "IOException exception checking missed.",
method = "MulticastSocket",
args = {int.class}
)
public void test_ConstructorI() {
// Test for method java.net.MulticastSocket(int)
// Used in tests
MulticastSocket dup = null;
try {
mss = new MulticastSocket();
int port = mss.getLocalPort();
dup = new MulticastSocket(port);
// regression test for Harmony-1162
assertTrue(dup.getReuseAddress());
} catch (IOException e) {
fail("duplicate binding not allowed: " + e);
}
if (dup != null)
dup.close();
SecurityManager sm = new SecurityManager() {
public void checkPermission(Permission perm) {
}
public void checkListen(int port) {
throw new SecurityException();
}
};
SecurityManager oldSm = System.getSecurityManager();
System.setSecurityManager(sm);
try {
new MulticastSocket(1);
fail("SecurityException should be thrown.");
} catch (SecurityException e) {
// expected
} catch (SocketException e) {
fail("SocketException was thrown.");
} catch (IOException e) {
fail("IOException was thrown.");
e.printStackTrace();
} finally {
System.setSecurityManager(oldSm);
}
}
/**
* @tests java.net.MulticastSocket#getInterface()
*/
@TestTargetNew(
level = TestLevel.COMPLETE,
notes = "",
method = "getInterface",
args = {}
)
@KnownFailure("No interfaces if there's no debugger connected")
public void test_getInterface() {
// Test for method java.net.InetAddress
// java.net.MulticastSocket.getInterface()
assertTrue("Used for testing.", true);
int groupPort = Support_PortManager.getNextPortForUDP();
try {
if (atLeastOneInterface) {
// validate that we get the expected response when one was not
// set
mss = new MulticastSocket(groupPort);
String preferIPv4StackValue = System
.getProperty("java.net.preferIPv4Stack");
String preferIPv6AddressesValue = System
.getProperty("java.net.preferIPv6Addresses");
if (((preferIPv4StackValue == null) || preferIPv4StackValue
.equalsIgnoreCase("false"))
&& (preferIPv6AddressesValue != null)
&& (preferIPv6AddressesValue.equals("true"))) {
// we expect an IPv6 ANY in this case
assertTrue("inet Address returned when not set:"
+ mss.getInterface().toString(), InetAddress
.getByName("::0").equals(mss.getInterface()));
} else {
// we expect an IPv4 ANY in this case
assertNotNull("inet Address returned when not set:",
mss.getInterface());
}
// validate that we get the expected response when we set via
// setInterface
Enumeration addresses = networkInterface1.getInetAddresses();
if (addresses != null) {
InetAddress firstAddress = (InetAddress) addresses
.nextElement();
mss.setInterface(firstAddress);
assertTrue(
"getNetworkInterface did not return interface set " +
"by setInterface. Expected:"
+ firstAddress + " Got:"
+ mss.getInterface(), firstAddress
.equals(mss.getInterface()));
groupPort = Support_PortManager.getNextPortForUDP();
mss = new MulticastSocket(groupPort);
mss.setNetworkInterface(networkInterface1);
InetAddress addr = mss.getInterface();
NetworkInterface if1 = NetworkInterface.getByInetAddress(addr);
assertEquals(
"getInterface did not return interface set by " +
"setNeworkInterface Expected: " + firstAddress
+ "Got:" + mss.getInterface(),
networkInterface1, if1);
}
mss.close();
try {
mss.getInterface();
fail("SocketException was not thrown.");
} catch(SocketException ioe) {
//expected
}
}
} catch (Exception e) {
fail("Exception during getInterface test: " + e.toString());
}
}
/**
* @throws IOException
* @tests java.net.MulticastSocket#getNetworkInterface()
*/
@TestTargetNew(
level = TestLevel.COMPLETE,
notes = "",
method = "getNetworkInterface",
args = {}
)
@KnownFailure("No interfaces if there's no debugger connected")
public void test_getNetworkInterface() throws IOException {
int groupPort = Support_PortManager.getNextPortForUDP();
if (atLeastOneInterface) {
// validate that we get the expected response when one was not
// set
mss = new MulticastSocket(groupPort);
NetworkInterface theInterface = mss.getNetworkInterface();
assertNotNull(
"network interface returned wrong network interface when " +
"not set:"
+ theInterface, theInterface.getInetAddresses());
InetAddress firstAddress = (InetAddress) theInterface
.getInetAddresses().nextElement();
// validate we the first address in the network interface is the
// ANY address
String preferIPv4StackValue = System
.getProperty("java.net.preferIPv4Stack");
String preferIPv6AddressesValue = System
.getProperty("java.net.preferIPv6Addresses");
if (((preferIPv4StackValue == null) || preferIPv4StackValue
.equalsIgnoreCase("false"))
&& (preferIPv6AddressesValue != null)
&& (preferIPv6AddressesValue.equals("true"))) {
assertTrue(
"network interface returned wrong network interface " +
"when not set:"
+ theInterface, InetAddress.getByName("::0")
.equals(firstAddress));
} else {
assertTrue(
"network interface returned wrong network interface " +
"when not set:"
+ theInterface, InetAddress
.getByName("0.0.0.0").equals(firstAddress));
}
mss.setNetworkInterface(networkInterface1);
assertTrue(
"getNetworkInterface did not return interface set by " +
"setNeworkInterface",
networkInterface1.equals(mss.getNetworkInterface()));
if (atLeastTwoInterfaces) {
mss.setNetworkInterface(networkInterface2);
assertTrue(
"getNetworkInterface did not return network interface " +
"set by second setNetworkInterface call",
networkInterface2.equals(mss.getNetworkInterface()));
}
groupPort = Support_PortManager.getNextPortForUDP();
mss = new MulticastSocket(groupPort);
if (IPV6networkInterface1 != null) {
mss.setNetworkInterface(IPV6networkInterface1);
assertTrue(
"getNetworkInterface did not return interface set " +
"by setNeworkInterface",
IPV6networkInterface1.equals(mss.getNetworkInterface()));
}
// validate that we get the expected response when we set via
// setInterface
groupPort = Support_PortManager.getNextPortForUDP();
mss = new MulticastSocket(groupPort);
Enumeration addresses = networkInterface1.getInetAddresses();
if (addresses != null) {
firstAddress = (InetAddress) addresses.nextElement();
mss.setInterface(firstAddress);
assertTrue(
"getNetworkInterface did not return interface set " +
"by setInterface",
networkInterface1.equals(mss.getNetworkInterface()));
}
mss.close();
try {
mss.getNetworkInterface();
fail("SocketException was not thrown.");
} catch(SocketException ioe) {
//expected
}
}
}
/**
* @tests java.net.MulticastSocket#getTimeToLive()
*/
@TestTargetNew(
level = TestLevel.COMPLETE,
notes = "",
method = "getTimeToLive",
args = {}
)
public void test_getTimeToLive() {
try {
mss = new MulticastSocket();
mss.setTimeToLive(120);
assertTrue("Returned incorrect 1st TTL: " + mss.getTimeToLive(),
mss.getTimeToLive() == 120);
mss.setTimeToLive(220);
assertTrue("Returned incorrect 2nd TTL: " + mss.getTimeToLive(),
mss.getTimeToLive() == 220);
mss.close();
try {
mss.getTimeToLive();
fail("IOException was not thrown.");
} catch(IOException ioe) {
//expected
}
ensureExceptionThrownIfOptionIsUnsupportedOnOS(SO_MULTICAST);
} catch (Exception e) {
handleException(e, SO_MULTICAST);
}
}
/**
* @tests java.net.MulticastSocket#getTTL()
*/
@TestTargetNew(
level = TestLevel.COMPLETE,
notes = "",
method = "getTTL",
args = {}
)
public void test_getTTL() {
// Test for method byte java.net.MulticastSocket.getTTL()
try {
mss = new MulticastSocket();
mss.setTTL((byte) 120);
assertTrue("Returned incorrect TTL: " + mss.getTTL(),
mss.getTTL() == 120);
mss.close();
try {
mss.getTTL();
fail("IOException was not thrown.");
} catch(IOException ioe) {
//expected
}
ensureExceptionThrownIfOptionIsUnsupportedOnOS(SO_MULTICAST);
} catch (Exception e) {
handleException(e, SO_MULTICAST);
}
}
/**
* @tests java.net.MulticastSocket#joinGroup(java.net.InetAddress)
*/
@TestTargetNew(
level = TestLevel.COMPLETE,
notes = "",
method = "joinGroup",
args = {java.net.InetAddress.class}
)
public void test_joinGroupLjava_net_InetAddress() throws InterruptedException {
// Test for method void
// java.net.MulticastSocket.joinGroup(java.net.InetAddress)
String msg = null;
InetAddress group = null;
int[] ports = Support_PortManager.getNextPortsForUDP(2);
int groupPort = ports[0];
try {
group = InetAddress.getByName("224.0.0.3");
server = new MulticastServer(group, groupPort);
server.start();
Thread.sleep(1000);
msg = "Hello World";
mss = new MulticastSocket(ports[1]);
DatagramPacket sdp = new DatagramPacket(msg.getBytes(), msg
.length(), group, groupPort);
mss.joinGroup(group);
mss.send(sdp, (byte) 10);
SecurityManager sm = new SecurityManager() {
public void checkPermission(Permission perm) {
}
public void checkMulticast(InetAddress maddr) {
throw new SecurityException();
}
};
SecurityManager oldSm = System.getSecurityManager();
System.setSecurityManager(sm);
try {
mss.joinGroup(group);
fail("SecurityException should be thrown.");
} catch (SecurityException e) {
// expected
} catch (SocketException e) {
fail("SocketException was thrown.");
} catch (IOException e) {
fail("IOException was thrown.");
e.printStackTrace();
} finally {
System.setSecurityManager(oldSm);
}
mss.close();
try {
mss.joinGroup(group);
fail("SocketException was not thrown.");
} catch(SocketException ioe) {
//expected
}
} catch (Exception e) {
fail("Exception during joinGroup test: " + e.toString());
}
DatagramPacket rdb = server.receive();
assertEquals("Group member did not recv data: ", msg,
new String(rdb.getData(), 0, rdb.getLength()));
}
/**
* @throws IOException
* @throws InterruptedException
* @tests java.net.MulticastSocket#joinGroup(java.net.SocketAddress,
* java.net.NetworkInterface)
*/
@TestTargetNew(
level = TestLevel.COMPLETE,
notes = "",
method = "joinGroup",
args = {java.net.SocketAddress.class, java.net.NetworkInterface.class}
)
@KnownFailure(value="bug 2155705")
public void test_joinGroupLjava_net_SocketAddressLjava_net_NetworkInterface()
throws IOException, InterruptedException {
// security manager that allows us to check that we only return the
// addresses that we should
class mySecurityManager extends SecurityManager {
public void checkPermission(Permission perm) {
}
public void checkMulticast(InetAddress address) {
throw new SecurityException("not allowed");
}
}
String msg = null;
InetAddress group = null;
SocketAddress groupSockAddr = null;
int[] ports = Support_PortManager.getNextPortsForUDP(2);
int groupPort = ports[0];
int serverPort = ports[1];
Enumeration theInterfaces = NetworkInterface.getNetworkInterfaces();
// first validate that we handle a null group ok
mss = new MulticastSocket(groupPort);
try {
mss.joinGroup(null, null);
fail("Did not get exception when group was null");
} catch (IllegalArgumentException e) {
}
// now validate we get the expected error if the address specified
// is not a multicast group
try {
groupSockAddr = new InetSocketAddress(InetAddress
.getByName("255.255.255.255"), groupPort);
mss.joinGroup(groupSockAddr, null);
fail("Did not get exception when group is not a multicast address");
} catch (IOException e) {
}
// now try to join a group if we are not authorized
// set the security manager that will make the first address not
// visible
System.setSecurityManager(new mySecurityManager());
try {
group = InetAddress.getByName("224.0.0.3");
groupSockAddr = new InetSocketAddress(group, groupPort);
mss.joinGroup(groupSockAddr, null);
fail("Did not get exception when joining group is not allowed");
} catch (SecurityException e) {
}
System.setSecurityManager(null);
if (atLeastOneInterface) {
// now validate that we can properly join a group with a null
// network interface
ports = Support_PortManager.getNextPortsForUDP(2);
groupPort = ports[0];
serverPort = ports[1];
mss = new MulticastSocket(groupPort);
mss.joinGroup(groupSockAddr, null);
mss.setTimeToLive(2);
Thread.sleep(1000);
// set up the server and join the group on networkInterface1
group = InetAddress.getByName("224.0.0.3");
groupSockAddr = new InetSocketAddress(group, groupPort);
server = new MulticastServer(groupSockAddr, serverPort,
networkInterface1);
server.start();
Thread.sleep(1000);
msg = "Hello World";
DatagramPacket sdp = new DatagramPacket(msg.getBytes(), msg
.length(), group, serverPort);
mss.setTimeToLive(2);
mss.send(sdp);
DatagramPacket rdp = server.receive();
// now vaildate that we received the data as expected
assertEquals("Group member did not recv data: ", msg,
new String(rdp.getData(), 0, rdp.getLength()));
server.stopServer();
// now validate that we handled the case were we join a
// different multicast address.
// verify we do not receive the data
ports = Support_PortManager.getNextPortsForUDP(2);
serverPort = ports[0];
server = new MulticastServer(groupSockAddr, serverPort,
networkInterface1);
server.start();
Thread.sleep(1000);
groupPort = ports[1];
mss = new MulticastSocket(groupPort);
InetAddress group2 = InetAddress.getByName("224.0.0.4");
mss.setTimeToLive(10);
msg = "Hello World - Different Group";
sdp = new DatagramPacket(msg.getBytes(), msg.length(), group2,
serverPort);
mss.send(sdp);
rdp = server.receive();
assertNull("Group member received data when sent on different group",
rdp);
server.stopServer();
// if there is more than one network interface then check that
// we can join on specific interfaces and that we only receive
// if data is received on that interface
if (atLeastTwoInterfaces) {
// set up server on first interfaces
NetworkInterface loopbackInterface = NetworkInterface
.getByInetAddress(InetAddress.getByName("127.0.0.1"));
theInterfaces = NetworkInterface.getNetworkInterfaces();
while (theInterfaces.hasMoreElements()) {
NetworkInterface thisInterface = (NetworkInterface)
theInterfaces.nextElement();
if ((thisInterface.getInetAddresses() != null && thisInterface
.getInetAddresses().hasMoreElements())
&& (Support_NetworkInterface
.useInterface(thisInterface) == true)) {
// get the first address on the interface
// start server which is joined to the group and has
// only asked for packets on this interface
Enumeration addresses = thisInterface
.getInetAddresses();
NetworkInterface sendingInterface = null;
boolean isLoopback = false;
if (addresses != null) {
InetAddress firstAddress = (InetAddress) addresses
.nextElement();
if (firstAddress.isLoopbackAddress()) {
isLoopback = true;
}
if (firstAddress instanceof Inet4Address) {
group = InetAddress.getByName("224.0.0.4");
if (networkInterface1.equals(NetworkInterface
.getByInetAddress(InetAddress
.getByName("127.0.0.1")))) {
sendingInterface = networkInterface2;
} else {
sendingInterface = networkInterface1;
}
} else {
// if this interface only seems to support
// IPV6 addresses
group = InetAddress
.getByName("FF01:0:0:0:0:0:2:8001");
sendingInterface = IPV6networkInterface1;
}
}
InetAddress useAddress = null;
addresses = sendingInterface.getInetAddresses();
if ((addresses != null)
&& (addresses.hasMoreElements())) {
useAddress = (InetAddress) addresses.nextElement();
}
ports = Support_PortManager.getNextPortsForUDP(2);
serverPort = ports[0];
groupPort = ports[1];
groupSockAddr = new InetSocketAddress(group, serverPort);
server = new MulticastServer(groupSockAddr, serverPort,
thisInterface);
server.start();
Thread.sleep(1000);
// Now send out a package on interface
// networkInterface 1. We should
// only see the packet if we send it on interface 1
InetSocketAddress theAddress = new InetSocketAddress(
useAddress, groupPort);
mss = new MulticastSocket(groupPort);
mss.setNetworkInterface(sendingInterface);
msg = "Hello World - Again" + thisInterface.getName();
sdp = new DatagramPacket(msg.getBytes(), msg.length(),
group, serverPort);
mss.send(sdp);
rdp = server.receive();
if (thisInterface.equals(sendingInterface)) {
assertEquals(
"Group member did not recv data when " +
"bound on specific interface: ", msg,
new String(rdp.getData(), 0, rdp.getLength()));
} else {
assertFalse(
"Group member received data on other " +
"interface when only asked for it on one " +
"interface: ",
new String(rdp.getData(), 0,
rdp.getLength()).equals(msg));
}
server.stopServer();
}
}
// validate that we can join the same address on two
// different interfaces but not on the same interface
groupPort = Support_PortManager.getNextPortForUDP();
mss = new MulticastSocket(groupPort);
mss.joinGroup(groupSockAddr, networkInterface1);
mss.joinGroup(groupSockAddr, networkInterface2);
try {
mss.joinGroup(groupSockAddr, networkInterface1);
fail("Did not get expected exception when joining for " +
"second time on same interface");
} catch (IOException e) {
}
}
}
System.setSecurityManager(null);
}
/**
* @tests java.net.MulticastSocket#leaveGroup(java.net.InetAddress)
*/
@TestTargetNew(
level = TestLevel.COMPLETE,
notes = "",
method = "leaveGroup",
args = {java.net.InetAddress.class}
)
public void test_leaveGroupLjava_net_InetAddress() {
// Test for method void
// java.net.MulticastSocket.leaveGroup(java.net.InetAddress)
String msg = null;
boolean except = false;
InetAddress group = null;
int[] ports = Support_PortManager.getNextPortsForUDP(2);
int groupPort = ports[0];
try {
group = InetAddress.getByName("224.0.0.3");
msg = "Hello World";
mss = new MulticastSocket(ports[1]);
DatagramPacket sdp = new DatagramPacket(msg.getBytes(), msg
.length(), group, groupPort);
mss.send(sdp, (byte) 10);
ensureExceptionThrownIfOptionIsUnsupportedOnOS(SO_MULTICAST);
} catch (Exception e) {
handleException(e, SO_MULTICAST);
}
try {
// Try to leave s group that mss is not a member of
mss.leaveGroup(group);
} catch (java.io.IOException e) {
// Correct
except = true;
}
assertTrue("Failed to throw exception leaving non-member group", except);
SecurityManager sm = new SecurityManager() {
public void checkPermission(Permission perm) {
}
public void checkMulticast(InetAddress maddr) {
throw new SecurityException();
}
};
SecurityManager oldSm = System.getSecurityManager();
System.setSecurityManager(sm);
try {
mss.leaveGroup(group);
fail("SecurityException should be thrown.");
} catch (SecurityException e) {
// expected
} catch (SocketException e) {
fail("SocketException was thrown.");
} catch (IOException e) {
fail("IOException was thrown.");
e.printStackTrace();
} finally {
System.setSecurityManager(oldSm);
}
}
/**
* @tests java.net.MulticastSocket#leaveGroup(java.net.SocketAddress,
* java.net.NetworkInterface)
*/
@TestTargetNew(
level = TestLevel.COMPLETE,
notes = "",
method = "leaveGroup",
args = {java.net.SocketAddress.class, java.net.NetworkInterface.class}
)
@KnownFailure(value="bug 2155705")
public void test_leaveGroupLjava_net_SocketAddressLjava_net_NetworkInterface() {
// security manager that allows us to check that we only return the
// addresses that we should
class mySecurityManager extends SecurityManager {
public void checkPermission(Permission p) {
}
public void checkMulticast(InetAddress address) {
throw new SecurityException("not allowed");
}
}
String msg = null;
InetAddress group = null;
int groupPort = Support_PortManager.getNextPortForUDP();
SocketAddress groupSockAddr = null;
SocketAddress groupSockAddr2 = null;
try {
Enumeration theInterfaces = NetworkInterface.getNetworkInterfaces();
// first validate that we handle a null group ok
mss = new MulticastSocket(groupPort);
try {
mss.leaveGroup(null, null);
fail("Did not get exception when group was null");
} catch (IllegalArgumentException e) {
}
// now validate we get the expected error if the address specified
// is not a multicast group
try {
group = InetAddress.getByName("255.255.255.255");
groupSockAddr = new InetSocketAddress(group, groupPort);
mss.leaveGroup(groupSockAddr, null);
fail("Did not get exception when group is not a " +
"multicast address");
} catch (IOException e) {
}
// now try to leave a group if we are not authorized
// set the security manager that will make the first address not
// visible
System.setSecurityManager(new mySecurityManager());
try {
group = InetAddress.getByName("224.0.0.3");
groupSockAddr = new InetSocketAddress(group, groupPort);
mss.leaveGroup(groupSockAddr, null);
fail("Did not get exception when joining group is " +
"not allowed");
} catch (SecurityException e) {
}
System.setSecurityManager(null);
if (atLeastOneInterface) {
// now test that we can join and leave a group successfully
groupPort = Support_PortManager.getNextPortForUDP();
mss = new MulticastSocket(groupPort);
groupSockAddr = new InetSocketAddress(group, groupPort);
mss.joinGroup(groupSockAddr, null);
mss.leaveGroup(groupSockAddr, null);
try {
mss.leaveGroup(groupSockAddr, null);
fail(
"Did not get exception when trying to leave " +
"group that was allready left");
} catch (IOException e) {
}
InetAddress group2 = InetAddress.getByName("224.0.0.4");
groupSockAddr2 = new InetSocketAddress(group2, groupPort);
mss.joinGroup(groupSockAddr, networkInterface1);
try {
mss.leaveGroup(groupSockAddr2, networkInterface1);
fail(
"Did not get exception when trying to leave " +
"group that was never joined");
} catch (IOException e) {
}
mss.leaveGroup(groupSockAddr, networkInterface1);
if (atLeastTwoInterfaces) {
mss.joinGroup(groupSockAddr, networkInterface1);
try {
mss.leaveGroup(groupSockAddr, networkInterface2);
fail(
"Did not get exception when trying to leave " +
"group on wrong interface joined on ["
+ networkInterface1
+ "] left on ["
+ networkInterface2 + "]");
} catch (IOException e) {
}
}
}
} catch (Exception e) {
fail("Exception during leaveGroup test: " + e.toString());
} finally {
System.setSecurityManager(null);
}
}
/**
* @tests java.net.MulticastSocket#send(java.net.DatagramPacket, byte)
*/
@TestTargetNew(
level = TestLevel.COMPLETE,
notes = "",
method = "send",
args = {java.net.DatagramPacket.class, byte.class}
)
public void test_sendLjava_net_DatagramPacketB() throws InterruptedException {
// Test for method void
// java.net.MulticastSocket.send(java.net.DatagramPacket, byte)
String msg = "Hello World";
InetAddress group = null;
int[] ports = Support_PortManager.getNextPortsForUDP(2);
int groupPort = ports[0];
try {
group = InetAddress.getByName("224.0.0.3");
mss = new MulticastSocket(ports[1]);
server = new MulticastServer(group, groupPort);
server.start();
Thread.sleep(200);
DatagramPacket sdp = new DatagramPacket(msg.getBytes(), msg
.length(), group, groupPort);
mss.send(sdp, (byte) 10);
Thread.sleep(1000);
ensureExceptionThrownIfOptionIsUnsupportedOnOS(SO_MULTICAST);
} catch (Exception e) {
handleException(e, SO_MULTICAST);
try {
mss.close();
} catch (Exception ex) {
}
return;
}
DatagramPacket sdp = new DatagramPacket(msg.getBytes(), msg
.length(), group, groupPort);
SecurityManager sm = new SecurityManager() {
public void checkPermission(Permission perm) {
}
public void checkConnect(String host,
int port) {
throw new SecurityException();
}
public void checkMulticast(InetAddress maddr) {
throw new SecurityException();
}
};
SecurityManager oldSm = System.getSecurityManager();
System.setSecurityManager(sm);
try {
mss.send(sdp);
fail("SecurityException should be thrown.");
} catch (SecurityException e) {
// expected
} catch (SocketException e) {
fail("SocketException was thrown.");
} catch (IOException e) {
fail("IOException was thrown.");
e.printStackTrace();
} finally {
System.setSecurityManager(oldSm);
}
mss.close();
try {
mss.send(sdp);
fail("IOException should be thrown.");
} catch(IOException ioe) {
//expected
}
DatagramPacket rdp = server.receive();
assertEquals("Failed to send data. Received " + rdp.getLength(), msg,
new String(rdp.getData(), 0, rdp.getLength()));
}
/**
* @tests java.net.MulticastSocket#setInterface(java.net.InetAddress)
*/
@TestTargetNew(
level = TestLevel.COMPLETE,
notes = "",
method = "setInterface",
args = {java.net.InetAddress.class}
)
public void test_setInterfaceLjava_net_InetAddress() {
// Test for method void
// java.net.MulticastSocket.setInterface(java.net.InetAddress)
// Note that the machine is not multi-homed
try {
mss = new MulticastSocket();
mss.setInterface(InetAddress.getLocalHost());
ensureExceptionThrownIfOptionIsUnsupportedOnOS(SO_MULTICAST_INTERFACE);
} catch (Exception e) {
//handleException(e, SO_MULTICAST_INTERFACE);
return;
}
try {
InetAddress theInterface = mss.getInterface();
// under IPV6 we are not guarrenteed to get the same address back as
// the address, all we should be guaranteed is that we get an
// address on the same interface
if (theInterface instanceof Inet6Address) {
assertTrue(
"Failed to return correct interface IPV6",
NetworkInterface
.getByInetAddress(mss.getInterface())
.equals(
NetworkInterface
.getByInetAddress(theInterface)));
} else {
assertTrue("Failed to return correct interface IPV4 got:"
+ mss.getInterface() + " excpeted: "
+ InetAddress.getLocalHost(), mss.getInterface()
.equals(InetAddress.getLocalHost()));
}
ensureExceptionThrownIfOptionIsUnsupportedOnOS(SO_MULTICAST);
} catch (SocketException e) {
handleException(e, SO_MULTICAST);
} catch (UnknownHostException e) {
fail("Exception during setInterface test: " + e.toString());
}
// Regression test for Harmony-2410
try {
mss = new MulticastSocket();
mss.setInterface(InetAddress.getByName("224.0.0.5"));
} catch (UnknownHostException uhe) {
fail("Unable to get InetAddress by name from '224.0.0.5' addr: "
+ uhe.toString());
} catch (SocketException se) {
// expected
} catch (IOException ioe) {
handleException(ioe, SO_MULTICAST_INTERFACE);
return;
}
}
/**
* @throws IOException
* @throws InterruptedException
* @tests java.net.MulticastSocket#setNetworkInterface(
* java.net.NetworkInterface)
*/
@TestTargetNew(
level = TestLevel.COMPLETE,
notes = "",
method = "setNetworkInterface",
args = {java.net.NetworkInterface.class}
)
public void test_setNetworkInterfaceLjava_net_NetworkInterface()
throws IOException, InterruptedException {
String msg = null;
InetAddress group = null;
int[] ports = Support_PortManager.getNextPortsForUDP(2);
int groupPort = ports[0];
int serverPort = ports[1];
if (atLeastOneInterface) {
// validate that null interface is handled ok
mss = new MulticastSocket(groupPort);
// this should through a socket exception to be compatible
try {
mss.setNetworkInterface(null);
fail("No socket exception when we set then network " +
"interface with NULL");
} catch (SocketException ex) {
}
// validate that we can get and set the interface
groupPort = Support_PortManager.getNextPortForUDP();
mss = new MulticastSocket(groupPort);
mss.setNetworkInterface(networkInterface1);
assertTrue(
"Interface did not seem to be set by setNeworkInterface",
networkInterface1.equals(mss.getNetworkInterface()));
// set up the server and join the group
group = InetAddress.getByName("224.0.0.3");
Enumeration theInterfaces = NetworkInterface.getNetworkInterfaces();
while (theInterfaces.hasMoreElements()) {
NetworkInterface thisInterface = (NetworkInterface) theInterfaces
.nextElement();
if (thisInterface.getInetAddresses() != null
&& thisInterface.getInetAddresses().hasMoreElements()) {
if ((!((InetAddress) thisInterface.getInetAddresses()
.nextElement()).isLoopbackAddress())
&&
// for windows we cannot use these pseudo
// interfaces for the test as the packets still
// come from the actual interface, not the
// Pseudo interface that was set
(Support_NetworkInterface
.useInterface(thisInterface) == true)) {
ports = Support_PortManager.getNextPortsForUDP(2);
serverPort = ports[0];
server = new MulticastServer(group, serverPort);
server.start();
// give the server some time to start up
Thread.sleep(1000);
// Send the packets on a particular interface. The
// source address in the received packet
// should be one of the addresses for the interface
// set
groupPort = ports[1];
mss = new MulticastSocket(groupPort);
mss.setNetworkInterface(thisInterface);
msg = thisInterface.getName();
byte theBytes[] = msg.getBytes();
DatagramPacket sdp = new DatagramPacket(theBytes,
theBytes.length, group, serverPort);
mss.send(sdp);
DatagramPacket rdp = server.receive();
String receivedMessage = new String(rdp.getData(), 0, rdp.getLength());
assertEquals("Group member did not recv data when send on "
+ "a specific interface: ", msg, receivedMessage);
assertEquals("Datagram was not received as expected.",
thisInterface, NetworkInterface.getByInetAddress(rdp.getAddress()));
// stop the server
server.stopServer();
}
}
}
}
}
/**
* @tests java.net.MulticastSocket#setTimeToLive(int)
*/
@TestTargetNew(
level = TestLevel.COMPLETE,
notes = "",
method = "setTimeToLive",
args = {int.class}
)
public void test_setTimeToLiveI() {
try {
mss = new MulticastSocket();
mss.setTimeToLive(120);
assertTrue("Returned incorrect 1st TTL: " + mss.getTimeToLive(),
mss.getTimeToLive() == 120);
mss.setTimeToLive(220);
assertTrue("Returned incorrect 2nd TTL: " + mss.getTimeToLive(),
mss.getTimeToLive() == 220);
mss.close();
try {
mss.setTimeToLive(1);
fail("IOException was not thrown.");
}catch(IOException ioe) {
//expected
}
ensureExceptionThrownIfOptionIsUnsupportedOnOS(SO_MULTICAST);
} catch (Exception e) {
handleException(e, SO_MULTICAST);
}
}
/**
* @tests java.net.MulticastSocket#setTTL(byte)
*/
@TestTargetNew(
level = TestLevel.COMPLETE,
notes = "",
method = "setTTL",
args = {byte.class}
)
public void test_setTTLB() {
// Test for method void java.net.MulticastSocket.setTTL(byte)
try {
mss = new MulticastSocket();
mss.setTTL((byte) 120);
assertTrue("Failed to set TTL: " + mss.getTTL(),
mss.getTTL() == 120);
mss.close();
try {
mss.setTTL((byte) 1);
fail("IOException was not thrown.");
} catch(IOException ioe) {
//expected
}
ensureExceptionThrownIfOptionIsUnsupportedOnOS(SO_MULTICAST);
} catch (Exception e) {
handleException(e, SO_MULTICAST);
}
}
/**
* @tests java.net.MulticastSocket#MulticastSocket(java.net.SocketAddress)
*/
@TestTargetNew(
level = TestLevel.COMPLETE,
notes = "",
method = "MulticastSocket",
args = {java.net.SocketAddress.class}
)
public void test_ConstructorLjava_net_SocketAddress() throws Exception {
MulticastSocket ms = new MulticastSocket((SocketAddress) null);
assertTrue("should not be bound", !ms.isBound() && !ms.isClosed()
&& !ms.isConnected());
ms.bind(new InetSocketAddress(InetAddress.getLocalHost(),
Support_PortManager.getNextPortForUDP()));
assertTrue("should be bound", ms.isBound() && !ms.isClosed()
&& !ms.isConnected());
ms.close();
assertTrue("should be closed", ms.isClosed());
ms = new MulticastSocket(new InetSocketAddress(InetAddress
.getLocalHost(), Support_PortManager.getNextPortForUDP()));
assertTrue("should be bound", ms.isBound() && !ms.isClosed()
&& !ms.isConnected());
ms.close();
assertTrue("should be closed", ms.isClosed());
ms = new MulticastSocket(new InetSocketAddress("localhost",
Support_PortManager.getNextPortForUDP()));
assertTrue("should be bound", ms.isBound() && !ms.isClosed()
&& !ms.isConnected());
ms.close();
assertTrue("should be closed", ms.isClosed());
boolean exception = false;
try {
ms = new MulticastSocket(new InetSocketAddress("unresolvedname",
Support_PortManager.getNextPortForUDP()));
} catch (IOException e) {
exception = true;
}
assertTrue("Expected IOException", exception);
// regression test for Harmony-1162
InetSocketAddress addr = new InetSocketAddress("0.0.0.0", 0);
MulticastSocket s = new MulticastSocket(addr);
assertTrue(s.getReuseAddress());
InetSocketAddress isa = new InetSocketAddress(InetAddress
.getLocalHost(), Support_PortManager.getNextPortForUDP());
SecurityManager sm = new SecurityManager() {
public void checkPermission(Permission perm) {
}
public void checkListen(int port) {
throw new SecurityException();
}
};
SecurityManager oldSm = System.getSecurityManager();
System.setSecurityManager(sm);
try {
new MulticastSocket(isa);
fail("SecurityException should be thrown.");
} catch (SecurityException e) {
// expected
} catch (SocketException e) {
fail("SocketException was thrown.");
} catch (IOException e) {
fail("IOException was thrown.");
e.printStackTrace();
} finally {
System.setSecurityManager(oldSm);
}
}
/**
* @tests java.net.MulticastSocket#getLoopbackMode()
*/
@TestTargetNew(
level = TestLevel.COMPLETE,
notes = "",
method = "getLoopbackMode",
args = {}
)
public void test_getLoopbackMode() {
try {
MulticastSocket ms = new MulticastSocket((SocketAddress) null);
assertTrue("should not be bound", !ms.isBound() && !ms.isClosed()
&& !ms.isConnected());
ms.getLoopbackMode();
assertTrue("should not be bound", !ms.isBound() && !ms.isClosed()
&& !ms.isConnected());
ms.close();
assertTrue("should be closed", ms.isClosed());
try {
ms.getLoopbackMode();
fail("SocketException was not thrown.");
} catch(SocketException ioe) {
//expected
}
ensureExceptionThrownIfOptionIsUnsupportedOnOS(SO_USELOOPBACK);
} catch (IOException e) {
handleException(e, SO_USELOOPBACK);
}
}
/**
* @tests java.net.MulticastSocket#setLoopbackMode(boolean)
*/
@TestTargetNew(
level = TestLevel.COMPLETE,
notes = "",
method = "setLoopbackMode",
args = {boolean.class}
)
public void test_setLoopbackModeZ() {
try {
MulticastSocket ms = new MulticastSocket();
ms.setLoopbackMode(true);
assertTrue("loopback should be true", ms.getLoopbackMode());
ms.setLoopbackMode(false);
assertTrue("loopback should be false", !ms.getLoopbackMode());
ms.close();
assertTrue("should be closed", ms.isClosed());
try {
ms.setLoopbackMode(true);
fail("SocketException was not thrown.");
} catch(SocketException se) {
//expected
}
ensureExceptionThrownIfOptionIsUnsupportedOnOS(SO_USELOOPBACK);
} catch (IOException e) {
handleException(e, SO_USELOOPBACK);
}
}
/**
* @tests java.net.MulticastSocket#setLoopbackMode(boolean)
*/
@TestTargetNew(
level = TestLevel.ADDITIONAL,
notes = "SocketException checking missed",
method = "setLoopbackMode",
args = {boolean.class}
)
public void test_setLoopbackModeSendReceive() throws IOException{
final String ADDRESS = "224.1.2.3";
final int PORT = Support_PortManager.getNextPortForUDP();
final String message = "Hello, world!";
// test send receive
MulticastSocket socket = null;
try {
// open a multicast socket
socket = new MulticastSocket(PORT);
socket.setLoopbackMode(false); // false indecates doing loop back
socket.joinGroup(InetAddress.getByName(ADDRESS));
// send the datagram
byte[] sendData = message.getBytes();
DatagramPacket sendDatagram = new DatagramPacket(sendData, 0,
sendData.length, new InetSocketAddress(InetAddress
.getByName(ADDRESS), PORT));
socket.send(sendDatagram);
// receive the datagram
byte[] recvData = new byte[100];
DatagramPacket recvDatagram = new DatagramPacket(recvData,
recvData.length);
socket.setSoTimeout(5000); // prevent eternal block in
// socket.receive()
socket.receive(recvDatagram);
String recvMessage = new String(recvData, 0, recvDatagram
.getLength());
assertEquals(message, recvMessage);
} finally {
if (socket != null)
socket.close();
}
}
/**
* @tests java.net.MulticastSocket#setReuseAddress(boolean)
*/
@TestTargetNew(
level = TestLevel.PARTIAL,
notes = "SocketException checking missesd. Method inherited from " +
"class java.net.DatagramSocket",
method = "setReuseAddress",
args = {boolean.class}
)
public void test_setReuseAddressZ() {
try {
// test case were we set it to false
MulticastSocket theSocket1 = null;
MulticastSocket theSocket2 = null;
try {
InetSocketAddress theAddress = new InetSocketAddress(
InetAddress.getLocalHost(), Support_PortManager
.getNextPortForUDP());
theSocket1 = new MulticastSocket(null);
theSocket2 = new MulticastSocket(null);
theSocket1.setReuseAddress(false);
theSocket2.setReuseAddress(false);
theSocket1.bind(theAddress);
theSocket2.bind(theAddress);
fail(
"No exception when trying to connect to do " +
"duplicate socket bind with re-useaddr set to false");
} catch (BindException e) {
}
if (theSocket1 != null)
theSocket1.close();
if (theSocket2 != null)
theSocket2.close();
// test case were we set it to true
try {
InetSocketAddress theAddress = new InetSocketAddress(
InetAddress.getLocalHost(), Support_PortManager
.getNextPortForUDP());
theSocket1 = new MulticastSocket(null);
theSocket2 = new MulticastSocket(null);
theSocket1.setReuseAddress(true);
theSocket2.setReuseAddress(true);
theSocket1.bind(theAddress);
theSocket2.bind(theAddress);
} catch (Exception e) {
fail(
"unexpected exception when trying to connect " +
"to do duplicate socket bind with re-useaddr set " +
"to true");
}
if (theSocket1 != null)
theSocket1.close();
if (theSocket2 != null)
theSocket2.close();
// test the default case which we expect to be the same on all
// platforms
try {
InetSocketAddress theAddress = new InetSocketAddress(
InetAddress.getLocalHost(), Support_PortManager
.getNextPortForUDP());
theSocket1 = new MulticastSocket(null);
theSocket2 = new MulticastSocket(null);
theSocket1.bind(theAddress);
theSocket2.bind(theAddress);
} catch (BindException e) {
fail(
"unexpected exception when trying to connect to do " +
"duplicate socket bind with re-useaddr left as default");
}
if (theSocket1 != null)
theSocket1.close();
if (theSocket2 != null)
theSocket2.close();
ensureExceptionThrownIfOptionIsUnsupportedOnOS(SO_REUSEADDR);
} catch (Exception e) {
handleException(e, SO_REUSEADDR);
}
}
/**
* Sets up the fixture, for example, open a network connection. This method
* is called before a test is executed.
*/
protected void setUp() {
Enumeration theInterfaces = null;
try {
theInterfaces = NetworkInterface.getNetworkInterfaces();
} catch (Exception e) {
}
// only consider interfaces that have addresses associated with them.
// Otherwise tests don't work so well
if (theInterfaces != null) {
atLeastOneInterface = false;
while (theInterfaces.hasMoreElements()
&& (atLeastOneInterface == false)) {
networkInterface1 = (NetworkInterface) theInterfaces
.nextElement();
if ((networkInterface1.getInetAddresses() != null)
&& networkInterface1.getInetAddresses()
.hasMoreElements() &&
// we only want real interfaces
(Support_NetworkInterface
.useInterface(networkInterface1) == true)) {
atLeastOneInterface = true;
}
}
atLeastTwoInterfaces = false;
if (theInterfaces.hasMoreElements()) {
while (theInterfaces.hasMoreElements()
&& (atLeastTwoInterfaces == false)) {
networkInterface2 = (NetworkInterface) theInterfaces
.nextElement();
if ((networkInterface2.getInetAddresses() != null)
&& networkInterface2.getInetAddresses()
.hasMoreElements() &&
// we only want real interfaces
(Support_NetworkInterface
.useInterface(networkInterface2) == true)) {
atLeastTwoInterfaces = true;
}
}
}
Enumeration addresses;
// first the first interface that supports IPV6 if one exists
try {
theInterfaces = NetworkInterface.getNetworkInterfaces();
} catch (Exception e) {
}
boolean found = false;
while (theInterfaces.hasMoreElements() && !found) {
NetworkInterface nextInterface = (NetworkInterface) theInterfaces
.nextElement();
addresses = nextInterface.getInetAddresses();
if (addresses != null) {
while (addresses.hasMoreElements()) {
InetAddress nextAddress = (InetAddress) addresses
.nextElement();
if (nextAddress instanceof Inet6Address) {
IPV6networkInterface1 = nextInterface;
found = true;
break;
}
}
}
}
}
}
/**
* Tears down the fixture, for example, close a network connection. This
* method is called after a test is executed.
*/
protected void tearDown() throws InterruptedException {
if (t != null)
t.interrupt();
if (mss != null)
mss.close();
if (server != null)
server.stopServer();
}
}