/******************************************************************************* * Copyright (c) 2007, 2010 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) *******************************************************************************/ package org.eclipse.cdt.internal.pdom.tests; import java.io.File; import java.net.URI; import java.net.URL; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.regex.Pattern; import junit.framework.Test; import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.dom.ILinkage; import org.eclipse.cdt.core.dom.IPDOMManager; import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; import org.eclipse.cdt.core.index.IIndexLocationConverter; import org.eclipse.cdt.core.index.IIndexerStateEvent; import org.eclipse.cdt.core.index.IIndexerStateListener; import org.eclipse.cdt.core.index.IndexFilter; import org.eclipse.cdt.core.index.ResourceContainerRelativeLocationConverter; import org.eclipse.cdt.core.index.URIRelativeLocationConverter; import org.eclipse.cdt.core.index.export.ExternalExportProjectProvider; import org.eclipse.cdt.core.index.export.IExportProjectProvider; 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.CTestPlugin; import org.eclipse.cdt.internal.core.index.IIndexFragment; import org.eclipse.cdt.internal.core.pdom.WritablePDOM; import org.eclipse.cdt.internal.core.pdom.export.GeneratePDOMApplication; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.FileLocator; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.Path; import org.eclipse.equinox.app.IApplication; import org.eclipse.equinox.app.IApplicationContext; import org.osgi.framework.Bundle; /** * Tests the GeneratePDOMApplication */ public class GeneratePDOMApplicationTest extends PDOMTestBase { private static final URI BASEURI= URI.create("file:///base/"); // unimportant what the value is private static final String SDK_VERSION = "com.acme.sdk.version"; private static final String ACME_SDK_ID= "com.acme.sdk.4.0.1"; private static final String LOC_TSTPRJ1= "resources/pdomtests/generatePDOMTests/project1"; private static final String LOC_TSTPRJ2= "resources/pdomtests/generatePDOMTests/project2"; private static final String LOC_TSTPRJ3= "resources/pdomtests/generatePDOMTests/project3"; private static final String LOC_CYCINC1= "resources/pdomtests/generatePDOMTests/cyclicIncludes1"; private static final String LOC_CYCINC2= "resources/pdomtests/generatePDOMTests/cyclicIncludes2"; private static List toDeleteOnTearDown= new ArrayList(); public static Test suite() { return suite(GeneratePDOMApplicationTest.class); } protected File target; // the location of the generated PDOM @Override protected void setUp() throws Exception { toDeleteOnTearDown.clear(); target= File.createTempFile("test", "pdom"); target.delete(); } @Override protected void tearDown() throws Exception { for(Iterator i= toDeleteOnTearDown.iterator(); i.hasNext(); ) { ICProject cproject= (ICProject) i.next(); cproject.getProject().delete(true, new NullProgressMonitor()); } } public void testBrokenExportProjectProvider1() throws Exception { setExpectedNumberOfLoggedNonOKStatusObjects(1); // IExportProjectProvider implementation returns null for createProject doGenerate(new String[] { GeneratePDOMApplication.OPT_TARGET, target.getAbsolutePath(), GeneratePDOMApplication.OPT_PROJECTPROVIDER, TestProjectProvider1.class.getName() }); } public void testBrokenExportProjectProvider2() throws Exception { setExpectedNumberOfLoggedNonOKStatusObjects(1); // IExportProjectProvider implementation returns null for getLocationConverter doGenerate(new String[] { GeneratePDOMApplication.OPT_TARGET, target.getAbsolutePath(), GeneratePDOMApplication.OPT_PROJECTPROVIDER, TestProjectProvider2.class.getName() }); } public void testSimpleExportProjectProvider1() throws Exception { doGenerate(new String[] { GeneratePDOMApplication.OPT_TARGET, target.getAbsolutePath(), GeneratePDOMApplication.OPT_PROJECTPROVIDER, TestProjectProvider3.class.getName() }); assertTrue(target.exists()); WritablePDOM wpdom= new WritablePDOM(target, new URIRelativeLocationConverter(BASEURI), LanguageManager.getInstance().getPDOMLinkageFactoryMappings()); verifyProject1Content(wpdom); String fid; wpdom.acquireReadLock(); try { fid = wpdom.getProperty(IIndexFragment.PROPERTY_FRAGMENT_ID); } finally { wpdom.releaseReadLock(); } assertNotNull(fid); assertTrue(fid.startsWith("export")); // check for default export id } public void testSimpleExportProjectProvider2() throws Exception { doGenerate(new String[] { GeneratePDOMApplication.OPT_TARGET, target.getAbsolutePath(), GeneratePDOMApplication.OPT_PROJECTPROVIDER, TestProjectProvider4.class.getName() }); assertTrue(target.exists()); WritablePDOM wpdom= new WritablePDOM(target, new URIRelativeLocationConverter(BASEURI), LanguageManager.getInstance().getPDOMLinkageFactoryMappings()); verifyProject1Content(wpdom); wpdom.acquireReadLock(); try { String fid = wpdom.getProperty(IIndexFragment.PROPERTY_FRAGMENT_ID); assertNotNull(fid); assertEquals(ACME_SDK_ID, fid); // check for custom export id String sdkVer = wpdom.getProperty(SDK_VERSION); assertNotNull(sdkVer); assertEquals("4.0.1", sdkVer); // check for custom property value } finally { wpdom.releaseReadLock(); } } public void testExternalExportProjectProvider_BadCmdLine1() throws Exception { setExpectedNumberOfLoggedNonOKStatusObjects(1); // Expected failure: -source must be specified doGenerate(new String[] { GeneratePDOMApplication.OPT_TARGET, target.getAbsolutePath(), GeneratePDOMApplication.OPT_PROJECTPROVIDER, ExternalExportProjectProvider.class.getName() }); assertFalse(target.exists()); } public void testExternalExportProjectProvider_BadCmdLine2() throws Exception { TestProjectProvider4 tpp4= new TestProjectProvider4(); ICProject cproject= tpp4.createProject(); setExpectedNumberOfLoggedNonOKStatusObjects(1); // Expected failure: -id must be specified doGenerate(new String[] { GeneratePDOMApplication.OPT_TARGET, target.getAbsolutePath(), GeneratePDOMApplication.OPT_PROJECTPROVIDER, ExternalExportProjectProvider.class.getName(), ExternalExportProjectProvider.OPT_SOURCE, cproject.getProject().getLocation().toFile().getAbsolutePath() }); assertFalse(target.exists()); } public void testExternalExportProjectProvider_BadCmdLine3() throws Exception { TestProjectProvider4 tpp4= new TestProjectProvider4(); ICProject cproject= tpp4.createProject(); setExpectedNumberOfLoggedNonOKStatusObjects(1); // Expected failure: -target must be specified doGenerate(new String[] { GeneratePDOMApplication.OPT_PROJECTPROVIDER, ExternalExportProjectProvider.class.getName(), ExternalExportProjectProvider.OPT_SOURCE, cproject.getProject().getLocation().toFile().getAbsolutePath() }); assertFalse(target.exists()); } public void testExternalExportProjectProvider() throws Exception { final int[] stateCount= new int[1]; WritablePDOM wpdom= generatePDOM(LOC_TSTPRJ1, ExternalExportProjectProvider.class, stateCount); verifyProject1Content(wpdom); wpdom.acquireReadLock(); try { String fid = wpdom.getProperty(IIndexFragment.PROPERTY_FRAGMENT_ID); assertNotNull(fid); assertEquals("generate.pdom.tests.id."+getName(), fid); // check for id passed on command-line } finally { wpdom.releaseReadLock(); } // depending on the timing the index of the temporary project is changed once or twice. assertTrue("state is "+ stateCount[0], stateCount[0] == 2 || stateCount[0] == 4); } public void testExternalExportProjectProvider_SysIncludes() throws Exception { WritablePDOM wpdom= generatePDOM(LOC_TSTPRJ2, ExternalExportProjectProvider.class, null); verifyProject2Content(wpdom); } public void testGenerateOnCyclicIncludes1() throws Exception { // testing for zero NON-OK status objects (see BaseTestCase.setExpectedNumberOfLoggedNonOKStatusObjects) WritablePDOM wpdom= generatePDOM(LOC_CYCINC1, ExternalExportProjectProvider.class, null); } public void testGenerateOnCyclicIncludes2() throws Exception { // testing for zero NON-OK status objects (see BaseTestCase.setExpectedNumberOfLoggedNonOKStatusObjects) WritablePDOM wpdom= generatePDOM(LOC_CYCINC2, ExternalExportProjectProvider.class, null); } public void testExternalExportProjectProvider_CLinkage() throws Exception { WritablePDOM wpdom= generatePDOM(LOC_TSTPRJ3, TestProjectProvider5.class, null); IndexFilter CLinkage= new IndexFilter() { @Override public boolean acceptLinkage(ILinkage linkage) { return linkage.getLinkageID() == ILinkage.C_LINKAGE_ID; } }; IndexFilter CPPLinkage= new IndexFilter() { @Override public boolean acceptLinkage(ILinkage linkage) { return linkage.getLinkageID() == ILinkage.CPP_LINKAGE_ID; } }; wpdom.acquireReadLock(); try { assertEquals(1, wpdom.findBindings(new char[][] { "foo" .toCharArray() }, CLinkage, npm()).length); assertEquals(0, wpdom.findBindings(new char[][] { "foo" .toCharArray() }, CPPLinkage, npm()).length); } finally { wpdom.releaseReadLock(); } } public void verifyProject1Content(WritablePDOM wpdom) throws Exception { wpdom.acquireReadLock(); try { IBinding[] bindings= wpdom.findBindings(Pattern.compile(".*foo.*"), false, IndexFilter.ALL, PROGRESS); assertEquals(1, bindings.length); bindings= wpdom.findBindings(Pattern.compile(".*bar.*"), false, IndexFilter.ALL, PROGRESS); assertEquals(1, bindings.length); } finally { wpdom.releaseReadLock(); } } public void verifyProject2Content(WritablePDOM wpdom) throws Exception { wpdom.acquireReadLock(); try { IBinding[] bindings= wpdom.findBindings(Pattern.compile(".*"), true, IndexFilter.ALL, npm()); assertEquals(2, bindings.length); int b= bindings[0].getName().equals("A") ? 1 : 0; assertTrue(bindings[0] instanceof ICPPClassType); assertTrue(bindings[1] instanceof ICPPClassType); assertTrue(((ICPPClassType)bindings[1-b]).getBases().length==0); assertTrue(((ICPPClassType)bindings[b]).getBases().length==1); } finally { wpdom.releaseReadLock(); } } private WritablePDOM generatePDOM(String testProject, Class<?> provider, final int[] stateCount) throws Exception { IIndexerStateListener listener= null; if(stateCount != null) { listener= new IIndexerStateListener() { public void indexChanged(IIndexerStateEvent event) { stateCount[0]++; } }; CCorePlugin.getIndexManager().joinIndexer(8000, new NullProgressMonitor()); CCorePlugin.getIndexManager().addIndexerStateListener(listener); } URL url= FileLocator.find(CTestPlugin.getDefault().getBundle(), new Path(testProject), null); String baseDir= FileLocator.toFileURL(url).getFile(); doGenerate(new String[] { GeneratePDOMApplication.OPT_TARGET, target.getAbsolutePath(), GeneratePDOMApplication.OPT_PROJECTPROVIDER, provider.getName(), ExternalExportProjectProvider.OPT_SOURCE, baseDir, ExternalExportProjectProvider.OPT_FRAGMENT_ID, "generate.pdom.tests.id."+getName() }); assertTrue(target.exists()); if(listener!=null) { CCorePlugin.getIndexManager().removeIndexerStateListener(listener); } return new WritablePDOM(target, new URIRelativeLocationConverter(BASEURI), LanguageManager.getInstance().getPDOMLinkageFactoryMappings()); } private void doGenerate(String[] args) throws CoreException { GeneratePDOMApplication app = new GeneratePDOMApplication(); IApplicationContext ac= new MockApplicationContext(args); app.start(ac); } /* * IExportProjectProvider test implementations */ public static class TestProjectProvider1 implements IExportProjectProvider { public ICProject createProject() throws CoreException {return null;} public Map getExportProperties() {return null;} public IIndexLocationConverter getLocationConverter(ICProject cproject) {return null;} public void setApplicationArguments(String[] arguments) {} } public static class TestProjectProvider2 implements IExportProjectProvider { public ICProject createProject() throws CoreException { ICProject cproject= CProjectHelper.createCCProject("test"+System.currentTimeMillis(), null, IPDOMManager.ID_NO_INDEXER); toDeleteOnTearDown.add(cproject); CProjectHelper.importSourcesFromPlugin(cproject, CTestPlugin.getDefault().getBundle(), LOC_TSTPRJ1); return cproject; } public Map getExportProperties() {return null;} public IIndexLocationConverter getLocationConverter(ICProject cproject) {return null;} public void setApplicationArguments(String[] arguments) {} } public static class TestProjectProvider3 implements IExportProjectProvider { public ICProject createProject() throws CoreException { ICProject cproject= CProjectHelper.createCCProject("test"+System.currentTimeMillis(), null, IPDOMManager.ID_NO_INDEXER); toDeleteOnTearDown.add(cproject); CProjectHelper.importSourcesFromPlugin(cproject, CTestPlugin.getDefault().getBundle(), LOC_TSTPRJ1); return cproject; } public Map getExportProperties() {return null;} public IIndexLocationConverter getLocationConverter(ICProject cproject) { return new ResourceContainerRelativeLocationConverter(cproject.getProject()); } public void setApplicationArguments(String[] arguments) {} } public static class TestProjectProvider4 implements IExportProjectProvider { public ICProject createProject() throws CoreException { ICProject cproject= CProjectHelper.createCCProject("test"+System.currentTimeMillis(), null, IPDOMManager.ID_NO_INDEXER); toDeleteOnTearDown.add(cproject); CProjectHelper.importSourcesFromPlugin(cproject, CTestPlugin.getDefault().getBundle(), LOC_TSTPRJ1); return cproject; } public Map getExportProperties() { Map map= new HashMap(); map.put(SDK_VERSION, "4.0.1"); map.put(IIndexFragment.PROPERTY_FRAGMENT_ID, ACME_SDK_ID); return map; } public IIndexLocationConverter getLocationConverter(ICProject cproject) { return new ResourceContainerRelativeLocationConverter(cproject.getProject()); } public void setApplicationArguments(String[] arguments) {} } public static class TestProjectProvider5 implements IExportProjectProvider { public ICProject createProject() throws CoreException { ICProject cproject= CProjectHelper.createCProject("test"+System.currentTimeMillis(), null, IPDOMManager.ID_NO_INDEXER); toDeleteOnTearDown.add(cproject); CProjectHelper.importSourcesFromPlugin(cproject, CTestPlugin.getDefault().getBundle(), LOC_TSTPRJ3); return cproject; } public Map getExportProperties() { Map map= new HashMap(); map.put(SDK_VERSION, "4.0.1"); map.put(IIndexFragment.PROPERTY_FRAGMENT_ID, ACME_SDK_ID); return map; } public IIndexLocationConverter getLocationConverter(ICProject cproject) { return new ResourceContainerRelativeLocationConverter(cproject.getProject()); } public void setApplicationArguments(String[] arguments) {} } } class MockApplicationContext implements IApplicationContext { Map arguments; MockApplicationContext(String[] appArgs) { arguments= new HashMap(); arguments.put(APPLICATION_ARGS, appArgs); } public void applicationRunning() {} public Map getArguments() {return arguments;} public String getBrandingApplication() {return null;} public Bundle getBrandingBundle() {return null;} public String getBrandingDescription() {return null;} public String getBrandingId() {return null;} public String getBrandingName() {return null;} public String getBrandingProperty(String key) {return null;} public void setResult(Object result, IApplication application) {} }