diff --git a/de.gebit.integrity.runner/src/de/gebit/integrity/runner/IntegrityDSLSetup.java b/de.gebit.integrity.runner/src/de/gebit/integrity/runner/IntegrityDSLSetup.java index b93885c0c..84ca36930 100644 --- a/de.gebit.integrity.runner/src/de/gebit/integrity/runner/IntegrityDSLSetup.java +++ b/de.gebit.integrity.runner/src/de/gebit/integrity/runner/IntegrityDSLSetup.java @@ -7,10 +7,15 @@ *******************************************************************************/ package de.gebit.integrity.runner; +import com.google.inject.Binder; import com.google.inject.Guice; import com.google.inject.Injector; +import com.google.inject.Module; +import com.google.inject.util.Modules; import de.gebit.integrity.DSLStandaloneSetup; +import de.gebit.integrity.runner.modelcheck.ModelChecker; +import de.gebit.integrity.runner.modelcheck.NullModelChecker; /** * Initialization support for running Xtext languages without equinox extension registry. @@ -27,9 +32,23 @@ public IntegrityDSLSetup() { super(); } + /** + * Whether model checking shall be disabled by overriding the model checker. + */ + protected boolean disableModelChecks; + + public void setDisableModelChecks(boolean aDisableModelChecksFlag) { + disableModelChecks = aDisableModelChecksFlag; + } + @Override public Injector createInjector() { - return Guice.createInjector(createGuiceModule(getClassLoader())); + return Guice.createInjector(Modules.override(createGuiceModule(getClassLoader())).with(new Module() { + @Override + public void configure(Binder aBinder) { + overrideBindings(aBinder); + } + })); } /** @@ -43,4 +62,17 @@ protected IntegrityRunnerModule createGuiceModule(ClassLoader aClassLoader) { return new IntegrityRunnerModule(aClassLoader); } + /** + * Overrides certain bindings with non-default classes. This can also be used in subclasses to override bindings, as + * an alternative to creating a new module based on the default {@link IntegrityRunnerModule}, although the latter + * is the suggested method. + * + * @param aBinder + */ + protected void overrideBindings(Binder aBinder) { + if (disableModelChecks) { + aBinder.bind(ModelChecker.class).to(NullModelChecker.class); + } + } + } diff --git a/de.gebit.integrity.runner/src/de/gebit/integrity/runner/TestModel.java b/de.gebit.integrity.runner/src/de/gebit/integrity/runner/TestModel.java index 69b43f2b3..a76db8fa7 100644 --- a/de.gebit.integrity.runner/src/de/gebit/integrity/runner/TestModel.java +++ b/de.gebit.integrity.runner/src/de/gebit/integrity/runner/TestModel.java @@ -12,7 +12,6 @@ import java.util.Comparator; import java.util.HashMap; import java.util.HashSet; -import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Map; @@ -22,11 +21,7 @@ import org.eclipse.emf.common.util.TreeIterator; import org.eclipse.emf.common.util.URI; import org.eclipse.emf.ecore.EObject; -import org.eclipse.emf.ecore.InternalEObject; -import org.eclipse.emf.ecore.resource.Resource; import org.eclipse.emf.ecore.resource.Resource.Diagnostic; -import org.eclipse.emf.ecore.resource.ResourceSet; -import org.eclipse.emf.ecore.util.EcoreUtil; import org.eclipse.xtext.resource.IResourceFactory; import org.eclipse.xtext.resource.XtextResource; import org.eclipse.xtext.resource.XtextResourceSet; @@ -49,7 +44,6 @@ import de.gebit.integrity.modelsource.ModelSourceExplorer; import de.gebit.integrity.runner.callbacks.TestRunnerCallback; import de.gebit.integrity.runner.exceptions.ModelAmbiguousException; -import de.gebit.integrity.runner.exceptions.ModelLinkException; import de.gebit.integrity.runner.exceptions.ModelLoadException; import de.gebit.integrity.runner.exceptions.ModelParseException; import de.gebit.integrity.runner.providers.TestResourceProvider; @@ -323,16 +317,16 @@ public int compare(ConstantDefinition aFirst, ConstantDefinition aSecond) { * * @param aResourceProvider * the resource provider to use for loading the model - * @param aResolveAllFlag - * whether the model should be resolved after loading (this helps finding linking errors immediately, but - * can take some time) + * @param aSkipModelChecksFlag + * if true, the test runner will skip the model consistency checks it would otherwise perform during the + * dry run * @param aSetupClass * the setup class to use for EMF setup and Guice initialization (if null, the default class is used) * @return the test model ready for execution * @throws ModelLoadException * if any errors occur during loading (syntax errors or unresolvable references) */ - public static TestModel loadTestModel(TestResourceProvider aResourceProvider, boolean aResolveAllFlag, + public static TestModel loadTestModel(TestResourceProvider aResourceProvider, boolean aSkipModelChecksFlag, Class aSetupClass) throws ModelLoadException { Class tempSetupClass = aSetupClass; if (tempSetupClass == null) { @@ -349,9 +343,13 @@ public static TestModel loadTestModel(TestResourceProvider aResourceProvider, bo throw new IllegalArgumentException("Provided setup class '" + tempSetupClass + "' could not be instantiated.", exc); } + if (aResourceProvider.getClassLoader() != null) { tempSetup.setClassLoader(aResourceProvider.getClassLoader()); } + tempSetup.setDisableModelChecks(aSkipModelChecksFlag); + + // Behold...the mighty Injector is born! Injector tempInjector = tempSetup.createInjectorAndDoEMFRegistration(); XtextResourceSet tempResourceSet = tempInjector.getInstance(XtextResourceSet.class); @@ -385,20 +383,6 @@ public static TestModel loadTestModel(TestResourceProvider aResourceProvider, bo tempErrors); } - // Full resolving has been made optional because for some not-yet-known reason, resolveAll takes a huge amount - // of time since the change to XText 2.2. - if (aResolveAllFlag) { - System.out.print("Resolving the test model..."); - EcoreUtil.resolveAll(tempResourceSet); - System.out.println("done!"); - - Set tempUnresolvedProxies = findUnresolvedProxies(tempResourceSet); - if (tempUnresolvedProxies.size() > 0) { - throw new ModelLinkException("Encountered " + tempUnresolvedProxies.size() - + " unresolvable references while linking test model.", tempUnresolvedProxies); - } - } - TestModel tempModel = new TestModel(tempModels); tempInjector.injectMembers(tempModel); if (tempModel.getDuplicateDefinitions().size() > 0) { @@ -408,47 +392,6 @@ public static TestModel loadTestModel(TestResourceProvider aResourceProvider, bo return tempModel; } - /** - * Searches for all unresolved proxy objects in the given resource set. - * - * @param aResourceSet - * - * @return all proxy objects that are not resolvable - */ - protected static Set findUnresolvedProxies(ResourceSet aResourceSet) { - Set tempUnresolvedProxies = new java.util.LinkedHashSet(); - - for (Resource tempResource : aResourceSet.getResources()) { - tempUnresolvedProxies.addAll(findUnresolvedProxies(tempResource)); - } - return tempUnresolvedProxies; - } - - /** - * Searches for all unresolved proxy objects in the given resource. - * - * @param aResource - * - * @return all proxy objects that are not resolvable - */ - protected static Set findUnresolvedProxies(Resource aResource) { - Set tempUnresolvedProxies = new java.util.LinkedHashSet(); - - for (Iterator tempIterator = EcoreUtil.getAllContents(aResource, true); tempIterator.hasNext();) { - InternalEObject tempNextElement = (InternalEObject) tempIterator.next(); - if (tempNextElement.eIsProxy()) { - tempUnresolvedProxies.add(tempNextElement); - } - for (EObject tempElement : tempNextElement.eCrossReferences()) { - tempElement = EcoreUtil.resolve(tempElement, aResource); - if (tempElement.eIsProxy()) { - tempUnresolvedProxies.add(tempElement); - } - } - } - return tempUnresolvedProxies; - } - /** * Initializes a fresh test runner instance, based on this test model. * diff --git a/de.gebit.integrity.runner/src/de/gebit/integrity/runner/console/ConsoleTestExecutor.java b/de.gebit.integrity.runner/src/de/gebit/integrity/runner/console/ConsoleTestExecutor.java index 9b58fe50a..bbd7c150b 100644 --- a/de.gebit.integrity.runner/src/de/gebit/integrity/runner/console/ConsoleTestExecutor.java +++ b/de.gebit.integrity.runner/src/de/gebit/integrity/runner/console/ConsoleTestExecutor.java @@ -121,11 +121,11 @@ public void run(String[] someArgs) { "[{--remotehost} host]"); SimpleCommandLineParser.BooleanOption tempWaitForPlayOption = new SimpleCommandLineParser.BooleanOption("w", "wait", "Wait with test execution for a 'play' signal via remoting", "[{-w,--wait}]"); - SimpleCommandLineParser.BooleanOption tempResolveAllReferences = new SimpleCommandLineParser.BooleanOption( + SimpleCommandLineParser.BooleanOption tempSkipModelCheck = new SimpleCommandLineParser.BooleanOption( null, - "resolve", - "Enable pre-executional resolving of all references in the loaded scripts. This may slow down the startup phase, but you lower the risk of getting strange NullPointerExceptions during execution due to unresolved links.", - "[{--resolve}]"); + "nomodelcheck", + "Disables model checking. This can decrease startup time, especially with big script collections, but you greatly increase the risk of getting strange NullPointerExceptions during execution due to unresolved links.", + "[{--nomodelcheck}]"); SimpleCommandLineParser.StringOption tempParameterizedConstantOption = new SimpleCommandLineParser.StringOption( "p", "parameter", "Define a parameterized constants' value (can be used multiple times!)", "[{-p,--parameter} fully.qualified.constant.name=value]"); @@ -136,8 +136,7 @@ public void run(String[] someArgs) { tempParser.addOptions(tempConsoleOption, tempXmlOption, tempXsltOption, tempNameOption, tempVariantOption, tempNoremoteOption, tempRemoteportOption, tempRemoteHostOption, tempWaitForPlayOption, - tempResolveAllReferences, tempParameterizedConstantOption, tempSeedOption, - tempExcludeConsoleStreamsOption); + tempSkipModelCheck, tempParameterizedConstantOption, tempSeedOption, tempExcludeConsoleStreamsOption); if (someArgs.length == 0) { System.out.print(tempParser.getHelp(REMAINING_ARGS_HELP)); @@ -168,8 +167,7 @@ public void run(String[] someArgs) { validateResourceProvider(tempResourceProvider); try { - TestModel tempModel = TestModel.loadTestModel(tempResourceProvider, tempResolveAllReferences.isSet(), - setupClass); + TestModel tempModel = TestModel.loadTestModel(tempResourceProvider, tempSkipModelCheck.isSet(), setupClass); SuiteDefinition tempRootSuite = tempModel.getSuiteByName(tempRootSuiteName); VariantDefinition tempVariant = null; diff --git a/de.gebit.integrity.runner/src/de/gebit/integrity/runner/modelcheck/NullModelChecker.java b/de.gebit.integrity.runner/src/de/gebit/integrity/runner/modelcheck/NullModelChecker.java new file mode 100644 index 000000000..ea6aafab2 --- /dev/null +++ b/de.gebit.integrity.runner/src/de/gebit/integrity/runner/modelcheck/NullModelChecker.java @@ -0,0 +1,51 @@ +/******************************************************************************* + * Copyright (c) 2013 Rene Schneider, GEBIT Solutions GmbH 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 + *******************************************************************************/ +package de.gebit.integrity.runner.modelcheck; + +import de.gebit.integrity.dsl.Call; +import de.gebit.integrity.dsl.CustomOperation; +import de.gebit.integrity.dsl.Suite; +import de.gebit.integrity.dsl.TableTest; +import de.gebit.integrity.dsl.Test; +import de.gebit.integrity.exceptions.ModelRuntimeLinkException; + +/** + * This {@link ModelChecker} implementation does not perform any checks. The normally used checker is replaced with this + * one if the checks shall be omitted (for example for performance reasons). + * + * @author Rene Schneider - initial API and implementation + * + */ +public class NullModelChecker implements ModelChecker { + + @Override + public void check(Test aTest) throws ModelRuntimeLinkException { + // do nothing + } + + @Override + public void check(Call aCall) throws ModelRuntimeLinkException { + // do nothing + } + + @Override + public void check(TableTest aTableTest) throws ModelRuntimeLinkException { + // do nothing + } + + @Override + public void check(CustomOperation aCustomOperation) throws ModelRuntimeLinkException { + // do nothing + } + + @Override + public void check(Suite aSuite) throws ModelRuntimeLinkException { + // do nothing + } + +}