1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-23 22:52:11 +02:00

178998: apply fix for controlled behaviour on prebuilt pdom version mismatch

This commit is contained in:
Andrew Ferguson 2007-03-27 11:32:21 +00:00
parent bcb116eda7
commit 6ddba293ac
7 changed files with 163 additions and 39 deletions

View file

@ -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);
}
}
}

View file

@ -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;
}
}

View file

@ -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<pFragments.length; i++) {
fragments.put(pFragments[i].getProperty(IIndexFragment.PROPERTY_FRAGMENT_ID), pFragments[i]);
safeAddFragment(fragments, pFragments[i]);
}
}
}
@ -95,16 +95,14 @@ public class IndexFactory {
for (Iterator iter = selectedProjects.iterator(); iter.hasNext(); ) {
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);
if(pd!=null) {
ICConfigurationDescription activeCfg= pd.getActiveConfiguration();
IIndexFragment[] pFragments= m.getProvidedIndexFragments(activeCfg);
for(int i=0; i<pFragments.length; i++) {
fragments.put(pFragments[i].getProperty(IIndexFragment.PROPERTY_FRAGMENT_ID), pFragments[i]);
safeAddFragment(fragments, pFragments[i]);
}
}
}
@ -186,13 +184,13 @@ public class IndexFactory {
ICProject p = (ICProject) iter.next();
IWritableIndexFragment pdom= (IWritableIndexFragment) fPDOMManager.getPDOM(p);
if (pdom != null) {
fragments.put(pdom.getProperty(IIndexFragment.PROPERTY_FRAGMENT_ID), pdom);
safeAddFragment(fragments, (IIndexFragment) pdom);
ICProjectDescription pd= CoreModel.getDefault().getProjectDescription(p.getProject(), false);
if(pd!=null) {
ICConfigurationDescription activeCfg= pd.getActiveConfiguration();
IIndexFragment[] pFragments= m.getProvidedIndexFragments(activeCfg);
for(int i=0; i<pFragments.length; i++) {
readOnlyFrag.put(pFragments[i].getProperty(IIndexFragment.PROPERTY_FRAGMENT_ID), pFragments[i]);
safeAddFragment(readOnlyFrag, pFragments[i]);
}
}
}
@ -203,10 +201,7 @@ public class IndexFactory {
for (Iterator iter = selectedProjects.iterator(); iter.hasNext(); ) {
ICProject cproject = (ICProject) iter.next();
IWritableIndexFragment pdom= (IWritableIndexFragment) fPDOMManager.getPDOM(cproject);
if (pdom != null) {
readOnlyFrag.put(pdom.getProperty(IIndexFragment.PROPERTY_FRAGMENT_ID), pdom);
}
safeAddFragment(readOnlyFrag, (IIndexFragment) fPDOMManager.getPDOM(cproject));
}
if (fragments.isEmpty()) {
@ -219,4 +214,29 @@ public class IndexFactory {
return new WritableCIndex((IWritableIndexFragment[]) pdoms.toArray(new IWritableIndexFragment[pdoms.size()]),
(IIndexFragment[]) roPdoms.toArray(new IIndexFragment[roPdoms.size()]) );
}
/**
* Add an entry for the specified fragment. This copes with problems occuring when reading
* the fragment ID.
* @param id2fragment the map to add the entry to
* @param fragment the fragment or null (which will result in no action)
*/
private void safeAddFragment(Map id2fragment, IIndexFragment fragment) {
if(fragment!=null) {
try {
fragment.acquireReadLock();
try {
String id= fragment.getProperty(IIndexFragment.PROPERTY_FRAGMENT_ID);
id2fragment.put(id, fragment);
} finally {
fragment.releaseReadLock();
}
} catch(CoreException ce) {
CCorePlugin.log(ce);
} catch(InterruptedException ie) {
CCorePlugin.log(ie);
}
}
}
}

View file

@ -16,6 +16,7 @@ public class Messages extends NLS {
private static final String BUNDLE_NAME = "org.eclipse.cdt.internal.core.index.provider.messages"; //$NON-NLS-1$
public static String IndexProviderManager_0;
public static String OfflinePDOMProviderBridge_UnsupportedUsage;
public static String PDOMCache_VersionTooOld;
static {
// initialize resource bundle
NLS.initializeMessages(BUNDLE_NAME, Messages.class);

View file

@ -11,8 +11,11 @@
package org.eclipse.cdt.internal.core.index.provider;
import java.io.File;
import java.text.MessageFormat;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.index.IIndexLocationConverter;
@ -25,12 +28,14 @@ import org.eclipse.core.runtime.IPath;
*/
class PDOMCache {
private Map/*<File, PDOM>*/ path2pdom; // gives the pdom for a particular path
private Set/*<File>*/ 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;
}
}

View file

@ -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<descs.length; i++) {
preresult.add(PDOMCache.getInstance().getPDOM(descs[i].getLocation(), descs[i].getIndexLocationConverter()));
PDOM pdom= PDOMCache.getInstance().getPDOM(descs[i].getLocation(), descs[i].getIndexLocationConverter());
if(pdom!=null) {
preresult.add(pdom);
}
}
}

View file

@ -1,2 +1,3 @@
IndexProviderManager_0=Ignoring unrecognized implementation of IIndexProvider contributed by {0}
OfflinePDOMProviderBridge_UnsupportedUsage=Unsupported usage of IOfflinePDOMProvider
PDOMCache_VersionTooOld=External index (PDOM) version is not supported: {0}