From d76357807964c6f939870bb07f553b10ded19d00 Mon Sep 17 00:00:00 2001 From: Sergey Prigogin Date: Tue, 16 Oct 2012 14:20:23 -0700 Subject: [PATCH] Added OneSourceMultipleHeadersTestCase class. --- .../tests/IndexBindingResolutionTestBase.java | 42 +++---- .../core/testplugin/util/BaseTestCase.java | 4 +- .../OneSourceMultipleHeadersTestCase.java | 113 ++++++++++++++++++ .../testplugin/util/TestSourceReader.java | 85 +++++++++---- 4 files changed, 198 insertions(+), 46 deletions(-) create mode 100644 core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/core/testplugin/util/OneSourceMultipleHeadersTestCase.java diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexBindingResolutionTestBase.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexBindingResolutionTestBase.java index 37b10fbad55..978a6f18bd0 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexBindingResolutionTestBase.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexBindingResolutionTestBase.java @@ -97,7 +97,7 @@ public abstract class IndexBindingResolutionTestBase extends BaseTestCase { return name; } } - + return null; } @@ -122,7 +122,7 @@ public abstract class IndexBindingResolutionTestBase extends BaseTestCase { IASTName name= findName(section, len); assertNotNull("Name not found for \"" + section + "\"", name); assertEquals(section.substring(0, len), name.getRawSignature()); - + IBinding binding = name.resolveBinding(); assertNotNull("No binding for " + name.getRawSignature(), binding); assertFalse("Binding is a ProblemBinding for name \"" + name.getRawSignature() + "\"", IProblemBinding.class.isAssignableFrom(name.resolveBinding().getClass())); @@ -136,11 +136,11 @@ public abstract class IndexBindingResolutionTestBase extends BaseTestCase { protected T getBindingFromASTName(String section, int len) { if (len <= 0) len += section.length(); - + IASTName name= findName(section, len); assertNotNull("Name not found for \"" + section + "\"", name); assertEquals(section.substring(0, len), name.getRawSignature()); - + IBinding binding = name.resolveBinding(); assertNotNull("No binding for " + name.getRawSignature(), binding); assertFalse("Binding is a ProblemBinding for name \"" + name.getRawSignature() + "\"", IProblemBinding.class.isAssignableFrom(name.resolveBinding().getClass())); @@ -157,7 +157,7 @@ public abstract class IndexBindingResolutionTestBase extends BaseTestCase { IASTName name= findName(section, len); assertNotNull("Name not found for \"" + section + "\"", name); assertEquals(section.substring(0, len), name.getRawSignature()); - + IBinding binding = name.resolveBinding(); assertNotNull("No binding for " + name.getRawSignature(), binding); assertTrue("Binding is not a ProblemBinding for name \"" + name.getRawSignature() + "\"", IProblemBinding.class.isAssignableFrom(name.resolveBinding().getClass())); @@ -267,13 +267,13 @@ public abstract class IndexBindingResolutionTestBase extends BaseTestCase { return null; return nameList.get(idx); } - + public int size() { return nameList.size(); } } - interface ITestStrategy { + protected interface ITestStrategy { IIndex getIndex(); void setUp() throws Exception; void tearDown() throws Exception; @@ -300,7 +300,7 @@ public abstract class IndexBindingResolutionTestBase extends BaseTestCase { public ICProject getCProject() { return cproject; } - + @Override public StringBuilder[] getTestData() { return testData; @@ -365,7 +365,7 @@ public abstract class IndexBindingResolutionTestBase extends BaseTestCase { public IIndex getIndex() { return index; } - + @Override public boolean isCompositeIndex() { return false; @@ -426,7 +426,7 @@ public abstract class IndexBindingResolutionTestBase extends BaseTestCase { IFile cppfile= TestSourceReader.createFile(cproject.getProject(), new Path("references.c" + (cpp ? "pp" : "")), testData[1].toString()); waitForIndexer(cproject); - + if (DEBUG) { System.out.println("Project PDOM: " + getName()); ((PDOM) CCoreInternals.getPDOMManager().getPDOM(cproject)).accept(new PDOMPrettyPrinter()); @@ -452,7 +452,7 @@ public abstract class IndexBindingResolutionTestBase extends BaseTestCase { public IIndex getIndex() { return index; } - + @Override public boolean isCompositeIndex() { return false; @@ -467,7 +467,7 @@ public abstract class IndexBindingResolutionTestBase extends BaseTestCase { * to put the contents of the section to. To request the AST of a file, put an asterisk after * the file name. */ - class SinglePDOMTestNamedFilesStrategy implements ITestStrategy { + protected class SinglePDOMTestNamedFilesStrategy implements ITestStrategy { private IIndex index; private ICProject cproject; private StringBuilder[] testData; @@ -536,7 +536,7 @@ public abstract class IndexBindingResolutionTestBase extends BaseTestCase { } CCorePlugin.getIndexManager().setIndexerId(cproject, IPDOMManager.ID_FAST_INDEXER); waitForIndexer(cproject); - + if (DEBUG) { System.out.println("Project PDOM: " + getName()); ((PDOM) CCoreInternals.getPDOMManager().getPDOM(cproject)).accept(new PDOMPrettyPrinter()); @@ -564,7 +564,7 @@ public abstract class IndexBindingResolutionTestBase extends BaseTestCase { public IIndex getIndex() { return index; } - + @Override public boolean isCompositeIndex() { return false; @@ -586,7 +586,7 @@ public abstract class IndexBindingResolutionTestBase extends BaseTestCase { public ICProject getCProject() { return cproject; } - + @Override public void tearDown() throws Exception { if (index != null) { @@ -620,7 +620,7 @@ public abstract class IndexBindingResolutionTestBase extends BaseTestCase { IndexerPreferences.set(cproject.getProject(), IndexerPreferences.KEY_INDEXER_ID, IPDOMManager.ID_FAST_INDEXER); CCorePlugin.getIndexManager().reindex(cproject); waitForIndexer(cproject); - + if (DEBUG) { System.out.println("Online: "+getName()); ((PDOM) CCoreInternals.getPDOMManager().getPDOM(cproject)).accept(new PDOMPrettyPrinter()); @@ -637,17 +637,17 @@ public abstract class IndexBindingResolutionTestBase extends BaseTestCase { CProjectHelper.createCProject("ReferencedContent" + System.currentTimeMillis(), "bin", IPDOMManager.ID_NO_INDEXER); String content = testData[0].toString(); IFile file = TestSourceReader.createFile(referenced.getProject(), new Path("header.h"), content); - + IndexerPreferences.set(referenced.getProject(), IndexerPreferences.KEY_INDEXER_ID, IPDOMManager.ID_FAST_INDEXER); CCorePlugin.getIndexManager().reindex(referenced); - + waitForIndexer(referenced); - + if (DEBUG) { System.out.println("Referenced: "+getName()); ((PDOM) CCoreInternals.getPDOMManager().getPDOM(referenced)).accept(new PDOMPrettyPrinter()); } - + return referenced; } @@ -679,7 +679,7 @@ public abstract class IndexBindingResolutionTestBase extends BaseTestCase { public StringBuilder[] getTestData() { return testData; } - + @Override public boolean isCompositeIndex() { return true; diff --git a/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/core/testplugin/util/BaseTestCase.java b/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/core/testplugin/util/BaseTestCase.java index 6d23969e328..9c366e76317 100644 --- a/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/core/testplugin/util/BaseTestCase.java +++ b/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/core/testplugin/util/BaseTestCase.java @@ -240,7 +240,7 @@ public class BaseTestCase extends TestCase { * in the log should fail the test. If the logged number of non-OK status objects * differs from the last value passed, the test is failed. If this method is not called * at all, the expected number defaults to zero. - * @param value + * @param count the expected number of logged error and warning messages */ public void setExpectedNumberOfLoggedNonOKStatusObjects(int count) { fExpectedLoggedNonOK= count; @@ -306,7 +306,7 @@ public class BaseTestCase extends TestCase { assertTrue(indexManager.isProjectRegistered(project)); assertTrue(indexManager.joinIndexer(INDEXER_TIMEOUT_SEC * 1000, npm())); } - + public static void waitUntilFileIsIndexed(IIndex index, IFile file) throws Exception { TestSourceReader.waitUntilFileIsIndexed(index, file, INDEXER_TIMEOUT_SEC * 1000); } diff --git a/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/core/testplugin/util/OneSourceMultipleHeadersTestCase.java b/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/core/testplugin/util/OneSourceMultipleHeadersTestCase.java new file mode 100644 index 00000000000..eb681dc47e3 --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/core/testplugin/util/OneSourceMultipleHeadersTestCase.java @@ -0,0 +1,113 @@ +/******************************************************************************* + * Copyright (c) 2012 Google, 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: + * Sergey Prigogin (Google) - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.core.testplugin.util; + +import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.core.dom.IPDOMManager; +import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; +import org.eclipse.cdt.core.index.IIndex; +import org.eclipse.cdt.core.model.ICProject; +import org.eclipse.cdt.core.testplugin.CProjectHelper; +import org.eclipse.cdt.internal.core.CCoreInternals; +import org.eclipse.cdt.internal.core.pdom.PDOM; +import org.eclipse.cdt.internal.pdom.tests.PDOMPrettyPrinter; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.core.runtime.Path; + +/** + * Base class for tests that use AST. The files in the test project are created from the comments + * preceding the test case. The test project will contain a single source file called source.cpp or + * source.c, depending on whether the project is for C++ or C, and zero or more header files called + * header1.h, header2.h, etc. The AST is created for the source file only and can be obtained + * by calling getAst(). + */ +public class OneSourceMultipleHeadersTestCase extends BaseTestCase { + private static final boolean DEBUG = false; + + private final TestSourceReader testSourceReader; + private final boolean cpp; + private IIndex index; + private ICProject cproject; + private StringBuilder[] testData; + private IASTTranslationUnit ast; + + public OneSourceMultipleHeadersTestCase(TestSourceReader testSourceReader, boolean cpp) { + this(null, testSourceReader, cpp); + } + + public OneSourceMultipleHeadersTestCase(String name, TestSourceReader testSourceReader, + boolean cpp) { + super(name); + this.testSourceReader = testSourceReader; + this.cpp = cpp; + } + + protected ICProject getCProject() { + return cproject; + } + + protected IIndex getIndex() { + return index; + } + + protected StringBuilder[] getTestData() { + return testData; + } + + protected IASTTranslationUnit getAst() { + return ast; + } + + public String getAstSource() { + return testData[testData.length - 1].toString(); + } + + @Override + protected void setUp() throws Exception { + cproject = cpp ? + CProjectHelper.createCCProject(getName() + System.currentTimeMillis(), "bin", IPDOMManager.ID_NO_INDEXER) : + CProjectHelper.createCProject(getName() + System.currentTimeMillis(), "bin", IPDOMManager.ID_NO_INDEXER); + testData = testSourceReader.getContentsForTest(getName()); + + if (testData.length > 0) { + for (int i = 0; i < testData.length - 1; i++) { + String filename = String.format("header%d.h", i + 1); + IFile file = TestSourceReader.createFile(cproject.getProject(), new Path(filename), testData[i].toString()); + CCorePlugin.getIndexManager().setIndexerId(cproject, IPDOMManager.ID_FAST_INDEXER); + } + } + + IFile cppfile= TestSourceReader.createFile(cproject.getProject(), new Path("source.c" + (cpp ? "pp" : "")), getAstSource()); + waitForIndexer(cproject); + + if (DEBUG) { + System.out.println("Project PDOM: " + getName()); + ((PDOM) CCoreInternals.getPDOMManager().getPDOM(cproject)).accept(new PDOMPrettyPrinter()); + } + + index= CCorePlugin.getIndexManager().getIndex(cproject); + + index.acquireReadLock(); + ast = TestSourceReader.createIndexBasedAST(index, cproject, cppfile); + } + + @Override + protected void tearDown() throws Exception { + if (index != null) { + index.releaseReadLock(); + } + if (cproject != null) { + cproject.getProject().delete(IResource.FORCE | IResource.ALWAYS_DELETE_PROJECT_CONTENT, new NullProgressMonitor()); + } + } +} diff --git a/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/core/testplugin/util/TestSourceReader.java b/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/core/testplugin/util/TestSourceReader.java index c27a7e263f6..7295d0ef6c7 100644 --- a/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/core/testplugin/util/TestSourceReader.java +++ b/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/core/testplugin/util/TestSourceReader.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2006, 2010 Wind River Systems, Inc. and others. + * Copyright (c) 2006, 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 @@ -8,7 +8,8 @@ * Contributors: * Markus Schorn - initial API and implementation * Andrew Ferguson (Symbian) - *******************************************************************************/ + * Sergey Prigogin (Google) + *******************************************************************************/ package org.eclipse.cdt.core.testplugin.util; import java.io.BufferedReader; @@ -57,23 +58,61 @@ import org.osgi.framework.Bundle; * Utilities for reading test source code from plug-in .java sources */ public class TestSourceReader { + private final Bundle bundle; + private final String srcRoot; + private final Class clazz; + private final int numSections; + + /** + * @param bundle the bundle containing the source, if {@code null} can try to load using + * classpath (source folder has to be in the classpath for this to work) + * @param srcRoot the directory inside the bundle containing the packages + * @param clazz the name of the class containing the test + */ + public TestSourceReader(Bundle bundle, String srcRoot, Class clazz) { + this(bundle, srcRoot, clazz, 0); + } + + /** + * @param bundle the bundle containing the source, if {@code null} can try to load using + * classpath (source folder has to be in the classpath for this to work) + * @param srcRoot the directory inside the bundle containing the packages + * @param clazz the name of the class containing the test + * @param numSections the number of comment sections preceding the named test to return. + * Pass zero to get all available sections. + */ + public TestSourceReader(Bundle bundle, String srcRoot, Class clazz, int numSections) { + this.bundle = bundle; + this.srcRoot = srcRoot; + this.clazz = clazz; + this.numSections = numSections; + } + + public StringBuilder[] getContentsForTest(final String testName) throws IOException { + return getContentsForTest(bundle, srcRoot, clazz, testName, numSections); + } + + public String readTaggedComment(String tag) throws IOException { + return readTaggedComment(bundle, tag, clazz, tag); + } + /** * Returns an array of StringBuilder objects for each comment section found preceding the named * test in the source code. * - * @param bundle the bundle containing the source, if null can try to load using classpath - * (source folder has to be in the classpath for this to work) + * @param bundle the bundle containing the source, if {@code null} can try to load using + * classpath (source folder has to be in the classpath for this to work) * @param srcRoot the directory inside the bundle containing the packages * @param clazz the name of the class containing the test * @param testName the name of the test - * @param sections the number of comment sections preceding the named test to return. Pass zero - * to get all available sections. + * @param numSections the number of comment sections preceding the named test to return. + * Pass zero to get all available sections. * @return an array of StringBuilder objects for each comment section found preceding the named - * test in the source code. + * test in the source code. * @throws IOException */ public static StringBuilder[] getContentsForTest(Bundle bundle, String srcRoot, Class clazz, - final String testName, int sections) throws IOException { + final String testName, int numSections) throws IOException { // Walk up the class inheritance chain until we find the test method. try { while (clazz.getMethod(testName).getDeclaringClass() != clazz) { @@ -91,7 +130,7 @@ public class TestSourceReader { fqn = fqn.indexOf("$") == -1 ? fqn : fqn.substring(0, fqn.indexOf("$")); String classFile = fqn + ".java"; IPath filePath= new Path(srcRoot + '/' + classFile); - + InputStream in; Class superclass = clazz.getSuperclass(); try { @@ -107,7 +146,7 @@ public class TestSourceReader { clazz = superclass; continue; } - + BufferedReader br = new BufferedReader(new InputStreamReader(in)); try { // Read the java file collecting comments until we encounter the test method. @@ -120,7 +159,7 @@ public class TestSourceReader { } else { if (!line.startsWith("@") && content.length() > 0) { contents.add(content); - if (sections > 0 && contents.size() == sections + 1) + if (numSections > 0 && contents.size() == numSections + 1) contents.remove(0); content = new StringBuilder(); } @@ -145,14 +184,14 @@ public class TestSourceReader { clazz = superclass; } } - + /** * Searches for the offset of the first occurrence of a string in a workspace file. * @param lookfor string to be searched for * @param fullPath full path of the workspace file * @return the offset or -1 - * @throws Exception - * @throws UnsupportedEncodingException + * @throws Exception + * @throws UnsupportedEncodingException * @since 4.0 */ public static int indexOfInFile(String lookfor, Path fullPath) throws Exception { @@ -183,7 +222,7 @@ public class TestSourceReader { reader.close(); } } - + public static int getLineNumber(int offset, Path fullPath) throws Exception { IFile file= ResourcesPlugin.getWorkspace().getRoot().getFile(fullPath); Reader reader= new BufferedReader(new InputStreamReader(file.getContents(), file.getCharset())); @@ -203,12 +242,12 @@ public class TestSourceReader { /** * Reads a section in comments form the source of the given class. The section - * is started with '// {tag}' and ends with the first line not started by '//' + * is started with '// {tag}' and ends with the first line not started by '//' * @since 4.0 */ public static String readTaggedComment(Bundle bundle, String srcRoot, Class clazz, final String tag) throws IOException { IPath filePath= new Path(srcRoot + '/' + clazz.getName().replace('.', '/') + ".java"); - + InputStream in= FileLocator.openStream(bundle, filePath, false); LineNumberReader reader= new LineNumberReader(new InputStreamReader(in)); boolean found= false; @@ -244,15 +283,15 @@ public class TestSourceReader { } /** - * Creates a file with content at the given path inside the given container. + * Creates a file with content at the given path inside the given container. * If the file exists its content is replaced. * @param container a container to create the file in * @param filePath the path relative to the container to create the file at * @param contents the content for the file * @return a file object. - * @throws CoreException + * @throws CoreException * @since 4.0 - */ + */ public static IFile createFile(final IContainer container, final IPath filePath, final CharSequence contents) throws CoreException { final IWorkspace ws = ResourcesPlugin.getWorkspace(); @@ -295,7 +334,7 @@ public class TestSourceReader { } /** - * Creates a file with content at the given path inside the given container. + * Creates a file with content at the given path inside the given container. * If the file exists its content is replaced. * @param container a container to create the file in * @param filePath the path relative to the container to create the file at @@ -309,7 +348,7 @@ public class TestSourceReader { /** * Waits until the given file is indexed. Fails if this does not happen within the - * given time. + * given time. * @param file * @param maxmillis * @throws Exception @@ -338,7 +377,7 @@ public class TestSourceReader { } finally { index.releaseReadLock(); } - + Thread.sleep(50); timeLeft= (int) (endTime - System.currentTimeMillis()); }