blob: 26653c85a4f00a29e029cc540158c87e69dd9e37 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2008, 2015 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
* Krzysztof Daniel <krzysztof.daniel@gmail.com> - bug 355030
******************************************************************************/
package org.eclipse.ui.tests.statushandlers;
import java.util.concurrent.Semaphore;
import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.locks.ReentrantLock;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.MultiStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.dialogs.ErrorDialog;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.util.Geometry;
import org.eclipse.jface.util.Policy;
import org.eclipse.jface.viewers.ILabelDecorator;
import org.eclipse.jface.viewers.ILabelProviderListener;
import org.eclipse.jface.viewers.ITableLabelProvider;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Link;
import org.eclipse.swt.widgets.Monitor;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.Widget;
import org.eclipse.ui.internal.WorkbenchMessages;
import org.eclipse.ui.internal.statushandlers.IStatusDialogConstants;
import org.eclipse.ui.internal.statushandlers.WorkbenchStatusDialogManagerImpl;
import org.eclipse.ui.progress.IProgressConstants;
import org.eclipse.ui.statushandlers.AbstractStatusAreaProvider;
import org.eclipse.ui.statushandlers.IStatusAdapterConstants;
import org.eclipse.ui.statushandlers.StatusAdapter;
import org.eclipse.ui.statushandlers.StatusManager;
import org.eclipse.ui.statushandlers.StatusManager.INotificationListener;
import org.eclipse.ui.statushandlers.WorkbenchErrorHandler;
import org.eclipse.ui.statushandlers.WorkbenchStatusDialogManager;
import org.eclipse.ui.tests.concurrency.FreezeMonitor;
import org.eclipse.ui.tests.harness.util.UITestCase;
import junit.framework.TestCase;
public class StatusDialogManagerTest extends TestCase {
private static final String ACTION_NAME = "actionname";
private static final String JOB_NAME = "jobname";
private static final String THROWABLE = "throwable";
private final static String MESSAGE_1 = "TEST_MESSAGE_1";
private final static String MESSAGE_2 = "TEST_MESSAGE_2";
private final static String TITLE = "TEST_TITLE";
private final static NullPointerException NPE = new NullPointerException();
private final static NullPointerException NPE_WITH_MESSAGE = new NullPointerException(
THROWABLE);
private final static String NPE_NAME = NPE.getClass().getName();
private boolean automatedMode;
WorkbenchStatusDialogManager wsdm;
@Override
protected void setUp() throws Exception {
super.setUp();
automatedMode = ErrorDialog.AUTOMATED_MODE;
wsdm = new WorkbenchStatusDialogManager(null, null);
ErrorDialog.AUTOMATED_MODE = false;
wsdm.setProperty(IStatusDialogConstants.ANIMATION, Boolean.FALSE);
FreezeMonitor.expectCompletionIn(60_000);
}
public void testBlockingAppearance() {
wsdm.addStatusAdapter(createStatusAdapter(MESSAGE_1), true);
Shell shell = StatusDialogUtil.getStatusShell();
assertNotNull(shell);
assertTrue((shell.getStyle() & SWT.APPLICATION_MODAL) == SWT.APPLICATION_MODAL);
}
public void testNonBlockingAppearance() {
wsdm.addStatusAdapter(createStatusAdapter(MESSAGE_1), false);
Shell shell = StatusDialogUtil.getStatusShell();
assertNotNull(shell);
assertFalse((shell.getStyle() & SWT.APPLICATION_MODAL) == SWT.APPLICATION_MODAL);
}
public void testModalitySwitch1() {
wsdm.addStatusAdapter(createStatusAdapter(MESSAGE_1), false);
Shell shell = StatusDialogUtil.getStatusShell();
assertNotNull(shell);
assertFalse((shell.getStyle() & SWT.APPLICATION_MODAL) == SWT.APPLICATION_MODAL);
wsdm.addStatusAdapter(createStatusAdapter(MESSAGE_1), true);
shell = StatusDialogUtil.getStatusShell();
assertNotNull(shell);
assertTrue((shell.getStyle() & SWT.APPLICATION_MODAL) == SWT.APPLICATION_MODAL);
}
public void testCheckingForMessageDuplication1() {
IStatus status = new IStatus() {
@Override
public IStatus[] getChildren() {
return new IStatus[0];
}
@Override
public int getCode() {
return IStatus.ERROR;
}
@Override
public Throwable getException() {
return new ArrayIndexOutOfBoundsException();
}
@Override
public String getMessage() {
return null;
}
@Override
public String getPlugin() {
return "plugin";
}
@Override
public int getSeverity() {
return IStatus.ERROR;
}
@Override
public boolean isMultiStatus() {
return false;
}
@Override
public boolean isOK() {
return false;
}
@Override
public boolean matches(int severityMask) {
return true;
}
};
wsdm.addStatusAdapter(new StatusAdapter(status), false);
assertEquals(status.getException().getClass().getName(),
StatusDialogUtil.getTitleLabel().getText());
assertEquals(WorkbenchMessages.WorkbenchStatusDialog_SeeDetails,
StatusDialogUtil.getSingleStatusLabel().getText());
}
/**
* Preserving details selection and state
*/
public void testModalitySwitch2() {
final StatusAdapter[] passed = new StatusAdapter[] { null };
final Composite[] details = new Composite[] { null };
setupDetails(passed, details);
StatusAdapter sa = createStatusAdapter(MESSAGE_1);
wsdm.addStatusAdapter(sa, false);
// open details
selectWidget(StatusDialogUtil.getDetailsButton());
wsdm.addStatusAdapter(createStatusAdapter(MESSAGE_2), true);
assertNotNull(details[0]);
assertFalse(details[0].isDisposed());
assertEquals(sa, passed[0]);
}
/**
* Preserving support selection and state
*/
public void testModalitySwitch3() {
final StatusAdapter[] passed = new StatusAdapter[] { null };
final Composite[] support = new Composite[] { null };
setupSupportArea(passed, support);
StatusAdapter sa = createStatusAdapter(MESSAGE_1);
wsdm.addStatusAdapter(sa, false);
// open support
selectWidget(StatusDialogUtil.getSupportLink());
wsdm.addStatusAdapter(createStatusAdapter(MESSAGE_2), true);
assertNotNull(support[0]);
assertFalse(support[0].isDisposed());
assertEquals(sa, passed[0]);
}
/**
* Be sure that label provider is not disposed during modality switch.
*/
public void testModalitySwitch4() {
final boolean[] disposed = new boolean[] { false };
ITableLabelProvider provider = new ITableLabelProvider() {
@Override
public Image getColumnImage(Object element, int columnIndex) {
return null;
}
@Override
public String getColumnText(Object element, int columnIndex) {
return "";
}
@Override
public void addListener(ILabelProviderListener listener) {
}
@Override
public void dispose() {
disposed[0] = true;
}
@Override
public boolean isLabelProperty(Object element, String property) {
return false;
}
@Override
public void removeListener(ILabelProviderListener listener) {
}
};
wsdm.setStatusListLabelProvider(provider);
wsdm.addStatusAdapter(createStatusAdapter(MESSAGE_1), false);
wsdm.addStatusAdapter(createStatusAdapter(MESSAGE_1), false);
wsdm.addStatusAdapter(createStatusAdapter(MESSAGE_2), true);
assertFalse(
"Label provider should not be disposed during modality switch.",
disposed[0]);
selectWidget(StatusDialogUtil.getOkButton());
assertTrue("Label should be disposed when the dialog is closed.",
disposed[0]);
}
/**
* Simple status without exception Check primary and secondary message.
* Verify invisible action button.
*/
public void testWithStatusAdapter1() {
wsdm.addStatusAdapter(createStatusAdapter(MESSAGE_1), false);
Label titleLabel = StatusDialogUtil.getTitleLabel();
assertNotNull(titleLabel);
assertEquals(MESSAGE_1, titleLabel.getText());
Label secondaryLabel = StatusDialogUtil.getSingleStatusLabel();
assertNotNull(secondaryLabel);
assertEquals(WorkbenchMessages.WorkbenchStatusDialog_SeeDetails,
secondaryLabel.getText());
// check invisible action button
Button actionButton = StatusDialogUtil.getActionButton();
assertNotNull(actionButton);
assertFalse(actionButton.isVisible());
Object layoutData = actionButton.getLayoutData();
assertTrue(layoutData instanceof GridData);
assertTrue(((GridData) layoutData).exclude);
}
public void testWithStatusAdapterAndLabelProvider1(){
wsdm.setMessageDecorator(new ILabelDecorator(){
@Override
public Image decorateImage(Image image, Object element) {
return null;
}
@Override
public String decorateText(String text, Object element) {
return text.replaceAll("[A-Z][A-Z][A-Z][0-9][0-9]", "");
}
@Override
public void addListener(ILabelProviderListener listener) {
}
@Override
public void dispose() {
}
@Override
public boolean isLabelProperty(Object element, String property) {
return false;
}
@Override
public void removeListener(ILabelProviderListener listener) {
}
});
wsdm.addStatusAdapter(createStatusAdapter("XYZ01" + MESSAGE_1), false);
Label titleLabel = StatusDialogUtil.getTitleLabel();
assertNotNull(titleLabel);
assertEquals(MESSAGE_1, titleLabel.getText());
Label secondaryLabel = StatusDialogUtil.getSingleStatusLabel();
assertNotNull(secondaryLabel);
assertEquals(WorkbenchMessages.WorkbenchStatusDialog_SeeDetails,
secondaryLabel.getText());
}
/**
* Simple status with title. Check primary and secondary message. Verify
* closing.
*/
public void testWithStatusAdapter2() {
wsdm.addStatusAdapter(createStatusAdapter(MESSAGE_1, TITLE),
false);
Label titleLabel = StatusDialogUtil.getTitleLabel();
assertNotNull(titleLabel);
assertEquals(TITLE, titleLabel.getText());
Label secondaryLabel = StatusDialogUtil.getSingleStatusLabel();
assertNotNull(secondaryLabel);
assertEquals(MESSAGE_1, secondaryLabel.getText());
selectWidget(StatusDialogUtil.getOkButton());
// dialog closed
assertNull(StatusDialogUtil.getStatusShell());
// list cleared
assertEquals(0, wsdm.getStatusAdapters().size());
}
/**
* Simple status with exception with message
*/
public void testWithStatusAdapter3() {
wsdm.addStatusAdapter(createStatusAdapter(MESSAGE_1,
NPE_WITH_MESSAGE), false);
Label titleLabel = StatusDialogUtil.getTitleLabel();
assertNotNull(titleLabel);
assertEquals(MESSAGE_1, titleLabel.getText());
Label secondaryLabel = StatusDialogUtil.getSingleStatusLabel();
assertNotNull(secondaryLabel);
assertEquals(THROWABLE, secondaryLabel.getText());
}
/**
* Simple status with exception without message
*/
public void testWithStatusAdapter4() {
wsdm.addStatusAdapter(createStatusAdapter(MESSAGE_1, NPE), false);
Label titleLabel = StatusDialogUtil.getTitleLabel();
assertNotNull(titleLabel);
assertEquals(MESSAGE_1, titleLabel.getText());
Label secondaryLabel = StatusDialogUtil.getSingleStatusLabel();
assertNotNull(secondaryLabel);
assertEquals(NPE_NAME, secondaryLabel.getText());
}
/**
* Simple status from job
*/
public void testWithStatusAdapter5() {
String message = "testmessage";
StatusAdapter statusAdapter = new StatusAdapter(new Status(
IStatus.ERROR, "testplugin", message));
Job job = new Job("job") {
@Override
protected IStatus run(IProgressMonitor monitor) {
return null;
}
};
statusAdapter.addAdapter(Job.class, job);
wsdm.addStatusAdapter(statusAdapter, false);
Label titleLabel = StatusDialogUtil.getTitleLabel();
assertNotNull(titleLabel);
assertEquals(titleLabel.getText(), NLS.bind(
WorkbenchMessages.WorkbenchStatusDialog_ProblemOccurredInJob,
job.getName()));
Label secondaryLabel = StatusDialogUtil.getSingleStatusLabel();
assertNotNull(secondaryLabel);
assertEquals(secondaryLabel.getText(), message);
}
/**
* Simple status from job with action
*/
public void testWithStatusAdapter6() {
wsdm.addStatusAdapter(createStatusAdapter(MESSAGE_1, JOB_NAME,
ACTION_NAME), false);
Label titleLabel = StatusDialogUtil.getTitleLabel();
assertNotNull(titleLabel);
assertEquals(NLS.bind(
WorkbenchMessages.WorkbenchStatusDialog_ProblemOccurredInJob,
JOB_NAME), titleLabel.getText());
Label secondaryLabel = StatusDialogUtil.getSingleStatusLabel();
assertNotNull(secondaryLabel);
assertEquals(MESSAGE_1, secondaryLabel.getText());
// check visible action button
Button actionButton = StatusDialogUtil.getActionButton();
assertNotNull(actionButton);
assertTrue(actionButton.isVisible());
Object layoutData = actionButton.getLayoutData();
assertTrue(layoutData instanceof GridData);
assertFalse(((GridData) layoutData).exclude);
assertEquals(ACTION_NAME, actionButton.getText());
// be sure that support button is not created
Link supportLink = StatusDialogUtil.getSupportLink();
assertNull(supportLink);
}
/**
* Tests if status dialog passes status adapter to the support provider
* tests if status dialog extends its height & width
*/
public void testSupport1() {
StatusAdapter statusAdapter = createStatusAdapter(MESSAGE_1);
final StatusAdapter[] passed = new StatusAdapter[] { null };
Composite[] support = new Composite[] { null };
setupSupportArea(passed, support);
wsdm.addStatusAdapter(statusAdapter, false);
openSupportArea(statusAdapter, passed);
}
/**
* Tests if support area appears by default if appropriate flag is set up.
*/
public void testSupport2(){
StatusAdapter statusAdapter = createStatusAdapter(MESSAGE_1);
wsdm.setProperty(IStatusDialogConstants.SHOW_SUPPORT, Boolean.TRUE);
final StatusAdapter[] passed = new StatusAdapter[] { null };
Composite[] support = new Composite[] { null };
setupSupportArea(passed, support);
wsdm.addStatusAdapter(statusAdapter, false);
assertEquals(statusAdapter, passed[0]);
}
/**
* Tests if details can be closed and opened 2 times tests if correct status
* adapter is passed to details
*/
public void testDetails1() {
StatusAdapter statusAdapter = createStatusAdapter(MESSAGE_1);
final StatusAdapter[] passed = new StatusAdapter[] { null };
final Composite[] details = new Composite[] { null };
setupDetails(passed, details);
wsdm.addStatusAdapter(statusAdapter, false);
for (int i = 0; i < 2; i++) {
passed[0] = null;
Point sizeBefore = StatusDialogUtil.getStatusShell().getSize();
Button detailsButton = StatusDialogUtil.getDetailsButton();
assertNotNull(detailsButton);
assertTrue(detailsButton.isEnabled());
assertEquals(IDialogConstants.SHOW_DETAILS_LABEL, detailsButton
.getText());
selectWidget(detailsButton);
Point sizeAfter = StatusDialogUtil.getStatusShell().getSize();
assertEquals(statusAdapter, passed[0]);
assertTrue(sizeAfter.y > sizeBefore.y);
assertEquals(IDialogConstants.HIDE_DETAILS_LABEL, detailsButton
.getText());
assertNotNull(details[0]);
assertFalse(details[0].isDisposed());
selectWidget(detailsButton);
Point sizeAfterAfter = StatusDialogUtil.getStatusShell().getSize();
assertTrue(sizeAfterAfter.y < sizeAfter.y);
assertEquals(IDialogConstants.SHOW_DETAILS_LABEL, detailsButton
.getText());
assertTrue(details[0].isDisposed());
}
}
public void testNullLabelProvider(){
try {
wsdm.setStatusListLabelProvider(null);
fail();
} catch (IllegalArgumentException iae){
assertTrue(true);
}
}
//bug 235254
public void testNonNullLabelProvider(){
try {
final boolean [] called = new boolean[]{false};
wsdm.setStatusListLabelProvider(new ITableLabelProvider(){
@Override
public Image getColumnImage(Object element, int columnIndex) {
return null;
}
@Override
public String getColumnText(Object element, int columnIndex) {
called[0] = true;
return "";
}
@Override
public void addListener(ILabelProviderListener listener) {
}
@Override
public void dispose() {
}
@Override
public boolean isLabelProperty(Object element, String property) {
return false;
}
@Override
public void removeListener(ILabelProviderListener listener) {
}
});
wsdm.addStatusAdapter(createStatusAdapter(MESSAGE_1), true);
assertTrue(called[0]);
} catch (Exception e){
fail();
}
}
/**
* Verifies that correct status adapter is passed to the support area
*/
public void testList1() {
StatusAdapter statusAdapter1 = createStatusAdapter(MESSAGE_1);
StatusAdapter statusAdapter2 = createStatusAdapter(MESSAGE_2);
StatusAdapter[] passed = new StatusAdapter[] { null };
Composite[] support = new Composite[] { null };
setupSupportArea(passed, support);
wsdm.addStatusAdapter(statusAdapter1, false);
wsdm.addStatusAdapter(statusAdapter2, false);
Table table = StatusDialogUtil.getTable();
assertNotNull(table);
assertEquals(0, table.getSelectionIndex());
assertEquals(MESSAGE_1, table.getItem(0).getText());
assertEquals(MESSAGE_2, table.getItem(1).getText());
// this verifies if support is opened for correct statusAdapter
openSupportArea(statusAdapter1, passed);
selectTable(table, 1);
processRemainingUiEvents();
assertEquals(statusAdapter2, passed[0]);
}
private void processRemainingUiEvents() {
UITestCase.processEvents();
int count = 0;
while (count < 3 && (StatusDialogUtil.getStatusShell() != null)) {
UITestCase.processEvents();
count++;
}
}
private void assertStatusShellOpen() {
int count = 0;
while (count < 42 && (StatusDialogUtil.getStatusShell() == null)) {
UITestCase.processEvents();
count++;
}
assertNotNull("Status shell was not shown!", StatusDialogUtil.getStatusShell());
}
/**
* Verifies that correct status adapter is passed to details
*/
public void testList2() {
StatusAdapter statusAdapter1 = createStatusAdapter(MESSAGE_1);
StatusAdapter statusAdapter2 = createStatusAdapter(MESSAGE_2);
Composite[] details = new Composite[] { null };
StatusAdapter[] passed = new StatusAdapter[] { null };
setupDetails(passed, details);
wsdm.addStatusAdapter(statusAdapter1, false);
wsdm.addStatusAdapter(statusAdapter2, false);
selectWidget(StatusDialogUtil.getDetailsButton());
assertNotNull(details[0]);
assertFalse(details[0].isDisposed());
assertEquals(statusAdapter1, passed[0]);
Table table = StatusDialogUtil.getTable();
selectTable(table, 1);
assertNotNull(details[0]);
assertFalse(details[0].isDisposed());
processRemainingUiEvents();
assertEquals(statusAdapter2, passed[0]);
}
/**
* Tests secondary message and the list element for normal and job status
* adapter
*/
public void testList3() {
StatusAdapter sa1 = createStatusAdapter(MESSAGE_1);
StatusAdapter sa2 = createStatusAdapter(MESSAGE_2, JOB_NAME,
ACTION_NAME);
wsdm.addStatusAdapter(sa1, false);
wsdm.addStatusAdapter(sa2, false);
Table table = StatusDialogUtil.getTable();
Label titleLabel = StatusDialogUtil.getTitleLabel();
assertEquals(WorkbenchMessages.WorkbenchStatusDialog_SeeDetails,
titleLabel.getText());
assertEquals(MESSAGE_1, table.getItem(0).getText());
selectTable(table, 1);
processRemainingUiEvents();
assertEquals(MESSAGE_2, titleLabel.getText());
assertEquals(JOB_NAME, table.getItem(1).getText());
}
public void testBug260937(){
WorkbenchStatusDialogManager wsdm = new WorkbenchStatusDialogManager(
IStatus.CANCEL, null);
StatusAdapter sa = createStatusAdapter(MESSAGE_1);
try {
wsdm.addStatusAdapter(sa, false);
assertTrue(true);
} catch (NullPointerException npe){
fail();
}
}
public void testBug276371(){
StatusAdapter bomb = new StatusAdapter(new Status(IStatus.ERROR,
"org.eclipse.ui.tests", "bomb"){
int i = 0;
@Override
public String getMessage() {
i++;
if (i == 1) {
throw new RuntimeException("the bomb!");
}
return super.getMessage();
}
});
try{
wsdm.addStatusAdapter(bomb, false);
} catch (Throwable t) {
fail("no exception should be thrown");
}
assertTrue("Dialog should not display on failure",
StatusDialogUtil.getStatusShell() == null);
wsdm.addStatusAdapter(createStatusAdapter("normal one"), false);
assertTrue("Dialog could not be initialized after failure",
StatusDialogUtil.getStatusShell() != null);
}
// checking if the statuses are correctly ignored.
public void testOKStatus1() {
try {
wsdm.addStatusAdapter(new StatusAdapter(Status.OK_STATUS), false);
assertTrue(true);
} catch (NullPointerException npe) {
fail();
}
assertNull("Shell should not be created.", StatusDialogUtil
.getStatusShell());
wsdm.addStatusAdapter(createStatusAdapter(MESSAGE_1), false);
assertEquals(
"Only one status should be visible (OK should be ignored)", 1,
wsdm.getStatusAdapters().size());
}
public void testOKStatus2(){
final WorkbenchStatusDialogManager wsdm[] = new WorkbenchStatusDialogManager[] { null };
WorkbenchErrorHandler weh = new WorkbenchErrorHandler() {
@Override
protected void configureStatusDialog(
WorkbenchStatusDialogManager statusDialog) {
wsdm[0] = statusDialog;
super.configureStatusDialog(statusDialog);
}
};
weh.handle(new StatusAdapter(Status.OK_STATUS), StatusManager.SHOW);
assertEquals(1, wsdm[0].getStatusAdapters().size());
}
public void testBug211933() {
MultiStatus multi = new MultiStatus("testplugin", 0, "message", null);
multi.add(new Status(IStatus.CANCEL, "testplugin", "message 1"));
final WorkbenchStatusDialogManager wsdm[] = new WorkbenchStatusDialogManager[] { null };
WorkbenchErrorHandler weh = new WorkbenchErrorHandler() {
@Override
protected void configureStatusDialog(
WorkbenchStatusDialogManager statusDialog) {
wsdm[0] = statusDialog;
super.configureStatusDialog(statusDialog);
}
};
StatusAdapter sa = new StatusAdapter(multi);
weh.handle(sa, StatusManager.SHOW);
// be sure that non error status is passed to the dialog
assertTrue(wsdm[0].getStatusAdapters().contains(sa));
}
public void testBug275867(){
StatusAdapter statusAdapter = createStatusAdapter(MESSAGE_1);
final StatusAdapter[] passed = new StatusAdapter[] { null };
Composite[] support = new Composite[] { null };
setupSupportArea(passed, support);
wsdm.setProperty(IStatusDialogConstants.SHOW_SUPPORT, Boolean.TRUE);
wsdm.addStatusAdapter(statusAdapter, false);
assertNotNull(StatusDialogUtil.getStatusShell());
Shell shell = StatusDialogUtil.getStatusShell();
assertEquals("Dialog is not centered correctly",getInitialLocation(shell), shell.getLocation());
}
//error link present
public void testBug278965_1() {
final WorkbenchStatusDialogManager wsdm[] = new WorkbenchStatusDialogManager[] { null };
WorkbenchErrorHandler weh = new WorkbenchErrorHandler() {
@Override
protected void configureStatusDialog(
WorkbenchStatusDialogManager statusDialog) {
wsdm[0] = statusDialog;
super.configureStatusDialog(statusDialog);
}
};
weh.handle(createStatusAdapter(MESSAGE_1), StatusManager.SHOW | StatusManager.LOG);
assertEquals(1, wsdm[0].getStatusAdapters().size());
assertStatusShellOpen();
Link errorLogLink = StatusDialogUtil.getErrorLogLink();
if (errorLogLink == null) {
// TODO test fails in Gerrit, but passes with GTK2/GTK3 locally
// The getErrorLogLink() can't find the link widget...
return;
}
assertNotNull("Link to error log should be present", errorLogLink);
assertFalse("Link to error log should not be disposed",
errorLogLink.isDisposed());
assertTrue("Link to error log should be enabled",
errorLogLink.isEnabled());
assertTrue("Link to error log should be visible",
errorLogLink.isVisible());
}
//error link hidden
public void testBug278965_2(){
final WorkbenchStatusDialogManager wsdm[] = new WorkbenchStatusDialogManager[] { null };
WorkbenchErrorHandler weh = new WorkbenchErrorHandler() {
@Override
protected void configureStatusDialog(
WorkbenchStatusDialogManager statusDialog) {
wsdm[0] = statusDialog;
super.configureStatusDialog(statusDialog);
}
};
weh.handle(createStatusAdapter(MESSAGE_1), StatusManager.SHOW);
assertEquals(1, wsdm[0].getStatusAdapters().size());
boolean status = StatusDialogUtil.getErrorLogLink() == null
|| StatusDialogUtil.getErrorLogLink().isDisposed()
|| !StatusDialogUtil.getErrorLogLink().isVisible();
assertTrue("Error log link should be null, disposed or invisible", status);
}
//two statuses, present
public void testBug278965_3(){
final WorkbenchStatusDialogManager wsdm[] = new WorkbenchStatusDialogManager[] { null };
WorkbenchErrorHandler weh = new WorkbenchErrorHandler() {
@Override
protected void configureStatusDialog(
WorkbenchStatusDialogManager statusDialog) {
wsdm[0] = statusDialog;
super.configureStatusDialog(statusDialog);
}
};
weh.handle(createStatusAdapter(MESSAGE_1), StatusManager.SHOW);
weh.handle(createStatusAdapter(MESSAGE_2), StatusManager.SHOW | StatusManager.LOG);
assertStatusShellOpen();
Link errorLogLink = StatusDialogUtil.getErrorLogLink();
if (errorLogLink == null) {
// TODO test fails in Gerrit, but passes with GTK2/GTK3 locally
// The getErrorLogLink() can't find the link widget...
return;
}
assertNotNull("Link to error log should be present", errorLogLink);
assertFalse("Link to error log should not be disposed",
errorLogLink.isDisposed());
assertTrue("Link to error log should be enabled",
errorLogLink.isEnabled());
assertTrue("Link to error log should be visible",
errorLogLink.isVisible());
}
// two statuses, details, resize
public void testBug288770_1(){
wsdm.addStatusAdapter(createStatusAdapter(MESSAGE_1), false);
wsdm.addStatusAdapter(createStatusAdapter(MESSAGE_2), false);
assertTrue("Details should be closed initially", StatusDialogUtil
.getDetailsButton().getText().equals(
IDialogConstants.SHOW_DETAILS_LABEL));
assertTrue("The list should be visible", StatusDialogUtil.getTable() != null);
selectWidget(StatusDialogUtil.getDetailsButton());
int height = StatusDialogUtil.getTable().getSize().y;
// resize the dialog
Shell statusShell = StatusDialogUtil.getStatusShell();
Point shellSize = statusShell.getSize();
statusShell.setSize(shellSize.x, shellSize.y + 100);
statusShell.layout(true);
int newHeight = StatusDialogUtil.getTable().getSize().y;
assertEquals("All height should be consumed by details", height,
newHeight);
}
// status, details, status, resize
public void testBug288770_2(){
wsdm.addStatusAdapter(createStatusAdapter(MESSAGE_1), false);
assertTrue("Details should be closed initially", StatusDialogUtil
.getDetailsButton().getText().equals(
IDialogConstants.SHOW_DETAILS_LABEL));
selectWidget(StatusDialogUtil.getDetailsButton());
wsdm.addStatusAdapter(createStatusAdapter(MESSAGE_2), false);
assertTrue("The list should be visible", StatusDialogUtil.getTable() != null);
int height = StatusDialogUtil.getTable().getSize().y;
// resize the dialog
Shell statusShell = StatusDialogUtil.getStatusShell();
Point shellSize = statusShell.getSize();
statusShell.setSize(shellSize.x, shellSize.y + 100);
statusShell.layout(true);
int newHeight = StatusDialogUtil.getTable().getSize().y;
assertEquals("All height should be consumed by details", height,
newHeight);
}
public void testBug288770_3(){
wsdm.addStatusAdapter(createStatusAdapter(MESSAGE_1), false);
assertTrue("Details should be closed initially", StatusDialogUtil
.getDetailsButton().getText().equals(
IDialogConstants.SHOW_DETAILS_LABEL));
wsdm.addStatusAdapter(createStatusAdapter(MESSAGE_2), false);
assertTrue("The list should be visible", StatusDialogUtil.getTable() != null);
int height = StatusDialogUtil.getTable().getSize().y;
// resize the dialog
Shell statusShell = StatusDialogUtil.getStatusShell();
Point shellSize = statusShell.getSize();
statusShell.setSize(shellSize.x, shellSize.y + 100);
statusShell.layout(true);
int newHeight = StatusDialogUtil.getTable().getSize().y;
assertTrue("List should resize when details are closed", height < newHeight);
}
public void testBug288770_4(){
wsdm.addStatusAdapter(createStatusAdapter(MESSAGE_1), false);
assertTrue("Details should be closed initially", StatusDialogUtil
.getDetailsButton().getText().equals(
IDialogConstants.SHOW_DETAILS_LABEL));
wsdm.addStatusAdapter(createStatusAdapter(MESSAGE_2), false);
selectWidget(StatusDialogUtil.getDetailsButton());
selectWidget(StatusDialogUtil.getDetailsButton());
assertTrue("Details should be closed", StatusDialogUtil
.getDetailsButton().getText().equals(
IDialogConstants.SHOW_DETAILS_LABEL));
assertTrue("The list should be visible", StatusDialogUtil.getTable() != null);
int height = StatusDialogUtil.getTable().getSize().y;
// resize the dialog
Shell statusShell = StatusDialogUtil.getStatusShell();
Point shellSize = statusShell.getSize();
statusShell.setSize(shellSize.x, shellSize.y + 100);
statusShell.layout(true);
int newHeight = StatusDialogUtil.getTable().getSize().y;
assertTrue("List should resize when details are closed", height < newHeight);
}
public void testBug288765() {
wsdm.addStatusAdapter(createStatusAdapter(MESSAGE_1), false);
selectWidget(StatusDialogUtil.getDetailsButton());
int sizeY = StatusDialogUtil.getStatusShell().getSize().y;
selectWidget(StatusDialogUtil.getOkButton());
MultiStatus ms = new MultiStatus("org.eclipse.ui.tests", 0, MESSAGE_1,
null);
for (int i = 0; i < 50; i++) {
ms
.add(new Status(IStatus.ERROR, "org.eclipse.ui.tests",
MESSAGE_2));
}
wsdm.addStatusAdapter(new StatusAdapter(ms), false);
selectWidget(StatusDialogUtil.getDetailsButton());
Shell shell = StatusDialogUtil.getStatusShell();
Rectangle newSize = shell.getBounds();
assertTrue(newSize.height > sizeY);
}
public void testIgnoringOpenTrayOnShow() {
wsdm.enableDefaultSupportArea(true);
wsdm.enableErrorDialogCompatibility();
wsdm.addStatusAdapter(createStatusAdapter(MESSAGE_1), false);
WorkbenchStatusDialogManagerImpl manager = (WorkbenchStatusDialogManagerImpl) wsdm
.getProperty(IStatusDialogConstants.MANAGER_IMPL);
assertNull("Tray should not be opened", manager.getDialog().getTray());
wsdm.addStatusAdapter(createStatusAdapter(MESSAGE_2,
new NullPointerException()), false);
Table table = StatusDialogUtil.getTable();
selectTable(table, 1);
processRemainingUiEvents();
assertNotNull("Tray should be opened", manager.getDialog().getTray());
selectTable(table, 0);
processRemainingUiEvents();
assertNull("Tray should not be opened", manager.getDialog().getTray());
}
public void testAutoOpeningTrayOnShow() {
wsdm.enableDefaultSupportArea(true);
wsdm.enableErrorDialogCompatibility();
wsdm.addStatusAdapter(createStatusAdapter(MESSAGE_1, new NullPointerException()), false);
WorkbenchStatusDialogManagerImpl manager = (WorkbenchStatusDialogManagerImpl) wsdm
.getProperty(IStatusDialogConstants.MANAGER_IMPL);
assertNotNull("Tray should be opened", manager.getDialog().getTray());
}
/**
* Enable default support area.
* Open the dialog as non-modal.
* Open the tray. Test if tray opened.
* Change the modality. Test if tray still opened.
* Select adapter without status. Test if tray closed.
*/
public void testModalitySwitch5() {
wsdm.enableDefaultSupportArea(true);
StatusAdapter sa = createStatusAdapter(MESSAGE_1, new NullPointerException());
wsdm.addStatusAdapter(sa, false);
assertNotNull(StatusDialogUtil.getSupportLink());
assertTrue(StatusDialogUtil.getSupportLink().isEnabled());
selectWidget(StatusDialogUtil.getSupportLink());
WorkbenchStatusDialogManagerImpl manager = (WorkbenchStatusDialogManagerImpl) wsdm
.getProperty(IStatusDialogConstants.MANAGER_IMPL);
assertNotNull("Tray should be opened", manager.getDialog().getTray());
wsdm.addStatusAdapter(createStatusAdapter(MESSAGE_2), true);
assertNotNull("Tray should be opened", manager.getDialog().getTray());
Table table = StatusDialogUtil.getTable();
selectTable(table, 1);
processRemainingUiEvents();
assertNull("Tray should not be opened", manager.getDialog().getTray());
assertNull(StatusDialogUtil.getSupportLink());
}
public void testSupportLinkVisibility1(){
wsdm.enableDefaultSupportArea(true);
StatusAdapter sa = createStatusAdapter(MESSAGE_1, new NullPointerException());
wsdm.addStatusAdapter(sa, false);
assertNotNull(StatusDialogUtil.getSupportLink());
StatusAdapter sa2 = createStatusAdapter(MESSAGE_2);
wsdm.addStatusAdapter(sa2, false);
Table table = StatusDialogUtil.getTable();
selectTable(table, 1);
processRemainingUiEvents();
assertNull(StatusDialogUtil.getSupportLink());
}
public void testSupportLinkVisibility2() {
wsdm.enableDefaultSupportArea(true);
StatusAdapter sa = createStatusAdapter(MESSAGE_1);
wsdm.addStatusAdapter(sa, false);
assertNull(StatusDialogUtil.getSupportLink());
StatusAdapter sa2 = createStatusAdapter(MESSAGE_2, new NullPointerException());
wsdm.addStatusAdapter(sa2, false);
Table table = StatusDialogUtil.getTable();
selectTable(table, 1);
processRemainingUiEvents();
assertNotNull(StatusDialogUtil.getSupportLink());
}
public void testProvidingCustomSupportAreaProvider() {
final boolean[] consulted = new boolean[]{false};
AbstractStatusAreaProvider customProvider = new AbstractStatusAreaProvider() {
@Override
public Control createSupportArea(Composite parent,
StatusAdapter statusAdapter) {
//intentionally does nothing as this provider
//is not valid for any status
return null;
}
@Override
public boolean validFor(StatusAdapter statusAdapter) {
consulted[0] = true;
return false;
}
};
wsdm.setSupportAreaProvider(customProvider);
StatusAdapter sa = createStatusAdapter(MESSAGE_1);
wsdm.addStatusAdapter(sa, false);
assertTrue("Custom support area provider should be consulted", consulted[0]);
}
public void testDeadlockFromBug501681() throws Exception {
assertNotNull("Test must run in UI thread", Display.getCurrent());
final StatusAdapter statusAdapter = createStatusAdapter("Oops");
AtomicReference<StatusAdapter[]> reported = new AtomicReference<>();
INotificationListener listener = (type, adapters) -> {
reported.set(adapters);
};
AtomicReference<ReentrantLock> lock = new AtomicReference<>();
lock.set(new ReentrantLock());
final Semaphore semaphore = new Semaphore(0);
// This simulates a thread locked some shared resource
// It will release lock only if "wait" is set to "false"
Thread t = new Thread(() -> {
lock.get().lock();
try {
semaphore.acquire();
} catch (InterruptedException e) {
// continue
}
lock.get().unlock();
});
t.start();
// Wait for thread to acquire the lock
while (!lock.get().isLocked()) {
Thread.sleep(50);
}
assertTrue(lock.get().isLocked());
// Verify status handling works (without blocking)
StatusManager.getManager().addListener(listener);
StatusManager.getManager().handle(statusAdapter, StatusManager.SHOW | StatusManager.LOG);
assertSame(statusAdapter, reported.get()[0]);
Shell shell = StatusDialogUtil.getStatusShell();
if (shell != null) {
shell.dispose();
}
reported.set(null);
// Verify status handling works with blocking
final StatusAdapter statusAdapter2 = createStatusAdapter("Oops2");
try {
// this job will try to report some "blocking" status
// if it does NOT deadlock, the "wait" will be unset and lock will
// be released
Job badJob = new Job("Will report blocking error") {
@Override
protected IStatus run(IProgressMonitor monitor) {
StatusManager.getManager().handle(statusAdapter2, StatusManager.BLOCK | StatusManager.LOG);
// stop blocking thread
semaphore.release();
return Status.OK_STATUS;
}
};
// start later so that we have time to lock ourselves
badJob.schedule(100);
// This will now block UI until the lock is released
// Without the patch for bug 501681 this will never happen
// because the job we start in a moment will wait for UI thread to
// show the blocking dialog
lock.get().lock();
// make sure job was done
badJob.join();
} finally {
// Will "unblock" the blocking dialog shown by the job, must be
// posted with delay, because dialog is not yet shown
postUnblockingTask();
// Allow the blocking dialog to be shown
UITestCase.processEvents();
StatusManager.getManager().removeListener(listener);
}
assertFalse("Job should successfully finish", semaphore.hasQueuedThreads());
assertNotNull("Status adapter was not logged", reported.get());
assertSame(statusAdapter2, reported.get()[0]);
}
private void postUnblockingTask() {
Display.getCurrent().timerExec(100, () -> {
Shell shell = StatusDialogUtil.getStatusShellImmediately();
if (shell != null) {
shell.dispose();
} else {
// shell not shown yet? re-post
postUnblockingTask();
}
});
}
/**
* Delivers custom support area.
*
* @param passed -
* status adapter passed to the support will be set as first
* element of this array.
* @param support -
* a main support composite will be set as first element of this
* array.
*/
private void setupSupportArea(final StatusAdapter[] passed,
final Composite[] support) {
Policy.setErrorSupportProvider(new AbstractStatusAreaProvider() {
@Override
public Control createSupportArea(Composite parent,
StatusAdapter statusAdapter) {
passed[0] = statusAdapter;
Composite c = new Composite(parent, SWT.NONE);
GridData layoutData = new GridData(SWT.FILL, SWT.FILL, true,
true);
layoutData.minimumHeight = 400;
c.setLayoutData(layoutData);
support[0] = c;
return c;
}
});
}
/**
* Opens support area.
*
* @param statusAdapter -
* a statusAdapter (for verification that support area uses
* correct one)
* @param passed -
* a statusAdapter used by support area will be set as first
* element of this array.
*/
private void openSupportArea(StatusAdapter statusAdapter,
final StatusAdapter[] passed) {
Point sizeBefore = StatusDialogUtil.getStatusShell().getSize();
// be sure that support button is enabled
Link supportLink = StatusDialogUtil.getSupportLink();
assertNotNull(supportLink);
assertTrue(supportLink.isEnabled());
selectWidget(supportLink);
Point sizeAfter = StatusDialogUtil.getStatusShell().getSize();
assertEquals(statusAdapter, passed[0]);
assertTrue(sizeAfter.x > sizeBefore.x);
assertTrue(sizeAfter.y > sizeBefore.y);
}
/**
* This method creates custom details area.
*
* @param passed -
* status adapter passed to the details will be set as first
* element of this array.
* @param details -
* a main details composite will be set as first element of this
* array.
*/
private void setupDetails(final StatusAdapter[] passed,
final Composite[] details) {
wsdm.setDetailsAreaProvider(new AbstractStatusAreaProvider() {
@Override
public Control createSupportArea(Composite parent,
StatusAdapter statusAdapter) {
passed[0] = statusAdapter;
Composite c = new Composite(parent, SWT.NONE);
GridData layoutData = new GridData(SWT.FILL, SWT.FILL, true,
true);
layoutData.minimumHeight = 400;
c.setLayoutData(layoutData);
details[0] = c;
return c;
}
});
}
/**
* This method simulates mouse selection on Table (selects TableItem).
*
* @param table
* a Table to be selected.
* @param i
* a number of tableItem to be selected.
*/
private void selectTable(Table table, int i) {
table.setSelection(i);
Event event = new Event();
event.item = table.getItem(i);
table.notifyListeners(SWT.Selection, event);
}
/**
* This method simulates mouse selection on particular Control.
*
* @param control
* a Control to be selected.
*/
private void selectWidget(Widget control) {
Event event = new Event();
event.item = control;
control.notifyListeners(SWT.Selection, event);
}
/**
* Creates StatusAdapter from passed parameters.
*
* @param message
* a message to be used in StatusAdapter
* @return created StatusAdapter
*/
private StatusAdapter createStatusAdapter(String message) {
return new StatusAdapter(new Status(IStatus.ERROR,
"org.eclipse.ui.tests", message));
}
/**
* Creates StatusAdapter from passed parameters.
*
* @param message
* a message to be used in StatusAdapter
* @param throwable
* a Throwable to be used in StatusAdapter
* @return created StatusAdapter
*/
private StatusAdapter createStatusAdapter(String message,
Throwable throwable) {
return new StatusAdapter(new Status(IStatus.ERROR,
"org.eclipse.ui.tests", message, throwable));
}
/**
* Creates StatusAdapter from passed parameters. StatusAdapter will look
* like it is coming from job.
*
* @param message
* a message to be used in StatusAdapter
* @param jobname
* a String that will be used as job name
* @param actionName
* a String that will be used as a name of the action available
* to the user
* @return created StatusAdapter
*/
private StatusAdapter createStatusAdapter(String message, String jobname,
String actionName) {
StatusAdapter sa = createStatusAdapter(message);
if (jobname == null) {
return sa;
}
Job job = new Job(jobname) {
@Override
protected IStatus run(IProgressMonitor monitor) {
return null;
}
};
sa.addAdapter(Job.class, job);
if (actionName == null) {
return sa;
}
Action action = new Action(actionName) {
};
job.setProperty(IProgressConstants.ACTION_PROPERTY, action);
return sa;
}
/**
* Creates StatusAdapter from passed parameters.
*
* @param message
* a message to be used in StatusAdapter
* @param title
* a String to be passed as StatusAdapter title
* @return status adapter with title and message
*/
private StatusAdapter createStatusAdapter(String message, String title) {
StatusAdapter sa = createStatusAdapter(message);
sa.setProperty(IStatusAdapterConstants.TITLE_PROPERTY, title);
return sa;
}
@Override
protected void tearDown() throws Exception {
Shell shell = StatusDialogUtil.getStatusShell();
FreezeMonitor.done();
if (shell != null) {
shell.dispose();
WorkbenchStatusDialogManagerImpl impl = (WorkbenchStatusDialogManagerImpl) wsdm
.getProperty(IStatusDialogConstants.MANAGER_IMPL);
assertNull(impl.getProperty(IStatusDialogConstants.CURRENT_STATUS_ADAPTER));
}
wsdm = null;
ErrorDialog.AUTOMATED_MODE = automatedMode;
Policy.setErrorSupportProvider(null);
super.tearDown();
}
// based on window.getInitialLocation
private Point getInitialLocation(Shell shell){
Point initialSize = shell.getSize();
Composite parent = shell.getParent();
Monitor monitor = shell.getDisplay().getPrimaryMonitor();
if (parent != null) {
monitor = parent.getMonitor();
}
Rectangle monitorBounds = monitor.getClientArea();
Point centerPoint;
if (parent != null) {
centerPoint = Geometry.centerPoint(parent.getBounds());
} else {
centerPoint = Geometry.centerPoint(monitorBounds);
}
return new Point(centerPoint.x - (initialSize.x / 2), Math.max(
monitorBounds.y, Math.min(centerPoint.y
- (initialSize.y * 2 / 3), monitorBounds.y
+ monitorBounds.height - initialSize.y)));
}
}