/* * Copyright 2016 the original author or authors. * * Licensed 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 org.springframework.yarn.net; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.nullValue; import static org.hamcrest.Matchers.notNullValue; import static org.junit.Assert.assertThat; import static org.powermock.api.mockito.PowerMockito.mock; import static org.powermock.api.mockito.PowerMockito.when; import java.net.InetAddress; import java.net.InterfaceAddress; import java.net.NetworkInterface; import java.net.SocketException; import java.util.Arrays; import java.util.List; import org.junit.Test; import org.junit.runner.RunWith; import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.PowerMockRunner; import org.springframework.yarn.net.DefaultHostInfoDiscoveryTests.MockDefaultHostInfoDiscovery; import org.springframework.yarn.net.HostInfoDiscovery.HostInfo; @RunWith(PowerMockRunner.class) @PrepareForTest({NetworkInterface.class, InterfaceAddress.class, MockDefaultHostInfoDiscovery.class}) public class DefaultHostInfoDiscoveryTests { private static final byte NET_PREFIX = (byte) 24; private static final byte[] IPV4_ADDRESS1 = new byte[] { (byte) 192, (byte) 168, 1, 1 }; private static final byte[] IPV4_ADDRESS2 = new byte[] { 10, 10, 10, 10 }; private static final byte[] IPV4_ADDRESS3 = new byte[] { (byte) 192, (byte) 168, (byte) 128, 1 }; private static final byte[] IPV6_ADDRESS1 = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }; private static final byte[] IPV4_LOCALHOST = new byte[] { 127, 0, 0, 1 }; @Test public void testOnlyLoopbackItDisabled() throws Exception { NetworkInterface nic0 = mock(NetworkInterface.class); InterfaceAddress addresses0[] = new InterfaceAddress[]{ mockInterfaceAddress(IPV4_LOCALHOST) }; when(nic0.getInterfaceAddresses()).thenReturn(Arrays.asList(addresses0)); when(nic0.isLoopback()).thenReturn(true); when(nic0.isPointToPoint()).thenReturn(false); when(nic0.getName()).thenReturn("lo"); MockDefaultHostInfoDiscovery discovery = new MockDefaultHostInfoDiscovery(Arrays.asList(nic0)); HostInfo hostInfo = discovery.getHostInfo(); assertThat(hostInfo, nullValue()); } @Test public void testOnlyLoopbackItEnabled() throws Exception { NetworkInterface nic0 = mock(NetworkInterface.class); InterfaceAddress addresses0[] = new InterfaceAddress[]{ mockInterfaceAddress(IPV4_LOCALHOST) }; when(nic0.getInterfaceAddresses()).thenReturn(Arrays.asList(addresses0)); when(nic0.isLoopback()).thenReturn(true); when(nic0.isPointToPoint()).thenReturn(false); when(nic0.getName()).thenReturn("lo"); MockDefaultHostInfoDiscovery discovery = new MockDefaultHostInfoDiscovery(Arrays.asList(nic0)); discovery.setLoopback(true); HostInfo hostInfo = discovery.getHostInfo(); assertThat(hostInfo, notNullValue()); assertThat(hostInfo.getAddress(), is("127.0.0.1")); assertThat(hostInfo.getHostname(), is("localhost")); } @Test public void testSingleEthSiteAddress() throws Exception { NetworkInterface nic0 = mock(NetworkInterface.class); InterfaceAddress addresses0[] = new InterfaceAddress[]{ mockInterfaceAddress(IPV4_LOCALHOST) }; when(nic0.getInterfaceAddresses()).thenReturn(Arrays.asList(addresses0)); when(nic0.isLoopback()).thenReturn(true); when(nic0.isPointToPoint()).thenReturn(false); when(nic0.getName()).thenReturn("lo"); NetworkInterface nic1 = mock(NetworkInterface.class); InterfaceAddress addresses1[] = new InterfaceAddress[]{ mockInterfaceAddress(IPV4_ADDRESS1), mockInterfaceAddress(IPV6_ADDRESS1) }; when(nic1.getInterfaceAddresses()).thenReturn(Arrays.asList(addresses1)); when(nic1.isPointToPoint()).thenReturn(false); when(nic1.getName()).thenReturn("eth0"); MockDefaultHostInfoDiscovery discovery = new MockDefaultHostInfoDiscovery(Arrays.asList(nic0, nic1)); HostInfo hostInfo = discovery.getHostInfo(); assertThat(hostInfo, notNullValue()); assertThat(hostInfo.getAddress(), is("192.168.1.1")); assertThat(hostInfo.getHostname(), is("fakeHostName")); } @Test public void testTwoNicsPreferEth() throws Exception { NetworkInterface nic0 = mock(NetworkInterface.class); InterfaceAddress addresses0[] = new InterfaceAddress[]{ mockInterfaceAddress(IPV4_LOCALHOST) }; when(nic0.getInterfaceAddresses()).thenReturn(Arrays.asList(addresses0)); when(nic0.isLoopback()).thenReturn(true); when(nic0.isPointToPoint()).thenReturn(false); when(nic0.getName()).thenReturn("lo"); NetworkInterface nic1 = mock(NetworkInterface.class); InterfaceAddress addresses1[] = new InterfaceAddress[]{ mockInterfaceAddress(IPV4_ADDRESS1), mockInterfaceAddress(IPV6_ADDRESS1) }; when(nic1.getInterfaceAddresses()).thenReturn(Arrays.asList(addresses1)); when(nic1.isPointToPoint()).thenReturn(false); when(nic1.getName()).thenReturn("eth0"); NetworkInterface nic2 = mock(NetworkInterface.class); InterfaceAddress addresses2[] = new InterfaceAddress[]{ mockInterfaceAddress(IPV4_ADDRESS2) }; when(nic2.getInterfaceAddresses()).thenReturn(Arrays.asList(addresses2)); when(nic2.isPointToPoint()).thenReturn(false); when(nic2.getName()).thenReturn("foo0"); MockDefaultHostInfoDiscovery discovery = new MockDefaultHostInfoDiscovery(Arrays.asList(nic0, nic1, nic2)); HostInfo hostInfo = discovery.getHostInfo(); assertThat(hostInfo, notNullValue()); assertThat(hostInfo.getAddress(), is("192.168.1.1")); assertThat(hostInfo.getHostname(), is("fakeHostName")); } @Test public void testTwoNicsPreferEn() throws Exception { NetworkInterface nic0 = mock(NetworkInterface.class); InterfaceAddress addresses0[] = new InterfaceAddress[]{ mockInterfaceAddress(IPV4_LOCALHOST) }; when(nic0.getInterfaceAddresses()).thenReturn(Arrays.asList(addresses0)); when(nic0.isLoopback()).thenReturn(true); when(nic0.isPointToPoint()).thenReturn(false); when(nic0.getName()).thenReturn("lo"); NetworkInterface nic1 = mock(NetworkInterface.class); InterfaceAddress addresses1[] = new InterfaceAddress[]{ mockInterfaceAddress(IPV4_ADDRESS1), mockInterfaceAddress(IPV6_ADDRESS1) }; when(nic1.getInterfaceAddresses()).thenReturn(Arrays.asList(addresses1)); when(nic1.isPointToPoint()).thenReturn(false); when(nic1.getName()).thenReturn("en0"); NetworkInterface nic2 = mock(NetworkInterface.class); InterfaceAddress addresses2[] = new InterfaceAddress[]{ mockInterfaceAddress(IPV4_ADDRESS2) }; when(nic2.getInterfaceAddresses()).thenReturn(Arrays.asList(addresses2)); when(nic2.isPointToPoint()).thenReturn(false); when(nic2.getName()).thenReturn("foo0"); MockDefaultHostInfoDiscovery discovery = new MockDefaultHostInfoDiscovery(Arrays.asList(nic0, nic1, nic2)); HostInfo hostInfo = discovery.getHostInfo(); assertThat(hostInfo, notNullValue()); assertThat(hostInfo.getAddress(), is("192.168.1.1")); assertThat(hostInfo.getHostname(), is("fakeHostName")); } @Test public void testMatchInterface() throws Exception { NetworkInterface nic0 = mock(NetworkInterface.class); InterfaceAddress addresses0[] = new InterfaceAddress[]{ mockInterfaceAddress(IPV4_LOCALHOST) }; when(nic0.getInterfaceAddresses()).thenReturn(Arrays.asList(addresses0)); when(nic0.isLoopback()).thenReturn(true); when(nic0.isPointToPoint()).thenReturn(false); when(nic0.getName()).thenReturn("lo"); NetworkInterface nic1 = mock(NetworkInterface.class); InterfaceAddress addresses1[] = new InterfaceAddress[]{ mockInterfaceAddress(IPV4_ADDRESS1) }; when(nic1.getInterfaceAddresses()).thenReturn(Arrays.asList(addresses1)); when(nic1.isPointToPoint()).thenReturn(false); when(nic1.getName()).thenReturn("en0"); NetworkInterface nic2 = mock(NetworkInterface.class); InterfaceAddress addresses2[] = new InterfaceAddress[]{ mockInterfaceAddress(IPV4_ADDRESS2) }; when(nic2.getInterfaceAddresses()).thenReturn(Arrays.asList(addresses2)); when(nic2.isPointToPoint()).thenReturn(false); when(nic2.getName()).thenReturn("foo0"); MockDefaultHostInfoDiscovery discovery = new MockDefaultHostInfoDiscovery(Arrays.asList(nic0, nic1, nic2)); discovery.setMatchInterface("foo\\d*"); HostInfo hostInfo = discovery.getHostInfo(); assertThat(hostInfo, notNullValue()); assertThat(hostInfo.getAddress(), is("10.10.10.10")); assertThat(hostInfo.getHostname(), is("fakeHostName")); } @Test public void testMatchCidr1() throws Exception { NetworkInterface nic0 = mock(NetworkInterface.class); InterfaceAddress addresses0[] = new InterfaceAddress[]{ mockInterfaceAddress(IPV4_LOCALHOST) }; when(nic0.getInterfaceAddresses()).thenReturn(Arrays.asList(addresses0)); when(nic0.isLoopback()).thenReturn(true); when(nic0.isPointToPoint()).thenReturn(false); when(nic0.getName()).thenReturn("lo"); NetworkInterface nic1 = mock(NetworkInterface.class); InterfaceAddress addresses1[] = new InterfaceAddress[]{ mockInterfaceAddress(IPV4_ADDRESS1) }; when(nic1.getInterfaceAddresses()).thenReturn(Arrays.asList(addresses1)); when(nic1.isPointToPoint()).thenReturn(false); when(nic1.getName()).thenReturn("eth0"); NetworkInterface nic2 = mock(NetworkInterface.class); InterfaceAddress addresses2[] = new InterfaceAddress[]{ mockInterfaceAddress(IPV4_ADDRESS2) }; when(nic2.getInterfaceAddresses()).thenReturn(Arrays.asList(addresses2)); when(nic2.isPointToPoint()).thenReturn(false); when(nic2.getName()).thenReturn("eth1"); NetworkInterface nic3 = mock(NetworkInterface.class); InterfaceAddress addresses3[] = new InterfaceAddress[]{ mockInterfaceAddress(IPV4_ADDRESS3) }; when(nic3.getInterfaceAddresses()).thenReturn(Arrays.asList(addresses3)); when(nic3.isPointToPoint()).thenReturn(false); when(nic3.getName()).thenReturn("eth2"); MockDefaultHostInfoDiscovery discovery = new MockDefaultHostInfoDiscovery(Arrays.asList(nic0, nic1, nic2, nic3)); discovery.setMatchIpv4("192.168.1.1/24"); HostInfo hostInfo = discovery.getHostInfo(); assertThat(hostInfo, notNullValue()); assertThat(hostInfo.getAddress(), is("192.168.1.1")); assertThat(hostInfo.getHostname(), is("fakeHostName")); } @Test public void testMatchCidr2() throws Exception { NetworkInterface nic0 = mock(NetworkInterface.class); InterfaceAddress addresses0[] = new InterfaceAddress[]{ mockInterfaceAddress(IPV4_LOCALHOST) }; when(nic0.getInterfaceAddresses()).thenReturn(Arrays.asList(addresses0)); when(nic0.isLoopback()).thenReturn(true); when(nic0.isPointToPoint()).thenReturn(false); when(nic0.getName()).thenReturn("lo"); NetworkInterface nic1 = mock(NetworkInterface.class); InterfaceAddress addresses1[] = new InterfaceAddress[]{ mockInterfaceAddress(IPV4_ADDRESS1) }; when(nic1.getInterfaceAddresses()).thenReturn(Arrays.asList(addresses1)); when(nic1.isPointToPoint()).thenReturn(false); when(nic1.getName()).thenReturn("eth0"); NetworkInterface nic2 = mock(NetworkInterface.class); InterfaceAddress addresses2[] = new InterfaceAddress[]{ mockInterfaceAddress(IPV4_ADDRESS2) }; when(nic2.getInterfaceAddresses()).thenReturn(Arrays.asList(addresses2)); when(nic2.isPointToPoint()).thenReturn(false); when(nic2.getName()).thenReturn("eth1"); NetworkInterface nic3 = mock(NetworkInterface.class); InterfaceAddress addresses3[] = new InterfaceAddress[]{ mockInterfaceAddress(IPV4_ADDRESS3) }; when(nic3.getInterfaceAddresses()).thenReturn(Arrays.asList(addresses3)); when(nic3.isPointToPoint()).thenReturn(false); when(nic3.getName()).thenReturn("eth2"); MockDefaultHostInfoDiscovery discovery = new MockDefaultHostInfoDiscovery(Arrays.asList(nic0, nic1, nic2, nic3)); discovery.setMatchIpv4("192.168.128.1/22"); HostInfo hostInfo = discovery.getHostInfo(); assertThat(hostInfo, notNullValue()); assertThat(hostInfo.getAddress(), is("192.168.128.1")); assertThat(hostInfo.getHostname(), is("fakeHostName")); } @Test public void testPreferNicIndex() throws Exception { NetworkInterface nic0 = mock(NetworkInterface.class); InterfaceAddress addresses0[] = new InterfaceAddress[]{ mockInterfaceAddress(IPV4_LOCALHOST) }; when(nic0.getInterfaceAddresses()).thenReturn(Arrays.asList(addresses0)); when(nic0.isLoopback()).thenReturn(true); when(nic0.isPointToPoint()).thenReturn(false); when(nic0.getName()).thenReturn("lo"); NetworkInterface nic1 = mock(NetworkInterface.class); InterfaceAddress addresses1[] = new InterfaceAddress[]{ mockInterfaceAddress(IPV4_ADDRESS1) }; when(nic1.getInterfaceAddresses()).thenReturn(Arrays.asList(addresses1)); when(nic1.isPointToPoint()).thenReturn(false); when(nic1.getName()).thenReturn("eth1"); when(nic1.getIndex()).thenReturn(1); NetworkInterface nic2 = mock(NetworkInterface.class); InterfaceAddress addresses2[] = new InterfaceAddress[]{ mockInterfaceAddress(IPV4_ADDRESS2) }; when(nic2.getInterfaceAddresses()).thenReturn(Arrays.asList(addresses2)); when(nic2.isPointToPoint()).thenReturn(false); when(nic2.getName()).thenReturn("eth0"); when(nic2.getIndex()).thenReturn(0); NetworkInterface nic3 = mock(NetworkInterface.class); InterfaceAddress addresses3[] = new InterfaceAddress[]{ mockInterfaceAddress(IPV4_ADDRESS3) }; when(nic3.getInterfaceAddresses()).thenReturn(Arrays.asList(addresses3)); when(nic3.isPointToPoint()).thenReturn(false); when(nic3.getName()).thenReturn("eth2"); when(nic3.getIndex()).thenReturn(2); MockDefaultHostInfoDiscovery discovery = new MockDefaultHostInfoDiscovery(Arrays.asList(nic0, nic1, nic2, nic3)); HostInfo hostInfo = discovery.getHostInfo(); assertThat(hostInfo, notNullValue()); assertThat(hostInfo.getAddress(), is("10.10.10.10")); assertThat(hostInfo.getHostname(), is("fakeHostName")); } @Test public void testComplexDiscoveryOptions() throws Exception { NetworkInterface nic0 = mock(NetworkInterface.class); InterfaceAddress addresses0[] = new InterfaceAddress[]{ mockInterfaceAddress(IPV4_LOCALHOST) }; when(nic0.getInterfaceAddresses()).thenReturn(Arrays.asList(addresses0)); when(nic0.isLoopback()).thenReturn(true); when(nic0.isPointToPoint()).thenReturn(false); when(nic0.getName()).thenReturn("lo"); NetworkInterface nic1 = mock(NetworkInterface.class); InterfaceAddress addresses1[] = new InterfaceAddress[]{ mockInterfaceAddress(IPV4_ADDRESS1), mockInterfaceAddress(IPV6_ADDRESS1) }; when(nic1.getInterfaceAddresses()).thenReturn(Arrays.asList(addresses1)); when(nic1.isPointToPoint()).thenReturn(false); when(nic1.getName()).thenReturn("eth0"); MockDefaultHostInfoDiscovery discovery = new MockDefaultHostInfoDiscovery(Arrays.asList(nic0, nic1)); discovery.setMatchInterface("eth\\d*"); discovery.setMatchIpv4("192.168.1.1/24"); HostInfo hostInfo = discovery.getHostInfo(); assertThat(hostInfo, notNullValue()); assertThat(hostInfo.getAddress(), is("192.168.1.1")); assertThat(hostInfo.getHostname(), is("fakeHostName")); } private InterfaceAddress mockInterfaceAddress(final byte[] netAddress) { final InterfaceAddress intAddress = mockInterfaceAddress(netAddress, NET_PREFIX); if (netAddress.equals(IPV4_LOCALHOST)) { InetAddress address = mock(InetAddress.class); when(address.getAddress()).thenReturn(IPV4_LOCALHOST); when(address.isLoopbackAddress()).thenReturn(true); when(address.isAnyLocalAddress()).thenReturn(false); when(address.getHostAddress()).thenReturn("127.0.0.1"); when(address.getHostName()).thenReturn("localhost"); when(intAddress.getAddress()).thenReturn(address); } else if (netAddress.equals(IPV4_ADDRESS1)) { InetAddress address = mock(InetAddress.class); when(address.getAddress()).thenReturn(IPV4_ADDRESS1); when(address.isLoopbackAddress()).thenReturn(false); when(address.isAnyLocalAddress()).thenReturn(false); when(address.getHostAddress()).thenReturn("192.168.1.1"); when(address.getHostName()).thenReturn("fakeHostName"); when(intAddress.getAddress()).thenReturn(address); } else if (netAddress.equals(IPV4_ADDRESS2)) { InetAddress address = mock(InetAddress.class); when(address.getAddress()).thenReturn(IPV4_ADDRESS2); when(address.isLoopbackAddress()).thenReturn(false); when(address.getHostAddress()).thenReturn("10.10.10.10"); when(address.getHostName()).thenReturn("fakeHostName"); when(intAddress.getAddress()).thenReturn(address); } else if (netAddress.equals(IPV4_ADDRESS3)) { InetAddress address = mock(InetAddress.class); when(address.getAddress()).thenReturn(IPV4_ADDRESS3); when(address.isLoopbackAddress()).thenReturn(false); when(address.isAnyLocalAddress()).thenReturn(false); when(address.getHostAddress()).thenReturn("192.168.128.1"); when(address.getHostName()).thenReturn("fakeHostName"); when(intAddress.getAddress()).thenReturn(address); } return intAddress; } private InterfaceAddress mockInterfaceAddress(final byte[] netAddress, final int netPrefix) { InetAddress address = mock(InetAddress.class); when(address.getAddress()).thenReturn(netAddress); InterfaceAddress adapter = mock(InterfaceAddress.class); when(adapter.getAddress()).thenReturn(address); when(adapter.getNetworkPrefixLength()).thenReturn((short) netPrefix); return adapter; } public static class MockDefaultHostInfoDiscovery extends DefaultHostInfoDiscovery { List<NetworkInterface> interfaces; public MockDefaultHostInfoDiscovery(List<NetworkInterface> interfaces) { this.interfaces = interfaces; } @Override protected List<NetworkInterface> getAllAvailableInterfaces() throws SocketException { return interfaces; } } }