1 /*
   2  * Copyright (c) 2007, 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 6541903
  27   @summary Tests if the realSync() throws the IllegalThreadException while invoked on the EDT
  28   @author anthony.petrov: area=awt.toolkit
  29   @modules java.desktop/sun.awt
  30   @run main/timeout=10 RealSyncOnEDT
  31 */
  32 
  33 
  34 /**
  35  * RealSyncOnEDT.java
  36  *
  37  * summary: Tests if the realSync() throws the IllegalThreadException while invoked on the EDT
  38  */
  39 
  40 import java.awt.*;
  41 import java.awt.event.*;
  42 
  43 
  44 public class RealSyncOnEDT
  45 {
  46     static Exception exceptionCaught = null;
  47 
  48     private static void init()
  49     {
  50         String[] instructions =
  51         {
  52             "This is an AUTOMATIC test, simply wait until it is done.",
  53             "The result (passed or failed) will be shown in the",
  54             "message window below."
  55         };
  56         Sysout.createDialog( );
  57         Sysout.printInstructions( instructions );
  58 
  59 
  60         // Try to invoke the realSync() on the EDT
  61         try {
  62             EventQueue.invokeAndWait(new Runnable() {
  63                 public void run() {
  64                     Frame frame = new Frame("Test frame");
  65 
  66                     frame.setSize(100, 100);
  67                     frame.setVisible(true);
  68 
  69                     try {
  70                         ((sun.awt.SunToolkit)java.awt.Toolkit.getDefaultToolkit()).realSync();
  71                     } catch (Exception e) {
  72                         exceptionCaught = e;
  73                     }
  74                 }
  75             });
  76         } catch (InterruptedException e) {
  77             e.printStackTrace();
  78             fail("Unexpected exception caught: " + e);
  79             return;
  80         } catch (java.lang.reflect.InvocationTargetException e) {
  81             e.printStackTrace();
  82             fail("Unexpected exception caught: " + e);
  83             return;
  84         }
  85 
  86         // We expect the IllegalThreadException to be thrown.
  87         if (exceptionCaught == null) {
  88             fail("No exception was thrown by the realSync() method.");
  89             return;
  90         } else if (!exceptionCaught.getClass().getName().equals("sun.awt.SunToolkit$IllegalThreadException")) {
  91             exceptionCaught.printStackTrace();
  92             fail("Unexpected exception caught while invoking the realSync(): " + exceptionCaught);
  93             return;
  94         }
  95         pass();
  96 
  97     }//End  init()
  98 
  99 
 100 
 101     /*****************************************************
 102      * Standard Test Machinery Section
 103      * DO NOT modify anything in this section -- it's a
 104      * standard chunk of code which has all of the
 105      * synchronisation necessary for the test harness.
 106      * By keeping it the same in all tests, it is easier
 107      * to read and understand someone else's test, as
 108      * well as insuring that all tests behave correctly
 109      * with the test harness.
 110      * There is a section following this for test-
 111      * classes
 112      ******************************************************/
 113     private static boolean theTestPassed = false;
 114     private static boolean testGeneratedInterrupt = false;
 115     private static String failureMessage = "";
 116 
 117     private static Thread mainThread = null;
 118 
 119     private static int sleepTime = 300000;
 120 
 121     // Not sure about what happens if multiple of this test are
 122     //  instantiated in the same VM.  Being static (and using
 123     //  static vars), it aint gonna work.  Not worrying about
 124     //  it for now.
 125     public static void main( String args[] ) throws InterruptedException
 126     {
 127         mainThread = Thread.currentThread();
 128         try
 129         {
 130             init();
 131         }
 132         catch( TestPassedException e )
 133         {
 134             //The test passed, so just return from main and harness will
 135             // interepret this return as a pass
 136             return;
 137         }
 138         //At this point, neither test pass nor test fail has been
 139         // called -- either would have thrown an exception and ended the
 140         // test, so we know we have multiple threads.
 141 
 142         //Test involves other threads, so sleep and wait for them to
 143         // called pass() or fail()
 144         try
 145         {
 146             Thread.sleep( sleepTime );
 147             //Timed out, so fail the test
 148             throw new RuntimeException( "Timed out after " + sleepTime/1000 + " seconds" );
 149         }
 150         catch (InterruptedException e)
 151         {
 152             //The test harness may have interrupted the test.  If so, rethrow the exception
 153             // so that the harness gets it and deals with it.
 154             if( ! testGeneratedInterrupt ) throw e;
 155 
 156             //reset flag in case hit this code more than once for some reason (just safety)
 157             testGeneratedInterrupt = false;
 158 
 159             if ( theTestPassed == false )
 160             {
 161                 throw new RuntimeException( failureMessage );
 162             }
 163         }
 164 
 165     }//main
 166 
 167     public static synchronized void setTimeoutTo( int seconds )
 168     {
 169         sleepTime = seconds * 1000;
 170     }
 171 
 172     public static synchronized void pass()
 173     {
 174         Sysout.println( "The test passed." );
 175         Sysout.println( "The test is over, hit  Ctl-C to stop Java VM" );
 176         //first check if this is executing in main thread
 177         if ( mainThread == Thread.currentThread() )
 178         {
 179             //Still in the main thread, so set the flag just for kicks,
 180             // and throw a test passed exception which will be caught
 181             // and end the test.
 182             theTestPassed = true;
 183             throw new TestPassedException();
 184         }
 185         theTestPassed = true;
 186         testGeneratedInterrupt = true;
 187         mainThread.interrupt();
 188     }//pass()
 189 
 190     public static synchronized void fail()
 191     {
 192         //test writer didn't specify why test failed, so give generic
 193         fail( "it just plain failed! :-)" );
 194     }
 195 
 196     public static synchronized void fail( String whyFailed )
 197     {
 198         Sysout.println( "The test failed: " + whyFailed );
 199         Sysout.println( "The test is over, hit  Ctl-C to stop Java VM" );
 200         //check if this called from main thread
 201         if ( mainThread == Thread.currentThread() )
 202         {
 203             //If main thread, fail now 'cause not sleeping
 204             throw new RuntimeException( whyFailed );
 205         }
 206         theTestPassed = false;
 207         testGeneratedInterrupt = true;
 208         failureMessage = whyFailed;
 209         mainThread.interrupt();
 210     }//fail()
 211 
 212 }// class RealSyncOnEDT
 213 
 214 //This exception is used to exit from any level of call nesting
 215 // when it's determined that the test has passed, and immediately
 216 // end the test.
 217 class TestPassedException extends RuntimeException
 218 {
 219 }
 220 
 221 //*********** End Standard Test Machinery Section **********
 222 
 223 
 224 //************ Begin classes defined for the test ****************
 225 
 226 // if want to make listeners, here is the recommended place for them, then instantiate
 227 //  them in init()
 228 
 229 /* Example of a class which may be written as part of a test
 230 class NewClass implements anInterface
 231  {
 232    static int newVar = 0;
 233 
 234    public void eventDispatched(AWTEvent e)
 235     {
 236       //Counting events to see if we get enough
 237       eventCount++;
 238 
 239       if( eventCount == 20 )
 240        {
 241          //got enough events, so pass
 242 
 243          RealSyncOnEDT.pass();
 244        }
 245       else if( tries == 20 )
 246        {
 247          //tried too many times without getting enough events so fail
 248 
 249          RealSyncOnEDT.fail();
 250        }
 251 
 252     }// eventDispatched()
 253 
 254  }// NewClass class
 255 
 256 */
 257 
 258 
 259 //************** End classes defined for the test *******************
 260 
 261 
 262 
 263 
 264 /****************************************************
 265  Standard Test Machinery
 266  DO NOT modify anything below -- it's a standard
 267   chunk of code whose purpose is to make user
 268   interaction uniform, and thereby make it simpler
 269   to read and understand someone else's test.
 270  ****************************************************/
 271 
 272 /**
 273  This is part of the standard test machinery.
 274  It creates a dialog (with the instructions), and is the interface
 275   for sending text messages to the user.
 276  To print the instructions, send an array of strings to Sysout.createDialog
 277   WithInstructions method.  Put one line of instructions per array entry.
 278  To display a message for the tester to see, simply call Sysout.println
 279   with the string to be displayed.
 280  This mimics System.out.println but works within the test harness as well
 281   as standalone.
 282  */
 283 
 284 class Sysout
 285 {
 286     private static TestDialog dialog;
 287 
 288     public static void createDialogWithInstructions( String[] instructions )
 289     {
 290         dialog = new TestDialog( new Frame(), "Instructions" );
 291         dialog.printInstructions( instructions );
 292         dialog.setVisible(true);
 293         println( "Any messages for the tester will display here." );
 294     }
 295 
 296     public static void createDialog( )
 297     {
 298         dialog = new TestDialog( new Frame(), "Instructions" );
 299         String[] defInstr = { "Instructions will appear here. ", "" } ;
 300         dialog.printInstructions( defInstr );
 301         dialog.setVisible(true);
 302         println( "Any messages for the tester will display here." );
 303     }
 304 
 305 
 306     public static void printInstructions( String[] instructions )
 307     {
 308         dialog.printInstructions( instructions );
 309     }
 310 
 311 
 312     public static void println( String messageIn )
 313     {
 314         dialog.displayMessage( messageIn );
 315         System.out.println(messageIn);
 316     }
 317 
 318 }// Sysout  class
 319 
 320 /**
 321   This is part of the standard test machinery.  It provides a place for the
 322    test instructions to be displayed, and a place for interactive messages
 323    to the user to be displayed.
 324   To have the test instructions displayed, see Sysout.
 325   To have a message to the user be displayed, see Sysout.
 326   Do not call anything in this dialog directly.
 327   */
 328 class TestDialog extends Dialog
 329 {
 330 
 331     TextArea instructionsText;
 332     TextArea messageText;
 333     int maxStringLength = 80;
 334 
 335     //DO NOT call this directly, go through Sysout
 336     public TestDialog( Frame frame, String name )
 337     {
 338         super( frame, name );
 339         int scrollBoth = TextArea.SCROLLBARS_BOTH;
 340         instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth );
 341         add( "North", instructionsText );
 342 
 343         messageText = new TextArea( "", 5, maxStringLength, scrollBoth );
 344         add("Center", messageText);
 345 
 346         pack();
 347 
 348         setVisible(true);
 349     }// TestDialog()
 350 
 351     //DO NOT call this directly, go through Sysout
 352     public void printInstructions( String[] instructions )
 353     {
 354         //Clear out any current instructions
 355         instructionsText.setText( "" );
 356 
 357         //Go down array of instruction strings
 358 
 359         String printStr, remainingStr;
 360         for( int i=0; i < instructions.length; i++ )
 361         {
 362             //chop up each into pieces maxSringLength long
 363             remainingStr = instructions[ i ];
 364             while( remainingStr.length() > 0 )
 365             {
 366                 //if longer than max then chop off first max chars to print
 367                 if( remainingStr.length() >= maxStringLength )
 368                 {
 369                     //Try to chop on a word boundary
 370                     int posOfSpace = remainingStr.
 371                         lastIndexOf( ' ', maxStringLength - 1 );
 372 
 373                     if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1;
 374 
 375                     printStr = remainingStr.substring( 0, posOfSpace + 1 );
 376                     remainingStr = remainingStr.substring( posOfSpace + 1 );
 377                 }
 378                 //else just print
 379                 else
 380                 {
 381                     printStr = remainingStr;
 382                     remainingStr = "";
 383                 }
 384 
 385                 instructionsText.append( printStr + "\n" );
 386 
 387             }// while
 388 
 389         }// for
 390 
 391     }//printInstructions()
 392 
 393     //DO NOT call this directly, go through Sysout
 394     public void displayMessage( String messageIn )
 395     {
 396         messageText.append( messageIn + "\n" );
 397         System.out.println(messageIn);
 398     }
 399 
 400 }// TestDialog  class