Home | History | Annotate | Download | only in net
      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 
     18 package org.apache.harmony.tests.java.net;
     19 
     20 import java.net.InetAddress;
     21 
     22 import tests.support.Support_Configuration;
     23 
     24 public class InetAddressThreadTest extends junit.framework.TestCase {
     25 
     26     private static boolean someoneDone[] = new boolean[2];
     27 
     28     protected static boolean threadedTestSucceeded;
     29 
     30     protected static String threadedTestErrorString;
     31 
     32     /**
     33      * This class is used to test inet_ntoa, gethostbyaddr and gethostbyname
     34      * functions in the VM to make sure they're threadsafe. getByName will cause
     35      * the gethostbyname function to be called. getHostName will cause the
     36      * gethostbyaddr to be called. getHostAddress will cause inet_ntoa to be
     37      * called.
     38      */
     39     static class threadsafeTestThread extends Thread {
     40         private String lookupName;
     41 
     42         private InetAddress testAddress;
     43 
     44         private int testType;
     45 
     46         /*
     47          * REP_NUM can be adjusted if desired. Since this error is
     48          * non-deterministic it may not always occur. Setting REP_NUM higher,
     49          * increases the chances of an error being detected, but causes the test
     50          * to take longer. Because the Java threads spend a lot of time
     51          * performing operations other than running the native code that may not
     52          * be threadsafe, it is quite likely that several thousand iterations
     53          * will elapse before the first error is detected.
     54          */
     55         private static final int REP_NUM = 20000;
     56 
     57         public threadsafeTestThread(String name, String lookupName,
     58                 InetAddress testAddress, int type) {
     59             super(name);
     60             this.lookupName = lookupName;
     61             this.testAddress = testAddress;
     62             testType = type;
     63         }
     64 
     65         public void run() {
     66             try {
     67                 String correctName = testAddress.getHostName();
     68                 String correctAddress = testAddress.getHostAddress();
     69                 long startTime = System.currentTimeMillis();
     70 
     71                 synchronized (someoneDone) {
     72                 }
     73 
     74                 for (int i = 0; i < REP_NUM; i++) {
     75                     if (someoneDone[testType]) {
     76                         break;
     77                     } else if ((i % 25) == 0
     78                             && System.currentTimeMillis() - startTime > 240000) {
     79                         System.out
     80                                 .println("Exiting due to time limitation after "
     81                                         + i + " iterations");
     82                         break;
     83                     }
     84 
     85                     InetAddress ia = InetAddress.getByName(lookupName);
     86                     String hostName = ia.getHostName();
     87                     String hostAddress = ia.getHostAddress();
     88 
     89                     // Intentionally not looking for exact name match so that
     90                     // the test works across different platforms that may or
     91                     // may not include a domain suffix on the hostname
     92                     if (!hostName.startsWith(correctName)) {
     93                         threadedTestSucceeded = false;
     94                         threadedTestErrorString = (testType == 0 ? "gethostbyname"
     95                                 : "gethostbyaddr")
     96                                 + ": getHostName() returned "
     97                                 + hostName
     98                                 + " instead of " + correctName;
     99                         break;
    100                     }
    101                     // IP addresses should match exactly
    102                     if (!correctAddress.equals(hostAddress)) {
    103                         threadedTestSucceeded = false;
    104                         threadedTestErrorString = (testType == 0 ? "gethostbyname"
    105                                 : "gethostbyaddr")
    106                                 + ": getHostName() returned "
    107                                 + hostAddress
    108                                 + " instead of " + correctAddress;
    109                         break;
    110                     }
    111 
    112                 }
    113                 someoneDone[testType] = true;
    114             } catch (Exception e) {
    115                 threadedTestSucceeded = false;
    116                 threadedTestErrorString = e.toString();
    117             }
    118         }
    119     }
    120 
    121     /**
    122      * java.net.InetAddress#getHostName()
    123      */
    124     public void test_getHostName() throws Exception {
    125         // Test for method java.lang.String java.net.InetAddress.getHostName()
    126 
    127         // Make sure there is no caching
    128         String originalPropertyValue = System
    129                 .getProperty("networkaddress.cache.ttl");
    130         System.setProperty("networkaddress.cache.ttl", "0");
    131 
    132         // Test for threadsafety
    133         try {
    134             InetAddress lookup1 = InetAddress.getByName("localhost");
    135             assertEquals("127.0.0.1", lookup1.getHostAddress());
    136             InetAddress lookup2 = InetAddress.getByName("localhost");
    137             assertEquals("127.0.0.1", lookup2.getHostAddress());
    138             threadsafeTestThread thread1 = new threadsafeTestThread("1",
    139                     lookup1.getHostName(), lookup1, 0);
    140             threadsafeTestThread thread2 = new threadsafeTestThread("2",
    141                     lookup2.getHostName(), lookup2, 0);
    142             threadsafeTestThread thread3 = new threadsafeTestThread("3",
    143                     lookup1.getHostAddress(), lookup1, 1);
    144             threadsafeTestThread thread4 = new threadsafeTestThread("4",
    145                     lookup2.getHostAddress(), lookup2, 1);
    146 
    147             // initialize the flags
    148             threadedTestSucceeded = true;
    149             synchronized (someoneDone) {
    150                 thread1.start();
    151                 thread2.start();
    152                 thread3.start();
    153                 thread4.start();
    154             }
    155             thread1.join();
    156             thread2.join();
    157             thread3.join();
    158             thread4.join();
    159             /* FIXME: comment the assertion below because it is platform/configuration dependent
    160              * Please refer to HARMONY-1664 (https://issues.apache.org/jira/browse/HARMONY-1664)
    161              * for details
    162              */
    163 //            assertTrue(threadedTestErrorString, threadedTestSucceeded);
    164         } finally {
    165             // restore the old value of the property
    166             if (originalPropertyValue == null)
    167                 // setting the property to -1 has the same effect as having the
    168                 // property be null
    169                 System.setProperty("networkaddress.cache.ttl", "-1");
    170             else
    171                 System.setProperty("networkaddress.cache.ttl",
    172                         originalPropertyValue);
    173         }
    174     }
    175 }
    176