/******************************************************************************* * Copyright (c) 2007, 2014 Symbian Software Systems 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: * Andrew Ferguson (Symbian) - Initial implementation * Markus Schorn (Wind River Systems) * Sergey Prigogin (Google) *******************************************************************************/ package org.eclipse.cdt.internal.pdom.tests; import java.io.File; import java.util.regex.Pattern; import junit.framework.Test; import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.dom.IName; import org.eclipse.cdt.core.dom.IPDOMManager; import org.eclipse.cdt.core.dom.ast.IFunction; import org.eclipse.cdt.core.dom.ast.cpp.ICPPBinding; import org.eclipse.cdt.core.index.IIndexBinding; import org.eclipse.cdt.core.index.IIndexLocationConverter; import org.eclipse.cdt.core.index.IndexFilter; import org.eclipse.cdt.core.index.ResourceContainerRelativeLocationConverter; import org.eclipse.cdt.core.model.ICProject; import org.eclipse.cdt.core.model.LanguageManager; import org.eclipse.cdt.core.testplugin.CProjectHelper; import org.eclipse.cdt.core.testplugin.util.BaseTestCase; import org.eclipse.cdt.core.testplugin.util.TestSourceReader; import org.eclipse.cdt.internal.core.CCoreInternals; import org.eclipse.cdt.internal.core.index.IIndexFragment; import org.eclipse.cdt.internal.core.index.IWritableIndexFragment; import org.eclipse.cdt.internal.core.pdom.PDOM; import org.eclipse.cdt.internal.core.pdom.PDOMManager; import org.eclipse.cdt.internal.core.pdom.WritablePDOM; import org.eclipse.cdt.internal.core.pdom.db.ChunkCache; import org.eclipse.cdt.internal.core.pdom.indexer.IndexerPreferences; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IFolder; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.NullProgressMonitor; /** * Tests bugs found in the PDOM. */ public class PDOMCPPBugsTest extends BaseTestCase { ICProject cproject; public static Test suite() { return suite(PDOMCPPBugsTest.class); } @Override protected void setUp() throws Exception { super.setUp(); cproject= CProjectHelper.createCCProject("PDOMBugsTest" + System.currentTimeMillis(), "bin", IPDOMManager.ID_FAST_INDEXER); waitForIndexer(cproject); } @Override protected void tearDown() throws Exception { if (cproject != null) { cproject.getProject().delete(IResource.FORCE | IResource.ALWAYS_DELETE_PROJECT_CONTENT, new NullProgressMonitor()); } super.tearDown(); } public void testPDOMProperties() throws Exception { PDOM pdom = (PDOM) CCoreInternals.getPDOMManager().getPDOM(cproject); pdom.acquireWriteLock(0, null); try { WritablePDOM wpdom = (WritablePDOM) pdom; IIndexBinding[] b = wpdom.findBindings(Pattern.compile(".+"), false, IndexFilter.ALL, null); wpdom.setProperty("a", "b"); assertEquals("b", wpdom.getProperty("a")); wpdom.setProperty("c", "d"); assertEquals("d", wpdom.getProperty("c")); wpdom.setProperty("c", "e"); assertEquals("e", wpdom.getProperty("c")); } finally { pdom.releaseWriteLock(0, true); } } public void testProjectPDOMProperties() throws Exception { PDOM pdom = (PDOM) CCoreInternals.getPDOMManager().getPDOM(cproject); pdom.acquireReadLock(); try { String id= pdom.getProperty(IIndexFragment.PROPERTY_FRAGMENT_ID); assertNotNull(id); CCoreInternals.getPDOMManager().reindex(cproject); String id2= pdom.getProperty(IIndexFragment.PROPERTY_FRAGMENT_ID); assertNotNull(id2); assertEquals(id, id2); } finally { pdom.releaseReadLock(); } } public void testProjectPDOMPropertiesOnExport() throws Exception { // this test is currently failing on the cdt test build machine, but // not on my local linux or windows boxes. File tmp = nonExistentTempFile("temp", ".pdom"); IIndexLocationConverter cvr= new ResourceContainerRelativeLocationConverter(cproject.getProject()); final PDOMManager pdomManager = CCoreInternals.getPDOMManager(); pdomManager.exportProjectPDOM(cproject, tmp, cvr, null); IWritableIndexFragment pdom = new WritablePDOM(tmp, cvr, new ChunkCache(), LanguageManager.getInstance().getPDOMLinkageFactoryMappings()); pdom.acquireReadLock(); try { String id= pdom.getProperty(IIndexFragment.PROPERTY_FRAGMENT_ID); assertNotNull("Exported pdom ID is null", id); String id2 = getFragmentID(cproject); assertNotNull("Project pdom ID is null", id2); assertFalse("Project pdom ID equals export PDOM id", id2.equals(id)); pdomManager.reindex(cproject); waitForIndexer(cproject); String id3= pdom.getProperty(IIndexFragment.PROPERTY_FRAGMENT_ID); assertNotNull("Exported pdom ID is null after project reindex", id3); assertEquals("Exported pdom ID hasChanged during reindex", id, id3); String id4= getFragmentID(cproject); assertNotNull("Reindexed project pdom ID is null", id4); assertFalse("Reindexex project pdom ID equals exported pdom ID", id4.equals(id)); } finally { pdom.releaseReadLock(); } } private String getFragmentID(final ICProject cproject) throws CoreException, InterruptedException { PDOMManager pdomManager= CCoreInternals.getPDOMManager(); final PDOM projectPDOM = (PDOM)pdomManager.getPDOM(cproject); String id2; projectPDOM.acquireReadLock(); try { id2= (projectPDOM).getProperty(IIndexFragment.PROPERTY_FRAGMENT_ID); } finally { projectPDOM.releaseReadLock(); } return id2; } public void testInterruptingAcquireReadLock() throws Exception { final PDOM pdom= (PDOM) CCoreInternals.getPDOMManager().getPDOM(cproject); final boolean[] ok= {false}; pdom.acquireWriteLock(null); try { Thread other= new Thread() { @Override public void run() { try { pdom.acquireReadLock(); } catch (InterruptedException e) { ok[0]= true; } } }; other.start(); other.interrupt(); other.join(); assertTrue("thread was not interrupted", ok[0]); } finally { pdom.releaseWriteLock(); } pdom.acquireWriteLock(null); pdom.releaseWriteLock(); } public void testInterruptingAcquireWriteLock() throws Exception { final WritablePDOM pdom= (WritablePDOM) CCoreInternals.getPDOMManager().getPDOM(cproject); final boolean[] ok= {false}; pdom.acquireReadLock(); try { Thread other= new Thread() { @Override public void run() { try { pdom.acquireReadLock(); pdom.acquireWriteLock(1, null); } catch (InterruptedException e) { ok[0]= true; pdom.releaseReadLock(); } } }; other.start(); other.interrupt(); other.join(); assertTrue("thread was not interrupted", ok[0]); } finally { pdom.releaseReadLock(); } pdom.acquireWriteLock(null); pdom.releaseWriteLock(); } public void test191679() throws Exception { IProject project= cproject.getProject(); IFolder cHeaders= cproject.getProject().getFolder("cHeaders"); cHeaders.create(true, true, npm()); LanguageManager lm= LanguageManager.getInstance(); IFile cHeader= TestSourceReader.createFile(cHeaders, "cSource.c", "void foo(int i){}"); IFile cppSource= TestSourceReader.createFile(cHeaders, "cppSource.cpp", "extern \"C\" void foo(int i); void ref() {foo(1);}"); IndexerPreferences.set(project, IndexerPreferences.KEY_INDEXER_ID, IPDOMManager.ID_FAST_INDEXER); CCorePlugin.getIndexManager().reindex(cproject); waitForIndexer(cproject); final PDOM pdom= (PDOM) CCoreInternals.getPDOMManager().getPDOM(cproject); pdom.acquireReadLock(); try { { // test reference to 'foo' was resolved correctly IIndexBinding[] ib= pdom.findBindings(new char[][]{"foo".toCharArray()}, IndexFilter.ALL, npm()); assertEquals(2, ib.length); if (ib[0] instanceof ICPPBinding) { IIndexBinding h= ib[0]; ib[0]= ib[1]; ib[1]= h; } assertTrue(ib[0] instanceof IFunction); assertFalse(ib[0] instanceof ICPPBinding); assertTrue(ib[1] instanceof IFunction); assertTrue(ib[1] instanceof ICPPBinding); IName[] nms= pdom.findNames(ib[0], IIndexFragment.FIND_REFERENCES | IIndexFragment.SEARCH_ACROSS_LANGUAGE_BOUNDARIES); assertEquals(1, nms.length); assertTrue(nms[0].getFileLocation().getFileName().endsWith(".cpp")); nms= pdom.findNames(ib[0], IIndexFragment.FIND_REFERENCES); assertEquals(0, nms.length); nms= pdom.findNames(ib[1], IIndexFragment.FIND_DEFINITIONS | IIndexFragment.SEARCH_ACROSS_LANGUAGE_BOUNDARIES); assertEquals(1, nms.length); assertTrue(nms[0].getFileLocation().getFileName().endsWith(".c")); nms= pdom.findNames(ib[1], IIndexFragment.FIND_DEFINITIONS); assertEquals(0, nms.length); } } finally { pdom.releaseReadLock(); } } }