/*
 * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

/*
 * @test
 * @bug 8175325
 * @summary test NetworkInterface getInterfaceAddresses method on the NetworkInterface returned
 * from the getNetworkInterface invocation on a MulticastSocket bound to a wildcard address.
 *
 */

import java.net.MulticastSocket;
import java.net.NetworkInterface;
import java.net.SocketException;

public class NetworkInterfaceEmptyGetInetAddressesTest {

    static int exceptionCount = 0;

    public static void testMethods(NetworkInterface netIf) throws Exception {
        testNetworkInterface_getInterfaceAddresses(netIf);

        if (exceptionCount > 0) {
            throw new RuntimeException("Unexpected Exceptions in test");
        }
    }

    private static void testNetworkInterface_getInterfaceAddresses(
            NetworkInterface netIf) {
        try {
            netIf.getInterfaceAddresses();
        } catch (Exception ex) {
            ex.printStackTrace();
            incrementExceptionCount();
        }
    }

    private static void incrementExceptionCount() {
        exceptionCount++;
    }

    public static void main(String[] args) throws Exception {
        MulticastSocket mcastSock = null;
        try {
            mcastSock = new MulticastSocket();
            System.out.println("macst socket address == "
                    + mcastSock.getLocalAddress());
            NetworkInterface netIf = mcastSock.getNetworkInterface();
            testMethods(netIf);
        } finally {
            if (mcastSock != null) {
                mcastSock.close();
            }
        }
    }
}
