JOGL v2.6.0-rc-20250712
JOGL, High-Performance Graphics Binding for Java™ (public API).
TestBug1211IRQ00NEWT.java
Go to the documentation of this file.
1/**
2 * Copyright 2015 JogAmp Community. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without modification, are
5 * permitted provided that the following conditions are met:
6 *
7 * 1. Redistributions of source code must retain the above copyright notice, this list of
8 * conditions and the following disclaimer.
9 *
10 * 2. Redistributions in binary form must reproduce the above copyright notice, this list
11 * of conditions and the following disclaimer in the documentation and/or other materials
12 * provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
15 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
16 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
19 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
20 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
21 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
22 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23 *
24 * The views and conclusions contained in the software and documentation are those of the
25 * authors and should not be interpreted as representing official policies, either expressed
26 * or implied, of JogAmp Community.
27 */
28
29package com.jogamp.opengl.test.junit.newt;
30
31import java.io.IOException;
32
33import org.junit.Assert;
34import org.junit.FixMethodOrder;
35import org.junit.Test;
36import org.junit.runners.MethodSorters;
37
38import com.jogamp.common.ExceptionUtils;
39import com.jogamp.common.util.InterruptSource;
40import com.jogamp.common.util.SourcedInterruptedException;
41import com.jogamp.common.util.VersionUtil;
42import com.jogamp.junit.util.SingletonJunitCase;
43import com.jogamp.newt.opengl.GLWindow;
44import com.jogamp.newt.util.EDTUtil;
45import com.jogamp.opengl.GLCapabilities;
46import com.jogamp.opengl.GLCapabilitiesImmutable;
47import com.jogamp.opengl.GLProfile;
48import com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2;
49import com.jogamp.opengl.util.Animator;
50
51/**
52 * Unit test to identify Thread.interrupt() caller for DefaultEDTUtil.invokeImpl(..) wait interruption.
53 * <ul>
54 * <li>resize</li>
55 * <li>create/destroy</li>
56 * </ul>
57 */
58@FixMethodOrder(MethodSorters.NAME_ASCENDING)
59public class TestBug1211IRQ00NEWT extends SingletonJunitCase {
60 static long durationTest00 = 1000; // ms
61 static long durationTest01 = 1000; // ms
62 static int width = 800;
63 static int height = 600;
64
65 static GLWindow createWindow(final GLCapabilitiesImmutable caps) {
66 Assert.assertNotNull(caps);
67 //
68 // Create native windowing resources .. X11/Win/OSX
69 //
70 final GLWindow glWindow = GLWindow.create(caps);
71 Assert.assertNotNull(glWindow);
72 glWindow.setSize(width, height);
73
74 glWindow.setUpdateFPSFrames(1, null);
75
76 final GearsES2 demo = new GearsES2();
77 demo.setVerbose(false);
78 glWindow.addGLEventListener(demo);
79
80 return glWindow;
81 }
82
83 static void destroyWindow(final GLWindow glWindow) throws InterruptedException {
84 if(null!=glWindow) {
85 glWindow.destroy();
86 Assert.assertEquals(false,glWindow.isNativeValid());
87 }
88 }
89
90 static class MyThread extends InterruptSource.Thread implements Thread.UncaughtExceptionHandler {
91 volatile boolean myThreadStarted = false;
92 volatile boolean myThreadStopped = false;
93
94 public MyThread(final Runnable target, final String name) {
95 super(null, target, name);
96 setUncaughtExceptionHandler(this);
97 }
98
99 public static void testInterrupted1() throws InterruptedException {
100 if( java.lang.Thread.interrupted() ) {
101 throw SourcedInterruptedException.wrap(
102 new InterruptedException(java.lang.Thread.currentThread().getName()+".testInterrupted -> TRUE (silent interruption)"));
103 }
104 }
105 public synchronized void testInterrupted(final boolean ignore) throws InterruptedException {
106 if( isInterrupted() ) {
107 final boolean current;
108 if( this == java.lang.Thread.currentThread() ) {
109 java.lang.Thread.interrupted(); // clear!
110 current = true;
111 } else {
112 current = false;
113 }
114 final int counter = getInterruptCounter(false);
115 final Throwable source = getInterruptSource(true);
116 final InterruptedException e = new SourcedInterruptedException(
117 getName()+".testInterrupted -> TRUE (current "+current+", counter "+counter+")",
118 null, source);
119 if( !ignore ) {
120 throw e;
121 } else {
122 ExceptionUtils.dumpThrowable("Ignored", e);
123 }
124 }
125 }
126
127 @Override
128 public void run() {
129 myThreadStarted = true;
130 try {
131 super.run();
132 } finally {
133 myThreadStopped = true;
134 }
135 }
136
137 @Override
138 public void uncaughtException(final java.lang.Thread t, final Throwable e) {
139 System.err.println("UncaughtException on Thread "+t.getName()+": "+e.getMessage());
140 ExceptionUtils.dumpThrowable("UncaughtException", e);
141 }
142 }
143
144
145 volatile boolean interrupt1 = false;
146 volatile boolean interrupt2 = false;
147 volatile boolean interruptInit0 = false;
148
149 public void initTest() {
150 interrupt1 = false;
151 interrupt2 = false;
152 }
153
154 /**
155 * Test whether resize triggers DefaultEDTUtil.invokeImpl(..) wait interruption.
156 */
157 public void subTest00() {
158 final MyThread t = (MyThread)Thread.currentThread();
160 Assert.assertNotNull(caps);
161 final GLWindow window1 = createWindow(caps); // local
162 final EDTUtil edt = window1.getScreen().getDisplay().getEDTUtil();
163 final Animator anim = new Animator(window1);
164 try {
165 window1.setVisible(true);
166 Assert.assertEquals(true,window1.isVisible());
167 Assert.assertEquals(true,window1.isNativeValid());
168 anim.start();
169 boolean ok = true;
170 for(int i=0; ok && i*100<durationTest00; i++) {
171 Thread.sleep(100);
172 final int ow = window1.getWidth();
173 final int oh = window1.getHeight();
174 final int nw, nh;
175 if( 0 == i % 2 ) {
176 nw = ow + 100;
177 nh = oh + 100;
178 } else {
179 nw = ow - 100;
180 nh = oh - 100;
181 }
182 System.err.println("test00.resize["+i+"]: "+ow+"x"+oh+" -> "+nw+"x"+nh);
183 window1.setSize(nw, nh);
184 ok = 0==t.getInterruptCounter(false) && !t.isInterrupted() && edt.isRunning() && anim.isAnimating();
185 t.testInterrupted(false);
186 }
187 } catch (final InterruptedException e) {
188 ExceptionUtils.dumpThrowable("InterruptedException-1", e);
189 interrupt1 = true;
190 }
191 try {
192 anim.stop();
193 destroyWindow(window1);
194 t.testInterrupted(false);
195 } catch (final InterruptedException e) {
196 ExceptionUtils.dumpThrowable("InterruptedException-2", e);
197 interrupt2 = true;
198 }
199 Assert.assertEquals("interruptCounter not zero", 0, t.getInterruptCounter(false));
200 Assert.assertFalse("interrupt() occured!", t.isInterrupted());
201 Assert.assertFalse("Interrupt-1 occured!", interrupt1);
202 Assert.assertFalse("Interrupt-2 occured!", interrupt2);
203 }
204
205 /**
206 * Test whether create/destroy triggers DefaultEDTUtil.invokeImpl(..) wait interruption.
207 */
208 public void subTest01() {
209 final MyThread t = (MyThread)Thread.currentThread();
210 GLWindow lastWindow = null;
211 try {
212 final boolean ok = true;
213 for(int i=0; ok && i*100<durationTest01; i++) {
215 Assert.assertNotNull(caps);
216 final GLWindow window1 = createWindow(caps); // local
217 lastWindow = window1;
218 window1.setVisible(true);
219 Assert.assertEquals(true,window1.isVisible());
220 Assert.assertEquals(true,window1.isNativeValid());
221 System.err.println("test01.create["+i+"]: "+window1.getStateMaskString()+", "+window1.getWidth()+"x"+window1.getHeight());
222 final Animator anim = new Animator(window1);
223 anim.start();
224 Thread.sleep(100);
225 anim.stop();
226 destroyWindow(window1);
227 t.testInterrupted(false);
228 }
229 } catch (final InterruptedException e) {
230 ExceptionUtils.dumpThrowable("InterruptedException-1", e);
231 interrupt1 = true;
232 }
233 try {
234 destroyWindow(lastWindow);
235 t.testInterrupted(false);
236 } catch (final InterruptedException e) {
237 ExceptionUtils.dumpThrowable("InterruptedException-2", e);
238 interrupt2 = true;
239 }
240 Assert.assertEquals("interruptCounter not zero", 0, t.getInterruptCounter(false));
241 Assert.assertFalse("interrupt() occured!", t.isInterrupted());
242 Assert.assertFalse("Interrupt-1 occured!", interrupt1);
243 Assert.assertFalse("Interrupt-2 occured!", interrupt2);
244 }
245
246 @Test
247 public void testAll() {
248 interruptInit0 = false;
249 final MyThread t = new MyThread(new Runnable() {
250 public void run() {
251 final MyThread t = (MyThread)Thread.currentThread();
252 TestBug1211IRQ00NEWT test = null;
253 try {
254 System.err.println(VersionUtil.getPlatformInfo());
256 test = new TestBug1211IRQ00NEWT();
257 t.testInterrupted(false);
258 } catch (final InterruptedException e) {
259 ExceptionUtils.dumpThrowable("InterruptedException-Init0", e);
260 interruptInit0 = true;
261 test = null;
262 }
263 t.clearInterruptSource();
264 if( null != test ) {
265 test.initTest();
266 test.subTest00();
267
268 test.initTest();
269 test.subTest01();
270 }
271 }
272 }, "MyMainThread");
273 t.start();
274 boolean interrupted = false;
275 try {
276 MyThread.testInterrupted1();
277 while( !t.myThreadStarted ) {
278 Thread.yield();
279 MyThread.testInterrupted1();
280 }
281 while( !t.myThreadStopped ) {
282 Thread.yield();
283 MyThread.testInterrupted1();
284 }
285 MyThread.testInterrupted1();
286 } catch (final InterruptedException e) {
287 ExceptionUtils.dumpThrowable("InterruptedException-All", e);
288 interrupted = true;
289 }
290 Assert.assertFalse("Thread Interrupt-All occured!", interrupted);
291 Assert.assertFalse("Interrupt-Init0 occured!", interruptInit0);
292 }
293
294 static int atoi(final String a) {
295 int i=0;
296 try {
297 i = Integer.parseInt(a);
298 } catch (final Exception ex) { ex.printStackTrace(); }
299 return i;
300 }
301
302 public static void main(final String args[]) throws IOException {
303 // We like to allow concurrent manual tests!
304 SingletonJunitCase.enableSingletonLock(false);
305
306 for(int i=0; i<args.length; i++) {
307 if(args[i].equals("-time00")) {
308 durationTest00 = atoi(args[++i]);
309 } else if(args[i].equals("-time01")) {
310 durationTest01 = atoi(args[++i]);
311 } else if(args[i].equals("-width")) {
312 width = atoi(args[++i]);
313 } else if(args[i].equals("-height")) {
314 height = atoi(args[++i]);
315 }
316 }
317 System.out.println("durationTest00: "+durationTest00);
318 System.out.println("durationTest01: "+durationTest01);
319 System.out.println("defaultSize : "+width+"x"+height);
320 final String tstname = TestBug1211IRQ00NEWT.class.getName();
321 org.junit.runner.JUnitCore.main(tstname);
322 }
323
324}
abstract EDTUtil getEDTUtil()
abstract Display getDisplay()
An implementation of GLAutoDrawable and Window interface, using a delegated Window instance,...
Definition: GLWindow.java:121
final String getStateMaskString()
Returns a string representation of the current state mask.
Definition: GLWindow.java:246
final void setSize(final int width, final int height)
Sets the size of the window's client area in window units, excluding decorations.
Definition: GLWindow.java:625
final void setVisible(final boolean visible)
Calls setVisible(true, visible), i.e.
Definition: GLWindow.java:615
final int getHeight()
Returns the height of the client area excluding insets (window decorations) in window units.
Definition: GLWindow.java:451
final void destroy()
Destroys all resources associated with this GLAutoDrawable, inclusive the GLContext.
Definition: GLWindow.java:605
final int getWidth()
Returns the width of the client area excluding insets (window decorations) in window units.
Definition: GLWindow.java:446
static GLWindow create(final GLCapabilitiesImmutable caps)
Creates a new GLWindow attaching a new Window referencing a new default Screen and default Display wi...
Definition: GLWindow.java:169
Specifies a set of OpenGL capabilities.
Specifies the the OpenGL profile.
Definition: GLProfile.java:77
static GLProfile getDefault(final AbstractGraphicsDevice device)
Returns a default GLProfile object, reflecting the best for the running platform.
Definition: GLProfile.java:739
static void initSingleton()
Static initialization of JOGL.
Definition: GLProfile.java:204
Unit test to identify Thread.interrupt() caller for DefaultEDTUtil.invokeImpl(..) wait interruption.
void subTest00()
Test whether resize triggers DefaultEDTUtil.invokeImpl(..) wait interruption.
void subTest01()
Test whether create/destroy triggers DefaultEDTUtil.invokeImpl(..) wait interruption.
final synchronized boolean start()
Starts this animator, if not running.
Definition: Animator.java:344
final synchronized boolean stop()
Stops this animator.
Definition: Animator.java:368
EDT stands for Event Dispatch Thread.
Definition: EDTUtil.java:53
void setUpdateFPSFrames(int frames, PrintStream out)
void addGLEventListener(GLEventListener listener)
Adds the given listener to the end of this drawable queue.
Specifies an immutable set of OpenGL capabilities.