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