package com.workshare.msnos.core.protocols.ip; import org.junit.Test; import org.junit.runner.RunWith; import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.PowerMockRunner; import java.net.InetAddress; import java.net.InterfaceAddress; import java.net.NetworkInterface; import java.util.ArrayList; import java.util.Arrays; import java.util.Enumeration; import java.util.List; import java.util.Set; import static org.junit.Assert.*; import static org.mockito.Mockito.atLeastOnce; import static org.mockito.Mockito.verify; import static org.powermock.api.mockito.PowerMockito.mock; import static org.powermock.api.mockito.PowerMockito.when; @RunWith(PowerMockRunner.class) @PrepareForTest({NetworkInterface.class, InterfaceAddress.class, Network.class}) public class NetworkTest { private static final byte NET_PREFIX = (byte) 24; private static final byte[] IPV4_ADDRESS1 = new byte[]{110, 0, 1, 1}; private static final byte[] IPV4_ADDRESS2 = new byte[]{120, 0, 0, 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}; private static final byte FF = (byte) 255; @Test public void shouldSkipIpv6AddressesIfRequested() { NetworkInterface nic = mock(NetworkInterface.class); InterfaceAddress addresses[] = new InterfaceAddress[]{ mockInterfaceAddress(IPV4_ADDRESS2), mockInterfaceAddress(IPV4_ADDRESS1), mockInterfaceAddress(IPV6_ADDRESS1), }; when(nic.getInterfaceAddresses()).thenReturn(Arrays.asList(addresses)); Set<Network> nets = Network.list(nic, true); assertEquals(2, nets.size()); } @Test public void shouldIncludeIpv6AddressesIfRequested() { NetworkInterface nic = mock(NetworkInterface.class); InterfaceAddress addresses[] = new InterfaceAddress[]{ mockInterfaceAddress(IPV4_ADDRESS2), mockInterfaceAddress(IPV4_ADDRESS1), mockInterfaceAddress(IPV6_ADDRESS1), }; when(nic.getInterfaceAddresses()).thenReturn(Arrays.asList(addresses)); Set<Network> nets = Network.list(nic, false); assertEquals(3, nets.size()); } @Test public void shouldSkipLoopbackAddresses() { NetworkInterface nic = mock(NetworkInterface.class); InterfaceAddress addresses[] = new InterfaceAddress[]{ mockInterfaceAddress(IPV4_ADDRESS1), mockInterfaceAddress(IPV4_LOCALHOST), }; when(nic.getInterfaceAddresses()).thenReturn(Arrays.asList(addresses)); Set<Network> nets = Network.list(nic, true); assertEquals(1, nets.size()); assertEquals(IPV4_ADDRESS1, nets.iterator().next().getAddress()); } @Test public void shouldComputeNetmask() { Network net = new Network(IPV4_ADDRESS2, NET_PREFIX); assertArrayEquals(new byte[]{FF, FF, FF, 0}, net.getNetmask()); } @Test public void shouldComputeGetHostString() { Network net = new Network(new byte[]{10, 0, 0, 1}, (byte) 24); assertEquals("10.0.0.1", net.getHostString()); } @Test public void shouldComputeToString() { Network net = new Network(new byte[]{10, 0, 0, 1}, (byte) 24); assertTrue(net.toString().contains("10.0.0.1/24")); } @Test public void shouldComputeToStringWithNoNegativeDigitsPlease() { Network net = new Network(new byte[]{192 - 256, 168 - 256, 0, 1}, (byte) 24); assertTrue(net.toString().contains("192.168.0.1/24")); } @Test public void shouldComputeHashcode() { Network net1 = new Network(IPV4_ADDRESS2, NET_PREFIX); Network net2 = new Network(IPV4_ADDRESS1, NET_PREFIX); assertFalse(net1.hashCode() == net2.hashCode()); } @Test public void shouldComputeEquals() { Network net1 = new Network(IPV4_ADDRESS2, NET_PREFIX); Network net2 = new Network(IPV4_ADDRESS1, NET_PREFIX); assertFalse(net1.equals(net2)); } @Test public void shouldBeBuildableWithInterfaceAddress() { InterfaceAddress adapter = mockInterfaceAddress(IPV4_ADDRESS2, NET_PREFIX); Network network = new Network(adapter); assertEquals(network.getPrefix(), NET_PREFIX); assertEquals(network.getAddress(), IPV4_ADDRESS2); } @Test public void shouldTellIfIPIsPrivate() throws Exception { final byte[] privateIP = new byte[]{10, 0, 1, 1}; InterfaceAddress adapter = mockInterfaceAddress(privateIP, NET_PREFIX); Network network = new Network(adapter); assertTrue(network.isPrivate()); } @Test public void shouldTellIfIPIsPublic() throws Exception { InterfaceAddress adapter = mockInterfaceAddress(IPV4_ADDRESS1, NET_PREFIX); Network network = new Network(adapter); assertFalse(network.isPrivate()); } @Test public void shouldAttemptToFindPublicIPifPrivate() throws Exception { final byte[] privateIP = new byte[]{10, 0, 1, 1}; NetworkInterface nic = mock(NetworkInterface.class); InterfaceAddress addresses[] = new InterfaceAddress[]{ mockInterfaceAddress(IPV4_ADDRESS2), mockInterfaceAddress(privateIP), mockInterfaceAddress(IPV6_ADDRESS1), }; when(nic.getInterfaceAddresses()).thenReturn(Arrays.asList(addresses)); AddressResolver resolver = mock(AddressResolver.class); Network.listAll(asEnumeration(nic), true, false, resolver); verify(resolver, atLeastOnce()).findPublicIP(); } @Test public void shouldSkipVirtualNicsOnRequest() throws Exception { final NetworkInterface virtual = mock(NetworkInterface.class); final InterfaceAddress virtAddress = mockInterfaceAddress(IPV4_ADDRESS2); when(virtual.isVirtual()).thenReturn(true); when(virtual.getInterfaceAddresses()).thenReturn(Arrays.asList(new InterfaceAddress[]{ virtAddress, })); final NetworkInterface eth0 = mock(NetworkInterface.class); final InterfaceAddress eth0Address = mockInterfaceAddress(IPV4_ADDRESS1); when(eth0.isVirtual()).thenReturn(false); when(eth0.getInterfaceAddresses()).thenReturn(Arrays.asList(new InterfaceAddress[]{ eth0Address, })); AddressResolver resolver = mock(AddressResolver.class); Set<Network> res = Network.listAll(asEnumeration(eth0, virtual), true, false, resolver); assertEquals(1,res.size()); assertEquals(IPV4_ADDRESS1, res.iterator().next().getAddress()); } @Test public void shouldSkipLoopbackNics() throws Exception { final NetworkInterface loopback = mock(NetworkInterface.class); final InterfaceAddress localhost = mockInterfaceAddress(IPV4_LOCALHOST); when(loopback.isLoopback()).thenReturn(true); when(loopback.getInterfaceAddresses()).thenReturn(Arrays.asList(new InterfaceAddress[]{ localhost, })); final NetworkInterface eth0 = mock(NetworkInterface.class); final InterfaceAddress eth0Address = mockInterfaceAddress(IPV4_ADDRESS1); when(eth0.isVirtual()).thenReturn(false); when(eth0.getInterfaceAddresses()).thenReturn(Arrays.asList(new InterfaceAddress[]{ eth0Address, })); AddressResolver resolver = mock(AddressResolver.class); Set<Network> res = Network.listAll(asEnumeration(eth0, loopback), true, true, resolver); assertEquals(1,res.size()); assertEquals(IPV4_ADDRESS1, res.iterator().next().getAddress()); } @Test public void shouldReportOnlyTheListedNicsIfSpecified() throws Exception { System.setProperty(Network.SYSP_NET_BINDINGS, "eth0,wlan0"); final NetworkInterface wmnet8 = mock(NetworkInterface.class); final InterfaceAddress virtAddress = mockInterfaceAddress(IPV4_ADDRESS2); when(wmnet8.getName()).thenReturn("wmnet8"); when(wmnet8.isVirtual()).thenReturn(true); when(wmnet8.getInterfaceAddresses()).thenReturn(Arrays.asList(new InterfaceAddress[]{ virtAddress, })); final NetworkInterface eth0 = mock(NetworkInterface.class); final InterfaceAddress eth0Address = mockInterfaceAddress(IPV4_ADDRESS1); when(eth0.getName()).thenReturn("eth0"); when(eth0.isVirtual()).thenReturn(false); when(eth0.getInterfaceAddresses()).thenReturn(Arrays.asList(new InterfaceAddress[]{ eth0Address, })); AddressResolver resolver = mock(AddressResolver.class); Set<Network> res = Network.listAll(asEnumeration(eth0, wmnet8), true, true, resolver); assertEquals(1,res.size()); assertEquals(IPV4_ADDRESS1, res.iterator().next().getAddress()); } @Test public void shouldReturnTrueOnValidIPV4DottedAddress() { assertTrue(Network.isValidDottedIpv4Address("25.25.25.25")); } @Test public void shouldReturnFalseOnInvalidIPV4DottedAddress() { assertFalse(Network.isValidDottedIpv4Address("foo.25.25.25")); assertFalse(Network.isValidDottedIpv4Address("25.256.25.25")); assertFalse(Network.isValidDottedIpv4Address("25.25.25.25.25")); } private Enumeration<NetworkInterface> asEnumeration(NetworkInterface... nics) { final List<NetworkInterface> data = new ArrayList<NetworkInterface>(Arrays.asList(nics)); return new Enumeration<NetworkInterface>() { @Override public boolean hasMoreElements() { return data.size() > 0; } @Override public NetworkInterface nextElement() { return data.remove(0); } }; } private InterfaceAddress mockInterfaceAddress(final byte[] netAddress) { final InterfaceAddress intface = mockInterfaceAddress(netAddress, NET_PREFIX); if (netAddress.equals(IPV4_LOCALHOST)) { InetAddress address = mock(InetAddress.class); when(address.isLoopbackAddress()).thenReturn(true); when(intface.getAddress()).thenReturn(address); } return intface; } 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; } }