/******************************************************************************* * 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.math.BigInteger; import java.util.Map; import java.util.TreeMap; import java.util.concurrent.ExecutionException; import java.util.regex.Pattern; import junit.framework.AssertionFailedError; import org.eclipse.cdt.debug.core.CDIDebugModel; import org.eclipse.cdt.debug.core.model.ICBreakpointType; import org.eclipse.cdt.debug.core.model.ICLineBreakpoint; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.Path; import org.eclipse.debug.internal.ui.breakpoints.provisional.IBreakpointOrganizer; import org.eclipse.debug.internal.ui.breakpoints.provisional.IBreakpointUIConstants; import org.eclipse.debug.internal.ui.viewers.model.provisional.VirtualItem; import org.eclipse.jface.resource.ImageDescriptor; import org.eclipse.tcf.debug.test.services.RunControlCM.ContextState; import org.eclipse.tcf.debug.test.util.Transaction; import org.eclipse.tcf.internal.cdt.ui.breakpoints.BreakpointScopeOrganizer; import org.eclipse.tcf.internal.debug.model.TCFBreakpointsModel; import org.eclipse.tcf.internal.debug.ui.launch.TCFLaunchContext; import org.eclipse.tcf.protocol.Protocol; import org.eclipse.tcf.services.ILineNumbers.CodeArea; import org.eclipse.tcf.services.ISymbols.Symbol; import org.junit.Assert; @SuppressWarnings("restriction") public class BreakpointsViewTest extends AbstractTcfUITest { private BreakpointsListener fBpListener; @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); } @Override protected void tearDown() throws Exception { fBpListener.dispose(); super.tearDown(); } private CodeArea getFunctionCodeArea(final TestProcessInfo processInfo, String functionName) throws Exception { return new Transaction<CodeArea>() { @Override protected CodeArea process() throws InvalidCacheException, ExecutionException { ContextState state = validate ( fRunControlCM.getState(processInfo.fThreadId) ); String symId = validate ( fSymbolsCM.find(processInfo.fProcessId, new BigInteger(state.pc), "tcf_test_func0") ); Symbol sym = validate ( fSymbolsCM.getContext(symId) ); CodeArea[] area = validate ( fLineNumbersCM.mapToSource( processInfo.fProcessId, sym.getAddress(), new BigInteger(sym.getAddress().toString()).add(BigInteger.valueOf(1))) ); return area[0]; } }.get(); } private ICLineBreakpoint createLineBreakpoint(String file, int line, String query, String contexts) throws CoreException, ExecutionException, InterruptedException { // Initiate wait for the context changed event. final Object contextChangedWaitKey = new Object(); Protocol.invokeAndWait(new Runnable() { public void run() { fBreakpointsCM.waitContextAdded(contextChangedWaitKey); }}); final ICLineBreakpoint bp = CDIDebugModel.createBlankLineBreakpoint(); Map<String, Object> attrs = new TreeMap<String, Object>(); CDIDebugModel.setLineBreakpointAttributes(attrs, file, ICBreakpointType.REGULAR, line, true, 0, ""); attrs.put(TCFBreakpointsModel.ATTR_CONTEXT_QUERY, query); attrs.put(TCFBreakpointsModel.ATTR_CONTEXTIDS, contexts); CDIDebugModel.createBreakpointMarker(bp, ResourcesPlugin.getWorkspace().getRoot(), attrs, true); return bp; } public void testScopeGrouping() throws Exception { TestProcessInfo processInfo = initProcessModel("tcf_test_func0"); CodeArea func0CodeArea = getFunctionCodeArea(processInfo, "tcf_test_func0"); createLineBreakpoint(func0CodeArea.file, func0CodeArea.start_line, null, null); CodeArea func1CodeArea = getFunctionCodeArea(processInfo, "tcf_test_func1"); createLineBreakpoint(func1CodeArea.file, func1CodeArea.start_line, "test_query", null); CodeArea func2CodeArea = getFunctionCodeArea(processInfo, "tcf_test_func2"); createLineBreakpoint(func2CodeArea.file, func2CodeArea.start_line, null, "test_contexts"); CodeArea func3CodeArea = getFunctionCodeArea(processInfo, "tcf_test_func3"); createLineBreakpoint(func3CodeArea.file, func3CodeArea.start_line, "test_query", "test_contexts"); try { fBreakpointsViewListener.reset(); fBreakpointsViewViewer.getPresentationContext().setProperty( IBreakpointUIConstants.PROP_BREAKPOINTS_ORGANIZERS, new IBreakpointOrganizer[] { createScopeOrganizer() }); fBreakpointsViewViewer.setAutoExpandLevel(-1); fBreakpointsViewViewer.setActive(true); fBreakpointsViewListener.waitTillFinished(CONTENT_SEQUENCE_COMPLETE | LABEL_UPDATES_RUNNING); VirtualItem bpItem = fBreakpointsViewListener.findElement(new Pattern[] { Pattern.compile(".*Global.*"), Pattern.compile(".*" + new Path(func0CodeArea.file).lastSegment() + ".*line: " + func0CodeArea.start_line + ".*"),}); // thread Assert.assertTrue(bpItem != null); bpItem = fBreakpointsViewListener.findElement(new Pattern[] { Pattern.compile(".*test_query.*"), Pattern.compile(".*" + new Path(func1CodeArea.file).lastSegment() + ".*line: " + func1CodeArea.start_line + ".*"),}); // thread Assert.assertTrue(bpItem != null); bpItem = fBreakpointsViewListener.findElement(new Pattern[] { Pattern.compile(".*test_contexts.*"), Pattern.compile(".*" + new Path(func2CodeArea.file).lastSegment() + ".*line: " + func2CodeArea.start_line + ".*"),}); // thread Assert.assertTrue(bpItem != null); bpItem = fBreakpointsViewListener.findElement(new Pattern[] { Pattern.compile(".*test_query.*test_contexts.*"), Pattern.compile(".*" + new Path(func3CodeArea.file).lastSegment() + ".*line: " + func3CodeArea.start_line + ".*"),}); // thread Assert.assertTrue(bpItem != null); } catch (AssertionFailedError e) { System.out.print("Breakpoints view dump: \n:" + fBreakpointsViewViewer.toString()); throw e; } } private IBreakpointOrganizer createScopeOrganizer() { class MyBreakpointOrganizer extends BreakpointScopeOrganizer implements IBreakpointOrganizer { public String getLabel() { return "Scope"; } public ImageDescriptor getImageDescriptor() { return null; } public String getIdentifier() { return "tcf_scope"; } public String getOthersLabel() { return "others"; } } return new MyBreakpointOrganizer(); } }