/******************************************************************************* * Copyright (c) 2007, 2010 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 * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Markus Schorn - initial API and implementation *******************************************************************************/ package org.eclipse.cdt.internal.index.tests; import java.io.ByteArrayInputStream; import java.io.File; import java.util.Collection; import java.util.Iterator; import java.util.LinkedList; import junit.framework.TestSuite; import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.dom.IPDOMManager; import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IVariable; import org.eclipse.cdt.core.index.IIndex; import org.eclipse.cdt.core.index.IIndexManager; import org.eclipse.cdt.core.index.IndexFilter; import org.eclipse.cdt.core.model.CoreModel; import org.eclipse.cdt.core.model.ICProject; import org.eclipse.cdt.core.testplugin.CProjectHelper; import org.eclipse.cdt.core.testplugin.util.TestSourceReader; import org.eclipse.cdt.internal.core.pdom.indexer.IndexerPreferences; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IProjectDescription; import org.eclipse.core.resources.IWorkspace; import org.eclipse.core.resources.IWorkspaceRunnable; import org.eclipse.core.resources.ProjectScope; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.ui.internal.ide.IDEWorkbenchPlugin; public class TeamSharedIndexTest extends IndexTestBase { public static TestSuite suite() { return suite(TeamSharedIndexTest.class); } private Collection fProjects= new LinkedList(); private static final IIndexManager fPDOMManager = CCorePlugin.getIndexManager(); public TeamSharedIndexTest(String name) { super(name); } @Override protected void setUp() throws Exception { super.setUp(); fProjects.clear(); } @Override protected void tearDown() throws Exception { for (Iterator iterator = fProjects.iterator(); iterator.hasNext();) { ICProject project = (ICProject) iterator.next(); CProjectHelper.delete(project); } super.tearDown(); } private void registerProject(ICProject prj) { fProjects.add(prj); } private void unregisterProject(ICProject prj) { fProjects.remove(prj); } private ICProject createProject(String name) throws CoreException { ModelJoiner mj= new ModelJoiner(); try { ICProject project= CProjectHelper.createCCProject(name, null, IPDOMManager.ID_NO_INDEXER); registerProject(project); TestSourceReader.createFile(project.getProject(), "a.cpp", "int a;"); TestSourceReader.createFile(project.getProject(), "b.cpp", "int b;"); TestSourceReader.createFile(project.getProject(), "c.cpp", "int c;"); mj.join(); // in order we are sure the indexer task has been scheduled before joining the indexer fPDOMManager.setIndexerId(project, IPDOMManager.ID_FAST_INDEXER); assertTrue(fPDOMManager.joinIndexer(INDEXER_WAIT_TIME, npm())); return project; } finally { mj.dispose(); } } private ICProject recreateProject(final String prjName) throws Exception { final IWorkspace workspace = ResourcesPlugin.getWorkspace(); ModelJoiner pj= new ModelJoiner(); try { final IProject prjHandle= workspace.getRoot().getProject(prjName); workspace.run(new IWorkspaceRunnable() { public void run(IProgressMonitor monitor) throws CoreException { IProjectDescription desc= IDEWorkbenchPlugin.getPluginWorkspace().newProjectDescription(prjName); prjHandle.create(desc, npm()); prjHandle.open(0, npm()); } }, null); pj.join(); // in order we are sure the indexer task has been scheduled before joining the indexer } finally { pj.dispose(); } ICProject result= CoreModel.getDefault().create(workspace.getRoot().getProject(prjName)); waitForIndexer(result); return result; } private void checkVariable(ICProject prj, String var, int expectedCount) throws CoreException, InterruptedException { IIndex index= fPDOMManager.getIndex(prj); index.acquireReadLock(); try { IBinding[] binding= index.findBindings(var.toCharArray(), IndexFilter.ALL, npm()); int count= 0; assertTrue(binding.length < 2); if (binding.length == 1) { assertTrue(binding[0] instanceof IVariable); count= index.findNames(binding[0], IIndex.FIND_ALL_OCCURRENCES).length; } assertEquals(var, expectedCount, count); } finally { index.releaseReadLock(); } } public void testDefaultExport() throws Exception { String prjName= "__testDefaultExport__"; ICProject prj= createProject(prjName); String loc= IndexerPreferences.getIndexImportLocation(prj.getProject()); checkVariable(prj, "a", 1); checkVariable(prj, "b", 1); checkVariable(prj, "c", 1); // export the project. fPDOMManager.export(prj, loc, 0, npm()); // set indexer to the fake one. fPDOMManager.setIndexerId(prj, FakeIndexer.ID); IndexerPreferences.setScope(prj.getProject(), IndexerPreferences.SCOPE_PROJECT_SHARED); new ProjectScope(prj.getProject()).getNode(CCorePlugin.PLUGIN_ID).flush(); fPDOMManager.joinIndexer(INDEXER_WAIT_TIME, npm()); checkVariable(prj, "a", 0); checkVariable(prj, "b", 0); checkVariable(prj, "c", 0); // delete project deleteAndWait(prj); unregisterProject(prj); // import project prj = recreateProject(prjName); assertEquals(FakeIndexer.ID, fPDOMManager.getIndexerId(prj)); registerProject(prj); checkVariable(prj, "a", 1); checkVariable(prj, "b", 1); checkVariable(prj, "c", 1); } public void testExportWithFileChange() throws Exception { String prjName= "__testExportWithChange__"; ICProject prj= createProject(prjName); String loc= IndexerPreferences.getIndexImportLocation(prj.getProject()); checkVariable(prj, "a", 1); checkVariable(prj, "b", 1); checkVariable(prj, "c", 1); // export the project. IndexerPreferences.setScope(prj.getProject(), IndexerPreferences.SCOPE_PROJECT_SHARED); new ProjectScope(prj.getProject()).getNode(CCorePlugin.PLUGIN_ID).flush(); fPDOMManager.export(prj, loc, 0, npm()); fPDOMManager.joinIndexer(INDEXER_WAIT_TIME, npm()); // change file changeFile(prj); deleteAndWait(prj); unregisterProject(prj); // import project prj = recreateProject(prjName); registerProject(prj); checkVariable(prj, "a", 0); checkVariable(prj, "b", 1); checkVariable(prj, "c", 1); checkVariable(prj, "d", 1); } private void changeFile(ICProject prj) throws CoreException { final IFile file = prj.getProject().getFile("a.cpp"); final File location = file.getLocation().toFile(); final long lm= location.lastModified(); file.setContents(new ByteArrayInputStream("int d;".getBytes()), true, false, npm()); if (location.lastModified() == lm) { location.setLastModified(lm+1000); } } private void deleteAndWait(ICProject prj) throws CoreException { ModelJoiner dj= new ModelJoiner(); try { prj.getProject().delete(false, true, npm()); dj.join(); } finally { dj.dispose(); } } public void testExportWithFileChangeFake() throws Exception { String prjName= "__testExportWithChangeFake__"; ICProject prj= createProject(prjName); String loc= IndexerPreferences.getIndexImportLocation(prj.getProject()); checkVariable(prj, "a", 1); checkVariable(prj, "b", 1); checkVariable(prj, "c", 1); // export the project. fPDOMManager.export(prj, loc, 0, npm()); fPDOMManager.joinIndexer(INDEXER_WAIT_TIME, npm()); // set indexer to the fake one. fPDOMManager.setIndexerId(prj, FakeIndexer.ID); IndexerPreferences.setScope(prj.getProject(), IndexerPreferences.SCOPE_PROJECT_SHARED); new ProjectScope(prj.getProject()).getNode(CCorePlugin.PLUGIN_ID).flush(); fPDOMManager.joinIndexer(INDEXER_WAIT_TIME, npm()); checkVariable(prj, "a", 0); checkVariable(prj, "b", 0); checkVariable(prj, "c", 0); changeFile(prj); deleteAndWait(prj); unregisterProject(prj); // import project prj = recreateProject(prjName); registerProject(prj); checkVariable(prj, "a", 1); checkVariable(prj, "b", 1); checkVariable(prj, "c", 1); checkVariable(prj, "d", 0); } public void testExportWithAddition() throws Exception { String prjName= "__testExportWithAddition__"; ICProject prj= createProject(prjName); String loc= IndexerPreferences.getIndexImportLocation(prj.getProject()); checkVariable(prj, "a", 1); checkVariable(prj, "b", 1); checkVariable(prj, "c", 1); // export the project. IndexerPreferences.setScope(prj.getProject(), IndexerPreferences.SCOPE_PROJECT_SHARED); new ProjectScope(prj.getProject()).getNode(CCorePlugin.PLUGIN_ID).flush(); fPDOMManager.export(prj, loc, 0, npm()); fPDOMManager.joinIndexer(INDEXER_WAIT_TIME, npm()); // add file TestSourceReader.createFile(prj.getProject(), "d.cpp", "int d;"); deleteAndWait(prj); unregisterProject(prj); // import project prj = recreateProject(prjName); registerProject(prj); checkVariable(prj, "a", 1); checkVariable(prj, "b", 1); checkVariable(prj, "c", 1); checkVariable(prj, "d", 1); } public void testExportWithAdditionFake() throws Exception { String prjName= "__testExportWithAdditionFake__"; ICProject prj= createProject(prjName); String loc= IndexerPreferences.getIndexImportLocation(prj.getProject()); checkVariable(prj, "a", 1); checkVariable(prj, "b", 1); checkVariable(prj, "c", 1); // export the project. fPDOMManager.export(prj, loc, 0, npm()); fPDOMManager.joinIndexer(INDEXER_WAIT_TIME, npm()); // set indexer to the fake one. fPDOMManager.setIndexerId(prj, FakeIndexer.ID); IndexerPreferences.setScope(prj.getProject(), IndexerPreferences.SCOPE_PROJECT_SHARED); new ProjectScope(prj.getProject()).getNode(CCorePlugin.PLUGIN_ID).flush(); fPDOMManager.joinIndexer(INDEXER_WAIT_TIME, npm()); checkVariable(prj, "a", 0); checkVariable(prj, "b", 0); checkVariable(prj, "c", 0); // add file TestSourceReader.createFile(prj.getProject(), "d.cpp", "int d;"); deleteAndWait(prj); unregisterProject(prj); // import project prj = recreateProject(prjName); registerProject(prj); checkVariable(prj, "a", 1); checkVariable(prj, "b", 1); checkVariable(prj, "c", 1); checkVariable(prj, "d", 0); } public void testExportWithRemoval() throws Exception { String prjName= "__testExportWithRemoval__"; ICProject prj= createProject(prjName); String loc= IndexerPreferences.getIndexImportLocation(prj.getProject()); checkVariable(prj, "a", 1); checkVariable(prj, "b", 1); checkVariable(prj, "c", 1); // export the project. IndexerPreferences.setScope(prj.getProject(), IndexerPreferences.SCOPE_PROJECT_SHARED); new ProjectScope(prj.getProject()).getNode(CCorePlugin.PLUGIN_ID).flush(); fPDOMManager.export(prj, loc, 0, npm()); fPDOMManager.joinIndexer(INDEXER_WAIT_TIME, npm()); // delete file prj.getProject().getFile("a.cpp").delete(true, npm()); deleteAndWait(prj); unregisterProject(prj); // import project prj = recreateProject(prjName); registerProject(prj); checkVariable(prj, "a", 0); checkVariable(prj, "b", 1); checkVariable(prj, "c", 1); } public void testExportWithRemovalFake() throws Exception { String prjName= "__testExportWithRemovalFake__"; ICProject prj= createProject(prjName); String loc= IndexerPreferences.getIndexImportLocation(prj.getProject()); checkVariable(prj, "a", 1); checkVariable(prj, "b", 1); checkVariable(prj, "c", 1); // export the project. fPDOMManager.export(prj, loc, 0, npm()); fPDOMManager.joinIndexer(INDEXER_WAIT_TIME, npm()); // set indexer to the fake one. fPDOMManager.setIndexerId(prj, FakeIndexer.ID); IndexerPreferences.setScope(prj.getProject(), IndexerPreferences.SCOPE_PROJECT_SHARED); new ProjectScope(prj.getProject()).getNode(CCorePlugin.PLUGIN_ID).flush(); fPDOMManager.joinIndexer(INDEXER_WAIT_TIME, npm()); checkVariable(prj, "a", 0); checkVariable(prj, "b", 0); checkVariable(prj, "c", 0); // delete file prj.getProject().getFile("a.cpp").delete(true, npm()); deleteAndWait(prj); unregisterProject(prj); // import project prj = recreateProject(prjName); registerProject(prj); checkVariable(prj, "a", 0); checkVariable(prj, "b", 1); checkVariable(prj, "c", 1); } }