blob: 3e2ee818bb3ebfd237b879cc21f9ff47be69b0b9 [file] [log] [blame]
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.netbeans.modules.progress.ui;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Frame;
import java.awt.GraphicsEnvironment;
import java.awt.Image;
import java.awt.RenderingHints;
import java.awt.Toolkit;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.beans.PropertyChangeListener;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Future;
import java.util.concurrent.atomic.AtomicBoolean;
import javax.swing.Action;
import javax.swing.JFrame;
import junit.framework.AssertionFailedError;
import junit.framework.Test;
import junit.framework.TestSuite;
import org.netbeans.api.progress.ProgressHandle;
import org.openide.nodes.Node;
import org.openide.util.Exceptions;
import org.openide.windows.Mode;
import org.openide.windows.TopComponent;
import org.openide.windows.TopComponentGroup;
import org.openide.windows.WindowManager;
import org.netbeans.api.progress.ProgressHandleFactory;
import org.netbeans.api.progress.ProgressRunnable;
import org.netbeans.api.progress.ProgressUtils;
import org.netbeans.junit.MockServices;
import org.netbeans.junit.NbTestCase;
import org.openide.util.Lookup;
import org.openide.util.RequestProcessor;
import org.openide.windows.Workspace;
/**
*
* @author Tim Boudreau
*/
public class RunOffEDTImplTest extends NbTestCase {
public static Test suite() {
return GraphicsEnvironment.isHeadless() ? new TestSuite() : new TestSuite(RunOffEDTImplTest.class);
}
public RunOffEDTImplTest(String name) {
super(name);
}
public void setUp() {
MockServices.setServices(WM.class, RunOffEDTImpl.class);
}
private static boolean canTestGlassPane() {
Map<?,?> hintsMap = (Map)(Toolkit.getDefaultToolkit().getDesktopProperty("awt.font.desktophints")); //NOI18N
//Avoid translucent painting on, for example, remote X terminal
return hintsMap == null || !RenderingHints.VALUE_TEXT_ANTIALIAS_OFF.equals(hintsMap.get(RenderingHints.KEY_TEXT_ANTIALIASING));
}
public void testShowProgressDialogAndRun_3args_1_EQ() throws Exception {
final CountDownLatch latch = new CountDownLatch(1);
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
testShowProgressDialogAndRun_3args_1();
} finally {
latch.countDown();
}
}
});
latch.await();
}
public void testShowProgressDialogAndRun_3args_2_EQ() throws Exception {
final CountDownLatch latch = new CountDownLatch(1);
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
testShowProgressDialogAndRun_3args_2();
} catch (AssertionFailedError e) {
throw e;
} catch (Exception ex) {
throw new RuntimeException (ex);
} finally {
latch.countDown();
}
}
});
latch.await();
}
public void testShowProgressDialogAndRunLater() throws Exception {
final WM wm = Lookup.getDefault().lookup(WM.class);
//make sure main window is on screen before proceeding
wm.await();
final JFrame jf = (JFrame) WindowManager.getDefault().getMainWindow();
final CountDownLatch countDown = new CountDownLatch(1);
final AtomicBoolean glassPaneFound = new AtomicBoolean(false);
final boolean testGlassPane = canTestGlassPane();
class R implements ProgressRunnable<String> {
volatile boolean hasRun;
@Override
public String run(ProgressHandle handle) {
try {
wm.waitForGlassPane();
if (testGlassPane) {
glassPaneFound.set(jf.getGlassPane() instanceof RunOffEDTImpl.TranslucentMask);
}
hasRun = true;
return "Done";
} finally {
countDown.countDown();
}
}
}
R r = new R();
Future<String> f = ProgressUtils.showProgressDialogAndRunLater(r, ProgressHandleFactory.createHandle("Something"), true);
assertNotNull (f);
assertEquals ("Done", f.get());
countDown.await();
assertTrue (r.hasRun);
assertFalse (f.isCancelled());
assertTrue (f.isDone());
assertEquals ("Done", f.get());
assertTrue ("Glass pane not set", !testGlassPane || glassPaneFound.get());
}
public void testShowProgressDialogAndRunLaterEQ() throws Throwable {
EventQueue.invokeAndWait(new Runnable() {
@Override
public void run() {
try {
testShowProgressDialogAndRunLater();
} catch (Exception ex) {
throw new AssertionError(ex);
}
}
});
}
public void testShowProgressDialogAndRun_3args_1() {
assertEquals ("Done", ProgressUtils.showProgressDialogAndRun(new CB(), "Doing Stuff", true));
}
public void testShowProgressDialogAndRun_3args_2() throws InterruptedException {
final WM wm = Lookup.getDefault().lookup(WM.class);
//make sure main window is on screen before proceeding
wm.await();
final JFrame jf = (JFrame) WindowManager.getDefault().getMainWindow();
final CountDownLatch countDown = new CountDownLatch(1);
final AtomicBoolean glassPaneFound = new AtomicBoolean(false);
final boolean testGlassPane = canTestGlassPane();
class R implements Runnable {
volatile boolean hasRun;
@Override
public void run() {
try {
wm.waitForGlassPane();
if (testGlassPane) {
glassPaneFound.set(jf.getGlassPane() instanceof RunOffEDTImpl.TranslucentMask);
}
hasRun = true;
} finally {
countDown.countDown();
}
}
}
R r = new R();
ProgressUtils.showProgressDialogAndRun(r, "Something");
countDown.await();
assertTrue (r.hasRun);
assertTrue ("Glass pane not set", !testGlassPane || glassPaneFound.get());
}
public void testStressWithRandomContention() throws InterruptedException, Exception {
Random r = new Random(123456789);
for (int i = 0; i < 30; i++) {
testShowProgressDialogAndRun_3args_1();
createRandomContention(r);
testShowProgressDialogAndRun_3args_1_EQ();
createRandomContention(r);
testShowProgressDialogAndRun_3args_2();
createRandomContention(r);
testShowProgressDialogAndRun_3args_2_EQ();
}
}
private void createRandomContention(final Random r) throws Exception {
if (r.nextInt(10) > 7) {
RequestProcessor rp = new RequestProcessor(this.getClass().getName());
for (int i= 0; i < r.nextInt(5); i++) {
rp.post(new Runnable() {
@Override
public void run() {
try {
//No, Jesse, this will not affect the test
//passing or failing unless something else is
//broken
Thread.sleep(r.nextInt(200));
} catch (InterruptedException ex) {
//do nothing
}
}
});
EventQueue.invokeAndWait(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(r.nextInt(200));
} catch (InterruptedException ex) {
Exceptions.printStackTrace(ex);
}
}
});
}
}
}
private class CB implements ProgressRunnable<String> {
@Override
public String run(ProgressHandle handle) {
handle.switchToDeterminate(5);
for (int i= 0; i < 5; i++) {
handle.progress("Job " + i, i);
}
return "Done";
}
}
private static final class JF extends JFrame {
boolean inited;
private final CountDownLatch waitForGlassPane = new CountDownLatch(1);
JF () {
super ("Main Window");
inited = true;
}
@Override
public void addNotify() {
super.addNotify();
inited = true;
}
@Override
public void setGlassPane(java.awt.Component glassPane) {
super.setGlassPane(glassPane);
if (inited && glassPane instanceof RunOffEDTImpl.TranslucentMask) {
waitForGlassPane.countDown();
}
}
}
public static final class WM extends WindowManager implements WindowListener {
private final JF jf = new JF();
private CountDownLatch latch = new CountDownLatch(1);
public WM() {
jf.addWindowListener(this);
jf.setPreferredSize(new Dimension(400, 400));
jf.setVisible(true);
}
public void waitForGlassPane() {
try {
jf.waitForGlassPane.await();
} catch (InterruptedException ex) {
Exceptions.printStackTrace(ex);
}
}
public void await() {
if (!jf.isDisplayable()) {
try {
latch.await();
} catch (InterruptedException ex) {
throw new IllegalStateException(ex);
}
}
}
@Override
public Mode findMode(String name) {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public Mode findMode(TopComponent tc) {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public Set<? extends Mode> getModes() {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public Frame getMainWindow() {
return jf;
}
@Override
public void updateUI() {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
protected Component createTopComponentManager(TopComponent c) {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public Workspace createWorkspace(String name, String displayName) {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public Workspace findWorkspace(String name) {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public Workspace[] getWorkspaces() {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public void setWorkspaces(Workspace[] workspaces) {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public Workspace getCurrentWorkspace() {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public TopComponentGroup findTopComponentGroup(String name) {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public void addPropertyChangeListener(PropertyChangeListener l) {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public void removePropertyChangeListener(PropertyChangeListener l) {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
protected void topComponentOpen(TopComponent tc) {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
protected void topComponentClose(TopComponent tc) {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
protected void topComponentRequestActive(TopComponent tc) {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
protected void topComponentRequestVisible(TopComponent tc) {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
protected void topComponentDisplayNameChanged(TopComponent tc, String displayName) {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
protected void topComponentHtmlDisplayNameChanged(TopComponent tc, String htmlDisplayName) {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
protected void topComponentToolTipChanged(TopComponent tc, String toolTip) {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
protected void topComponentIconChanged(TopComponent tc, Image icon) {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
protected void topComponentActivatedNodesChanged(TopComponent tc, Node[] activatedNodes) {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
protected boolean topComponentIsOpened(TopComponent tc) {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
protected Action[] topComponentDefaultActions(TopComponent tc) {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
protected String topComponentID(TopComponent tc, String preferredID) {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public TopComponent findTopComponent(String tcID) {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public void windowOpened(WindowEvent e) {
latch.countDown();
}
@Override
public void windowClosing(WindowEvent e) {
//do nothing
}
@Override
public void windowClosed(WindowEvent e) {
//do nothing
}
@Override
public void windowIconified(WindowEvent e) {
//do nothing
}
@Override
public void windowDeiconified(WindowEvent e) {
//do nothing
}
@Override
public void windowActivated(WindowEvent e) {
//do nothing
}
@Override
public void windowDeactivated(WindowEvent e) {
//do nothing
}
}
}