/******************************************************************************* * Copyright (c) 2012-2013 Red Hat, Inc. * 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: * Red Hat - initial API and implementation *******************************************************************************/ package org.eclipse.linuxtools.systemtap.ui.ide.test.editors.stp; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.FileWriter; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import org.eclipse.core.runtime.FileLocator; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.Path; import org.eclipse.jface.text.BadLocationException; import org.eclipse.jface.text.Document; import org.eclipse.jface.text.IDocument; import org.eclipse.jface.text.contentassist.ICompletionProposal; import org.eclipse.linuxtools.internal.systemtap.ui.ide.editors.stp.STPCompletionProcessor; import org.eclipse.linuxtools.internal.systemtap.ui.ide.editors.stp.STPDocumentProvider; import org.eclipse.linuxtools.internal.systemtap.ui.ide.editors.stp.STPEditor; import org.eclipse.linuxtools.internal.systemtap.ui.ide.structures.TapsetLibrary; import org.junit.BeforeClass; import org.junit.Test; import org.osgi.framework.FrameworkUtil; public class STPCompletionProcessorTest { private static String TEST_STP_SCRIPT = ""+ "\n"+ "\n//marker1"+ "probe syscall.write{\n"+ " // Some comment inside a probe\n"+ " printf(\"%s fd %d\taddr%d\tcount%dargstr%s\n\", name, fd, buf_uaddr, count, argstr)\n"+ "}\n"+ "\n"; private static class MockSTPDocumentProvider extends STPDocumentProvider { private IDocument document; MockSTPDocumentProvider(IDocument document){ this.document = document; this.setupDocument(document); } protected IDocument createDocument() { return document; } } private static class MockSTPEditor extends STPEditor { public MockSTPEditor(IDocument document) { super(); setDocumentProvider(new MockSTPDocumentProvider(document)); } } /** * Use pre-written contents to populate the Function & Probe views. */ @BeforeClass public static void prepareTrees() { TapsetLibrary.stop(); IPath path = new Path(System.getenv("HOME")). //$NON-NLS-1$ append(".systemtapgui").append("TreeSettings"). addFileExtension("xml"); //$NON-NLS-1$ try (InputStream is = FileLocator.openStream( FrameworkUtil.getBundle(STPCompletionProcessorTest.class), new Path("helpers/TreeSettings.xml"), false); BufferedReader br = new BufferedReader( new InputStreamReader(is)); BufferedWriter writer = new BufferedWriter(new FileWriter(path.toFile()))) { String line; while ((line = br.readLine()) != null) { writer.write(line); writer.newLine(); } writer.flush(); TapsetLibrary.readTreeFile(); } catch (IOException e) { fail("Unable to read dummy function/probe tree file for testing"); } } @Test public void testCompletionRequest() { Document testDocument = new Document(""); STPCompletionProcessor completionProcessor = new STPCompletionProcessor(); ICompletionProposal[] proposals = completionProcessor .computeCompletionProposals(testDocument, 0); assertNotNull(proposals); } @Test public void testCompletionRequestAtEOF() { Document testDocument = new Document(TEST_STP_SCRIPT); STPCompletionProcessor completionProcessor = new STPCompletionProcessor(); ICompletionProposal[] proposals = completionProcessor .computeCompletionProposals(testDocument, TEST_STP_SCRIPT.length()); assertNotNull(proposals); } @Test public void testGlobalCompletion() { MockSTPDocumentProvider provider = new MockSTPDocumentProvider(new Document(TEST_STP_SCRIPT)); IDocument testDocument = provider.createDocument(); int offset = TEST_STP_SCRIPT.indexOf("//marker1"); STPCompletionProcessor completionProcessor = new STPCompletionProcessor(); ICompletionProposal[] proposals = completionProcessor .computeCompletionProposals(testDocument, offset); assertTrue(proposalsContain(proposals, "probe ")); assertTrue(proposalsContain(proposals, "global ")); assertTrue(proposalsContain(proposals, "function ")); } @Test public void testGlobalPartialCompletion() throws BadLocationException { String prefix = "prob"; ICompletionProposal[] proposals = getCompletionsForPrefix(prefix); assertTrue(proposalsContain(proposals, "probe ")); assertTrue(!proposalsContain(proposals, "global ")); assertTrue(!proposalsContain(proposals, "function ")); } @Test public void testProbeCompletion() throws BadLocationException { String prefix = "probe "; ICompletionProposal[] proposals = getCompletionsForPrefix(prefix); assertTrue(proposalsContain(proposals, "syscall")); assertTrue(!proposalsContain(proposals, "syscall.write")); } @Test public void testMultiProbeCompletion() throws BadLocationException { String prefix = "probe begin,e"; ICompletionProposal[] proposals = getCompletionsForPrefix(prefix); assertTrue(proposalsContain(proposals, "end")); assertTrue(proposalsContain(proposals, "error")); prefix = "probe myBegin = b"; proposals = getCompletionsForPrefix(prefix); assertTrue(proposalsContain(proposals, "begin")); } @Test public void testGlobalInvalidCompletion() throws BadLocationException { ICompletionProposal[] proposals = getCompletionsForPrefix("probe fake.fake"); assertEquals(proposals.length, 0); } @Test public void testStaticProbeCompletion() throws BadLocationException { ICompletionProposal[] proposals = getCompletionsForPrefix("probe kernel."); assertTrue(proposalsContain(proposals, "kernel.function(string)")); assertTrue(proposalsContain(proposals, "kernel.mark(string)")); } @Test public void testEndProbeCompletion() throws BadLocationException { Document testDocument = new Document(TEST_STP_SCRIPT); @SuppressWarnings("unused") MockSTPEditor editor = new MockSTPEditor(testDocument); int offset = TEST_STP_SCRIPT.indexOf("//marker1"); String prefix = "probe end{}"; testDocument.replace(offset, 0, prefix); offset += prefix.length() - 1; STPCompletionProcessor completionProcessor = new STPCompletionProcessor(); ICompletionProposal[] proposals = completionProcessor .computeCompletionProposals(testDocument, offset); assertTrue(proposalsContain(proposals, "addr")); assertTrue(proposalsContain(proposals, "backtrace")); assertTrue(proposalsContain(proposals, "cmdline_args")); } @Test public void testProbeVariableCompletion() throws BadLocationException { Document testDocument = new Document(TEST_STP_SCRIPT); @SuppressWarnings("unused") MockSTPEditor editor = new MockSTPEditor(testDocument); int offset = TEST_STP_SCRIPT.indexOf("//marker1"); String prefix = "probe syscall.write{}"; testDocument.replace(offset, 0, prefix); offset += prefix.length() - 1; STPCompletionProcessor completionProcessor = new STPCompletionProcessor(); ICompletionProposal[] proposals = completionProcessor .computeCompletionProposals(testDocument, offset); assertTrue(proposalsContain(proposals, "fd:long")); assertTrue(proposalsContain(proposals, "name:string")); assertTrue(proposalsContain(proposals, "buf_uaddr:long")); } @Test public void testStaticProbeNormalizationCompletion() throws BadLocationException { ICompletionProposal[] proposals = getCompletionsForPrefix("probe kernel.function(\"PATTERNASDF\")."); assertTrue(proposalsContain(proposals, "kernel.function(string).return")); proposals = getCompletionsForPrefix("probe probe process(\"PAT/H/\")."); assertTrue(proposalsContain(proposals, "process(string).begin")); assertTrue(proposalsContain(proposals, "process(string).end")); proposals = getCompletionsForPrefix("probe process(123)."); assertTrue(proposalsContain(proposals, "process(number).begin")); assertTrue(proposalsContain(proposals, "process(number).end")); proposals = getCompletionsForPrefix("probe module(\"MPATTERasdfN\")."); assertTrue(proposalsContain(proposals, "module(string).function(string)")); assertTrue(proposalsContain(proposals, "module(string).statement(string)")); } private static ICompletionProposal[] getCompletionsForPrefix(String prefix) throws BadLocationException { MockSTPDocumentProvider provider = new MockSTPDocumentProvider(new Document(TEST_STP_SCRIPT)); IDocument testDocument = provider.createDocument(); int offset = TEST_STP_SCRIPT.indexOf("//marker1"); testDocument.replace(offset, 0, prefix); offset += prefix.length(); STPCompletionProcessor completionProcessor = new STPCompletionProcessor(); ICompletionProposal[] proposals = completionProcessor .computeCompletionProposals(testDocument, offset); return proposals; } @Test public void testFunctionCompletion() throws BadLocationException { Document testDocument = new Document(TEST_STP_SCRIPT); @SuppressWarnings("unused") MockSTPEditor editor = new MockSTPEditor(testDocument); int offset = TEST_STP_SCRIPT.indexOf("//marker1"); String prefix = "probe syscall.write{addr}"; testDocument.replace(offset, 0, prefix); offset += prefix.length() - 1; STPCompletionProcessor completionProcessor = new STPCompletionProcessor(); ICompletionProposal[] proposals = completionProcessor .computeCompletionProposals(testDocument, offset); assertTrue(proposalsContain(proposals, "addr")); assertTrue(proposalsContain(proposals, "addr_from_rqst")); assertTrue(proposalsContain(proposals, "addr_from_rqst_str")); } private static boolean proposalsContain(ICompletionProposal[] proposals, String proposal){ for (ICompletionProposal p : proposals) { if (p.getDisplayString().contains(proposal)) { return true; } } return false; } }