project/com.nokia.carbide.cpp.epoc.engine.tests/src/com/nokia/carbide/cpp/epoc/engine/tests/workspace/TestWorkspaceModelProvider.java
More portability fixes for Linux.
-- make EpocEnginePathHelper et al produce an IPath that matches an existing path in the filesystem even if the case doesn't match. File#getCanonical* does not do this in Unix.
-- SISBuilderInfo2 and bld.inf exports fixes for full path detection
-- make some tests less dependent on having specific SDKs available.
-- fix some warnings
/*
* Copyright (c) 2006 Nokia Corporation and/or its subsidiary(-ies).
* All rights reserved.
* This component and the accompanying materials are made available
* under the terms of the License "Eclipse Public License v1.0"
* which accompanies this distribution, and is available
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
*
* Initial Contributors:
* Nokia Corporation - initial contribution.
*
* Contributors:
*
* Description:
*
*/
package com.nokia.carbide.cpp.epoc.engine.tests.workspace;
import com.nokia.carbide.cdt.builder.CarbideBuilderPlugin;
import com.nokia.carbide.cdt.builder.DefaultMMPViewConfiguration;
import com.nokia.carbide.cpp.epoc.engine.DocumentFactory;
import com.nokia.carbide.cpp.epoc.engine.EpocEnginePlugin;
import com.nokia.carbide.cpp.epoc.engine.IBldInfViewRunnable;
import com.nokia.carbide.cpp.epoc.engine.IImageMakefileViewRunnable;
import com.nokia.carbide.cpp.epoc.engine.IMMPViewRunnable;
import com.nokia.carbide.cpp.epoc.engine.MMPViewRunnableAdapter;
import com.nokia.carbide.cpp.epoc.engine.image.ISVGSource;
import com.nokia.carbide.cpp.epoc.engine.model.IModelProvider;
import com.nokia.carbide.cpp.epoc.engine.model.IOwnedModel;
import com.nokia.carbide.cpp.epoc.engine.model.IViewParserConfiguration;
import com.nokia.carbide.cpp.epoc.engine.model.bldinf.IBldInfModel;
import com.nokia.carbide.cpp.epoc.engine.model.bldinf.IBldInfOwnedModel;
import com.nokia.carbide.cpp.epoc.engine.model.bldinf.IBldInfView;
import com.nokia.carbide.cpp.epoc.engine.model.makefile.image.IImageBuilderCommandLineConverter;
import com.nokia.carbide.cpp.epoc.engine.model.makefile.image.IImageMakefileModel;
import com.nokia.carbide.cpp.epoc.engine.model.makefile.image.IImageMakefileOwnedModel;
import com.nokia.carbide.cpp.epoc.engine.model.makefile.image.IImageMakefileView;
import com.nokia.carbide.cpp.epoc.engine.model.makefile.image.IImageMakefileViewConfiguration;
import com.nokia.carbide.cpp.epoc.engine.model.makefile.image.ImageBuilderCommandLineConverterFactory;
import com.nokia.carbide.cpp.epoc.engine.model.mmp.EMMPStatement;
import com.nokia.carbide.cpp.epoc.engine.model.mmp.IMMPModel;
import com.nokia.carbide.cpp.epoc.engine.model.mmp.IMMPOwnedModel;
import com.nokia.carbide.cpp.epoc.engine.model.mmp.IMMPView;
import com.nokia.carbide.cpp.epoc.engine.model.mmp.IMMPViewConfiguration;
import com.nokia.carbide.cpp.epoc.engine.preprocessor.AcceptedNodesViewFilter;
import com.nokia.carbide.cpp.epoc.engine.preprocessor.IDefine;
import com.nokia.carbide.cpp.epoc.engine.preprocessor.IViewFilter;
import com.nokia.carbide.cpp.epoc.engine.tests.model.ModelProviderThreadTests;
import com.nokia.carbide.internal.cpp.epoc.engine.model.ModelProviderBase;
import com.nokia.cpp.internal.api.utils.core.FileUtils;
import com.nokia.sdt.utils.StandaloneFileTracker;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Path;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.Collection;
/**
* Basic tests of workspace sanity (real tests in TestModelProvider)
*
*/
public class TestWorkspaceModelProvider extends BaseProjectTests {
private static final String TEST_BLDINF_0 = "PRJ_PLATFORMS default\n"+
"PRJ_MMPFILES\n"+
"test.mmp\n";
private static final String TEST_MMP_0 = "";
private static final String TEST_MMP_USER_0 = "SOURCE bar.cpp\n";
/* (non-Javadoc)
* @see com.nokia.carbide.cpp.epoc.engine.tests.BaseTest#setUp()
*/
@Override
protected void setUp() throws Exception {
super.setUp();
((ModelProviderBase) bldInfModelProvider).reset();
((ModelProviderBase) mmpModelProvider).reset();
}
/* (non-Javadoc)
* @see junit.framework.TestCase#tearDown()
*/
@Override
protected void tearDown() throws Exception {
super.tearDown();
}
protected IPath getFullPath(IPath wsPath) {
return ResourcesPlugin.getWorkspace().getRoot().getLocation().append(wsPath);
}
public void testCreateModel() throws CoreException {
IPath thePath = (new Path(projectName + "/group/bld.inf"));
IBldInfOwnedModel model = bldInfModelProvider.createModel(thePath);
assertNotNull(model);
model.setDocument(DocumentFactory.createDocument(TEST_BLDINF_0));
bldInfModelProvider.registerModel(model);
// assert the file now exists
IFile[] files = ResourcesPlugin.getWorkspace().getRoot().findFilesForLocation(model.getPath());
assertTrue(files.length > 0 && files[0].exists());
// and it's got the right contents
InputStream is = files[0].getContents();
char[] cs = FileUtils.readInputStreamContents(is, null);
assertEquals(TEST_BLDINF_0, new String(cs));
// and ensure we can find it
IBldInfModel sharedModel = bldInfModelProvider.findSharedModel(thePath);
assertNotNull(sharedModel);
bldInfModelProvider.releaseSharedModel(sharedModel);
bldInfModelProvider.releaseSharedModel(model);
}
public void testModelResourceListenersConflict() throws Exception {
IPath thePath = (new Path(projectName + "/group/bld.inf"));
IBldInfOwnedModel ownedModel = bldInfModelProvider.createModel(thePath);
ownedModel.setDocument(DocumentFactory.createDocument(TEST_BLDINF_0));
bldInfModelProvider.registerModel(ownedModel);
IBldInfModel model = bldInfModelProvider.getSharedModel(thePath);
IBldInfView view = model.createView(configuration);
// make the mmp, empty
IPath mmpPath = new Path(projectName).append(view.getAllMMPReferences()[0].getPath());
IMMPOwnedModel ownedMmp = mmpModelProvider.createModel(mmpPath);
ownedMmp.setDocument(DocumentFactory.createDocument(TEST_MMP_0));
mmpModelProvider.registerModel(ownedMmp);
mmpModelProvider.releaseSharedModel(ownedMmp);
IMMPModel mmp = mmpModelProvider.getSharedModel(mmpPath);
IMMPView mmpView = mmp.createView(mmpConfiguration);
mmpView.getSources().add(new Path("src/foo.cpp"));
// now, someone changes the mmp on disk!
IFile mmpFile = ResourcesPlugin.getWorkspace().getRoot().getFile(mmpPath);
InputStream source = new ByteArrayInputStream(TEST_MMP_USER_0.getBytes());
mmpFile.setContents(source, false, true, new NullProgressMonitor());
source.close();
// wait for resource listener
sleep();
// ensure the view is dirty
assertTrue(mmpView.needsSynchonize());
mmpView.revert();
assertEquals(1, mmpView.getSources().size());
assertEquals(new Path("group/bar.cpp"), mmpView.getSources().get(0));
mmpView.dispose();
mmpModelProvider.releaseSharedModel(mmp);
mmpModelProvider.unregisterModel(ownedMmp);
bldInfModelProvider.releaseSharedModel(model);
bldInfModelProvider.unregisterModel(ownedModel);
}
/** test that normal commit works, but doesn't act screwy */
public void testModelResourceListenersNormalSave() throws Exception {
// make the mmp, empty
IPath mmpPath = (new Path(projectName + "/group/test.mmp"));
IMMPOwnedModel ownedMmp = mmpModelProvider.createModel(mmpPath);
ownedMmp.setDocument(DocumentFactory.createDocument(TEST_MMP_0));
mmpModelProvider.registerModel(ownedMmp);
mmpModelProvider.releaseSharedModel(ownedMmp);
IMMPModel mmp = mmpModelProvider.getSharedModel(mmpPath);
IMMPView mmpView = mmp.createView(mmpConfiguration);
mmpView.getSources().add(new Path("src/foo.cpp"));
// now save
mmpView.commit();
// wait for a while so Eclipse dispatches listeners, etc...
sleep();
// ensure the view is okay
assertFalse(mmpView.needsSynchonize());
mmpView.dispose();
mmpModelProvider.releaseSharedModel(mmp);
}
private static final String TEST_MMP_2 =
"SOURCEPATH ..\\src\n"+
"SOURCE a.cpp b.cpp\n"+
"TARGETTYPE exe\n"+
"TARGET foo.exe\n";
private static final String TEST_MMP_2_m =
"TARGETTYPE exe\n";
/**
* Ensure that the model provider detects a change to the document
* and persists it.
* @throws Exception
*/
public void testModifyModel() throws Exception {
// make an mmp
IPath mmpPath = (new Path(projectName + "/group/test.mmp"));
IMMPOwnedModel ownedMmp = mmpModelProvider.createModel(mmpPath);
ownedMmp.setDocument(DocumentFactory.createDocument(TEST_MMP_2));
mmpModelProvider.registerModel(ownedMmp);
mmpModelProvider.releaseSharedModel(ownedMmp);
IMMPModel model = mmpModelProvider.getSharedModel(mmpPath);
IMMPView view = model.createView(mmpConfiguration);
view.getSources().clear();
view.getSingleArgumentSettings().remove(EMMPStatement.TARGET);
view.commit();
IFile file = ResourcesPlugin.getWorkspace().getRoot().getFile(mmpPath);
assertNotNull(file);
InputStream is = file.getContents();
char[] text = FileUtils.readInputStreamContents(is, null);
assertEquals(TEST_MMP_2_m, new String(text));
}
public void testMMPViewRunner() throws Exception {
// make the mmp
IPath mmpPath = (new Path(projectName + "/group/test.mmp"));
IMMPOwnedModel ownedMmp = mmpModelProvider.createModel(mmpPath);
ownedMmp.setDocument(DocumentFactory.createDocument(TEST_MMP_USER_0));
mmpModelProvider.registerModel(ownedMmp);
mmpModelProvider.releaseSharedModel(ownedMmp);
///
final boolean failed[] = new boolean[1];
Object result = EpocEnginePlugin.runWithMMPView(mmpPath, mmpConfiguration,
new IMMPViewRunnable() {
public Object failedLoad(CoreException exception) {
failed[0] = true;
return null;
}
public Object run(IMMPView view) {
return view.getSources().get(0);
}
});
assertEquals(new Path("group/bar.cpp"), result);
assertFalse(failed[0]);
// twice, with a change
EpocEnginePlugin.runWithMMPView(mmpPath, mmpConfiguration,
new IMMPViewRunnable() {
public Object failedLoad(CoreException exception) {
failed[0] = true;
return null;
}
public Object run(IMMPView view) {
view.getSources().remove(0);
view.commit();
return null;
}
});
assertFalse(failed[0]);
// validate change
result = EpocEnginePlugin.runWithMMPView(mmpPath, mmpConfiguration,
new IMMPViewRunnable() {
public Object failedLoad(CoreException exception) {
failed[0] = true;
return null;
}
public Object run(IMMPView view) {
return view.getSources().size();
}
});
assertEquals(0, result);
assertFalse(failed[0]);
}
final static String TEST_IMAGE_MAKEFILE_0 =
"RESOURCE:\n"+
"\tmifconv foo.mif /c32,8 bar.svg\n";
public void testImageMakefileViewRunner() throws Exception {
// make the ImageMakefile
IPath imageMakefilePath = (new Path(projectName + "/group/Icons.mk"));
IModelProvider<IImageMakefileOwnedModel, IImageMakefileModel> imageMakefileModelProvider = EpocEnginePlugin.getImageMakefileModelProvider();
IImageMakefileOwnedModel ownedImageMakefile = imageMakefileModelProvider.createModel(imageMakefilePath);
ownedImageMakefile.setDocument(DocumentFactory.createDocument(TEST_IMAGE_MAKEFILE_0));
imageMakefileModelProvider.registerModel(ownedImageMakefile);
imageMakefileModelProvider.releaseSharedModel(ownedImageMakefile);
IImageMakefileViewConfiguration imageMakefileViewConfiguration = new IImageMakefileViewConfiguration() {
public IImageBuilderCommandLineConverter getImageBuilderCommandLineConverter() {
return ImageBuilderCommandLineConverterFactory.createMifConvConverter();
}
public String getImageBuilderName() {
return "mifconv";
}
public String getMakefileStyle() {
return "GNU";
}
public Collection<IDefine> getMacros() {
return configuration.getMacros();
}
public IViewFilter getViewFilter() {
return configuration.getViewFilter();
}
public IViewParserConfiguration getViewParserConfiguration() {
return configuration.getViewParserConfiguration();
}
};
// access it
///
final boolean failed[] = new boolean[1];
Object result = EpocEnginePlugin.runWithImageMakefileView(imageMakefilePath, imageMakefileViewConfiguration,
new IImageMakefileViewRunnable() {
public Object failedLoad(CoreException exception) {
failed[0] = true;
return null;
}
public Object run(IImageMakefileView view) {
return view.getMultiImageSources().get(0).getSources().get(0).getPath();
}
});
assertEquals(new Path("group/bar.svg"), result);
assertFalse(failed[0]);
// twice, with a change
EpocEnginePlugin.runWithImageMakefileView(imageMakefilePath, imageMakefileViewConfiguration,
new IImageMakefileViewRunnable() {
public Object failedLoad(CoreException exception) {
failed[0] = true;
return null;
}
public Object run(IImageMakefileView view) {
ISVGSource svg = view.getMultiImageSources().get(0).createSVGSource();
svg.setColor(true);
svg.setDepth(32);
svg.setMaskDepth(0);
svg.setPath(new Path("gfx/pix.svg"));
view.getMultiImageSources().get(0).getSources().add(svg);
view.commit();
return null;
}
});
assertFalse(failed[0]);
// validate change
result = EpocEnginePlugin.runWithImageMakefileView(imageMakefilePath, imageMakefileViewConfiguration,
new IImageMakefileViewRunnable() {
public Object failedLoad(CoreException exception) {
failed[0] = true;
return null;
}
public Object run(IImageMakefileView view) {
return view.getMultiImageSources().get(0).getSources().size();
}
});
assertEquals(2, result);
assertFalse(failed[0]);
}
/**
* Ensure the models work sanely with threading.
* @throws Exception
*/
public void testThreading() throws CoreException {
IPath mmpPath = new Path(project.getName()).append("test.mmp");
ModelProviderThreadTests test = new ModelProviderThreadTests();
test.testThreading(mmpModelProvider, mmpConfiguration, mmpPath);
}
/** Inspired by bug 3088 which is a non-bug */
public void testDetectUpdates() throws CoreException {
project.getFolder("group").create(false, true, null);
for (int i = 0; i < 5; i++) {
updateRound();
}
}
private void updateRound() throws CoreException {
IPath wsBldInfPath = new Path(project.getName()).append("group/bld.inf");
createOrSaveFile(wsBldInfPath,
"PRJ_MMPFILES\n"+
"orig.mmp\n"+
"test.mmp\n");
EpocEnginePlugin.runWithBldInfView(wsBldInfPath, configuration,
new IBldInfViewRunnable() {
public Object failedLoad(CoreException exception) {
return null;
}
public Object run(IBldInfView view) {
assertEquals(2, view.getMakMakeReferences().size());
return null;
}
});
createOrSaveFile(wsBldInfPath,
"PRJ_MMPFILES\n"+
"orig.mmp\n");
EpocEnginePlugin.runWithBldInfView(wsBldInfPath, configuration,
new IBldInfViewRunnable() {
public Object failedLoad(CoreException exception) {
return null;
}
public Object run(IBldInfView view) {
assertEquals(1, view.getMakMakeReferences().size());
return null;
}
});
}
/**
* Ensure that files living and modified outside the workspace are reloaded when changed.
* @throws Exception
*/
public void testExternalModification_bug3557() throws Exception {
// make the mmp
IPath fullMmpPath = new Path(getTokenAbsolutePath()).append("tempmodel.mmp");
String text =
"START BITMAP foo.mbm\n"+
"SOURCE C8,BAD foo.bmp bar.bmp\n"+
"END\n";
IMMPOwnedModel ownedMmp = mmpModelProvider.createModel(fullMmpPath);
ownedMmp.setDocument(DocumentFactory.createDocument(text));
mmpModelProvider.registerModel(ownedMmp);
mmpModelProvider.releaseSharedModel(ownedMmp);
IMMPModel model = EpocEnginePlugin.getMMPModelProvider().getSharedModel(fullMmpPath);
assertNotNull(model);
IMMPView view = model.createView(mmpConfiguration);
assertEquals(1, view.getBitmaps().size());
assertEquals(1, view.getBitmaps().get(0).getBitmapSources().size());
String text2 =
"START BITMAP foo.mbm\n"+
"SOURCE C8 foo.bmp bar.bmp\n"+
"END\n";
// wait long enough for the timestamp to differ
Thread.sleep(1000);
// rewrite outside
new StandaloneFileTracker().saveFileText(fullMmpPath.toFile(), null, text2.toCharArray());
// we don't detect it here
assertFalse(view.needsSynchonize());
view.dispose();
EpocEnginePlugin.getMMPModelProvider().releaseSharedModel(model);
///
// this version should be updated
model = EpocEnginePlugin.getMMPModelProvider().getSharedModel(fullMmpPath);
assertNotNull(model);
assertEquals(text2, ((IOwnedModel)model).getDocument().get());
view = model.createView(mmpConfiguration);
assertEquals(1, view.getBitmaps().size());
assertEquals(2, view.getBitmaps().get(0).getBitmapSources().size());
fullMmpPath.toFile().delete();
}
public void testMultiDocumentStorageTracking() throws Exception {
IPath wsMmpPath = new Path(project.getName()).append("group/test.mmp");
createOrSaveFile(wsMmpPath,
"#include \"header.mmh\"\n"+
"SOURCEPATH SRCDIR\n"+
"SOURCE a.cpp\n");
IPath wsMmhPath = new Path(project.getName()).append("group/header.mmh");
createOrSaveFile(wsMmhPath,
"#define SRCDIR ..\\src\n"+
"BASEADDRESS 0x6000\n");
IMMPViewConfiguration config = new DefaultMMPViewConfiguration(
CarbideBuilderPlugin.getBuildManager().getProjectInfo(project),
new AcceptedNodesViewFilter());
addWaitingResourceListener(wsMmhPath);
// make change to header
EpocEnginePlugin.runWithMMPView(wsMmpPath, config,
new MMPViewRunnableAdapter() {
public Object run(IMMPView view) {
assertEquals(new Path("src/a.cpp"),
view.getSources().get(0));
assertEquals("0x6000",
view.getSingleArgumentSettings().get(
EMMPStatement.BASEADDRESS));
view.getSingleArgumentSettings().put(
EMMPStatement.BASEADDRESS,
"0");
view.commit();
return null;
}
});
// verify model-wise
EpocEnginePlugin.runWithMMPView(wsMmpPath, config,
new MMPViewRunnableAdapter() {
public Object run(IMMPView view) {
assertEquals(new Path("src/a.cpp"),
view.getSources().get(0));
assertEquals("0",
view.getSingleArgumentSettings().get(
EMMPStatement.BASEADDRESS));
return null;
}
});
// verify file-wise
while (!waitingResourceChanged) {
sleep();
}
IFile file = ResourcesPlugin.getWorkspace().getRoot().getFile(wsMmhPath);
assertNotNull(file);
InputStream is = file.getContents();
char[] text = FileUtils.readInputStreamContents(is, null);
assertEquals("#define SRCDIR ..\\src\n"+
"BASEADDRESS 0\n",
new String(text));
}
}