001/* WatchDog timer for tests 002 003 @Copyright (c) 2003-2017 The Regents of the University of California. 004 All rights reserved. 005 006 Permission is hereby granted, without written agreement and without 007 license or royalty fees, to use, copy, modify, and distribute this 008 software and its documentation for any purpose, provided that the 009 above copyright notice and the following two paragraphs appear in all 010 copies of this software. 011 012 IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY 013 FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 014 ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF 015 THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF 016 SUCH DAMAGE. 017 018 THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, 019 INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 020 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE 021 PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF 022 CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, 023 ENHANCEMENTS, OR MODIFICATIONS. 024 025 PT_COPYRIGHT_VERSION_2 026 COPYRIGHTENDKEY 027 028 */ 029package ptolemy.util.test; 030 031import java.util.Date; 032import java.util.Timer; 033import java.util.TimerTask; 034 035import ptolemy.util.StringUtilities; 036 037////////////////////////////////////////////////////////////////////////// 038//// WatchDog 039 040/** This class creates a Timer that calls System.exit() after 041 a certain amount of time. 042 043 @author Christopher Hylands 044 @version $Id$ 045 @since Ptolemy II 10.0 046 @Pt.ProposedRating Red (cxh) 047 @Pt.AcceptedRating Red (cxh) 048 */ 049public class WatchDog { 050 /** Create a timer that will go off after timeToDie milliseconds. 051 * @param timeToDie The time in millesconds when the timer will 052 * go off. 053 */ 054 public WatchDog(final long timeToDie) { 055 // Timers are new in JDK1.3 056 // For information about Timers, see 057 // http://download.oracle.com/javase/tutorial/uiswing/misc/timer.html 058 if (timeToDie <= 0) { 059 return; 060 } 061 062 TimerTask doTimeToDie = new TimerTask() { 063 @Override 064 public void run() { 065 try { 066 System.err.println("*** ptolemy.util.test.WatchDog went " 067 + "off after " + timeToDie + "ms. " 068 + new Date().toString()); 069 070 // Get the root ThreadGroup 071 ThreadGroup parent; 072 073 // Get the root ThreadGroup 074 ThreadGroup rootGroup; 075 076 parent = Thread.currentThread().getThreadGroup(); 077 078 do { 079 rootGroup = parent; 080 parent = parent.getParent(); 081 } while (parent != null); 082 083 // Display all the threads 084 Thread[] threads = new Thread[rootGroup.activeCount()]; 085 rootGroup.enumerate(threads); 086 087 for (int i = 0; i < threads.length; i++) { 088 System.err.println(i + ". " + threads[i]); 089 090 // It would be nice to display the stack traces, 091 // but this is hard to do. Thread.dumpStack() 092 // only dumps the stack trace for the current thread. 093 // For an idea using Thread.stop(), see 094 // http://forum.java.sun.com/thread.jsp?forum=4&thread=178641&start=15&range=15&hilite=false&q= 095 } 096 } catch (Exception e) { 097 System.err.println(e); 098 } finally { 099 System.out.println("ptolemy.util.test.WatchDog went off"); 100 watchDogWentOff = true; 101 102 if (_exitOnTimeOut) { 103 String userDir = ""; 104 try { 105 userDir = System.getProperty("user.dir"); 106 } catch (Exception ex) { 107 // ignore 108 userDir = "ptolemy.util.test.WatchDog went off"; 109 } 110 System.out.println("The string below is so that " 111 + "the nightly build will notice\n" 112 + "Failed: 666 Total Tests: 0 " 113 + "((Passed: 0, Newly Passed: 0) " 114 + "Known Failed: 0) " + userDir); 115 116 // Do not pass go, do not collect $200 117 StringUtilities.exit(4); 118 } 119 } 120 } 121 }; 122 123 if (_timer == null) { 124 // Create the timer as a Daemon.. This way it won't prevent 125 // the compiler from exiting if an exception occurs. 126 _timer = new Timer(true); 127 } 128 129 _timer.schedule(doTimeToDie, timeToDie); 130 } 131 132 /** Cancel the currently pending watchdog. 133 */ 134 public void cancel() { 135 System.out.println( 136 "ptolemy.util.test.WatchDog.cancel(): canceling " + new Date()); 137 138 if (_timer == null) { 139 System.out.println("ptolemy.util.test.WatchDog.cancel(): " 140 + "Warning: cancel called twice?"); 141 } else { 142 _timer.cancel(); 143 _timer = null; 144 } 145 } 146 147 /** Determine whether the JVM will exit when the time interval 148 * has passed. This method is used for testing this class. 149 * @param exitOnTimeOut True if the JVM will exit when 150 * the time interval has passed. 151 */ 152 public void setExitOnTimeOut(boolean exitOnTimeOut) { 153 _exitOnTimeOut = exitOnTimeOut; 154 } 155 156 /** Set to true if the watch time timer interval has passed. 157 * Used primarily for testing. 158 */ 159 public boolean watchDogWentOff = false; 160 161 private Timer _timer = null; 162 163 // If true, then exit if the interval passes 164 private boolean _exitOnTimeOut = true; 165}