project/com.nokia.carbide.cpp.epoc.engine.tests/src/com/nokia/carbide/cpp/epoc/engine/tests/model/TestModelProvider.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/project/com.nokia.carbide.cpp.epoc.engine.tests/src/com/nokia/carbide/cpp/epoc/engine/tests/model/TestModelProvider.java Fri Apr 03 23:33:03 2009 +0100
@@ -0,0 +1,444 @@
+/*
+* 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.model;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.jface.text.Document;
+
+import com.nokia.carbide.cpp.epoc.engine.model.BldInfModelFactory;
+import com.nokia.carbide.cpp.epoc.engine.model.IOwnedModel;
+import com.nokia.carbide.cpp.epoc.engine.model.IModelListener;
+import com.nokia.carbide.cpp.epoc.engine.model.IModelProvider;
+import com.nokia.carbide.cpp.epoc.engine.model.IView;
+import com.nokia.carbide.cpp.epoc.engine.model.IViewConfiguration;
+import com.nokia.carbide.cpp.epoc.engine.model.IViewParserConfiguration;
+import com.nokia.carbide.cpp.epoc.engine.model.MMPModelFactory;
+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.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.BaseTest;
+import com.nokia.carbide.internal.cpp.epoc.engine.model.ModelProviderBase;
+
+/**
+ * Test basics of the model provider
+ *
+ */
+public class TestModelProvider extends BaseTest {
+
+ private static final String PROJECT_NAME = "test-models";
+ private static final String TEST_BLDINF_0 = "PRJ_PLATFORMS default\n"+
+ "PRJ_MMPFILES\n"+
+ "test.mmp\n";
+ private static final String TEST_MMP_0 =
+ "SOURCEPATH ..\\src\n"+
+ "SOURCE test.cpp\n";
+
+ private IModelProvider<IBldInfOwnedModel, IBldInfModel> bldInfModelProvider;
+ private IModelProvider<IMMPOwnedModel, IMMPModel> mmpModelProvider;
+ private IViewConfiguration configuration;
+ protected Collection<IDefine> macros;
+ private IMMPViewConfiguration mmpConfiguration;
+ private Map<IPath, String> fs;
+
+ /* (non-Javadoc)
+ * @see com.nokia.carbide.cpp.epoc.engine.tests.BaseTest#setUp()
+ */
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ fs = new HashMap<IPath, String>();
+ bldInfModelProvider = new MemoryFileSystemModelProvider(fs, new BldInfModelFactory());
+ ((ModelProviderBase) bldInfModelProvider).cacheModels(false);
+ mmpModelProvider = new MemoryFileSystemModelProvider(fs, new MMPModelFactory());
+ ((ModelProviderBase) mmpModelProvider).cacheModels(false);
+
+ parserConfig.projectPath = new Path(PROJECT_NAME);
+
+ macros = new ArrayList<IDefine>();
+ configuration = new IViewConfiguration() {
+
+ public Collection<IDefine> getMacros() {
+ return macros;
+ }
+
+ public IViewFilter getViewFilter() {
+ return new AcceptedNodesViewFilter();
+ }
+
+ public IViewParserConfiguration getViewParserConfiguration() {
+ return parserConfig;
+ }
+
+ };
+
+ mmpConfiguration = new IMMPViewConfiguration() {
+
+ public Collection<IDefine> getMacros() {
+ return macros;
+ }
+
+ public IViewFilter getViewFilter() {
+ return new AcceptedNodesViewFilter();
+ }
+
+ public IViewParserConfiguration getViewParserConfiguration() {
+ return parserConfig;
+ }
+
+ public boolean isStatementSupported(EMMPStatement statement) {
+ return true;
+ }
+
+ public String getDefaultDefFileBase(boolean isASSP) {
+ return "BWINS";
+ }
+
+ public boolean isEmulatorBuild() {
+ return true;
+ }
+ };
+ }
+
+ public void testCreateModel() throws CoreException {
+
+ fs.clear();
+
+ Path thePath = new Path(PROJECT_NAME + "/group/bld.inf");
+ IBldInfOwnedModel model = bldInfModelProvider.createModel(thePath);
+ assertNotNull(model);
+
+ // not registered so can do this twice
+ IBldInfOwnedModel model2 = bldInfModelProvider.createModel(thePath);
+ assertNotNull(model2);
+ assertNotSame(model, model2);
+
+ // not registered yet!
+ assertNull(bldInfModelProvider.findSharedModel(thePath));
+
+ // no document for new model
+ assertNull(model.getDocument());
+
+ // this should be allowed from a nonregistered model
+ model.setDocument(new Document(TEST_BLDINF_0));
+
+ bldInfModelProvider.registerModel(model);
+
+ // assert the file now exists
+ assertTrue(fs.containsKey(thePath));
+ }
+
+ public void testLoadModel() throws Exception {
+ fs.clear();
+
+ IPath thePath = new Path(PROJECT_NAME + "/group/bld.inf");
+
+ fs.put(thePath, TEST_BLDINF_0);
+
+ IBldInfOwnedModel model = bldInfModelProvider.createModel(thePath);
+ assertNotNull(model);
+
+ // not loaded here
+ assertNull(model.getDocument());
+
+ // register
+ bldInfModelProvider.registerModel(model);
+
+ // make sure not saved!
+ assertFalse(((MemoryFileSystemModelProvider)bldInfModelProvider).saved);
+
+ // ensure loaded
+ assertNotNull(model.getDocument());
+
+ // ensure it's got the right contents
+ assertEquals(TEST_BLDINF_0, model.getDocument().get());
+
+ }
+
+ /**
+ * Test explicit registration of models
+ *
+ */
+ public void testRegisterModels() throws CoreException {
+
+ fs.clear();
+
+ IPath thePath = new Path(PROJECT_NAME + "/group/bld.inf");
+ IBldInfOwnedModel model = bldInfModelProvider.createModel(thePath);
+ assertNotNull(model);
+ model.setDocument(new Document(TEST_BLDINF_0));
+ bldInfModelProvider.registerModel(model);
+
+ // make sure it was saved
+ assertTrue(((MemoryFileSystemModelProvider)bldInfModelProvider).saved);
+ ((MemoryFileSystemModelProvider)bldInfModelProvider).saved = false;
+
+ // owner holds one reference
+ assertEquals(1, ((ModelProviderBase) bldInfModelProvider).testGetUseCount(model));
+
+ // and ensure we can find it
+ IBldInfModel sharedModel = bldInfModelProvider.findSharedModel(thePath);
+ assertNotNull(sharedModel);
+
+ // make sure it was not saved
+ assertFalse(((MemoryFileSystemModelProvider)bldInfModelProvider).saved);
+
+ // twice...
+ IBldInfModel sharedModel2 = bldInfModelProvider.findSharedModel(thePath);
+ assertSame(sharedModel, sharedModel2);
+
+ // make sure not saved!
+ assertFalse(((MemoryFileSystemModelProvider)bldInfModelProvider).saved);
+
+ // ensure it can be released...
+ bldInfModelProvider.releaseSharedModel(sharedModel2);
+ bldInfModelProvider.releaseSharedModel(sharedModel);
+
+ // and that it's not removed because of that -- we still hold one reference
+ assertNotNull(bldInfModelProvider.findSharedModel(thePath));
+
+ //////
+
+ /// check canonical paths
+ IPath funnyPath = new Path(PROJECT_NAME + "/GROUP/BLD.INF");
+ sharedModel = bldInfModelProvider.findSharedModel(funnyPath);
+ assertNotNull(sharedModel);
+ assertSame(sharedModel,sharedModel2);
+
+ assertEquals(sharedModel.getPath().toOSString(), sharedModel2.getPath().toOSString());
+
+ /////
+
+ // now unregister
+ bldInfModelProvider.unregisterModel(model);
+
+ // should be gone now
+ assertNull(bldInfModelProvider.findSharedModel(thePath));
+
+ }
+
+ /**
+ * Test a load that happens implicitly due to querying a shared model
+ *
+ */
+ public void testSharedModelLoading() throws Exception {
+ IPath thePath = new Path(PROJECT_NAME + "/group/bld.inf");
+ fs.put(thePath, TEST_BLDINF_0);
+
+ // verify not shared yet
+ IBldInfModel model = bldInfModelProvider.findSharedModel(thePath);
+ assertNull(model);
+
+ // implicitly load
+ model = bldInfModelProvider.getSharedModel(thePath);
+ assertNotNull(model);
+
+ // make sure not saved!
+ assertFalse(((MemoryFileSystemModelProvider)bldInfModelProvider).saved);
+
+ // not it's shared
+ assertEquals(model, bldInfModelProvider.findSharedModel(thePath));
+ // release reference
+ bldInfModelProvider.releaseSharedModel(model);
+
+ // be sure it was loaded
+ assertNotNull(((IOwnedModel)model).getDocument());
+ assertEquals(TEST_BLDINF_0, ((IOwnedModel)model).getDocument().get());
+
+ IBldInfView view = model.createView(configuration);
+ assertEquals(1, view.getAllMMPReferences().length);
+
+ view.dispose();
+
+ // release our view
+ bldInfModelProvider.releaseSharedModel(model);
+
+ // model should be gone now
+ assertNull(bldInfModelProvider.findSharedModel(thePath));
+ }
+
+ /**
+ * Test that implicit loads don't happen with nonexistent files
+ *
+ */
+ public void testSharedModelFileNotFound() throws Exception {
+ IPath thePath = new Path(PROJECT_NAME + "/group/bld.inf");
+
+ // verify not shared yet
+ IBldInfModel model = bldInfModelProvider.findSharedModel(thePath);
+ assertNull(model);
+
+ // try to implicitly load
+ model = bldInfModelProvider.getSharedModel(thePath);
+
+ // shouldn't be here
+ assertNull(model);
+
+ // make sure not saved!
+ assertFalse(((MemoryFileSystemModelProvider)bldInfModelProvider).saved);
+ }
+
+ /**
+ * Test that model lives when (dangling) views exist.
+ * @throws Exception
+ */
+ public void testModelLifetimeWithViews() throws Exception {
+ IPath thePath = new Path(PROJECT_NAME + "/group/bld.inf");
+ fs.put(thePath, TEST_BLDINF_0);
+
+ ////
+ // owned stuff: keep reference
+ IBldInfOwnedModel ownedModel = bldInfModelProvider.createModel(thePath);
+ bldInfModelProvider.registerModel(ownedModel);
+ assertEquals(1, ((ModelProviderBase) bldInfModelProvider).testGetUseCount(ownedModel));
+
+ ////
+ // client stuff
+ IBldInfModel model = bldInfModelProvider.findSharedModel(thePath);
+ assertSame(model, ownedModel);
+
+ IBldInfView view = model.createView(configuration);
+ assertEquals(1, view.getAllMMPReferences().length);
+ assertEquals(2, ((ModelProviderBase) bldInfModelProvider).testGetUseCount((IOwnedModel)model));
+
+ // release our model [OOPS! view not disposed!]
+ bldInfModelProvider.releaseSharedModel(model);
+
+ ////
+ // owned stuff
+ // assert that owner detects dangling view: this maintains the reference (to avoid cascading failures)
+ try {
+ bldInfModelProvider.releaseSharedModel(ownedModel);
+ fail();
+ } catch (IllegalStateException e) {
+
+ }
+
+ view.dispose();
+
+ // should work now
+ bldInfModelProvider.releaseSharedModel(ownedModel);
+
+ }
+
+ /** just sanity to ensure two model providers don't fight */
+ public void testModelProviderIntegration() throws Exception {
+ IPath thePath = new Path(PROJECT_NAME + "/group/bld.inf");
+ fs.put(thePath, TEST_BLDINF_0);
+ IPath theMMPPath = new Path(PROJECT_NAME + "/group/test.mmp");
+ fs.put(theMMPPath, TEST_MMP_0);
+
+ IBldInfModel bldInf = bldInfModelProvider.getSharedModel(thePath);
+ IBldInfView bldInfView = bldInf.createView(configuration);
+
+ IMMPModel mmpModel = mmpModelProvider.getSharedModel(
+ new Path(PROJECT_NAME).append(
+ bldInfView.getAllMMPReferences()[0].getPath()));
+ assertNotNull(mmpModel);
+
+ IMMPView mmpView = mmpModel.createView(mmpConfiguration);
+ assertEquals(1, mmpView.getSources().size());
+ assertEquals(new Path("src/test.cpp"), mmpView.getSources().get(0));
+ mmpView.dispose();
+
+ mmpModelProvider.releaseSharedModel(mmpModel);
+
+ bldInfView.dispose();
+ bldInfModelProvider.releaseSharedModel(bldInf);
+ }
+
+ private static final String TEST_BLDINF_1 = "PRJ_PLATFORMS default\n"+
+ "PRJ_MMPFILES\n";
+
+ public void testModelSaving() throws Exception {
+
+ IPath thePath = new Path(PROJECT_NAME + "/group/bld.inf");
+ fs.put(thePath, TEST_BLDINF_0);
+
+ IBldInfModel model = bldInfModelProvider.getSharedModel(thePath);
+ assertNotNull(model);
+
+ // change
+ IBldInfView view = model.createView(configuration);
+ view.getMakMakeReferences().remove(0);
+ view.commit();
+
+ // ensure change reported and propagated
+ assertEquals(TEST_BLDINF_1, fs.get(thePath));
+
+
+ }
+
+ public void testModelNotSaving() throws Exception {
+
+ IPath thePath = new Path(PROJECT_NAME + "/group/bld.inf");
+ fs.put(thePath, TEST_BLDINF_0);
+
+ IBldInfModel model = bldInfModelProvider.getSharedModel(thePath);
+ assertNotNull(model);
+
+ final boolean[] modelPinged = { false };
+ model.addListener(new IModelListener() {
+
+ public void modelChanged(IOwnedModel model) {
+ modelPinged[0] =true;
+ }
+
+ public void modelUpdated(IOwnedModel model, IView view) {
+ modelPinged[0] =true;
+ }
+
+ });
+
+ // no change!
+ IBldInfView view = model.createView(configuration);
+ view.commit();
+
+ // ensure change not reported and not propagated
+ assertFalse(modelPinged[0]);
+ assertEquals(TEST_BLDINF_0, fs.get(thePath));
+
+
+ }
+ /**
+ * Ensure the models work sanely with threading.
+ * @throws Exception
+ */
+ public void testThreading() throws CoreException {
+ IPath mmpPath = projectPath.append("test.mmp");
+
+ ModelProviderThreadTests test = new ModelProviderThreadTests();
+ test.testThreading(mmpModelProvider, mmpConfiguration, mmpPath);
+ }
+
+}