project/com.nokia.carbide.cpp.epoc.engine.tests/src/com/nokia/carbide/cpp/epoc/engine/tests/model/TestModelProvider.java
changeset 0 fb279309251b
child 636 f96e62c11eac
--- /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);
+	}
+	
+}