1/*
2 *  Licensed to the Apache Software Foundation (ASF) under one or more
3 *  contributor license agreements.  See the NOTICE file distributed with
4 *  this work for additional information regarding copyright ownership.
5 *  The ASF licenses this file to You under the Apache License, Version 2.0
6 *  (the "License"); you may not use this file except in compliance with
7 *  the License.  You may obtain a copy of the License at
8 *
9 *     http://www.apache.org/licenses/LICENSE-2.0
10 *
11 *  Unless required by applicable law or agreed to in writing, software
12 *  distributed under the License is distributed on an "AS IS" BASIS,
13 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 *  See the License for the specific language governing permissions and
15 *  limitations under the License.
16 */
17
18package org.apache.harmony.luni.tests.java.net;
19
20import java.net.InetAddress;
21import java.net.InterfaceAddress;
22import java.net.NetworkInterface;
23import java.net.SocketException;
24import java.util.ArrayList;
25import java.util.Enumeration;
26import java.util.List;
27
28public class NetworkInterfaceTest extends junit.framework.TestCase {
29
30	// private member variables used for tests
31    Enumeration<NetworkInterface> theInterfaces = null;
32
33	boolean atLeastOneInterface = false;
34
35	boolean atLeastTwoInterfaces = false;
36
37	private NetworkInterface networkInterface1 = null;
38
39	private NetworkInterface sameAsNetworkInterface1 = null;
40
41	private NetworkInterface networkInterface2 = null;
42
43	/**
44	 * @tests java.net.NetworkInterface#getName()
45	 */
46	public void test_getName() {
47		if (atLeastOneInterface) {
48			assertNotNull("validate that non null name is returned",
49					networkInterface1.getName());
50			assertFalse("validate that non-zero length name is generated",
51					networkInterface1.getName().equals(""));
52		}
53		if (atLeastTwoInterfaces) {
54			assertFalse(
55					"Validate strings are different for different interfaces",
56					networkInterface1.getName().equals(
57							networkInterface2.getName()));
58		}
59	}
60
61	/**
62	 * @tests java.net.NetworkInterface#getInetAddresses()
63	 */
64	public void test_getInetAddresses() throws Exception {
65		if (atLeastOneInterface) {
66            Enumeration theAddresses = networkInterface1.getInetAddresses();
67            while (theAddresses.hasMoreElements()) {
68                InetAddress theAddress = (InetAddress) theAddresses
69                        .nextElement();
70                assertNotNull("validate that address is not null", theAddress);
71            }
72        }
73
74		if (atLeastTwoInterfaces) {
75			Enumeration theAddresses = networkInterface2.getInetAddresses();
76			while (theAddresses.hasMoreElements()) {
77                InetAddress theAddress = (InetAddress) theAddresses
78                        .nextElement();
79                assertNotNull("validate that address is not null", theAddress);
80            }
81		}
82
83		// create the list of ok and not ok addresses to return
84		if (atLeastOneInterface) {
85			ArrayList okAddresses = new ArrayList();
86			Enumeration addresses = networkInterface1.getInetAddresses();
87			int index = 0;
88			ArrayList notOkAddresses = new ArrayList();
89			while (addresses.hasMoreElements()) {
90                InetAddress theAddress = (InetAddress) addresses.nextElement();
91                    okAddresses.add(theAddress);
92                index++;
93            }
94
95			// do the same for network interface 2 if it exists
96			if (atLeastTwoInterfaces) {
97				addresses = networkInterface2.getInetAddresses();
98				index = 0;
99				while (addresses.hasMoreElements()) {
100					InetAddress theAddress = (InetAddress) addresses
101							.nextElement();
102						okAddresses.add(theAddress);
103					index++;
104				}
105			}
106
107			// validate not ok addresses are not returned
108			for (int i = 0; i < notOkAddresses.size(); i++) {
109				Enumeration reducedAddresses = networkInterface1
110						.getInetAddresses();
111				while (reducedAddresses.hasMoreElements()) {
112                    InetAddress nextAddress = (InetAddress) reducedAddresses
113                            .nextElement();
114                    assertTrue(
115                            "validate that address without permission is not returned",
116                            !nextAddress.equals(notOkAddresses.get(i)));
117                }
118				if (atLeastTwoInterfaces) {
119                    reducedAddresses = networkInterface2.getInetAddresses();
120					while (reducedAddresses.hasMoreElements()) {
121						InetAddress nextAddress = (InetAddress) reducedAddresses
122								.nextElement();
123						assertTrue(
124								"validate that address without permission is not returned",
125								!nextAddress.equals(notOkAddresses.get(i)));
126					}
127				}
128			}
129
130			// validate that ok addresses are returned
131			for (int i = 0; i < okAddresses.size(); i++) {
132				boolean addressReturned = false;
133				Enumeration reducedAddresses = networkInterface1
134						.getInetAddresses();
135				while (reducedAddresses.hasMoreElements()) {
136                    InetAddress nextAddress = (InetAddress) reducedAddresses
137                            .nextElement();
138                    if (nextAddress.equals(okAddresses.get(i))) {
139                        addressReturned = true;
140                    }
141                }
142				if (atLeastTwoInterfaces) {
143					reducedAddresses = networkInterface2.getInetAddresses();
144					while (reducedAddresses.hasMoreElements()) {
145						InetAddress nextAddress = (InetAddress) reducedAddresses
146								.nextElement();
147						if (nextAddress.equals(okAddresses.get(i))) {
148							addressReturned = true;
149						}
150					}
151				}
152				assertTrue("validate that address with permission is returned",
153						addressReturned);
154			}
155
156			// validate that we can get the interface by specifying the address.
157			// This is to be compatible
158			for (int i = 0; i < notOkAddresses.size(); i++) {
159                assertNotNull(
160                        "validate we cannot get the NetworkInterface with an address for which we have no privs",
161                        NetworkInterface
162                                .getByInetAddress((InetAddress) notOkAddresses
163                                        .get(i)));
164            }
165
166			// validate that we can get the network interface for the good
167			// addresses
168			for (int i = 0; i < okAddresses.size(); i++) {
169                assertNotNull(
170                        "validate we cannot get the NetworkInterface with an address fro which we have no privs",
171                        NetworkInterface
172                                .getByInetAddress((InetAddress) okAddresses
173                                        .get(i)));
174            }
175		}
176	}
177
178	/**
179	 * @tests java.net.NetworkInterface#getDisplayName()
180	 */
181	public void test_getDisplayName() {
182		if (atLeastOneInterface) {
183			assertNotNull("validate that non null display name is returned",
184					networkInterface1.getDisplayName());
185			assertFalse(
186					"validate that non-zero length display name is generated",
187					networkInterface1.getDisplayName().equals(""));
188		}
189		if (atLeastTwoInterfaces) {
190			assertFalse(
191					"Validate strings are different for different interfaces",
192					networkInterface1.getDisplayName().equals(
193							networkInterface2.getDisplayName()));
194		}
195	}
196
197	/**
198	 * @tests java.net.NetworkInterface#getByName(java.lang.String)
199	 */
200	public void test_getByNameLjava_lang_String() throws Exception {
201		try {
202			assertNull("validate null handled ok",
203                                   NetworkInterface.getByName(null));
204			fail("getByName did not throw NullPointerException for null argument");
205		} catch (NullPointerException e) {
206		}
207
208		assertNull("validate handled ok if we ask for name not associated with any interface",
209                                  NetworkInterface.getByName("8not a name4"));
210
211		// for each address in an interface validate that we get the right
212		// interface for that name
213		if (atLeastOneInterface) {
214			String theName = networkInterface1.getName();
215			if (theName != null) {
216                assertEquals(
217                        "validate that Interface can be obtained with its name",
218                        networkInterface1, NetworkInterface.getByName(theName));
219            }
220		}
221
222		// validate that we get the right interface with the second interface as
223		// well (ie we just don't always get the first interface
224		if (atLeastTwoInterfaces) {
225			String theName = networkInterface2.getName();
226			if (theName != null) {
227                assertEquals(
228                        "validate that Interface can be obtained with its name",
229                        networkInterface2, NetworkInterface.getByName(theName));
230            }
231		}
232	}
233
234	/**
235	 * @tests java.net.NetworkInterface#getByInetAddress(java.net.InetAddress)
236	 */
237	public void test_getByInetAddressLjava_net_InetAddress() throws Exception {
238
239		byte addressBytes[] = new byte[4];
240		addressBytes[0] = 0;
241		addressBytes[1] = 0;
242		addressBytes[2] = 0;
243		addressBytes[3] = 0;
244
245		try {
246			assertNull("validate null handled ok",
247                                   NetworkInterface.getByInetAddress(null));
248			fail("should not get here if getByInetAddress throws "
249					+ "NullPointerException if null passed in");
250		} catch (NullPointerException e) {
251		}
252
253                assertNull("validate handled ok if we ask for address not associated with any interface",
254                           NetworkInterface.getByInetAddress(InetAddress
255                                                .getByAddress(addressBytes)));
256
257		// for each address in an interface validate that we get the right
258		// interface for that address
259		if (atLeastOneInterface) {
260			Enumeration addresses = networkInterface1.getInetAddresses();
261			while (addresses.hasMoreElements()) {
262                InetAddress theAddress = (InetAddress) addresses.nextElement();
263                assertEquals(
264                        "validate that Interface can be obtained with any one of its addresses",
265                        networkInterface1, NetworkInterface
266                                .getByInetAddress(theAddress));
267            }
268		}
269
270		// validate that we get the right interface with the second interface as
271		// well (ie we just don't always get the first interface
272		if (atLeastTwoInterfaces) {
273			Enumeration addresses = networkInterface2.getInetAddresses();
274			while (addresses.hasMoreElements()) {
275                InetAddress theAddress = (InetAddress) addresses.nextElement();
276                assertEquals(
277                        "validate that Interface can be obtained with any one of its addresses",
278                        networkInterface2, NetworkInterface
279                                .getByInetAddress(theAddress));
280            }
281		}
282	}
283
284	/**
285	 * @tests java.net.NetworkInterface#getNetworkInterfaces()
286	 */
287	public void test_getNetworkInterfaces() throws Exception {
288
289		// really this is tested by all of the other calls but just make sure we
290		// can call it and get a list of interfaces if they exist
291		Enumeration theInterfaces = NetworkInterface.getNetworkInterfaces();
292	}
293
294	/**
295	 * @tests java.net.NetworkInterface#equals(java.lang.Object)
296	 */
297	public void test_equalsLjava_lang_Object() {
298		// Test for method boolean
299		// java.net.SocketPermission.equals(java.lang.Object)
300		if (atLeastOneInterface) {
301            assertEquals("If objects are the same true is returned",
302                    sameAsNetworkInterface1, networkInterface1);
303            assertNotNull("Validate Null handled ok", networkInterface1);
304        }
305		if (atLeastTwoInterfaces) {
306			assertFalse("If objects are different false is returned",
307					networkInterface1.equals(networkInterface2));
308		}
309	}
310
311	/**
312	 * @tests java.net.NetworkInterface#hashCode()
313	 */
314	public void test_hashCode() {
315
316		if (atLeastOneInterface) {
317			assertTrue(
318					"validate that hash codes are the same for two calls on the same object",
319					networkInterface1.hashCode() == networkInterface1
320							.hashCode());
321			assertTrue(
322					"validate that hash codes are the same for two objects for which equals is true",
323					networkInterface1.hashCode() == sameAsNetworkInterface1
324							.hashCode());
325		}
326	}
327
328	/**
329	 * @tests java.net.NetworkInterface#toString()
330	 */
331	public void test_toString() {
332		if (atLeastOneInterface) {
333			assertNotNull("validate that non null string is generated",
334					networkInterface1.toString());
335			assertFalse("validate that non-zero length string is generated",
336					networkInterface1.toString().equals(""));
337
338		}
339		if (atLeastTwoInterfaces) {
340			assertFalse(
341					"Validate strings are different for different interfaces",
342					networkInterface1.toString().equals(
343							networkInterface2.toString()));
344
345		}
346	}
347
348    /**
349     *
350     * @tests java.net.NetworkInterface#getInterfaceAddresses()
351     *
352     * @since 1.6
353     */
354    public void test_getInterfaceAddresses() throws SocketException {
355        if (theInterfaces != null) {
356            while (theInterfaces.hasMoreElements()) {
357                NetworkInterface netif = theInterfaces.nextElement();
358                assertEquals(netif.getName()
359                        + " getInterfaceAddresses should contain no element", 0,
360                        netif.getInterfaceAddresses().size());
361            }
362
363            theInterfaces = NetworkInterface.getNetworkInterfaces();
364            while (theInterfaces.hasMoreElements()) {
365                NetworkInterface netif = theInterfaces.nextElement();
366                List<InterfaceAddress> interfaceAddrs = netif.getInterfaceAddresses();
367                assertTrue(interfaceAddrs instanceof ArrayList);
368                for (InterfaceAddress addr : interfaceAddrs) {
369                    assertNotNull(addr);
370                }
371
372                List<InterfaceAddress> interfaceAddrs2 = netif.getInterfaceAddresses();
373                // RI fails on this since it cannot tolerate null broadcast address.
374                assertEquals(interfaceAddrs, interfaceAddrs2);
375            }
376        }
377    }
378
379    /**
380     * @tests java.net.NetworkInterface#isLoopback()
381     *
382     * @since 1.6
383     */
384    public void test_isLoopback() throws SocketException {
385        if (theInterfaces != null) {
386            while (theInterfaces.hasMoreElements()) {
387                NetworkInterface netif = theInterfaces.nextElement();
388                boolean loopback = false;
389                Enumeration<InetAddress> addrs = netif.getInetAddresses();
390                while(addrs != null && addrs.hasMoreElements()){
391                    if(addrs.nextElement().isLoopbackAddress()){
392                        loopback = true;
393                        break;
394                    }
395                }
396                assertEquals(loopback, netif.isLoopback());
397            }
398        }
399    }
400
401    /**
402     * @tests java.net.NetworkInterface#getHardwareAddress()
403     *
404     * @since 1.6
405     */
406    public void test_getHardwareAddress() throws SocketException {
407        if (theInterfaces != null) {
408            while (theInterfaces.hasMoreElements()) {
409                NetworkInterface netif = theInterfaces.nextElement();
410                byte[] hwAddr = netif.getHardwareAddress();
411                if (netif.isLoopback()) {
412                    assertTrue(hwAddr == null || hwAddr.length == 0);
413                } else {
414                    assertTrue(hwAddr.length >= 0);
415                }
416            }
417        }
418    }
419
420    /**
421     *
422     * @tests java.net.NetworkInterface#getHardwareAddress()
423     *
424     * @since 1.6
425     */
426    public void test_getMTU() throws SocketException {
427        if (theInterfaces != null) {
428            while (theInterfaces.hasMoreElements()) {
429                NetworkInterface netif = theInterfaces.nextElement();
430                assertTrue(netif.getName() + "has non-positive MTU", netif.getMTU() >= 0);
431            }
432        }
433    }
434
435	protected void setUp() throws SocketException {
436
437		Enumeration theInterfaces = null;
438		try {
439			theInterfaces = NetworkInterface.getNetworkInterfaces();
440		} catch (Exception e) {
441			fail("Exception occurred getting network interfaces : " + e);
442		}
443
444		// Set up NetworkInterface instance members. Note that because the call
445		// to NetworkInterface.getNetworkInterfaces() returns *all* of the
446		// interfaces on the test machine it is possible that one or more of
447		// them will not currently be bound to an InetAddress. e.g. a laptop
448		// running connected by a wire to the local network may also have a
449		// wireless interface that is not active and so has no InetAddress
450		// bound to it. For these tests only work with NetworkInterface objects
451		// that are bound to an InetAddress.
452		if ((theInterfaces != null) && (theInterfaces.hasMoreElements())) {
453			while ((theInterfaces.hasMoreElements())
454					&& (atLeastOneInterface == false)) {
455				NetworkInterface theInterface = (NetworkInterface) theInterfaces
456						.nextElement();
457				if (theInterface.getInetAddresses().hasMoreElements()) {
458					// Ensure that the current NetworkInterface has at least
459					// one InetAddress bound to it.
460					Enumeration addrs = theInterface.getInetAddresses();
461					if ((addrs != null) && (addrs.hasMoreElements())) {
462						atLeastOneInterface = true;
463						networkInterface1 = theInterface;
464					}// end if
465				}
466			}
467
468			while ((theInterfaces.hasMoreElements())
469					&& (atLeastTwoInterfaces == false)) {
470				NetworkInterface theInterface = (NetworkInterface) theInterfaces
471						.nextElement();
472				if (theInterface.getInetAddresses().hasMoreElements()) {
473					// Ensure that the current NetworkInterface has at least
474					// one InetAddress bound to it.
475					Enumeration addrs = theInterface.getInetAddresses();
476					if ((addrs != null) && (addrs.hasMoreElements())) {
477						atLeastTwoInterfaces = true;
478						networkInterface2 = theInterface;
479					}// end if
480				}
481			}
482
483			// Only set sameAsNetworkInterface1 if we succeeded in finding
484			// at least one good NetworkInterface
485			if (atLeastOneInterface) {
486				Enumeration addresses = networkInterface1.getInetAddresses();
487				if (addresses.hasMoreElements()) {
488					try {
489						if (addresses.hasMoreElements()) {
490							sameAsNetworkInterface1 = NetworkInterface
491							.getByInetAddress((InetAddress) addresses
492									.nextElement());
493						}
494					} catch (SocketException e) {
495						fail("SocketException occurred : " + e);
496					}
497				}
498			}// end if atLeastOneInterface
499		}
500        theInterfaces = NetworkInterface.getNetworkInterfaces();
501	}
502}
503