/******************************************************************************* * 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.Set; import java.util.TreeSet; import java.util.regex.Pattern; import junit.framework.AssertionFailedError; 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.swt.SWT; import org.eclipse.swt.widgets.Display; import org.eclipse.tcf.debug.ui.ITCFDebugUIConstants; import org.eclipse.tcf.internal.cdt.ui.breakpoints.TCFBreakpointScopeDetailPane.ContextQueryElement; import org.eclipse.tcf.internal.cdt.ui.breakpoints.TCFBreakpointScopeDetailPane.ScopeDetailInputObject; import org.eclipse.tcf.internal.debug.ui.launch.TCFLaunchContext; import org.junit.Assert; @SuppressWarnings("restriction") public class BreakpointDetailPaneTest extends AbstractTcfUITest { private BreakpointsListener fBpListener; protected VirtualTreeModelViewer fContextQueryViewViewer; protected VirtualViewerUpdatesListener fContextQueryViewListener; @Override protected void setUp() throws Exception { super.setUp(); fBpListener = new BreakpointsListener(); // CDT Breakpoint integration depends on the TCF-CDT breakpoint // integration to be active. This is normally triggered by selecting // a stack frame in the UI. Here force activation of the plugin // artificially. None of the cdt integration packages are exported, so // use the TCF Launch Context extension point indirectly to force the // plugin to load. TCFLaunchContext.getLaunchContext(null); final Display display = Display.getDefault(); display.syncExec(new Runnable() { public void run() { fContextQueryViewViewer = new VirtualTreeModelViewer( display, SWT.NONE, new PresentationContext(ITCFDebugUIConstants.ID_CONTEXT_QUERY_VIEW)); fContextQueryViewListener = new VirtualViewerUpdatesListener(fContextQueryViewViewer); } }); } @Override protected void tearDown() throws Exception { final Display display = Display.getDefault(); display.syncExec(new Runnable() { public void run() { fContextQueryViewListener.dispose(); fContextQueryViewViewer.dispose(); } }); fBpListener.dispose(); super.tearDown(); } public void testContextQueryFilter() throws Exception { final TestProcessInfo processInfo1 = initProcessModel("tcf_test_func0"); final TestProcessInfo processInfo2 = initProcessModel("tcf_test_func0"); // Note: run control prefixes process ID with a "P", but the // filter expects the ID without the "P". String processId1 = processInfo1.fProcessId; if (processId1.startsWith("P")) processId1 = processId1.substring(1); final String queryPid1 = "pid=" + processId1; try { fContextQueryViewListener.reset(); Display.getDefault().syncExec(new Runnable() { public void run() { fContextQueryViewViewer.setAutoExpandLevel(-1); fContextQueryViewViewer.setInput(new ScopeDetailInputObject(new ContextQueryElement(queryPid1, null))); fContextQueryViewViewer.getPresentationContext().setProperty(ITCFDebugUIConstants.PROP_CONTEXT_QUERY, queryPid1); }}); fContextQueryViewListener.waitTillFinished(CONTENT_SEQUENCE_COMPLETE | LABEL_UPDATES_RUNNING); VirtualItem scopeItem = fContextQueryViewListener.findElement(new Pattern[] { Pattern.compile(".*pid\\="+processInfo1.fProcessId+".*") }); scopeItem = fContextQueryViewListener.findElement(new Pattern[] { Pattern.compile(escapeBrackets("(2) Filter: " + queryPid1)), // filter name Pattern.compile(escapeBrackets("(2) test.*")), // launch Pattern.compile(escapeBrackets("(1).*agent.*")), // process name Pattern.compile(".*" + processInfo1.fThreadId+".*") }); // thread Assert.assertTrue(scopeItem != null); fContextQueryViewListener.reset(); //fContextQueryViewListener.waitTillFinished(MODEL_CHANGED_COMPLETE | CONTENT_SEQUENCE_COMPLETE | LABEL_UPDATES_RUNNING); // Check that second process is filtered out. scopeItem = fContextQueryViewListener.findElement(new Pattern[] { Pattern.compile("\\([0-9]+\\) Filter: " + queryPid1), // filter name Pattern.compile("\\([0-9]+\\) test.*"), // launch Pattern.compile("\\([0-9]+\\) .*agent.*"), // process name Pattern.compile(".*"+processInfo2.fThreadId+".*") }); // thread Assert.assertTrue(scopeItem == null); scopeItem = fContextQueryViewListener.findElement(new Pattern[] { Pattern.compile(".*pid\\="+processInfo2.fProcessId+".*") }); Assert.assertTrue(scopeItem == null); // Allprocesses in query // TODO: need a filter that will match all // fContextQueryViewListener.reset(); // final String queryPidAll = "KernelName=Linux"; // Display.getDefault().syncExec(new Runnable() { public void run() { // fContextQueryViewViewer.setInput(new ScopeDetailInputObject(new ContextQueryElement(queryPidAll, null))); // fContextQueryViewViewer.getPresentationContext().setProperty(ITCFDebugUIConstants.PROP_CONTEXT_QUERY, queryPidAll); // }}); // fContextQueryViewListener.waitTillFinished(CONTENT_SEQUENCE_COMPLETE | LABEL_UPDATES_RUNNING); // // scopeItem = fContextQueryViewListener.findElement(new Pattern[] { // Pattern.compile(escapeBrackets("(4) Filter: " + queryPidAll)), // filter name // Pattern.compile(escapeBrackets("(4) test.*")), // launch // Pattern.compile(escapeBrackets("(1).*agent.*")), // process name // Pattern.compile(".*" + processInfo1.fThreadId+".*") }); // thread // Assert.assertTrue(scopeItem != null); // // scopeItem = fContextQueryViewListener.findElement(new Pattern[] { // Pattern.compile(escapeBrackets("(4) Filter: " + queryPidAll)), // filter name // Pattern.compile(escapeBrackets("(4) test.*")), // launch // Pattern.compile(escapeBrackets("(1).*agent.*")), // process name // Pattern.compile(".*" + processInfo2.fThreadId+".*") }); // thread // Assert.assertTrue(scopeItem != null); // } catch (AssertionFailedError e) { System.out.print("Context query view dump: \n:" + fContextQueryViewViewer.toString()); throw e; } } public void testContextsFilter() throws Exception { final TestProcessInfo processInfo1 = initProcessModel("tcf_test_func0"); final TestProcessInfo processInfo2 = initProcessModel("tcf_test_func0"); // Note: run control prefixes process ID with a "P", but the // filter expects the ID without the "P". final Set<String> processContexts1 = new TreeSet<String>(); processContexts1.add( fLaunch.getLaunchConfiguration().getName() + "/" + processInfo1.fThreadId ); try { fContextQueryViewListener.reset(); Display.getDefault().syncExec(new Runnable() { public void run() { fContextQueryViewViewer.setAutoExpandLevel(-1); fContextQueryViewViewer.setInput(new ScopeDetailInputObject(new ContextQueryElement(null, processContexts1))); fContextQueryViewViewer.getPresentationContext().setProperty(ITCFDebugUIConstants.PROP_FILTER_CONTEXTS, processContexts1); }}); fContextQueryViewListener.waitTillFinished(CONTENT_SEQUENCE_COMPLETE | LABEL_UPDATES_RUNNING); VirtualItem scopeItem = fContextQueryViewListener.findElement(new Pattern[] { Pattern.compile(".*pid\\="+processInfo1.fProcessId+".*") }); scopeItem = fContextQueryViewListener.findElement(new Pattern[] { Pattern.compile(escapeBrackets("(1) Contexts: " + processContexts1)), // filter name Pattern.compile(escapeBrackets("(1) test.*")), // launch Pattern.compile(escapeBrackets("(1).*agent.*")), // process name Pattern.compile(".*" + processInfo1.fThreadId+".*") }); // thread Assert.assertTrue(scopeItem != null); fContextQueryViewListener.reset(); // Check that second process is filtered out. scopeItem = fContextQueryViewListener.findElement(new Pattern[] { Pattern.compile("\\([0-9]+\\) Contexts: " + escapeBrackets(processContexts1.toString())), // filter name Pattern.compile("\\([0-9]+\\) test.*"), // launch Pattern.compile("\\([0-9]+\\) .*agent.*"), // process name Pattern.compile(".*"+processInfo2.fThreadId+".*") }); // thread Assert.assertTrue(scopeItem == null); scopeItem = fContextQueryViewListener.findElement(new Pattern[] { Pattern.compile(".*pid\\="+processInfo2.fProcessId+".*") }); Assert.assertTrue(scopeItem == null); // Allprocesses in query fContextQueryViewListener.reset(); final Set<String> processContextsAll = new TreeSet<String>(); processContextsAll.add( fLaunch.getLaunchConfiguration().getName() + "/" + processInfo1.fThreadId ); processContextsAll.add( fLaunch.getLaunchConfiguration().getName() + "/" + processInfo2.fThreadId ); Display.getDefault().syncExec(new Runnable() { public void run() { fContextQueryViewViewer.setInput(new ScopeDetailInputObject(new ContextQueryElement(null, processContextsAll))); fContextQueryViewViewer.getPresentationContext().setProperty(ITCFDebugUIConstants.PROP_FILTER_CONTEXTS, processContextsAll); }}); fContextQueryViewListener.waitTillFinished(CONTENT_SEQUENCE_COMPLETE | LABEL_UPDATES_RUNNING); scopeItem = fContextQueryViewListener.findElement(new Pattern[] { Pattern.compile(escapeBrackets("(2) Contexts: " + processContextsAll)), // filter name Pattern.compile(escapeBrackets("(2) test.*")), // launch Pattern.compile(escapeBrackets("(1).*agent.*")), // process name Pattern.compile(".*" + processInfo1.fThreadId+".*") }); // thread Assert.assertTrue(scopeItem != null); scopeItem = fContextQueryViewListener.findElement(new Pattern[] { Pattern.compile(escapeBrackets("(2) Contexts: " + processContextsAll)), // filter name Pattern.compile(escapeBrackets("(2) test.*")), // launch Pattern.compile(escapeBrackets("(1).*agent.*")), // process name Pattern.compile(".*" + processInfo2.fThreadId+".*") }); // thread Assert.assertTrue(scopeItem != null); } catch (AssertionFailedError e) { System.out.print("Context query view dump: \n:" + fContextQueryViewViewer.toString()); throw e; } } private String escapeBrackets(String s) { StringBuffer escaped = new StringBuffer(); for (int i = 0; i < s.length(); i++) { char c = s.charAt(i); if (c == '[' || c == ']' || c == '(' || c == ')') { escaped.append('\\'); } escaped.append(c); // Make spaces optional: if (c == ' ') { escaped.append("*"); } } return escaped.toString(); } }