/*******************************************************************************
* Copyright (c) 2012 Wind River Systems, Inc. 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:
* Wind River Systems - initial API and implementation
*******************************************************************************/
package org.eclipse.tcf.debug.test;
import java.util.concurrent.ExecutionException;
import java.util.regex.Pattern;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.internal.ui.IInternalDebugUIConstants;
import org.eclipse.debug.internal.ui.elements.adapters.DefaultBreakpointsViewInput;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext;
import org.eclipse.debug.internal.ui.viewers.model.provisional.PresentationContext;
import org.eclipse.debug.internal.ui.viewers.model.provisional.VirtualItem;
import org.eclipse.debug.internal.ui.viewers.model.provisional.VirtualTreeModelViewer;
import org.eclipse.debug.ui.DebugUITools;
import org.eclipse.debug.ui.IDebugUIConstants;
import org.eclipse.debug.ui.contexts.AbstractDebugContextProvider;
import org.eclipse.jface.dialogs.MessageDialogWithToggle;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.TreePath;
import org.eclipse.jface.viewers.TreeSelection;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Display;
import org.eclipse.tcf.debug.test.util.Transaction;
import org.eclipse.tcf.debug.ui.ITCFModel;
import org.eclipse.tcf.debug.ui.ITCFObject;
import org.eclipse.tcf.protocol.IChannel;
import org.eclipse.tcf.te.tests.interfaces.IConfigurationProperties;
import org.junit.Assert;
import org.osgi.framework.Bundle;
/**
* Base test for validating TCF Debugger UI.
*/
@SuppressWarnings("restriction")
public abstract class AbstractTcfUITest extends AbstractCMTest implements IViewerUpdatesListenerConstants {
protected VirtualTreeModelViewer fDebugViewViewer;
protected TestDebugContextProvider fDebugContextProvider;
protected VirtualViewerUpdatesListener fDebugViewListener;
protected VariablesVirtualTreeModelViewer fVariablesViewViewer;
protected VirtualViewerUpdatesListener fVariablesViewListener;
protected VariablesVirtualTreeModelViewer fRegistersViewViewer;
protected VirtualViewerUpdatesListener fRegistersViewListener;
protected VariablesVirtualTreeModelViewer fBreakpointsViewViewer;
protected VirtualViewerUpdatesListener fBreakpointsViewListener;
protected TestSourceDisplayService fSourceDisplayService;
protected SourceDisplayListener fSourceDisplayListener;
/* (non-Javadoc)
* @see org.eclipse.tcf.te.tests.CoreTestCase#getTestBundle()
*/
@Override
protected Bundle getTestBundle() {
return Activator.getDefault().getBundle();
}
/* (non-Javadoc)
* @see org.eclipse.tcf.te.tests.CoreTestCase#initialize()
*/
@Override
protected void initialize() {
// Turn off the automatic perspective switch and debug view activation to avoid
// JFace views from interfering with the virtual viewers used in tests.
IPreferenceStore prefs = DebugUITools.getPreferenceStore();
prefs.setValue(IInternalDebugUIConstants.PREF_ACTIVATE_DEBUG_VIEW, false);
prefs.setValue(IInternalDebugUIConstants.PREF_SWITCH_PERSPECTIVE_ON_SUSPEND, MessageDialogWithToggle.NEVER);
super.initialize();
// Do not activate debug view or debug perspective, also to avoid interfering
// with tests' virtual viewers.
setProperty(IConfigurationProperties.TARGET_PERSPECTIVE, "org.eclipse.cdt.ui.CPerspective"); //$NON-NLS-1$
setProperty(IConfigurationProperties.TARGET_VIEW, "org.eclipse.cdt.ui.CView"); //$NON-NLS-1$
}
@Override
protected void setUp() throws Exception {
super.setUp();
createDebugViewViewer();
}
@Override
protected void tearDown() throws Exception {
disposeDebugViewViewer();
super.tearDown();
}
private void createDebugViewViewer() {
final Display display = Display.getDefault();
display.syncExec(new Runnable() {
public void run() {
fDebugViewViewer = new VirtualTreeModelViewer(display, SWT.NONE, new PresentationContext(IDebugUIConstants.ID_DEBUG_VIEW));
fDebugViewViewer.setInput(DebugPlugin.getDefault().getLaunchManager());
fDebugViewViewer.setAutoExpandLevel(-1);
fDebugViewListener = new VirtualViewerUpdatesListener(fDebugViewViewer);
fDebugContextProvider = new TestDebugContextProvider(fDebugViewViewer);
fVariablesViewViewer = new VariablesVirtualTreeModelViewer(IDebugUIConstants.ID_VARIABLE_VIEW, fDebugContextProvider);
fVariablesViewListener = new VirtualViewerUpdatesListener(fVariablesViewViewer);
fRegistersViewViewer = new VariablesVirtualTreeModelViewer(IDebugUIConstants.ID_REGISTER_VIEW, fDebugContextProvider);
fRegistersViewListener = new VirtualViewerUpdatesListener(fRegistersViewViewer);
final IPresentationContext context = new PresentationContext(IDebugUIConstants.ID_BREAKPOINT_VIEW);
fBreakpointsViewViewer = new VariablesVirtualTreeModelViewer(
context,
new AbstractDebugContextProvider(null) {
private final ISelection fInput = new TreeSelection( new TreePath(new Object[] { new DefaultBreakpointsViewInput(context) }) );
@Override
public ISelection getActiveContext() {
return fInput;
}
});
fBreakpointsViewListener = new VirtualViewerUpdatesListener(fBreakpointsViewViewer);
fSourceDisplayService = new TestSourceDisplayService(fDebugContextProvider);
fSourceDisplayListener = new SourceDisplayListener();
}
});
}
private void disposeDebugViewViewer() {
final Display display = Display.getDefault();
display.syncExec(new Runnable() {
public void run() {
fSourceDisplayListener.dispose();
fSourceDisplayService.dispose();
fDebugViewListener.dispose();
fDebugContextProvider.dispose();
fDebugViewViewer.dispose();
fVariablesViewListener.dispose();
fVariablesViewViewer.dispose();
fRegistersViewListener.dispose();
fRegistersViewViewer.dispose();
}
});
}
protected TestProcessInfo initProcessModel(String testFunc) throws Exception {
String bpId = "entryPointBreakpoint";
createBreakpoint(bpId, testFunc);
fDebugViewListener.reset();
final TestProcessInfo processInfo = startProcess();
ITCFObject processTCFContext = new ITCFObject() {
@Override public String getID() { return processInfo.fProcessId; }
@Override public IChannel getChannel() { return channels[0]; }
@Override public Object getAdapter(@SuppressWarnings("rawtypes") Class adapter) { return null; }
@Override public ITCFModel getModel() { return null; }
@Override public ITCFObject getParent() { return null; }
};
ITCFObject threadTCFContext = new ITCFObject() {
@Override public String getID() { return processInfo.fThreadId; }
@Override public IChannel getChannel() { return channels[0]; }
@Override public Object getAdapter(@SuppressWarnings("rawtypes") Class adapter) { return null; }
@Override public ITCFModel getModel() { return null; }
@Override public ITCFObject getParent() { return null; }
};
// Make sure that delta is posted after launching process so that it doesn't interfere
// with the waiting for the whole viewer to update after breakpoint hit (below).
fDebugViewListener.waitTillFinished(MODEL_CHANGED_COMPLETE| CONTENT_SEQUENCE_COMPLETE);
fDebugViewListener.reset();
runToTestEntry(processInfo, testFunc);
removeBreakpoint(bpId);
final String topFrameId = new Transaction<String>() {
@Override
protected String process() throws InvalidCacheException, ExecutionException {
String[] frameIds = validate( fStackTraceCM.getChildren(processInfo.fThreadId) );
Assert.assertTrue("No stack frames" , frameIds.length != 0);
return frameIds[frameIds.length - 1];
}
}.get();
ITCFObject frameTCFContext = new ITCFObject() {
@Override public String getID() { return topFrameId; }
@Override public IChannel getChannel() { return channels[0]; }
@Override public Object getAdapter(@SuppressWarnings("rawtypes") Class adapter) { return null; }
@Override public ITCFModel getModel() { return null; }
@Override public ITCFObject getParent() { return null; }
};
VirtualItem topFrameItem = null;
long timeout = System.currentTimeMillis() + TIMEOUT_DEFAULT;
do {
fDebugViewListener.addLabelUpdate(new TreePath(new Object[] { fLaunch, processTCFContext, threadTCFContext, frameTCFContext }));
fDebugViewListener.waitTillFinished(MODEL_CHANGED_COMPLETE | CONTENT_SEQUENCE_COMPLETE | LABEL_SEQUENCE_COMPLETE | LABEL_UPDATES);
topFrameItem = fDebugViewListener.findElement(
new Pattern[] { Pattern.compile(".*"), Pattern.compile(".*"), Pattern.compile(".*" + processInfo.fProcessId + ".*\\(.*[Bb]reakpoint.*"), Pattern.compile(".*")});
fDebugViewListener.reset();
} while (topFrameItem == null && System.currentTimeMillis() < timeout);
if (topFrameItem == null) {
Assert.fail("Top stack frame not found. \n\nDebug view dump: \n:" + fDebugViewViewer.toString());
}
return processInfo;
}
}