1 /*
   2  * Copyright (c) 2004, 2015, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 /*
  25  * @test
  26  * @bug 6192124
  27  * @summary Tests that you can turn off the server connection timeout thread
  28  * @author Eamonn McManus
  29  * @modules java.management
  30  * @run clean NoServerTimeoutTest
  31  * @run build NoServerTimeoutTest
  32  * @run main NoServerTimeoutTest
  33  */
  34 
  35 import java.lang.management.*;
  36 import java.net.MalformedURLException;
  37 import java.util.*;
  38 import javax.management.*;
  39 import javax.management.remote.*;
  40 
  41 public class NoServerTimeoutTest {
  42     public static void main(String[] args) throws Exception {
  43         boolean ok = true;
  44 
  45         for (String proto : new String[] {"rmi", "iiop", "jmxmp"}) {
  46             JMXServiceURL url = new JMXServiceURL(proto, null, 0);
  47             try {
  48                 MBeanServer mbs = MBeanServerFactory.newMBeanServer();
  49                 // Create server just to see if the protocol is supported
  50                 JMXConnectorServerFactory.newJMXConnectorServer(url,
  51                                                                 null,
  52                                                                 mbs);
  53             } catch (MalformedURLException e) {
  54                 System.out.println();
  55                 System.out.println("Ignoring protocol: " + proto);
  56                 continue;
  57             }
  58             try {
  59                 ok &= test(url);
  60             } catch (Exception e) {
  61                 System.out.println("TEST FAILED WITH EXCEPTION:");
  62                 e.printStackTrace();
  63                 ok = false;
  64             }
  65         }
  66 
  67         System.out.println();
  68         if (ok)
  69             System.out.println("Test passed");
  70         else
  71             throw new Exception("Test failed");
  72     }
  73 
  74     private static enum Test {
  75         NO_ENV("No Map for connector server"),
  76         EMPTY_ENV("Empty Map for connector server"),
  77         PLAIN_TIMEOUT("Map with two-minute timeout as int"),
  78         PLAIN_STRING_TIMEOUT("Map with two-minute timeout as string"),
  79         INFINITE_TIMEOUT("Map with Long.MAX_VALUE timeout as long"),
  80         INFINITE_STRING_TIMEOUT("Map with Long.MAX_VALUE timeout as string");
  81 
  82         Test(String description) {
  83             this.description = description;
  84         }
  85 
  86         public String toString() {
  87             return description;
  88         }
  89 
  90         private final String description;
  91     }
  92     // define which tests should see a timeout thread
  93     private static final Set<Test> expectThread =
  94         EnumSet.copyOf(Arrays.asList(Test.NO_ENV,
  95                                      Test.EMPTY_ENV,
  96                                      Test.PLAIN_TIMEOUT,
  97                                      Test.PLAIN_STRING_TIMEOUT));
  98 
  99     private static boolean test(JMXServiceURL url) throws Exception {
 100         System.out.println();
 101         System.out.println("Test: " + url);
 102 
 103         boolean ok = true;
 104 
 105         for (Test test : Test.values())
 106             ok &= test(url, test);
 107 
 108         return ok;
 109     }
 110 
 111     private static final String TIMEOUT =
 112         "jmx.remote.x.server.connection.timeout";
 113 
 114     private static boolean test(JMXServiceURL url, Test test)
 115             throws Exception {
 116 
 117         System.out.println("* " + test);
 118 
 119         MBeanServer mbs = MBeanServerFactory.newMBeanServer();
 120         Map<String, Object> env = new HashMap<String, Object>();
 121         switch (test) {
 122         case NO_ENV: env = null; break;
 123         case EMPTY_ENV: break;
 124         case PLAIN_TIMEOUT: env.put(TIMEOUT, 120 * 1000L); break;
 125         case PLAIN_STRING_TIMEOUT: env.put(TIMEOUT, (120 * 1000L) + ""); break;
 126         case INFINITE_TIMEOUT: env.put(TIMEOUT, Long.MAX_VALUE); break;
 127         case INFINITE_STRING_TIMEOUT: env.put(TIMEOUT, "" + Long.MAX_VALUE);
 128             break;
 129         default: throw new AssertionError();
 130         }
 131 
 132         // In case there's a timeout thread left over from a previous run
 133         for (int i = 0; i < 10 && countTimeoutThreads() > 0; i++)
 134             Thread.sleep(500);
 135         if (countTimeoutThreads() > 0) {
 136             System.out.println("TIMEOUT THREAD(S) WOULD NOT GO AWAY");
 137             return false;
 138         }
 139 
 140         JMXConnectorServer cs =
 141             JMXConnectorServerFactory.newJMXConnectorServer(url, env, mbs);
 142         cs.start();
 143         JMXServiceURL addr = cs.getAddress();
 144         JMXConnector cc = JMXConnectorFactory.connect(addr);
 145         MBeanServerConnection mbsc = cc.getMBeanServerConnection();
 146         mbsc.getDefaultDomain();
 147         int expectTimeoutThreads = expectThread.contains(test) ? 1 : 0;
 148         int timeoutThreads = countTimeoutThreads();
 149         boolean ok = (expectTimeoutThreads == timeoutThreads);
 150         if (!ok) {
 151             System.out.println("TEST FAILS: Expected timeout threads: " +
 152                                expectTimeoutThreads +
 153                                "; actual timeout threads: " + timeoutThreads);
 154             ok = false;
 155         }
 156         cc.close();
 157         cs.stop();
 158         return ok;
 159     }
 160 
 161     private static int countTimeoutThreads() {
 162         ThreadMXBean mb = ManagementFactory.getThreadMXBean();
 163         int count = 0;
 164         long[] ids = mb.getAllThreadIds();
 165         for (ThreadInfo ti : mb.getThreadInfo(ids)) {
 166             if (ti != null &&
 167                 ti.getThreadName().startsWith("JMX server connection timeout"))
 168                 count++;
 169         }
 170         return count;
 171     }
 172 }