From 6ddba293ac9c7c4865e7158fc1d1afba13732047 Mon Sep 17 00:00:00 2001 From: Andrew Ferguson Date: Tue, 27 Mar 2007 11:32:21 +0000 Subject: [PATCH] 178998: apply fix for controlled behaviour on prebuilt pdom version mismatch --- .../pdom/tests/PDOMProviderTests.java | 68 +++++++++++++++++++ .../core/testplugin/util/BaseTestCase.java | 29 ++++---- .../cdt/internal/core/index/IndexFactory.java | 44 ++++++++---- .../core/index/provider/Messages.java | 1 + .../core/index/provider/PDOMCache.java | 53 +++++++++++---- .../provider/ReadOnlyPDOMProviderBridge.java | 6 +- .../core/index/provider/messages.properties | 1 + 7 files changed, 163 insertions(+), 39 deletions(-) diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/pdom/tests/PDOMProviderTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/pdom/tests/PDOMProviderTests.java index a08692162f8..f63c3cff0a8 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/pdom/tests/PDOMProviderTests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/pdom/tests/PDOMProviderTests.java @@ -28,11 +28,13 @@ import org.eclipse.cdt.core.index.provider.IPDOMDescriptor; import org.eclipse.cdt.core.index.provider.IReadOnlyPDOMProvider; import org.eclipse.cdt.core.model.ICProject; import org.eclipse.cdt.core.settings.model.ICConfigurationDescription; +import org.eclipse.cdt.core.settings.model.ICProjectDescription; import org.eclipse.cdt.core.testplugin.CProjectHelper; import org.eclipse.cdt.core.testplugin.util.TestSourceReader; import org.eclipse.cdt.internal.core.CCoreInternals; import org.eclipse.cdt.internal.core.index.provider.IndexProviderManager; import org.eclipse.cdt.internal.core.index.provider.ReadOnlyPDOMProviderBridge; +import org.eclipse.cdt.internal.core.pdom.WritablePDOM; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.Path; @@ -212,4 +214,70 @@ public class PDOMProviderTests extends PDOMTestBase { assertEquals(3, bindings.length); } } + + /* + * see bugzilla 178998 + */ + public void testVersionMismatchOfExternalPDOM() throws Exception { + final File tempPDOM= File.createTempFile("foo", "bar"); + + + { + ICProject cproject= CProjectHelper.createCCProject("foo"+System.currentTimeMillis(), null, IPDOMManager.ID_FAST_INDEXER); + TestSourceReader.createFile(cproject.getProject(), new Path("/this.h"), "class A {};\n\n"); + CCorePlugin.getIndexManager().joinIndexer(3000, NPM); + ResourceContainerRelativeLocationConverter cvr= new ResourceContainerRelativeLocationConverter(cproject.getProject()); + CCoreInternals.getPDOMManager().exportProjectPDOM(cproject, tempPDOM, cvr); + CProjectHelper.delete(cproject); + + // mimic a pdom with superceded version + WritablePDOM wpdom= new WritablePDOM(tempPDOM, cvr); + wpdom.acquireWriteLock(); + try { + wpdom.getDB().setVersion(1); + } finally { + wpdom.releaseWriteLock(); + wpdom.close(); + } + } + + final URI baseURI= new File("c:/ExternalSDK/").toURI(); + final ICProject cproject2= CProjectHelper.createCCProject("baz"+System.currentTimeMillis(), null, IPDOMManager.ID_FAST_INDEXER); + TestSourceReader.createFile(cproject2.getProject(), new Path("/source.cpp"), "namespace X { class A {}; }\n\n"); + CCorePlugin.getIndexManager().joinIndexer(3000, NPM); + + IndexProviderManager ipm= CCoreInternals.getPDOMManager().getIndexProviderManager(); + ipm.addIndexProvider(new ReadOnlyPDOMProviderBridge( + new IReadOnlyPDOMProvider() { + public IPDOMDescriptor[] getDescriptors( + ICConfigurationDescription config) { + return new IPDOMDescriptor[] { + new IPDOMDescriptor() { + public IIndexLocationConverter getIndexLocationConverter() { + return new URIRelativeLocationConverter(baseURI); + } + + public IPath getLocation() { + return new Path(tempPDOM.getAbsolutePath()); + } + + } + }; + } + public boolean providesFor(ICProject project) + throws CoreException { + return cproject2.equals(project); + } + } + )); + + setExpectedNumberOfLoggedNonOKStatusObjects(1); // (this applies to the entire test duration) + + for(int i=0; i<3; i++) { + // try several times in order to test the status is logged only once + ICProjectDescription pd= CCorePlugin.getDefault().getProjectDescription(cproject2.getProject(), false); + assertEquals(0, ipm.getProvidedIndexFragments(pd.getActiveConfiguration()).length); + } + + } } 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 1d7b648bf85..dc61a4fe1d3 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 @@ -38,7 +38,7 @@ public class BaseTestCase extends TestCase { private boolean fExpectFailure= false; private int fBugnumber= 0; - private boolean allowsCoreLogErrors= false; + private int fExpectedLoggedNonOK= 0; public BaseTestCase() { super(); @@ -111,16 +111,19 @@ public class BaseTestCase extends TestCase { try { super.runBare(); - if(!allowsCoreLogErrors && !statusLog.isEmpty()) { - StringBuffer msg= new StringBuffer("Non-OK Status was logged to CCorePlugin: \n"); + if(statusLog.size()!=fExpectedLoggedNonOK) { + StringBuffer msg= new StringBuffer("Expected number ("+fExpectedLoggedNonOK+") of "); + msg.append("non-OK status objects differs from actual ("+statusLog.size()+").\n"); Throwable cause= null; - for(Iterator i= statusLog.iterator(); i.hasNext(); ) { - IStatus status= (IStatus) i.next(); - if(cause==null) { - cause= status.getException(); + if(!statusLog.isEmpty()) { + for(Iterator i= statusLog.iterator(); i.hasNext(); ) { + IStatus status= (IStatus) i.next(); + if(cause==null) { + cause= status.getException(); + } + Throwable t= status.getException(); + msg.append("\t"+status.getMessage()+" "+(t!=null?t.getMessage():"")+"\n"); } - Throwable t= status.getException(); - msg.append("\t"+status.getMessage()+" "+(t!=null?t.getMessage():"")+"\n"); } AssertionFailedError afe= new AssertionFailedError(msg.toString()); afe.initCause(cause); @@ -168,10 +171,12 @@ public class BaseTestCase extends TestCase { /** * The last value passed to this method in the body of a testXXX method * will be used to determine whether or not the presence of non-OK status objects - * in the log should fail the test. + * 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 */ - public void setAllowCCorePluginLogErrors(boolean value) { - allowsCoreLogErrors= value; + public void setExpectedNumberOfLoggedNonOKStatusObjects(int count) { + fExpectedLoggedNonOK= count; } } \ No newline at end of file diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IndexFactory.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IndexFactory.java index 42d5f4e44e5..4cba2058cd5 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IndexFactory.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IndexFactory.java @@ -67,7 +67,7 @@ public class IndexFactory { ICProject cproject = (ICProject) iter.next(); IWritableIndexFragment pdom= (IWritableIndexFragment) fPDOMManager.getPDOM(cproject); if (pdom != null) { - fragments.put(pdom.getProperty(IIndexFragment.PROPERTY_FRAGMENT_ID), pdom); + safeAddFragment(fragments, pdom); if(!skipProvided) { ICProjectDescription pd= CoreModel.getDefault().getProjectDescription(cproject.getProject(), false); @@ -75,7 +75,7 @@ public class IndexFactory { ICConfigurationDescription activeCfg= pd.getActiveConfiguration(); IIndexFragment[] pFragments= m.getProvidedIndexFragments(activeCfg); for(int i=0; i*/ path2pdom; // gives the pdom for a particular path - + private Set/**/ versionMismatch; + private static PDOMCache singleton; private static Object singletonMutex = new Object(); private PDOMCache() { this.path2pdom = new HashMap(); + this.versionMismatch = new HashSet(); } /** @@ -51,24 +56,44 @@ class PDOMCache { * then one is created using the location converter specified. * @param path * @param converter - * @return a pdom instance + * @return a pdom instance or null if the pdom version was too old */ public PDOM getPDOM(IPath path, IIndexLocationConverter converter) { + PDOM result= null; File file = path.toFile(); - synchronized(path2pdom) { - PDOM result = null; - if(path2pdom.containsKey(file)) { - result = (PDOM) path2pdom.get(file); - } - if(result==null) { - try { - result = new PDOM(file, converter); - } catch(CoreException ce) { - CCorePlugin.log(ce); + + if(!versionMismatch.contains(file)) { + synchronized(path2pdom) { + if(path2pdom.containsKey(file)) { + result = (PDOM) path2pdom.get(file); } - path2pdom.put(file, result); + if(result==null) { + try { + result = new PDOM(file, converter); + + result.acquireReadLock(); + try { + if(result.versionMismatch()) { + versionMismatch.add(file); + String msg= MessageFormat.format(Messages.PDOMCache_VersionTooOld, new Object[] {file}); + CCorePlugin.log(msg); + return null; + } else { + path2pdom.put(file, result); + } + } finally { + result.releaseReadLock(); + } + } catch(CoreException ce) { + CCorePlugin.log(ce); + } catch(InterruptedException ie) { + CCorePlugin.log(ie); + } + } + } - return result; } + + return result; } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/provider/ReadOnlyPDOMProviderBridge.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/provider/ReadOnlyPDOMProviderBridge.java index d8dfd6b0a02..9e52f5021e9 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/provider/ReadOnlyPDOMProviderBridge.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/provider/ReadOnlyPDOMProviderBridge.java @@ -18,6 +18,7 @@ import org.eclipse.cdt.core.index.provider.IReadOnlyPDOMProvider; import org.eclipse.cdt.core.model.ICProject; import org.eclipse.cdt.core.settings.model.ICConfigurationDescription; import org.eclipse.cdt.internal.core.index.IIndexFragment; +import org.eclipse.cdt.internal.core.pdom.PDOM; import org.eclipse.core.runtime.CoreException; /** @@ -37,7 +38,10 @@ public class ReadOnlyPDOMProviderBridge implements IIndexFragmentProvider { if(descs!=null) { for(int i=0; i