diff options
author | Sven Gothel <[email protected]> | 2013-11-26 20:08:42 +0100 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2013-11-26 20:08:42 +0100 |
commit | 9310b11b2b6e1e89fa5ed9b8de26e56ff6a6b262 (patch) | |
tree | aec13af08d7cd3d97c468786b761ff74c8c00c6c /src | |
parent | 1617b3edfa006432dbb7332c283e219e6583f4ec (diff) |
Bug 910: Add Standalone Extended Applet Lifecycle Validation Test
Test is online @ http://jogamp.org/deployment/test/bug910/
Test validates the state of the added component:
TC1 - addNotify() and removeNotify() has been called from AWT-EDT.
TC2 - removeNotify() is not called before Applet.destroy()
Test also validates the Applet state:
TA1 - isActive()
TA2 - init count
TA3 - start count
TA4 - stop count
TA5 - destroy count
Diffstat (limited to 'src')
-rw-r--r-- | src/test/com/jogamp/opengl/test/bugs/DemoBug910ExtendedAWTAppletLifecycleCheck.java | 224 |
1 files changed, 224 insertions, 0 deletions
diff --git a/src/test/com/jogamp/opengl/test/bugs/DemoBug910ExtendedAWTAppletLifecycleCheck.java b/src/test/com/jogamp/opengl/test/bugs/DemoBug910ExtendedAWTAppletLifecycleCheck.java new file mode 100644 index 000000000..62891cc3c --- /dev/null +++ b/src/test/com/jogamp/opengl/test/bugs/DemoBug910ExtendedAWTAppletLifecycleCheck.java @@ -0,0 +1,224 @@ +/** + * Copyright 2013 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ +package com.jogamp.opengl.test.bugs; + +import java.applet.Applet; +import java.awt.BorderLayout; +import java.awt.Canvas; +import java.awt.Color; +import java.awt.Component; +import java.awt.EventQueue; +import java.awt.Graphics; +import java.lang.reflect.InvocationTargetException; + +@SuppressWarnings("serial") +public class DemoBug910ExtendedAWTAppletLifecycleCheck extends Applet { + + private static String currentThreadName() { return "["+Thread.currentThread().getName()+", isAWT-EDT "+EventQueue.isDispatchThread()+"]"; } + + private static void invoke(boolean wait, Runnable r) { + if(EventQueue.isDispatchThread()) { + r.run(); + } else { + try { + if(wait) { + EventQueue.invokeAndWait(r); + } else { + EventQueue.invokeLater(r); + } + } catch (InvocationTargetException e) { + throw new RuntimeException(e.getTargetException()); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + } + } + + private static final String comp2Str(Component c) { + return c.getClass().getSimpleName()+"[visible "+c.isVisible()+", showing "+c.isShowing()+", valid "+c.isValid()+ + ", displayable "+c.isDisplayable()+", "+c.getX()+"/"+c.getY()+" "+c.getWidth()+"x"+c.getHeight()+"]"; + } + + private void println(String msg) { + System.err.println(msg); + } + + private final void checkComponentState(String msg, boolean expIsContained, int expAddNotifyCount, int expRemoveNotifyCount) { + final int compCount = getComponentCount(); + final Component c = 1 <= compCount ? getComponent(0) : null; + final String clazzName = null != c ? c.getName() : "n/a"; + final boolean isContained = c == myCanvas; + final String okS = ( expIsContained == isContained && + expAddNotifyCount == myCanvas.addNotifyCount && + expRemoveNotifyCount == myCanvas.removeNotifyCount ) ? "OK" : "ERROR"; + println("Component-State @ "+msg+": "+okS+ + ", contained[exp "+expIsContained+", has "+isContained+"]"+(expIsContained!=isContained?"*":"")+ + ", addNotify[exp "+expAddNotifyCount+", has "+myCanvas.addNotifyCount+"]"+(expAddNotifyCount!=myCanvas.addNotifyCount?"*":"")+ + ", removeNotify[exp "+expRemoveNotifyCount+", has "+myCanvas.removeNotifyCount+"]"+(expRemoveNotifyCount!=myCanvas.removeNotifyCount?"*":"")+ + ", compCount "+compCount+", compClazz "+clazzName); + } + + volatile int initCount = 0; + volatile int startCount = 0; + volatile int stopCount = 0; + volatile int destroyCount = 0; + + private final void checkAppletState(String msg, boolean expIsActive, + int expInitCount, int expStartCount, int expStopCount, int expDestroyCount) { + final boolean isActive = this.isActive(); + final String okS = ( expInitCount == initCount && + expIsActive == isActive && + expStartCount == startCount && + expStopCount == stopCount && + expDestroyCount == destroyCount ) ? "OK" : "ERROR"; + println("Applet-State @ "+msg+": "+okS+ + ", active[exp "+expIsActive+", has "+isActive+"]"+(expIsActive!=isActive?"*":"")+ + ", init[exp "+expInitCount+", has "+initCount+"]"+(expInitCount!=initCount?"*":"")+ + ", start[exp "+expStartCount+", has "+startCount+"]"+(expStartCount!=startCount?"*":"")+ + ", stop[exp "+expStopCount+", has "+stopCount+"]"+(expStopCount!=stopCount?"*":"")+ + ", destroy[exp "+expDestroyCount+", has "+destroyCount+"]"+(expDestroyCount!=destroyCount?"*":"")); + } + + private class MyCanvas extends Canvas { + int addNotifyCount = 0; + int removeNotifyCount = 0; + int paintCount = 0; + + MyCanvas() { + setBackground( new Color( 200, 200, 255 ) ); + } + + public String toString() { + return comp2Str(this)+", add/remove[addNotify "+addNotifyCount+", removeCount "+removeNotifyCount+"]"; + } + + @Override + public void addNotify() { + addNotifyCount++; + println("Applet.Canvas.addNotify() - "+currentThreadName()); + if( !EventQueue.isDispatchThread() ) { + println("Applet.Canvas.addNotify() ERROR: Not on AWT-EDT"); + } + // Thread.dumpStack(); + super.addNotify(); + println("Applet.Canvas.addNotify(): "+this); + } + + @Override + public void removeNotify() { + removeNotifyCount++; + println("Applet.Canvas.removeNotify() - "+currentThreadName()); + println("Applet.Canvas.removeNotify(): "+this); + if( !EventQueue.isDispatchThread() ) { + println("Applet.Canvas.removeNotify() ERROR: Not on AWT-EDT"); + } + // Thread.dumpStack(); + super.removeNotify(); + } + + @Override + public void paint(Graphics g) { + super.paint(g); + paintCount++; + final int width = getWidth(); + final int height = getHeight(); + final String msg = "The payload Canvas. Paint "+width+"x"+height+" #"+paintCount; + g.setColor(Color.black); + g.drawString(msg, 64, 64); + } + } + MyCanvas myCanvas = null; + + @Override + public void init() { + final java.awt.Dimension aSize = getSize(); + println("Applet.init() START - applet.size "+aSize+" - "+currentThreadName()); + initCount++; + checkAppletState("init", false /* expIsActive */, 1 /* expInitCount */, 0 /* expStartCount */, 0 /* expStopCount */, 0 /* expDestroyCount */); + invoke(true, new Runnable() { + public void run() { + setLayout(new BorderLayout()); + myCanvas = new MyCanvas(); + println("Applet.init(): self "+comp2Str(DemoBug910ExtendedAWTAppletLifecycleCheck.this)); + println("Applet.init(): canvas "+comp2Str(myCanvas)); + checkComponentState("init-add.pre", false, 0, 0); + add(myCanvas, BorderLayout.CENTER); + validate(); + checkComponentState("init-add.post", true, 1, 0); + println("Applet.init(): canvas "+comp2Str(myCanvas)); + } } ); + println("Applet.init() END - "+currentThreadName()); + } + + @Override + public void start() { + println("Applet.start() START (isVisible "+isVisible()+", isDisplayable "+isDisplayable()+") - "+currentThreadName()); + startCount++; + checkAppletState("start", true /* expIsActive */, 1 /* expInitCount */, startCount /* expStartCount */, stopCount /* expStopCount */, 0 /* expDestroyCount */); + invoke(true, new Runnable() { + public void run() { + checkComponentState("start-visible.pre", true, 1, 0); + if( null != myCanvas ) { + myCanvas.setFocusable(true); + myCanvas.requestFocus(); + } + checkComponentState("start-visible.post", true, 1, 0); + println("Applet.start(): self "+comp2Str(DemoBug910ExtendedAWTAppletLifecycleCheck.this)); + println("Applet.start(): canvas "+comp2Str(myCanvas)); + } + }); + println("Applet.start() END - "+currentThreadName()); + } + + @Override + public void stop() { + println("Applet.stop() START - "+currentThreadName()); + stopCount++; + checkAppletState("stop", false /* expIsActive */, 1 /* expInitCount */, stopCount /* expStartCount */, stopCount /* expStopCount */, 0 /* expDestroyCount */); + invoke(true, new Runnable() { + public void run() { + checkComponentState("stop", true, 1, 0); + } } ); + println("Applet.stop() END - "+currentThreadName()); + } + + @Override + public void destroy() { + println("Applet.destroy() START - "+currentThreadName()); + destroyCount++; + checkAppletState("destroy", false /* expIsActive */, 1 /* expInitCount */, startCount /* expStartCount */, stopCount /* expStopCount */, 1 /* expDestroyCount */); + invoke(true, new Runnable() { + public void run() { + checkComponentState("destroy-remove.pre", true, 1, 0); + remove(myCanvas); + checkComponentState("destroy-remove.post", false, 1, 1); + } } ); + println("Applet.destroy() END - "+currentThreadName()); + } +} + |