diff options
author | liamfallon <liam.fallon@ericsson.com> | 2018-10-06 13:33:26 +0100 |
---|---|---|
committer | liamfallon <liam.fallon@ericsson.com> | 2018-10-07 22:45:35 +0100 |
commit | 7a5e85e17d58e4d75812a3015adc7cbc06e4e49c (patch) | |
tree | fa71bf921739219e6b7ebbc2bb2d1f7eb86a2ad8 /core/core-engine/src | |
parent | 9cedbd41c0ee3bade89de5d2e1e822cc4e9a36e7 (diff) |
Unit test for Apex engine
Coverage for unit test of engie state and state machine handling.
Added coverage of the facade and executor context classes
Added coverage for executors
Added coverage for the remainder of the core engine
Issue-ID: POLICY-1034
Change-Id: I85c66005dfdffdf2b4ee5672473a3ae4823d0d9c
Signed-off-by: liamfallon <liam.fallon@ericsson.com>
Diffstat (limited to 'core/core-engine/src')
31 files changed, 3672 insertions, 62 deletions
diff --git a/core/core-engine/src/main/java/org/onap/policy/apex/core/engine/context/ApexInternalContext.java b/core/core-engine/src/main/java/org/onap/policy/apex/core/engine/context/ApexInternalContext.java index f73281ada..8eb92a0f8 100644 --- a/core/core-engine/src/main/java/org/onap/policy/apex/core/engine/context/ApexInternalContext.java +++ b/core/core-engine/src/main/java/org/onap/policy/apex/core/engine/context/ApexInternalContext.java @@ -51,7 +51,7 @@ import org.onap.policy.apex.model.utilities.comparison.KeyedMapDifference; * * @author Liam Fallon */ -public final class ApexInternalContext implements AxConceptGetter<ContextAlbum> { +public class ApexInternalContext implements AxConceptGetter<ContextAlbum> { // The key of the currently running Apex model private AxArtifactKey key; diff --git a/core/core-engine/src/main/java/org/onap/policy/apex/core/engine/engine/impl/ApexEngineImpl.java b/core/core-engine/src/main/java/org/onap/policy/apex/core/engine/engine/impl/ApexEngineImpl.java index efd6aec5e..b703506ea 100644 --- a/core/core-engine/src/main/java/org/onap/policy/apex/core/engine/engine/impl/ApexEngineImpl.java +++ b/core/core-engine/src/main/java/org/onap/policy/apex/core/engine/engine/impl/ApexEngineImpl.java @@ -33,7 +33,9 @@ import org.onap.policy.apex.core.engine.engine.ApexEngine; import org.onap.policy.apex.core.engine.engine.EnEventListener; import org.onap.policy.apex.core.engine.event.EnEvent; import org.onap.policy.apex.core.engine.executor.exception.StateMachineException; +import org.onap.policy.apex.core.infrastructure.threading.ThreadUtilities; import org.onap.policy.apex.model.basicmodel.concepts.ApexException; +import org.onap.policy.apex.model.basicmodel.concepts.ApexRuntimeException; import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey; import org.onap.policy.apex.model.basicmodel.concepts.AxReferenceKey; import org.onap.policy.apex.model.enginemodel.concepts.AxEngineModel; @@ -201,30 +203,37 @@ public class ApexEngineImpl implements ApexEngine { public void stop() throws ApexException { LOGGER.entry("stop()->" + key); + // Check if the engine is already stopped + if (state == AxEngineState.STOPPED) { + throw new ApexException( + STOP + key.getId() + "," + state + ", cannot stop engine, engine is already stopped"); + } + // Stop the engine if it is in state READY, if it is in state EXECUTING, wait for execution to finish for (int increment = ApexEngineConstants.STOP_EXECUTION_WAIT_TIMEOUT; - increment > 0; - increment = ApexEngineConstants.STOP_EXECUTION_WAIT_TIMEOUT) { + increment > 0; increment -= ApexEngineConstants.APEX_ENGINE_STOP_EXECUTION_WAIT_INCREMENT) { + ThreadUtilities.sleep(ApexEngineConstants.APEX_ENGINE_STOP_EXECUTION_WAIT_INCREMENT); + synchronized (state) { switch (state) { - // Already stopped - case STOPPED: - - throw new ApexException(STOP + key.getId() + "," + state - + ", cannot stop engine, engine is already stopped"); - // The normal case, the engine wasn't doing anything or it was executing + // Engine is OK to stop or has been stopped on return of an event case READY: - case STOPPING: - + case STOPPED: state = AxEngineState.STOPPED; stateMachineHandler.stop(); engineStats.engineStop(); LOGGER.exit("stop()" + key); return; + // Engine is executing a policy, wait for it to stop case EXECUTING: state = AxEngineState.STOPPING; break; + + // Wait for the engine to stop + case STOPPING: + break; + default: throw new ApexException(STOP + key.getId() + "," + state + ", cannot stop engine, engine is in an undefined state"); @@ -232,7 +241,12 @@ public class ApexEngineImpl implements ApexEngine { } } - throw new ApexException(STOP + key.getId() + "," + state + ", cannot stop engine, engine stop timed out"); + // Force the engine to STOPPED state + synchronized (state) { + state = AxEngineState.STOPPED; + } + + throw new ApexException(STOP + key.getId() + "," + state + ", error stopping engine, engine stop timed out"); } /* @@ -336,9 +350,11 @@ public class ApexEngineImpl implements ApexEngine { ret = false; } synchronized (state) { - // Only go to READY if we are still in state EXECUTING, we could be in state STOPPING + // Only go to READY if we are still in state EXECUTING, we go to state STOPPED if we were STOPPING if (state == AxEngineState.EXECUTING) { state = AxEngineState.READY; + } else if (state == AxEngineState.STOPPING) { + state = AxEngineState.STOPPED; } } return ret; @@ -352,6 +368,18 @@ public class ApexEngineImpl implements ApexEngine { */ @Override public void addEventListener(final String listenerName, final EnEventListener listener) { + if (listenerName == null) { + String message = "addEventListener()<-" + key.getId() + "," + state + ", listenerName is null"; + LOGGER.warn(message); + throw new ApexRuntimeException(message); + } + + if (listener == null) { + String message = "addEventListener()<-" + key.getId() + "," + state + ", listener is null"; + LOGGER.warn(message); + throw new ApexRuntimeException(message); + } + eventListeners.put(listenerName, listener); } @@ -362,6 +390,12 @@ public class ApexEngineImpl implements ApexEngine { */ @Override public void removeEventListener(final String listenerName) { + if (listenerName == null) { + String message = "removeEventListener()<-" + key.getId() + "," + state + ", listenerName is null"; + LOGGER.warn(message); + throw new ApexRuntimeException(message); + } + eventListeners.remove(listenerName); } @@ -411,7 +445,7 @@ public class ApexEngineImpl implements ApexEngine { if (internalContext == null) { return currentContext; } - + for (final Entry<AxArtifactKey, ContextAlbum> contextAlbumEntry : internalContext.getContextAlbums() .entrySet()) { currentContext.put(contextAlbumEntry.getKey(), contextAlbumEntry.getValue()); diff --git a/core/core-engine/src/main/java/org/onap/policy/apex/core/engine/executor/ExecutorFactory.java b/core/core-engine/src/main/java/org/onap/policy/apex/core/engine/executor/ExecutorFactory.java index f092ce716..fb6c7b45e 100644 --- a/core/core-engine/src/main/java/org/onap/policy/apex/core/engine/executor/ExecutorFactory.java +++ b/core/core-engine/src/main/java/org/onap/policy/apex/core/engine/executor/ExecutorFactory.java @@ -32,7 +32,7 @@ import org.onap.policy.apex.model.policymodel.concepts.AxTask; * @author Liam Fallon */ -public abstract class ExecutorFactory { +public interface ExecutorFactory { /** * Get an executor for task selection logic. * diff --git a/core/core-engine/src/main/java/org/onap/policy/apex/core/engine/executor/StateFinalizerExecutor.java b/core/core-engine/src/main/java/org/onap/policy/apex/core/engine/executor/StateFinalizerExecutor.java index 1c225f7b8..c30bda1b9 100644 --- a/core/core-engine/src/main/java/org/onap/policy/apex/core/engine/executor/StateFinalizerExecutor.java +++ b/core/core-engine/src/main/java/org/onap/policy/apex/core/engine/executor/StateFinalizerExecutor.java @@ -101,7 +101,8 @@ public abstract class StateFinalizerExecutor public void prepare() throws StateMachineException { LOGGER.debug("prepare:" + finalizerLogic.getId() + "," + finalizerLogic.getLogicFlavour() + "," + finalizerLogic.getLogic()); - argumentOfClassNotNull(finalizerLogic.getLogic(), StateMachineException.class, "task logic cannot be null."); + argumentOfClassNotNull(finalizerLogic.getLogic(), StateMachineException.class, + "state finalizer logic cannot be null."); } /* @@ -237,7 +238,11 @@ public abstract class StateFinalizerExecutor */ @Override public String getOutgoing() { - return executionContext.getSelectedStateOutputName(); + if (executionContext != null) { + return executionContext.getSelectedStateOutputName(); + } else { + return null; + } } /* diff --git a/core/core-engine/src/main/java/org/onap/policy/apex/core/engine/executor/StateMachineExecutor.java b/core/core-engine/src/main/java/org/onap/policy/apex/core/engine/executor/StateMachineExecutor.java index 97d51bf78..34ba3942c 100644 --- a/core/core-engine/src/main/java/org/onap/policy/apex/core/engine/executor/StateMachineExecutor.java +++ b/core/core-engine/src/main/java/org/onap/policy/apex/core/engine/executor/StateMachineExecutor.java @@ -146,11 +146,8 @@ public class StateMachineExecutor implements Executor<EnEvent, EnEvent, AxPolicy StateOutput stateOutput = new StateOutput(new AxStateOutput(firstExecutor.getSubject().getKey(), incomingEvent.getKey(), firstExecutor.getSubject().getKey()), incomingEvent); while (true) { - // Execute the state + // Execute the state, it returns an output or throws an exception stateOutput = stateExecutor.execute(executionId, stateOutput.getOutputEvent()); - if (stateOutput == null) { - throw new StateMachineException("state execution failed, invalid state output returned"); - } // Use the next state of the state output to find if all the states have executed if (stateOutput.getNextState().equals(AxReferenceKey.getNullKey())) { diff --git a/core/core-engine/src/main/java/org/onap/policy/apex/core/engine/executor/TaskExecutor.java b/core/core-engine/src/main/java/org/onap/policy/apex/core/engine/executor/TaskExecutor.java index 2a62f3ae2..c55d4924d 100644 --- a/core/core-engine/src/main/java/org/onap/policy/apex/core/engine/executor/TaskExecutor.java +++ b/core/core-engine/src/main/java/org/onap/policy/apex/core/engine/executor/TaskExecutor.java @@ -41,14 +41,14 @@ import org.slf4j.ext.XLogger; import org.slf4j.ext.XLoggerFactory; /** - * This abstract class executes a task in a state of an Apex policy and is specialized by classes - * that implement execution of task logic. + * This abstract class executes a task in a state of an Apex policy and is specialized by classes that implement + * execution of task logic. * * @author Sven van der Meer (sven.van.der.meer@ericsson.com) * @author Liam Fallon (liam.fallon@ericsson.com) */ public abstract class TaskExecutor - implements Executor<Map<String, Object>, Map<String, Object>, AxTask, ApexInternalContext> { + implements Executor<Map<String, Object>, Map<String, Object>, AxTask, ApexInternalContext> { // Logger for this class private static final XLogger LOGGER = XLoggerFactory.getXLogger(TaskExecutor.class); @@ -86,7 +86,7 @@ public abstract class TaskExecutor */ @Override public void setContext(final Executor<?, ?, ?, ?> newParent, final AxTask newAxTask, - final ApexInternalContext newInternalContext) { + final ApexInternalContext newInternalContext) { this.parent = newParent; this.axTask = newAxTask; this.internalContext = newInternalContext; @@ -100,7 +100,7 @@ public abstract class TaskExecutor @Override public void prepare() throws StateMachineException { LOGGER.debug("prepare:" + axTask.getKey().getId() + "," + axTask.getTaskLogic().getLogicFlavour() + "," - + axTask.getTaskLogic().getLogic()); + + axTask.getTaskLogic().getLogic()); argumentOfClassNotNull(axTask.getTaskLogic().getLogic(), StateMachineException.class, "task logic cannot be null."); } @@ -108,43 +108,43 @@ public abstract class TaskExecutor /* * (non-Javadoc) * - * @see org.onap.policy.apex.core.engine.executor.Executor#execute(java.lang.long, - * java.lang.Object) + * @see org.onap.policy.apex.core.engine.executor.Executor#execute(java.lang.long, java.lang.Object) */ @Override public Map<String, Object> execute(final long executionId, final Map<String, Object> newIncomingFields) - throws StateMachineException, ContextException { + throws StateMachineException, ContextException { throw new StateMachineException( - "execute() not implemented on abstract TaskExecutor class, only on its subclasses"); + "execute() not implemented on abstract TaskExecutor class, only on its subclasses"); } /* * (non-Javadoc) * - * @see org.onap.policy.apex.core.engine.executor.Executor#executePre(java.lang.long, - * java.lang.Object) + * @see org.onap.policy.apex.core.engine.executor.Executor#executePre(java.lang.long, java.lang.Object) */ @Override public final void executePre(final long executionId, final Map<String, Object> newIncomingFields) - throws StateMachineException, ContextException { + throws StateMachineException, ContextException { LOGGER.debug("execute-pre:" + getSubject().getTaskLogic().getLogicFlavour() + "," - + getSubject().getKey().getId() + "," + getSubject().getTaskLogic().getLogic()); + + getSubject().getKey().getId() + "," + getSubject().getTaskLogic().getLogic()); // Check that the incoming event has all the input fields for this state final Set<String> missingTaskInputFields = new TreeSet<>(axTask.getInputFields().keySet()); missingTaskInputFields.removeAll(newIncomingFields.keySet()); // Remove fields from the set that are optional + final Set<String> optionalFields = new TreeSet<>(); for (final Iterator<String> missingFieldIterator = missingTaskInputFields.iterator(); missingFieldIterator - .hasNext();) { + .hasNext();) { final String missingField = missingFieldIterator.next(); if (axTask.getInputFields().get(missingField).getOptional()) { - missingTaskInputFields.remove(missingField); + optionalFields.add(missingField); } } + missingTaskInputFields.removeAll(optionalFields); if (!missingTaskInputFields.isEmpty()) { throw new StateMachineException("task input fields \"" + missingTaskInputFields - + "\" are missing for task \"" + axTask.getKey().getId() + "\""); + + "\" are missing for task \"" + axTask.getKey().getId() + "\""); } // Record the incoming fields @@ -157,8 +157,8 @@ public abstract class TaskExecutor } // Get task context object - executionContext = - new TaskExecutionContext(this, executionId, getSubject(), getIncoming(), getOutgoing(), getContext()); + executionContext = new TaskExecutionContext(this, executionId, getSubject(), getIncoming(), getOutgoing(), + getContext()); } /* @@ -170,7 +170,7 @@ public abstract class TaskExecutor public final void executePost(final boolean returnValue) throws StateMachineException, ContextException { if (!returnValue) { String errorMessage = "execute-post: task logic execution failure on task \"" + axTask.getKey().getName() - + "\" in model " + internalContext.getKey().getId(); + + "\" in model " + internalContext.getKey().getId(); if (executionContext.getMessage() != null) { errorMessage += ", user message: " + executionContext.getMessage(); } @@ -191,16 +191,19 @@ public abstract class TaskExecutor missingTaskOutputFields.removeAll(outgoingFields.keySet()); // Remove fields from the set that are optional + final Set<String> optionalOrCopiedFields = new TreeSet<>(); for (final Iterator<String> missingFieldIterator = missingTaskOutputFields.iterator(); missingFieldIterator - .hasNext();) { + .hasNext();) { final String missingField = missingFieldIterator.next(); - if (axTask.getInputFields().get(missingField).getOptional()) { - missingTaskOutputFields.remove(missingField); + if (axTask.getInputFields().containsKey(missingField) + || axTask.getOutputFields().get(missingField).getOptional()) { + optionalOrCopiedFields.add(missingField); } } + missingTaskOutputFields.removeAll(optionalOrCopiedFields); if (!missingTaskOutputFields.isEmpty()) { throw new StateMachineException("task output fields \"" + missingTaskOutputFields - + "\" are missing for task \"" + axTask.getKey().getId() + "\""); + + "\" are missing for task \"" + axTask.getKey().getId() + "\""); } // Finally, check that the outgoing field map don't have any extra fields, if present, raise @@ -210,7 +213,7 @@ public abstract class TaskExecutor extraTaskOutputFields.removeAll(axTask.getOutputFields().keySet()); if (!extraTaskOutputFields.isEmpty()) { throw new StateMachineException("task output fields \"" + extraTaskOutputFields - + "\" are unwanted for task \"" + axTask.getKey().getId() + "\""); + + "\" are unwanted for task \"" + axTask.getKey().getId() + "\""); } String message = "execute-post:" + axTask.getKey().getId() + ", returning fields " + outgoingFields.toString(); @@ -218,14 +221,13 @@ public abstract class TaskExecutor } /** - * If the input field exists on the output and it is not set in the task, then it should - * be copied to the output. + * If the input field exists on the output and it is not set in the task, then it should be copied to the output. * - * @param field the input field + * @param field the input field */ private void copyInputField2Output(String field) { // Check if the field exists and is not set on the output - if (!getOutgoing().containsKey(field) || getOutgoing().get(field) != null) { + if (getOutgoing().containsKey(field) && getOutgoing().get(field) != null) { return; } @@ -316,14 +318,13 @@ public abstract class TaskExecutor /* * (non-Javadoc) * - * @see - * org.onap.policy.apex.core.engine.executor.Executor#setNext(org.onap.policy.apex.core.engine. + * @see org.onap.policy.apex.core.engine.executor.Executor#setNext(org.onap.policy.apex.core.engine. * executor.Executor) */ @Override public void setNext( - final Executor<Map<String, Object>, Map<String, Object>, AxTask, ApexInternalContext> newNextExecutor) { - this.nextExecutor = newNextExecutor; + final Executor<Map<String, Object>, Map<String, Object>, AxTask, ApexInternalContext> nextEx) { + this.nextExecutor = nextEx; } /* @@ -339,10 +340,10 @@ public abstract class TaskExecutor /* * (non-Javadoc) * - * @see - * org.onap.policy.apex.core.engine.executor.Executor#setParameters(org.onap.policy.apex.core. - * engine. ExecutorParameters) + * @see org.onap.policy.apex.core.engine.executor.Executor#setParameters(org.onap.policy.apex.core. engine. + * ExecutorParameters) */ @Override - public void setParameters(final ExecutorParameters parameters) {} + public void setParameters(final ExecutorParameters parameters) { + } } diff --git a/core/core-engine/src/main/java/org/onap/policy/apex/core/engine/executor/context/AxTaskFacade.java b/core/core-engine/src/main/java/org/onap/policy/apex/core/engine/executor/context/AxTaskFacade.java index f7b53554d..f3906213f 100644 --- a/core/core-engine/src/main/java/org/onap/policy/apex/core/engine/executor/context/AxTaskFacade.java +++ b/core/core-engine/src/main/java/org/onap/policy/apex/core/engine/executor/context/AxTaskFacade.java @@ -20,7 +20,6 @@ package org.onap.policy.apex.core.engine.executor.context; -import org.onap.policy.apex.context.ContextRuntimeException; import org.onap.policy.apex.context.SchemaHelper; import org.onap.policy.apex.context.impl.schema.SchemaHelperFactory; import org.onap.policy.apex.core.engine.event.EnException; @@ -120,7 +119,7 @@ public class AxTaskFacade { // Get a schema helper to handle translations of fields to and from the schema try { return new SchemaHelperFactory().createSchemaHelper(field.getKey(), field.getSchema()); - } catch (final ContextRuntimeException e) { + } catch (final Exception e) { final String message = "schema helper cannot be created for task field \"" + fieldName + "\" with key \"" + field.getId() + "\" with schema \"" + field.getSchema() + "\""; LOGGER.warn(message, e); diff --git a/core/core-engine/src/main/java/org/onap/policy/apex/core/engine/executor/context/TaskSelectionExecutionContext.java b/core/core-engine/src/main/java/org/onap/policy/apex/core/engine/executor/context/TaskSelectionExecutionContext.java index 63052348a..312c2a058 100644 --- a/core/core-engine/src/main/java/org/onap/policy/apex/core/engine/executor/context/TaskSelectionExecutionContext.java +++ b/core/core-engine/src/main/java/org/onap/policy/apex/core/engine/executor/context/TaskSelectionExecutionContext.java @@ -76,7 +76,7 @@ public class TaskSelectionExecutionContext { * sets this field in its logic prior to executing and the Apex engine executes this task as the * task for this state. */ - public final AxArtifactKey selectedTask; + public AxArtifactKey selectedTask; /** * Logger for task selection execution, task selection logic can use this field to access and diff --git a/core/core-engine/src/main/java/org/onap/policy/apex/core/engine/executor/impl/ExecutorFactoryImpl.java b/core/core-engine/src/main/java/org/onap/policy/apex/core/engine/executor/impl/ExecutorFactoryImpl.java index d1f07e19a..c0e24dd5a 100644 --- a/core/core-engine/src/main/java/org/onap/policy/apex/core/engine/executor/impl/ExecutorFactoryImpl.java +++ b/core/core-engine/src/main/java/org/onap/policy/apex/core/engine/executor/impl/ExecutorFactoryImpl.java @@ -49,7 +49,7 @@ import org.slf4j.ext.XLoggerFactory; * * @author Liam Fallon (liam.fallon@ericsson.com) */ -public class ExecutorFactoryImpl extends ExecutorFactory { +public class ExecutorFactoryImpl implements ExecutorFactory { // Get a reference to the logger private static final XLogger LOGGER = XLoggerFactory.getXLogger(ExecutorFactoryImpl.class); @@ -220,7 +220,7 @@ public class ExecutorFactoryImpl extends ExecutorFactory { throw new StateMachineRuntimeException(errorMessage, e); } - // Check the class is a Task Selection Executor + // Check the class is the correct type of executor if (!(executorSuperClass.isAssignableFrom(executorObject.getClass()))) { final String errorMessage = "Executor on \"" + logicFlavour + "\" of type \"" + executorClass + "\" is not an instance of \"" + executorSuperClass.getCanonicalName() + "\""; diff --git a/core/core-engine/src/test/java/org/onap/policy/apex/core/engine/engine/impl/ApexEngineImplTest.java b/core/core-engine/src/test/java/org/onap/policy/apex/core/engine/engine/impl/ApexEngineImplTest.java new file mode 100644 index 000000000..2a80cf06b --- /dev/null +++ b/core/core-engine/src/test/java/org/onap/policy/apex/core/engine/engine/impl/ApexEngineImplTest.java @@ -0,0 +1,668 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2018 Ericsson. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.core.engine.engine.impl; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.io.IOException; +import java.lang.reflect.Field; +import java.util.HashMap; + +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.MockitoAnnotations; +import org.onap.policy.apex.context.parameters.ContextParameterConstants; +import org.onap.policy.apex.context.parameters.DistributorParameters; +import org.onap.policy.apex.context.parameters.LockManagerParameters; +import org.onap.policy.apex.context.parameters.PersistorParameters; +import org.onap.policy.apex.context.parameters.SchemaParameters; +import org.onap.policy.apex.core.engine.EngineParameterConstants; +import org.onap.policy.apex.core.engine.EngineParameters; +import org.onap.policy.apex.core.engine.context.ApexInternalContext; +import org.onap.policy.apex.core.engine.event.EnEvent; +import org.onap.policy.apex.core.engine.executor.StateMachineExecutor; +import org.onap.policy.apex.core.engine.executor.exception.StateMachineException; +import org.onap.policy.apex.model.basicmodel.concepts.ApexException; +import org.onap.policy.apex.model.basicmodel.concepts.ApexRuntimeException; +import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey; +import org.onap.policy.apex.model.basicmodel.concepts.AxReferenceKey; +import org.onap.policy.apex.model.basicmodel.service.ModelService; +import org.onap.policy.apex.model.contextmodel.concepts.AxContextAlbum; +import org.onap.policy.apex.model.contextmodel.concepts.AxContextSchema; +import org.onap.policy.apex.model.enginemodel.concepts.AxEngineState; +import org.onap.policy.apex.model.eventmodel.concepts.AxEvent; +import org.onap.policy.apex.model.eventmodel.concepts.AxEvents; +import org.onap.policy.apex.model.policymodel.concepts.AxPolicy; +import org.onap.policy.apex.model.policymodel.concepts.AxPolicyModel; +import org.onap.policy.apex.model.policymodel.concepts.AxState; +import org.onap.policy.common.parameters.ParameterService; + +/** + * Test the engine implementation. + */ +public class ApexEngineImplTest { + private AxPolicyModel policyModel; + private AxPolicyModel incompatiblePolicyModel; + private AxPolicyModel policyModelWithStates; + + @Mock + StateMachineHandler smHandlerMock; + + /** + * Set up services. + */ + @BeforeClass + public static void setup() { + ParameterService.register(new SchemaParameters()); + ParameterService.register(new DistributorParameters()); + ParameterService.register(new LockManagerParameters()); + ParameterService.register(new PersistorParameters()); + ParameterService.register(new EngineParameters()); + } + + /** + * Set up mocking. + */ + @Before + public void initializeMocking() throws ApexException { + MockitoAnnotations.initMocks(this); + + Mockito.doThrow(new StateMachineException("mocked state machine exception", + new IOException("nexted exception"))).when(smHandlerMock).execute(Mockito.anyObject()); + } + + /** + * Create policy models. + */ + @Before + public void createPolicyModels() { + AxArtifactKey modelKey = new AxArtifactKey("PolicyModel:0.0.1"); + policyModel = new AxPolicyModel(modelKey); + + AxArtifactKey schemaKey = new AxArtifactKey("Schema:0.0.1"); + AxContextSchema schema = new AxContextSchema(schemaKey, "Java", "java.lang.String"); + policyModel.getSchemas().getSchemasMap().put(schemaKey, schema); + + AxArtifactKey albumKey = new AxArtifactKey("Album:0.0.1"); + AxContextAlbum album = new AxContextAlbum(albumKey, "Policy", true, schemaKey); + + policyModel.getAlbums().getAlbumsMap().put(albumKey, album); + + AxEvents events = new AxEvents(); + AxArtifactKey eventKey = new AxArtifactKey("Event:0.0.1"); + AxEvent event = new AxEvent(eventKey, "event.name.space", "source", "target"); + events.getEventMap().put(eventKey, event); + policyModel.setEvents(events); + + AxArtifactKey incompatibleModelKey = new AxArtifactKey("IncompatiblePolicyModel:0.0.2"); + incompatiblePolicyModel = new AxPolicyModel(incompatibleModelKey); + + AxArtifactKey incompatibleSchemaKey = new AxArtifactKey("IncompatibleSchema:0.0.1"); + AxContextSchema incompatibleSchema = new AxContextSchema(incompatibleSchemaKey, "Java", "java.lang.Integer"); + incompatiblePolicyModel.getSchemas().getSchemasMap().put(incompatibleSchemaKey, incompatibleSchema); + + AxContextAlbum incompatibleAlbum = new AxContextAlbum(albumKey, "Policy", true, incompatibleSchemaKey); + incompatiblePolicyModel.getAlbums().getAlbumsMap().put(albumKey, incompatibleAlbum); + + AxArtifactKey modelKeyStates = new AxArtifactKey("PolicyModelStates:0.0.1"); + policyModelWithStates = new AxPolicyModel(modelKeyStates); + policyModelWithStates.getSchemas().getSchemasMap().put(schemaKey, schema); + policyModelWithStates.getAlbums().getAlbumsMap().put(albumKey, album); + policyModelWithStates.setEvents(events); + + AxPolicy policy0 = new AxPolicy(new AxArtifactKey("Policy0:0.0.1")); + AxState state0 = new AxState(new AxReferenceKey(policy0.getKey(), "state0")); + state0.setTrigger(eventKey); + policy0.getStateMap().put(state0.getKey().getLocalName(), state0); + policy0.setFirstState(state0.getKey().getLocalName()); + + policyModelWithStates.getPolicies().getPolicyMap().put(policy0.getKey(), policy0); + + AxPolicy policy1 = new AxPolicy(new AxArtifactKey("Policy1:0.0.1")); + AxState state1 = new AxState(new AxReferenceKey(policy1.getKey(), "state1")); + state1.setTrigger(eventKey); + policy1.getStateMap().put(state1.getKey().getLocalName(), state1); + policy1.setFirstState(state1.getKey().getLocalName()); + + policyModelWithStates.getPolicies().getPolicyMap().put(policy1.getKey(), policy1); + } + + /** + * Clear registrations. + */ + @AfterClass + public static void teardown() { + ParameterService.deregister(ContextParameterConstants.SCHEMA_GROUP_NAME); + ParameterService.deregister(ContextParameterConstants.DISTRIBUTOR_GROUP_NAME); + ParameterService.deregister(ContextParameterConstants.LOCKING_GROUP_NAME); + ParameterService.deregister(ContextParameterConstants.PERSISTENCE_GROUP_NAME); + ParameterService.deregister(EngineParameterConstants.MAIN_GROUP_NAME); + } + + @Test + public void testSanity() { + AxArtifactKey engineKey = new AxArtifactKey("Engine:0.0.1"); + ApexEngineImpl engine = (ApexEngineImpl) new ApexEngineFactory().createApexEngine(engineKey); + assertNotNull(engine); + assertEquals(engineKey, engine.getKey()); + + try { + engine.start(); + fail("test should throw an exception"); + } catch (ApexException ae) { + assertEquals("start()<-Engine:0.0.1,STOPPED, cannot start engine, " + + "engine has not been initialized, its model is not loaded", ae.getMessage()); + } + + try { + engine.stop(); + fail("test should throw an exception"); + } catch (ApexException ae) { + assertEquals("stop()<-Engine:0.0.1,STOPPED, cannot stop engine, " + "engine is already stopped", + ae.getMessage()); + } + + assertEquals(AxEngineState.STOPPED, engine.getState()); + assertEquals(0, engine.getEngineContext().size()); + assertEquals(engineKey, engine.getEngineStatus().getKey()); + assertNull(engine.getInternalContext()); + + try { + engine.clear(); + } catch (ApexException e) { + fail("test should not throw an exception"); + } + + try { + engine.addEventListener(null, null); + fail("test should throw an exception"); + } catch (ApexRuntimeException ae) { + assertEquals("addEventListener()<-Engine:0.0.1,STOPPED, listenerName is null", ae.getMessage()); + } + + try { + engine.addEventListener("myListener", null); + fail("test should throw an exception"); + } catch (ApexRuntimeException ae) { + assertEquals("addEventListener()<-Engine:0.0.1,STOPPED, listener is null", ae.getMessage()); + } + + try { + engine.removeEventListener(null); + fail("test should throw an exception"); + } catch (ApexRuntimeException ae) { + assertEquals("removeEventListener()<-Engine:0.0.1,STOPPED, listenerName is null", ae.getMessage()); + } + + try { + engine.addEventListener("myListener", new DummyListener()); + engine.removeEventListener("myListener"); + } catch (Exception e) { + fail("test should not throw an exception"); + } + + assertNull(engine.createEvent(null)); + + assertFalse(engine.handleEvent(null)); + + try { + engine.updateModel(null); + fail("test should throw an exception"); + } catch (ApexException ae) { + assertEquals("updateModel()<-Engine:0.0.1, Apex model is not defined, it has a null value", + ae.getMessage()); + } + + try { + engine.updateModel(policyModel); + } catch (ApexException e) { + fail("test should not throw an exception"); + } + + // Force a context exception + ModelService.registerModel(AxPolicyModel.class, new AxPolicyModel()); + try { + engine.updateModel(incompatiblePolicyModel); + fail("test should throw an exception"); + } catch (ApexException ae) { + assertEquals("updateModel()<-Engine:0.0.1, error setting the context for engine \"Engine:0.0.1\"", + ae.getMessage()); + } + + try { + engine.updateModel(policyModel); + } catch (ApexException e) { + fail("test should not throw an exception"); + } + + assertNotNull(engine.getInternalContext()); + assertEquals(1, engine.getEngineContext().size()); + + try { + engine.start(); + assertEquals(AxEngineState.READY, engine.getState()); + } catch (ApexException e) { + fail("test should not throw an exception"); + } + + try { + engine.start(); + fail("test should throw an exception"); + } catch (ApexException ae) { + assertEquals("start()<-Engine:0.0.1,READY, cannot start engine, engine not in state STOPPED", + ae.getMessage()); + } + + try { + engine.clear(); + fail("test should throw an exception"); + } catch (ApexException ae) { + assertEquals("clear()<-Engine:0.0.1,READY, cannot clear engine, engine is not stopped", ae.getMessage()); + } + + try { + engine.stop(); + assertEquals(AxEngineState.STOPPED, engine.getState()); + } catch (ApexException e) { + fail("test should not throw an exception"); + } + + try { + engine.clear(); + assertEquals(AxEngineState.STOPPED, engine.getState()); + } catch (ApexException e) { + fail("test should not throw an exception"); + } + + try { + engine.start(); + fail("test should throw an exception"); + } catch (ApexException ae) { + assertEquals("start()<-Engine:0.0.1,STOPPED, cannot start engine, " + + "engine has not been initialized, its model is not loaded", ae.getMessage()); + } + + try { + engine.updateModel(policyModel); + assertEquals(AxEngineState.STOPPED, engine.getState()); + } catch (ApexException e) { + fail("test should not throw an exception"); + } + + try { + engine.start(); + assertEquals(AxEngineState.READY, engine.getState()); + } catch (ApexException e) { + fail("test should not throw an exception"); + } + + assertNull(engine.createEvent(null)); + + AxArtifactKey eventKey = new AxArtifactKey("Event:0.0.1"); + EnEvent event = engine.createEvent(eventKey); + assertEquals(eventKey, event.getKey()); + + assertTrue(engine.handleEvent(event)); + assertEquals(AxEngineState.READY, engine.getState()); + + try { + engine.stop(); + assertEquals(AxEngineState.STOPPED, engine.getState()); + } catch (ApexException e) { + fail("test should not throw an exception"); + } + + try { + engine.addEventListener("myListener", new DummyListener()); + } catch (Exception e) { + fail("test should not throw an exception"); + } + + try { + engine.start(); + assertEquals(AxEngineState.READY, engine.getState()); + } catch (ApexException e) { + fail("test should not throw an exception"); + } + + try { + engine.updateModel(policyModel); + fail("test should throw an exception"); + } catch (ApexException ae) { + assertEquals("updateModel()<-Engine:0.0.1, cannot update model, " + + "engine should be stopped but is in state READY", ae.getMessage()); + } + + assertTrue(engine.handleEvent(event)); + assertEquals(AxEngineState.READY, engine.getState()); + + try { + engine.stop(); + assertEquals(AxEngineState.STOPPED, engine.getState()); + } catch (ApexException e) { + fail("test should not throw an exception"); + } + + try { + engine.addEventListener("badListener", new BadListener()); + } catch (Exception e) { + fail("test should not throw an exception"); + } + + try { + engine.start(); + assertEquals(AxEngineState.READY, engine.getState()); + } catch (ApexException e) { + fail("test should not throw an exception"); + } + + assertFalse(engine.handleEvent(event)); + assertEquals(AxEngineState.READY, engine.getState()); + try { + engine.stop(); + assertEquals(AxEngineState.STOPPED, engine.getState()); + } catch (ApexException e) { + fail("test should not throw an exception"); + } + + try { + engine.removeEventListener("badListener"); + engine.addEventListener("slowListener", new SlowListener()); + } catch (Exception e) { + fail("test should not throw an exception"); + } + } + + @Test + public void testState() throws InterruptedException { + AxArtifactKey engineKey = new AxArtifactKey("Engine:0.0.1"); + ApexEngineImpl engine = (ApexEngineImpl) new ApexEngineFactory().createApexEngine(engineKey); + assertNotNull(engine); + assertEquals(engineKey, engine.getKey()); + + try { + engine.updateModel(policyModel); + assertEquals(AxEngineState.STOPPED, engine.getState()); + } catch (ApexException e) { + fail("test should not throw an exception"); + } + + SlowListener slowListener = new SlowListener(); + try { + engine.addEventListener("slowListener", slowListener); + } catch (Exception e) { + fail("test should not throw an exception"); + } + + try { + engine.start(); + assertEquals(AxEngineState.READY, engine.getState()); + } catch (ApexException e) { + fail("test should not throw an exception"); + } + + assertEquals(AxEngineState.READY, engine.getState()); + + AxArtifactKey eventKey = new AxArtifactKey("Event:0.0.1"); + EnEvent event = engine.createEvent(eventKey); + assertEquals(eventKey, event.getKey()); + + // 1 second is less than the 3 second wait on engine stopping + slowListener.setWaitTime(1000); + (new Thread() { + public void run() { + assertTrue(engine.handleEvent(event)); + assertEquals(AxEngineState.STOPPED, engine.getState()); + } + }).start(); + + Thread.sleep(50); + assertEquals(AxEngineState.EXECUTING, engine.getState()); + + assertFalse(engine.handleEvent(event)); + assertNotNull(engine.createEvent(eventKey)); + + try { + engine.stop(); + assertEquals(AxEngineState.STOPPED, engine.getState()); + } catch (ApexException ae) { + fail("test should not throw an exception"); + } + + try { + engine.start(); + assertEquals(AxEngineState.READY, engine.getState()); + } catch (ApexException ae) { + fail("test should not throw an exception"); + } + + // 4 seconds is more than the 3 second wait on engine stopping + slowListener.setWaitTime(4000); + (new Thread() { + public void run() { + assertTrue(engine.handleEvent(event)); + assertEquals(AxEngineState.STOPPED, engine.getState()); + } + }).start(); + + Thread.sleep(50); + assertEquals(AxEngineState.EXECUTING, engine.getState()); + try { + engine.stop(); + assertEquals(AxEngineState.STOPPED, engine.getState()); + fail("test should throw an exception"); + } catch (ApexException ae) { + assertEquals("stop()<-Engine:0.0.1,STOPPED, error stopping engine, engine stop timed out", ae.getMessage()); + } + + try { + engine.clear(); + assertEquals(AxEngineState.STOPPED, engine.getState()); + } catch (ApexException e) { + fail("test should not throw an exception"); + } + } + + @Test + public void testStateMachineError() throws InterruptedException, IllegalArgumentException, IllegalAccessException, + NoSuchFieldException, SecurityException { + + AxArtifactKey engineKey = new AxArtifactKey("Engine:0.0.1"); + ApexEngineImpl engine = (ApexEngineImpl) new ApexEngineFactory().createApexEngine(engineKey); + assertNotNull(engine); + assertEquals(engineKey, engine.getKey()); + + try { + engine.updateModel(policyModel); + assertEquals(AxEngineState.STOPPED, engine.getState()); + } catch (ApexException e) { + fail("test should not throw an exception"); + } + + final Field smHandlerField = engine.getClass().getDeclaredField("stateMachineHandler"); + smHandlerField.setAccessible(true); + smHandlerField.set(engine, smHandlerMock); + + try { + engine.start(); + assertEquals(AxEngineState.READY, engine.getState()); + } catch (ApexException e) { + fail("test should not throw an exception"); + } + + assertEquals(AxEngineState.READY, engine.getState()); + + AxArtifactKey eventKey = new AxArtifactKey("Event:0.0.1"); + EnEvent event = engine.createEvent(eventKey); + assertEquals(eventKey, event.getKey()); + + assertFalse(engine.handleEvent(event)); + assertEquals(AxEngineState.READY, engine.getState()); + + try { + engine.stop(); + assertEquals(AxEngineState.STOPPED, engine.getState()); + } catch (ApexException ae) { + fail("test should not throw an exception"); + } + + try { + Mockito.doThrow(new StateMachineException("mocked state machine exception", + new IOException("nexted exception"))).when(smHandlerMock).start(); + + engine.start(); + fail("test should throw an exception"); + } catch (ApexException ae) { + assertEquals("updateModel()<-Engine:0.0.1, error starting the engine state machines \"Engine:0.0.1\"", + ae.getMessage()); + } + + assertEquals(AxEngineState.STOPPED, engine.getState()); + + try { + engine.clear(); + assertEquals(AxEngineState.STOPPED, engine.getState()); + } catch (ApexException e) { + fail("test should not throw an exception"); + } + } + + @Test + public void testStateMachineHandler() throws InterruptedException, IllegalArgumentException, IllegalAccessException, + NoSuchFieldException, SecurityException { + AxArtifactKey engineKey = new AxArtifactKey("Engine:0.0.1"); + ApexEngineImpl engine = (ApexEngineImpl) new ApexEngineFactory().createApexEngine(engineKey); + assertNotNull(engine); + assertEquals(engineKey, engine.getKey()); + + try { + engine.updateModel(policyModelWithStates); + assertEquals(AxEngineState.STOPPED, engine.getState()); + } catch (ApexException e) { + fail("test should not throw an exception"); + } + + try { + engine.start(); + assertEquals(AxEngineState.READY, engine.getState()); + } catch (ApexException e) { + fail("test should not throw an exception"); + } + + AxArtifactKey eventKey = new AxArtifactKey("Event:0.0.1"); + EnEvent event = engine.createEvent(eventKey); + assertEquals(eventKey, event.getKey()); + + try { + engine.stop(); + assertEquals(AxEngineState.STOPPED, engine.getState()); + } catch (ApexException ae) { + fail("test should not throw an exception"); + } + + assertEquals(AxEngineState.STOPPED, engine.getState()); + + try { + engine.start(); + assertEquals(AxEngineState.READY, engine.getState()); + } catch (ApexException e) { + fail("test should not throw an exception"); + } + + assertEquals(AxEngineState.READY, engine.getState()); + + // Can't work, state is not fully defined + assertFalse(engine.handleEvent(event)); + assertEquals(AxEngineState.READY, engine.getState()); + + final Field smHandlerField = engine.getClass().getDeclaredField("stateMachineHandler"); + smHandlerField.setAccessible(true); + StateMachineHandler smHandler = (StateMachineHandler) smHandlerField.get(engine); + + final Field smExecutorMapField = smHandler.getClass().getDeclaredField("stateMachineExecutorMap"); + smExecutorMapField.setAccessible(true); + @SuppressWarnings("unchecked") + HashMap<AxEvent, StateMachineExecutor> smExMap = (HashMap<AxEvent, StateMachineExecutor>) smExecutorMapField + .get(smHandler); + + assertEquals(1, smExMap.size()); + DummySmExecutor dummyExecutor = new DummySmExecutor(null, event.getKey()); + smExMap.put(event.getAxEvent(), dummyExecutor); + + try { + ApexInternalContext internalContext = new ApexInternalContext(policyModelWithStates); + dummyExecutor.setContext(null, null, internalContext); + } catch (Exception e) { + // Ignore this exception, we just need to set the internal context + } + + try { + engine.stop(); + assertEquals(AxEngineState.STOPPED, engine.getState()); + } catch (ApexException ae) { + fail("test should not throw an exception"); + } + + try { + engine.start(); + fail("test should throw an exception"); + } catch (ApexException ae) { + assertEquals("updateModel()<-Engine:0.0.1, error starting the engine state machines \"Engine:0.0.1\"", + ae.getMessage()); + } + + assertEquals(AxEngineState.STOPPED, engine.getState()); + + try { + engine.start(); + assertEquals(AxEngineState.READY, engine.getState()); + } catch (ApexException ae) { + fail("test should not throw an exception"); + } + + // Works, Dummy executor fakes event execution + assertTrue(engine.handleEvent(event)); + assertEquals(AxEngineState.READY, engine.getState()); + + try { + engine.stop(); + assertEquals(AxEngineState.STOPPED, engine.getState()); + } catch (ApexException ae) { + fail("test should not throw an exception"); + } + + try { + engine.clear(); + assertEquals(AxEngineState.STOPPED, engine.getState()); + } catch (ApexException e) { + fail("test should not throw an exception"); + } + } +} diff --git a/core/core-engine/src/test/java/org/onap/policy/apex/core/engine/engine/impl/BadListener.java b/core/core-engine/src/test/java/org/onap/policy/apex/core/engine/engine/impl/BadListener.java new file mode 100644 index 000000000..b829437d6 --- /dev/null +++ b/core/core-engine/src/test/java/org/onap/policy/apex/core/engine/engine/impl/BadListener.java @@ -0,0 +1,43 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2018 Ericsson. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.core.engine.engine.impl; + +import org.onap.policy.apex.core.engine.engine.EnEventListener; +import org.onap.policy.apex.core.engine.event.EnEvent; +import org.onap.policy.apex.model.basicmodel.concepts.ApexException; + +/** + * Dummy engine event listener for unit test. + * + */ +public class BadListener implements EnEventListener { + + /* + * (non-Javadoc) + * + * @see + * org.onap.policy.apex.core.engine.engine.EnEventListener#onEnEvent(org.onap.policy.apex.core.engine.event.EnEvent) + */ + @Override + public void onEnEvent(EnEvent enEvent) throws ApexException { + throw new ApexException("not implemented on dummy class"); + } +} diff --git a/core/core-engine/src/test/java/org/onap/policy/apex/core/engine/engine/impl/DummyListener.java b/core/core-engine/src/test/java/org/onap/policy/apex/core/engine/engine/impl/DummyListener.java new file mode 100644 index 000000000..33b434af1 --- /dev/null +++ b/core/core-engine/src/test/java/org/onap/policy/apex/core/engine/engine/impl/DummyListener.java @@ -0,0 +1,43 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2018 Ericsson. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.core.engine.engine.impl; + +import org.onap.policy.apex.core.engine.engine.EnEventListener; +import org.onap.policy.apex.core.engine.event.EnEvent; +import org.onap.policy.apex.model.basicmodel.concepts.ApexException; + +/** + * Dummy engine event listener for unit test. + * + */ +public class DummyListener implements EnEventListener { + + /* + * (non-Javadoc) + * + * @see + * org.onap.policy.apex.core.engine.engine.EnEventListener#onEnEvent(org.onap.policy.apex.core.engine.event.EnEvent) + */ + @Override + public void onEnEvent(EnEvent enEvent) throws ApexException { + // Do nothing + } +} diff --git a/core/core-engine/src/test/java/org/onap/policy/apex/core/engine/engine/impl/DummySmExecutor.java b/core/core-engine/src/test/java/org/onap/policy/apex/core/engine/engine/impl/DummySmExecutor.java new file mode 100644 index 000000000..db8fc32d9 --- /dev/null +++ b/core/core-engine/src/test/java/org/onap/policy/apex/core/engine/engine/impl/DummySmExecutor.java @@ -0,0 +1,87 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2018 Ericsson. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.core.engine.engine.impl; + +import org.onap.policy.apex.core.engine.event.EnEvent; +import org.onap.policy.apex.core.engine.executor.ExecutorFactory; +import org.onap.policy.apex.core.engine.executor.StateMachineExecutor; +import org.onap.policy.apex.core.engine.executor.exception.StateMachineException; +import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey; + +/** + * Dummy state machine executor for testing. + */ +public class DummySmExecutor extends StateMachineExecutor { + private boolean cleanupWorks = false; + private boolean prepareWorks; + + /** + * Constructor. + * + * @param executorFactory the factory for executors + * @param owner the owner key + */ + public DummySmExecutor(ExecutorFactory executorFactory, AxArtifactKey owner) { + super(executorFactory, owner); + } + + /* + * (non-Javadoc) + * + * @see org.onap.policy.apex.core.engine.executor.Executor#prepare() + */ + @Override + public void prepare() throws StateMachineException { + if (prepareWorks) { + prepareWorks = false; + } + else { + prepareWorks = true; + throw new StateMachineException("dummy state machine executor exception"); + } + } + + /* + * (non-Javadoc) + * + * @see org.onap.policy.apex.core.engine.executor.Executor#executeDirected(java.lang.long, java.lang.Object) + */ + @Override + public EnEvent execute(final long executionId, final EnEvent incomingEvent) { + return incomingEvent; + } + + /* + * (non-Javadoc) + * + * @see org.onap.policy.apex.core.engine.executor.Executor#cleanUp() + */ + @Override + public void cleanUp() throws StateMachineException { + if (cleanupWorks) { + cleanupWorks = false; + } + else { + cleanupWorks = true; + throw new StateMachineException("dummy state machine executor exception"); + } + } +} diff --git a/core/core-engine/src/test/java/org/onap/policy/apex/core/engine/engine/impl/SlowListener.java b/core/core-engine/src/test/java/org/onap/policy/apex/core/engine/engine/impl/SlowListener.java new file mode 100644 index 000000000..f3f885911 --- /dev/null +++ b/core/core-engine/src/test/java/org/onap/policy/apex/core/engine/engine/impl/SlowListener.java @@ -0,0 +1,58 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2018 Ericsson. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.core.engine.engine.impl; + +import org.onap.policy.apex.core.engine.engine.EnEventListener; +import org.onap.policy.apex.core.engine.event.EnEvent; +import org.onap.policy.apex.model.basicmodel.concepts.ApexException; + +/** + * Dummy engine event listener for unit test. + * + */ +public class SlowListener implements EnEventListener { + + private long waitTime; + + /* + * (non-Javadoc) + * + * @see + * org.onap.policy.apex.core.engine.engine.EnEventListener#onEnEvent(org.onap.policy.apex.core.engine.event.EnEvent) + */ + @Override + public void onEnEvent(EnEvent enEvent) throws ApexException { + try { + Thread.sleep(waitTime); + } + catch (InterruptedException ie) { + // Do nothing + } + } + + public long getWaitTime() { + return waitTime; + } + + public void setWaitTime(long waitTime) { + this.waitTime = waitTime; + } +} diff --git a/core/core-engine/src/test/java/org/onap/policy/apex/core/engine/executor/DummyFailingTaskExecutor.java b/core/core-engine/src/test/java/org/onap/policy/apex/core/engine/executor/DummyFailingTaskExecutor.java new file mode 100644 index 000000000..4d4fb639f --- /dev/null +++ b/core/core-engine/src/test/java/org/onap/policy/apex/core/engine/executor/DummyFailingTaskExecutor.java @@ -0,0 +1,30 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2018 Ericsson. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.core.engine.executor; + +/** + * Dummy task executor for testing. + */ +public class DummyFailingTaskExecutor extends TaskExecutor { + public DummyFailingTaskExecutor() throws InstantiationException { + throw new InstantiationException("I always fail"); + } +} diff --git a/core/core-engine/src/test/java/org/onap/policy/apex/core/engine/executor/DummyStateFinalizerExecutor.java b/core/core-engine/src/test/java/org/onap/policy/apex/core/engine/executor/DummyStateFinalizerExecutor.java new file mode 100644 index 000000000..abc11871e --- /dev/null +++ b/core/core-engine/src/test/java/org/onap/policy/apex/core/engine/executor/DummyStateFinalizerExecutor.java @@ -0,0 +1,68 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2018 Ericsson. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.core.engine.executor; + +import java.util.Map; + +import org.onap.policy.apex.context.ContextException; +import org.onap.policy.apex.core.engine.executor.exception.StateMachineException; + +/** + * Dummy state finalizer executor for testing. + */ +public class DummyStateFinalizerExecutor extends StateFinalizerExecutor { + private boolean override; + + private boolean returnBad; + + public DummyStateFinalizerExecutor() { + this(false); + } + + public DummyStateFinalizerExecutor(final boolean override) { + this.override = override; + } + + /* + * (non-Javadoc) + * + * @see org.onap.policy.apex.core.engine.executor.Executor#execute(java.lang.long, java.lang.Object) + */ + @Override + public String execute(final long executionId, final Map<String, Object> newIncomingFields) + throws StateMachineException, ContextException { + + if (!override) { + super.execute(executionId, newIncomingFields); + } + + if (returnBad) { + return "stateOutputBad"; + } + else { + return "stateOutput1"; + } + } + + public void setReturnBad(boolean returnBad) { + this.returnBad = returnBad; + } +} diff --git a/core/core-engine/src/test/java/org/onap/policy/apex/core/engine/executor/DummyTaskExecutor.java b/core/core-engine/src/test/java/org/onap/policy/apex/core/engine/executor/DummyTaskExecutor.java new file mode 100644 index 000000000..93fc6190f --- /dev/null +++ b/core/core-engine/src/test/java/org/onap/policy/apex/core/engine/executor/DummyTaskExecutor.java @@ -0,0 +1,94 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2018 Ericsson. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.core.engine.executor; + +import java.util.Map; + +import org.onap.policy.apex.context.ContextException; +import org.onap.policy.apex.core.engine.event.EnEvent; +import org.onap.policy.apex.core.engine.executor.exception.StateMachineException; +import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey; +import org.onap.policy.apex.model.policymodel.concepts.AxTask; + +/** + * Dummy task executor for testing. + */ +public class DummyTaskExecutor extends TaskExecutor { + private boolean override; + + public DummyTaskExecutor() { + this(false); + } + + public DummyTaskExecutor(final boolean override) { + this.override = override; + } + + @Override + public void prepare() throws StateMachineException { + if (!override) { + super.prepare(); + } + } + + /* + * (non-Javadoc) + * + * @see org.onap.policy.apex.core.engine.executor.Executor#execute(java.lang.long, java.lang.Object) + */ + @Override + public Map<String, Object> execute(final long executionId, final Map<String, Object> newIncomingFields) + throws StateMachineException, ContextException { + if (!override) { + super.execute(executionId, newIncomingFields); + } + + AxArtifactKey event0Key = new AxArtifactKey("Event0:0.0.1"); + return new EnEvent(event0Key); + } + + /* + * (non-Javadoc) + * + * @see org.onap.policy.apex.core.engine.executor.Executor#getSubject() + */ + @Override + public AxTask getSubject() { + if (!override) { + super.getSubject(); + } + + AxArtifactKey taskKey = new AxArtifactKey("FirstTask:0.0.1"); + return new AxTask(taskKey); + } + + /* + * (non-Javadoc) + * + * @see org.onap.policy.apex.core.engine.executor.Executor#cleanUp() + */ + @Override + public void cleanUp() throws StateMachineException { + if (!override) { + super.cleanUp(); + } + } +} diff --git a/core/core-engine/src/test/java/org/onap/policy/apex/core/engine/executor/DummyTaskSelectExecutor.java b/core/core-engine/src/test/java/org/onap/policy/apex/core/engine/executor/DummyTaskSelectExecutor.java new file mode 100644 index 000000000..abbb1bd79 --- /dev/null +++ b/core/core-engine/src/test/java/org/onap/policy/apex/core/engine/executor/DummyTaskSelectExecutor.java @@ -0,0 +1,82 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2018 Ericsson. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.core.engine.executor; + +import org.onap.policy.apex.context.ContextException; +import org.onap.policy.apex.core.engine.event.EnEvent; +import org.onap.policy.apex.core.engine.executor.exception.StateMachineException; +import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey; + +/** + * Dummy task selection executor for testing. + */ +public class DummyTaskSelectExecutor extends TaskSelectExecutor { + private boolean override; + + private static int taskNo; + + public DummyTaskSelectExecutor() { + this(false); + } + + public DummyTaskSelectExecutor(final boolean override) { + this.override = override; + } + + @Override + public void prepare() throws StateMachineException { + if (!override) { + super.prepare(); + } + } + + /* + * (non-Javadoc) + * + * @see org.onap.policy.apex.core.engine.executor.Executor#execute(java.lang.long, java.lang.Object) + */ + @Override + public AxArtifactKey execute(final long executionId, final EnEvent newIncomingEvent) + throws StateMachineException, ContextException { + if (!override) { + return super.execute(executionId, newIncomingEvent); + } + + return new AxArtifactKey("task" + (taskNo++) + ":0.0.1"); + } + + public void setTaskNo(int incomingTaskNo) { + taskNo = incomingTaskNo; + } + + + /* + * (non-Javadoc) + * + * @see org.onap.policy.apex.core.engine.executor.Executor#cleanUp() + */ + @Override + public void cleanUp() throws StateMachineException { + if (!override) { + super.cleanUp(); + } + } +} diff --git a/core/core-engine/src/test/java/org/onap/policy/apex/core/engine/executor/StateExecutorTest.java b/core/core-engine/src/test/java/org/onap/policy/apex/core/engine/executor/StateExecutorTest.java new file mode 100644 index 000000000..08ab03b06 --- /dev/null +++ b/core/core-engine/src/test/java/org/onap/policy/apex/core/engine/executor/StateExecutorTest.java @@ -0,0 +1,96 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2018 Ericsson. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.core.engine.executor; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.MockitoAnnotations; +import org.onap.policy.apex.core.engine.ExecutorParameters; +import org.onap.policy.apex.core.engine.context.ApexInternalContext; +import org.onap.policy.apex.core.engine.event.EnEvent; +import org.onap.policy.apex.model.basicmodel.concepts.AxReferenceKey; +import org.onap.policy.apex.model.policymodel.concepts.AxState; + +/** + * Test task executor. + */ +public class StateExecutorTest { + @Mock + private ApexInternalContext internalContextMock; + + @Mock + private AxState axStateMock; + + @Mock + private ExecutorFactory executorFactoryMock; + + @Mock + private Executor<EnEvent, StateOutput, AxState, ApexInternalContext> nextExecutorMock; + + /** + * Set up mocking. + */ + @Before + public void startMocking() { + MockitoAnnotations.initMocks(this); + + Mockito.doReturn(new AxReferenceKey("Policy:0.0.1:PolName:State0")).when(axStateMock).getKey(); + } + + @Test + public void testStateExecutor() { + StateExecutor executor = new StateExecutor(executorFactoryMock); + + executor.setContext(null, axStateMock, internalContextMock); + assertEquals("Policy:0.0.1:PolName:State0", executor.getKey().getId()); + assertEquals(null, executor.getParent()); + assertEquals(internalContextMock, executor.getContext()); + assertEquals(null, executor.getNext()); + assertEquals(null, executor.getIncoming()); + assertEquals(null, executor.getOutgoing()); + assertEquals(axStateMock, executor.getSubject()); + + executor.setParameters(new ExecutorParameters()); + executor.setNext(nextExecutorMock); + assertEquals(nextExecutorMock, executor.getNext()); + executor.setNext(null); + assertEquals(null, executor.getNext()); + + try { + executor.executePre(0, null); + fail("test should throw an exception"); + } catch (Exception ex) { + assertEquals("execution pre work not implemented on class", ex.getMessage()); + } + + try { + executor.executePost(false); + fail("test should throw an exception"); + } catch (Exception ex) { + assertEquals("execution post work not implemented on class", ex.getMessage()); + } + } +} diff --git a/core/core-engine/src/test/java/org/onap/policy/apex/core/engine/executor/StateFinalizerExecutorTest.java b/core/core-engine/src/test/java/org/onap/policy/apex/core/engine/executor/StateFinalizerExecutorTest.java new file mode 100644 index 000000000..82ac610c9 --- /dev/null +++ b/core/core-engine/src/test/java/org/onap/policy/apex/core/engine/executor/StateFinalizerExecutorTest.java @@ -0,0 +1,199 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2018 Ericsson. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.core.engine.executor; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + +import java.util.Map; + +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.MockitoAnnotations; +import org.onap.policy.apex.core.engine.ExecutorParameters; +import org.onap.policy.apex.core.engine.context.ApexInternalContext; +import org.onap.policy.apex.core.engine.event.EnEvent; +import org.onap.policy.apex.core.engine.executor.exception.StateMachineException; +import org.onap.policy.apex.model.basicmodel.concepts.AxReferenceKey; +import org.onap.policy.apex.model.policymodel.concepts.AxState; +import org.onap.policy.apex.model.policymodel.concepts.AxStateFinalizerLogic; + +/** + * Test task executor. + */ +public class StateFinalizerExecutorTest { + @Mock + private Executor<?, ?, ?, ?> parentMock; + + @Mock + private ApexInternalContext internalContextMock; + + @Mock + private AxStateFinalizerLogic stateFinalizerLogicMock; + + @Mock + private Executor<Map<String, Object>, String, AxStateFinalizerLogic, ApexInternalContext> nextExecutorMock; + + @Mock + private EnEvent incomingEvent; + + /** + * Set up mocking. + */ + @Before + public void startMocking() { + MockitoAnnotations.initMocks(this); + + AxState state = new AxState(); + state.getStateOutputs().put("ValidOutput", null); + + Mockito.doReturn(state).when(parentMock).getSubject(); + + Mockito.doReturn(new AxReferenceKey("State:0.0.1:StateName:StateSFL")).when(stateFinalizerLogicMock).getKey(); + } + + @Test + public void testStateFinalizerExecutor() { + DummyStateFinalizerExecutor executor = new DummyStateFinalizerExecutor(); + + executor.setContext(parentMock, stateFinalizerLogicMock, internalContextMock); + assertEquals("State:0.0.1:StateName:StateSFL", executor.getKey().getId()); + assertEquals(null, executor.getExecutionContext()); + assertEquals(parentMock, executor.getParent()); + assertEquals(internalContextMock, executor.getContext()); + assertEquals(null, executor.getNext()); + assertEquals(null, executor.getIncoming()); + assertEquals(null, executor.getOutgoing()); + assertEquals(stateFinalizerLogicMock, executor.getSubject()); + + executor.setParameters(new ExecutorParameters()); + executor.setNext(nextExecutorMock); + assertEquals(nextExecutorMock, executor.getNext()); + executor.setNext(null); + assertEquals(null, executor.getNext()); + + try { + executor.cleanUp(); + fail("test should throw an exception"); + } catch (Exception ex) { + assertEquals("cleanUp() not implemented on class", ex.getMessage()); + } + + Mockito.doReturn(null).when(stateFinalizerLogicMock).getLogic(); + + try { + executor.prepare(); + fail("test should throw an exception"); + } catch (Exception ex) { + assertEquals("state finalizer logic cannot be null.", ex.getMessage()); + } + + Mockito.doReturn("some task logic").when(stateFinalizerLogicMock).getLogic(); + + try { + executor.prepare(); + } catch (StateMachineException e) { + fail("test should not throw an exception"); + } + + try { + executor.executePre(0, incomingEvent); + } catch (Exception ex) { + assertEquals("task input fields \"[InField0]\" are missing for task \"Task0:0.0.1\"", ex.getMessage()); + } + + try { + executor.executePre(0, incomingEvent); + } catch (Exception e) { + fail("test should not throw an exception"); + } + + try { + executor.execute(0, incomingEvent); + fail("test should throw an exception"); + } catch (Exception ex) { + assertEquals("execute() not implemented on abstract StateFinalizerExecutionContext class, " + + "only on its subclasses", ex.getMessage()); + } + + try { + executor.executePost(false); + fail("test should throw an exception"); + } catch (Exception ex) { + assertEquals("execute-post: state finalizer logic execution failure on state \"NULL:0.0.0:NULL:NULL\" " + + "on finalizer logic null", ex.getMessage()); + } + + executor.getExecutionContext().setMessage("Execution message"); + try { + executor.executePost(false); + fail("test should throw an exception"); + } catch (Exception ex) { + assertEquals("execute-post: state finalizer logic execution failure on state \"NULL:0.0.0:NULL:NULL\" " + + "on finalizer logic null, user message: Execution message", ex.getMessage()); + } + + try { + executor.executePre(0, incomingEvent); + } catch (Exception ex) { + fail("test should not throw an exception"); + } + + try { + executor.executePost(true); + fail("test should throw an exception"); + } catch (Exception ex) { + assertEquals("execute-post: state finalizer logic \"null\" did not select an output state", + ex.getMessage()); + } + + try { + executor.executePre(0, incomingEvent); + } catch (Exception ex) { + fail("test should not throw an exception"); + } + + executor.getExecutionContext().setSelectedStateOutputName("ThisOutputDoesNotExist"); + try { + executor.executePost(true); + fail("test should throw an exception"); + } catch (Exception ex) { + assertEquals("execute-post: state finalizer logic \"null\" selected output state " + + "\"ThisOutputDoesNotExist\" that does not exsist on state \"NULL:0.0.0:NULL:NULL\"", + ex.getMessage()); + } + + try { + executor.executePre(0, incomingEvent); + } catch (Exception ex) { + fail("test should not throw an exception"); + } + + executor.getExecutionContext().setSelectedStateOutputName("ValidOutput"); + try { + executor.executePost(true); + } catch (Exception ex) { + fail("test should not throw an exception"); + } + } +} diff --git a/core/core-engine/src/test/java/org/onap/policy/apex/core/engine/executor/StateMachineExecutorTest.java b/core/core-engine/src/test/java/org/onap/policy/apex/core/engine/executor/StateMachineExecutorTest.java new file mode 100644 index 000000000..f9d3edc6c --- /dev/null +++ b/core/core-engine/src/test/java/org/onap/policy/apex/core/engine/executor/StateMachineExecutorTest.java @@ -0,0 +1,437 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2018 Ericsson. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.core.engine.executor; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.fail; + +import java.util.LinkedHashMap; +import java.util.Map; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.MockitoAnnotations; +import org.onap.policy.apex.context.parameters.SchemaParameters; +import org.onap.policy.apex.core.engine.ExecutorParameters; +import org.onap.policy.apex.core.engine.context.ApexInternalContext; +import org.onap.policy.apex.core.engine.event.EnEvent; +import org.onap.policy.apex.core.engine.executor.exception.StateMachineException; +import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey; +import org.onap.policy.apex.model.basicmodel.concepts.AxReferenceKey; +import org.onap.policy.apex.model.basicmodel.service.ModelService; +import org.onap.policy.apex.model.contextmodel.concepts.AxContextSchema; +import org.onap.policy.apex.model.contextmodel.concepts.AxContextSchemas; +import org.onap.policy.apex.model.eventmodel.concepts.AxEvent; +import org.onap.policy.apex.model.eventmodel.concepts.AxEvents; +import org.onap.policy.apex.model.eventmodel.concepts.AxField; +import org.onap.policy.apex.model.policymodel.concepts.AxPolicy; +import org.onap.policy.apex.model.policymodel.concepts.AxState; +import org.onap.policy.apex.model.policymodel.concepts.AxStateFinalizerLogic; +import org.onap.policy.apex.model.policymodel.concepts.AxStateOutput; +import org.onap.policy.apex.model.policymodel.concepts.AxStateTaskOutputType; +import org.onap.policy.apex.model.policymodel.concepts.AxStateTaskReference; +import org.onap.policy.apex.model.policymodel.concepts.AxTask; +import org.onap.policy.apex.model.policymodel.concepts.AxTasks; +import org.onap.policy.common.parameters.ParameterService; + +/** + * Test task executor. + */ +public class StateMachineExecutorTest { + @Mock + private ApexInternalContext internalContextMock; + + @Mock + private Executor<EnEvent, EnEvent, AxPolicy, ApexInternalContext> nextExecutorMock; + + @Mock + private ExecutorFactory executorFactoryMock; + + @Mock + private EnEvent incomingEventMock; + + private AxPolicy axPolicy = new AxPolicy(); + + private DummyTaskSelectExecutor dummyTsle; + + private DummyStateFinalizerExecutor dummySfle; + + /** + * Set up mocking. + */ + @Before + public void startMocking() { + MockitoAnnotations.initMocks(this); + + axPolicy.setKey(new AxArtifactKey("Policy:0.0.1")); + + AxReferenceKey state0Key = new AxReferenceKey(axPolicy.getKey(), "state0"); + AxState state0 = new AxState(state0Key); + + AxReferenceKey state1Key = new AxReferenceKey(axPolicy.getKey(), "state1"); + AxState state1 = new AxState(state1Key); + + axPolicy.getStateMap().put("State0", state0); + axPolicy.getStateMap().put("State1", state1); + axPolicy.setFirstState("state0"); + + AxArtifactKey event0Key = new AxArtifactKey("Event0:0.0.1"); + AxEvent event0 = new AxEvent(event0Key, "a.name.space", "source", "target"); + AxArtifactKey event1Key = new AxArtifactKey("Event1:0.0.1"); + AxEvent event1 = new AxEvent(event1Key, "a.name.space", "source", "target"); + AxArtifactKey event2Key = new AxArtifactKey("Event2:0.0.1"); + AxEvent event2 = new AxEvent(event2Key, "a.name.space", "source", "target"); + AxEvents events = new AxEvents(); + events.getEventMap().put(event0Key, event0); + events.getEventMap().put(event1Key, event1); + events.getEventMap().put(event2Key, event2); + ModelService.registerModel(AxEvents.class, events); + + AxReferenceKey fieldKey = new AxReferenceKey("Event1:0.0.1:event:Field0"); + AxArtifactKey stringSchemaKey = new AxArtifactKey("StringSchema:0.0.1"); + AxContextSchema stringSchema = new AxContextSchema(stringSchemaKey, "Java", "java.lang.String"); + AxContextSchemas schemas = new AxContextSchemas(); + schemas.getSchemasMap().put(stringSchemaKey, stringSchema); + ModelService.registerModel(AxContextSchemas.class, schemas); + + AxField event1Field0Definition = new AxField(fieldKey, stringSchemaKey); + event1.getParameterMap().put("Event1Field0", event1Field0Definition); + + event0.getParameterMap().put("Event1Field0", event1Field0Definition); + event0.getParameterMap().put("UnusedField", event1Field0Definition); + + Mockito.doReturn(event0Key).when(incomingEventMock).getKey(); + Mockito.doReturn(event0).when(incomingEventMock).getAxEvent(); + + state0.setTrigger(event0Key); + state1.setTrigger(event1Key); + + AxArtifactKey task0Key = new AxArtifactKey("task0:0.0.1"); + AxTask task0 = new AxTask(task0Key); + + AxArtifactKey task1Key = new AxArtifactKey("task1:0.0.1"); + AxTask task1 = new AxTask(task1Key); + + AxTasks tasks = new AxTasks(); + tasks.getTaskMap().put(task0Key, task0); + tasks.getTaskMap().put(task1Key, task1); + ModelService.registerModel(AxTasks.class, tasks); + + ParameterService.register(new SchemaParameters()); + + AxReferenceKey stateOutput0Key = new AxReferenceKey("Policy:0.0.1:state0:stateOutput0"); + AxStateOutput stateOutput0 = new AxStateOutput(stateOutput0Key, event1Key, state1.getKey()); + + state0.getStateOutputs().put(stateOutput0Key.getLocalName(), stateOutput0); + + AxReferenceKey stateOutput1Key = new AxReferenceKey("Policy:0.0.1:state0:stateOutput1"); + AxStateOutput stateOutput1 = new AxStateOutput(stateOutput1Key, event2Key, AxReferenceKey.getNullKey()); + + state1.getStateOutputs().put(stateOutput1Key.getLocalName(), stateOutput1); + + AxReferenceKey str0Key = new AxReferenceKey("Policy:0.0.1:state0:str0"); + AxStateTaskReference str0 = new AxStateTaskReference(str0Key, AxStateTaskOutputType.DIRECT, stateOutput0Key); + state0.getTaskReferences().put(task0Key, str0); + + AxReferenceKey sflKey = new AxReferenceKey("Policy:0.0.1:state1:sfl"); + AxStateFinalizerLogic sfl = new AxStateFinalizerLogic(sflKey, "Java", "State fianlizer logic"); + state1.getStateFinalizerLogicMap().put("sfl", sfl); + + AxReferenceKey str1Key = new AxReferenceKey("Policy:0.0.1:state1:str1"); + AxStateTaskReference str1 = new AxStateTaskReference(str1Key, AxStateTaskOutputType.LOGIC, sflKey); + state1.getTaskReferences().put(task1Key, str1); + + Mockito.doReturn(new DummyTaskExecutor(true)).when(executorFactoryMock).getTaskExecutor(Mockito.anyObject(), + Mockito.anyObject(), Mockito.anyObject()); + + dummyTsle = new DummyTaskSelectExecutor(true); + Mockito.doReturn(dummyTsle).when(executorFactoryMock).getTaskSelectionExecutor(Mockito.anyObject(), + Mockito.anyObject(), Mockito.anyObject()); + + dummySfle = new DummyStateFinalizerExecutor(true); + Mockito.doReturn(dummySfle).when(executorFactoryMock).getStateFinalizerExecutor(Mockito.anyObject(), + Mockito.anyObject(), Mockito.anyObject()); + } + + @After + public void cleardown() { + ParameterService.clear(); + ModelService.clear(); + } + + @Test + public void testStateMachineExecutor() { + StateMachineExecutor executor = new StateMachineExecutor(executorFactoryMock, + new AxArtifactKey("OwnerKey:0.0.1")); + + try { + executor.execute(0, incomingEventMock); + fail("test should throw an exception"); + } catch (Exception ex) { + assertEquals("no states defined on state machine", ex.getMessage()); + } + + executor.setContext(null, axPolicy, internalContextMock); + assertEquals("Policy:0.0.1", executor.getKey().getId()); + assertEquals(null, executor.getParent()); + assertEquals(internalContextMock, executor.getContext()); + assertEquals(null, executor.getNext()); + assertEquals(null, executor.getIncoming()); + assertEquals(null, executor.getOutgoing()); + assertEquals(axPolicy, executor.getSubject()); + + executor.setParameters(new ExecutorParameters()); + executor.setNext(nextExecutorMock); + assertEquals(nextExecutorMock, executor.getNext()); + executor.setNext(null); + assertEquals(null, executor.getNext()); + + try { + executor.executePre(0, null); + fail("test should throw an exception"); + } catch (Exception ex) { + assertEquals("execution pre work not implemented on class", ex.getMessage()); + } + + try { + executor.executePost(false); + fail("test should throw an exception"); + } catch (Exception ex) { + assertEquals("execution post work not implemented on class", ex.getMessage()); + } + + try { + executor.prepare(); + } catch (StateMachineException e) { + fail("test should not throw an exception"); + } + + axPolicy.setFirstState("BadState"); + executor.setContext(null, axPolicy, internalContextMock); + try { + executor.execute(0, incomingEventMock); + fail("test should throw an exception"); + } catch (Exception ex) { + assertEquals("first state not defined on state machine", ex.getMessage()); + } + + axPolicy.setFirstState("state0"); + executor.setContext(null, axPolicy, internalContextMock); + try { + executor.execute(0, incomingEventMock); + } catch (Exception ex) { + fail("test should not throw an exception"); + } + + dummyTsle.setTaskNo(0); + try { + executor.execute(0, incomingEventMock); + } catch (Exception ex) { + fail("test should not throw an exception"); + } + + AxReferenceKey badStateKey = new AxReferenceKey("Policy:0.0.1:PName:BadState"); + axPolicy.getStateMap().get("State1").getStateOutputs().get("stateOutput1").setNextState(badStateKey); + dummyTsle.setTaskNo(0); + try { + executor.execute(0, incomingEventMock); + fail("test should throw an exception"); + } catch (Exception ex) { + assertEquals("state execution failed, next state \"Policy:0.0.1:PName:BadState\" not found", + ex.getMessage()); + } + + axPolicy.getStateMap().get("State1").getStateOutputs().get("stateOutput1") + .setNextState(AxReferenceKey.getNullKey()); + dummyTsle.setTaskNo(0); + try { + executor.execute(0, incomingEventMock); + } catch (Exception ex) { + fail("test should not throw an exception"); + } + + axPolicy.getStateMap().get("State1").setTrigger(new AxArtifactKey("BadTrigger:0.0.1")); + dummyTsle.setTaskNo(0); + try { + executor.execute(0, incomingEventMock); + fail("test should throw an exception"); + } catch (Exception ex) { + assertEquals("incoming event \"Event1:0.0.1\" does not match trigger \"BadTrigger:0.0.1\" " + + "of state \"Policy:0.0.1:NULL:state1\"", ex.getMessage()); + } + + axPolicy.getStateMap().get("State1").setTrigger(new AxArtifactKey("Event1:0.0.1")); + dummyTsle.setTaskNo(0); + try { + executor.execute(0, incomingEventMock); + } catch (Exception ex) { + fail("test should not throw an exception"); + } + + AxStateFinalizerLogic savedSfl = axPolicy.getStateMap().get("State1").getStateFinalizerLogicMap().get("sfl"); + axPolicy.getStateMap().get("State1").getStateFinalizerLogicMap().put("sfl", null); + try { + executor.setContext(null, axPolicy, internalContextMock); + fail("test should throw an exception"); + } catch (Exception ex) { + assertEquals("state finalizer logic on task reference " + + "\"AxStateTaskReference:(stateKey=AxReferenceKey:(parentKeyName=Policy," + + "parentKeyVersion=0.0.1,parentLocalName=state1,localName=str1)," + + "outputType=LOGIC,output=AxReferenceKey:(parentKeyName=Policy,parentKeyVersion=0.0.1," + + "parentLocalName=state1,localName=sfl))\" on state \"Policy:0.0.1:NULL:state1\" " + + "does not exist", ex.getMessage()); + } + + axPolicy.getStateMap().get("State1").getStateFinalizerLogicMap().put("sfl", savedSfl); + executor.setContext(null, axPolicy, internalContextMock); + + dummyTsle.setTaskNo(0); + try { + executor.execute(0, incomingEventMock); + } catch (Exception ex) { + fail("test should not throw an exception"); + } + + AxArtifactKey task1Key = new AxArtifactKey("task1:0.0.1"); + try { + axPolicy.getStateMap().get("State1").getTaskReferences().get(task1Key) + .setStateTaskOutputType(AxStateTaskOutputType.UNDEFINED); + executor.setContext(null, axPolicy, internalContextMock); + fail("test should throw an exception"); + } catch (Exception ex) { + assertEquals("invalid state output type on task reference \"AxStateTaskReference:(stateKey=AxReferenceKey:" + + "(parentKeyName=Policy,parentKeyVersion=0.0.1,parentLocalName=state1,localName=str1)," + + "outputType=UNDEFINED,output=AxReferenceKey:(parentKeyName=Policy," + + "parentKeyVersion=0.0.1,parentLocalName=state1,localName=sfl))\" " + + "on state \"Policy:0.0.1:NULL:state1\"", ex.getMessage()); + } + + axPolicy.getStateMap().get("State1").getTaskReferences().get(task1Key) + .setStateTaskOutputType(AxStateTaskOutputType.LOGIC); + executor.setContext(null, axPolicy, internalContextMock); + + dummyTsle.setTaskNo(0); + try { + executor.execute(0, incomingEventMock); + } catch (Exception ex) { + fail("test should not throw an exception"); + } + + dummyTsle.setTaskNo(0); + dummySfle.setReturnBad(true); + try { + executor.execute(0, incomingEventMock); + fail("test should throw an exception"); + } catch (Exception ex) { + assertEquals("State execution of state \"Policy:0.0.1:NULL:state1\" on task \"task1:0.0.1\" failed: " + + "state output definition for state output \"stateOutputBad\" not found for " + + "state \"Policy:0.0.1:NULL:state1\"", ex.getMessage()); + } + + dummyTsle.setTaskNo(0); + dummySfle.setReturnBad(false); + try { + executor.execute(0, incomingEventMock); + } catch (Exception ex) { + fail("test should not throw an exception"); + } + + try { + executor.cleanUp(); + } catch (Exception ex) { + fail("test should not throw an exception"); + } + } + + @Test + public void testStateOutput() { + StateOutput output = new StateOutput( + axPolicy.getStateMap().get("State0").getStateOutputs().get("stateOutput0")); + assertNotNull(output); + + assertEquals("stateOutput0", output.getStateOutputDefinition().getKey().getLocalName()); + + try { + output.setEventFields(null, null); + fail("test should throw an exception"); + } catch (Exception ex) { + assertEquals("incomingFieldDefinitionMap may not be null", ex.getMessage()); + } + + Map<String, AxField> incomingFieldDefinitionMap = new LinkedHashMap<>(); + try { + output.setEventFields(incomingFieldDefinitionMap, null); + fail("test should throw an exception"); + } catch (Exception ex) { + assertEquals("eventFieldMap may not be null", ex.getMessage()); + } + + Map<String, Object> eventFieldMap = new LinkedHashMap<>(); + try { + output.setEventFields(incomingFieldDefinitionMap, eventFieldMap); + } catch (Exception ex) { + fail("test should not throw an exception"); + } + + eventFieldMap.put("key", "Value"); + try { + output.setEventFields(incomingFieldDefinitionMap, eventFieldMap); + fail("test should throw an exception"); + } catch (Exception ex) { + assertEquals("field definitions and values do not match for event Event1:0.0.1\n[]\n[key]", + ex.getMessage()); + } + + AxField axBadFieldDefinition = new AxField(); + incomingFieldDefinitionMap.put("key", axBadFieldDefinition); + try { + output.setEventFields(incomingFieldDefinitionMap, eventFieldMap); + fail("test should throw an exception"); + } catch (Exception ex) { + assertEquals("field \"key\" does not exist on event \"Event1:0.0.1\"", ex.getMessage()); + } + + incomingFieldDefinitionMap.clear(); + eventFieldMap.clear(); + AxArtifactKey stringSchemaKey = new AxArtifactKey("StringSchema:0.0.1"); + AxReferenceKey fieldKey = new AxReferenceKey("Event1:0.0.1:event:Field0"); + AxField event1Field0Definition = new AxField(fieldKey, stringSchemaKey); + incomingFieldDefinitionMap.put("Event1Field0", event1Field0Definition); + eventFieldMap.put("Event1Field0", "Value"); + try { + output.setEventFields(incomingFieldDefinitionMap, eventFieldMap); + } catch (Exception ex) { + fail("test should not throw an exception"); + } + + output = new StateOutput(axPolicy.getStateMap().get("State0").getStateOutputs().get("stateOutput0")); + + EnEvent incomingEvent = new EnEvent(new AxArtifactKey("Event0:0.0.1")); + output.copyUnsetFields(incomingEvent); + + incomingEvent.put("Event1Field0", "Hello"); + output.copyUnsetFields(incomingEvent); + } +} diff --git a/core/core-engine/src/test/java/org/onap/policy/apex/core/engine/executor/TaskExecutorTest.java b/core/core-engine/src/test/java/org/onap/policy/apex/core/engine/executor/TaskExecutorTest.java new file mode 100644 index 000000000..bfc8e2b6d --- /dev/null +++ b/core/core-engine/src/test/java/org/onap/policy/apex/core/engine/executor/TaskExecutorTest.java @@ -0,0 +1,251 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2018 Ericsson. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.core.engine.executor; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.fail; + +import java.util.LinkedHashMap; +import java.util.Map; + +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.MockitoAnnotations; +import org.onap.policy.apex.core.engine.ExecutorParameters; +import org.onap.policy.apex.core.engine.context.ApexInternalContext; +import org.onap.policy.apex.core.engine.executor.exception.StateMachineException; +import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey; +import org.onap.policy.apex.model.eventmodel.concepts.AxInputField; +import org.onap.policy.apex.model.eventmodel.concepts.AxOutputField; +import org.onap.policy.apex.model.policymodel.concepts.AxTask; +import org.onap.policy.apex.model.policymodel.concepts.AxTaskLogic; + +/** + * Test task excutor. + */ +public class TaskExecutorTest { + @Mock + private AxTask axTaskMock; + + @Mock + private ApexInternalContext internalContextMock; + + @Mock + private AxInputField axInputFieldMock; + + @Mock + private AxInputField axOptionalInputFieldMock; + + @Mock + private AxOutputField axOutputFieldMock; + + @Mock + private AxOutputField axOptionalOutputFieldMock; + + @Mock + private AxOutputField axMissingOutputFieldMock; + + @Mock + private Executor<Map<String, Object>, Map<String, Object>, AxTask, ApexInternalContext> nextExecutorMock; + + @Mock + private AxTaskLogic taskLogicMock; + + private LinkedHashMap<String, Object> inFieldMap; + private LinkedHashMap<String, Object> outFieldMap; + + /** + * Set up mocking. + */ + @Before + public void startMocking() { + MockitoAnnotations.initMocks(this); + + AxArtifactKey task0Key = new AxArtifactKey("Task0:0.0.1"); + Mockito.doReturn(task0Key).when(axTaskMock).getKey(); + Mockito.doReturn(task0Key.getId()).when(axTaskMock).getId(); + + inFieldMap = new LinkedHashMap<>(); + outFieldMap = new LinkedHashMap<>(); + + inFieldMap.put("InField0", axInputFieldMock); + inFieldMap.put("InField1", axOptionalInputFieldMock); + outFieldMap.put("OutField0", axOutputFieldMock); + outFieldMap.put("OutField0", axOptionalOutputFieldMock); + + AxArtifactKey schemaKey = new AxArtifactKey("Schema:0.0.1"); + Mockito.doReturn(schemaKey).when(axInputFieldMock).getSchema(); + Mockito.doReturn(schemaKey).when(axOptionalInputFieldMock).getSchema(); + Mockito.doReturn(schemaKey).when(axOutputFieldMock).getSchema(); + Mockito.doReturn(schemaKey).when(axOptionalOutputFieldMock).getSchema(); + Mockito.doReturn(schemaKey).when(axMissingOutputFieldMock).getSchema(); + + Mockito.doReturn(true).when(axOptionalInputFieldMock).getOptional(); + Mockito.doReturn(true).when(axOptionalOutputFieldMock).getOptional(); + Mockito.doReturn(false).when(axMissingOutputFieldMock).getOptional(); + + Mockito.doReturn(inFieldMap).when(axTaskMock).getInputFields(); + Mockito.doReturn(outFieldMap).when(axTaskMock).getOutputFields(); + Mockito.doReturn(taskLogicMock).when(axTaskMock).getTaskLogic(); + + Mockito.doReturn(new AxArtifactKey("Context:0.0.1")).when(internalContextMock).getKey(); + } + + @Test + public void testTaskExecutor() { + DummyTaskExecutor executor = new DummyTaskExecutor(); + + executor.setContext(null, axTaskMock, internalContextMock); + assertEquals("Task0:0.0.1", executor.getKey().getId()); + assertEquals(null, executor.getExecutionContext()); + assertEquals(null, executor.getParent()); + assertEquals(internalContextMock, executor.getContext()); + assertEquals(null, executor.getNext()); + assertEquals(null, executor.getIncoming()); + assertEquals(null, executor.getOutgoing()); + assertNotNull(executor.getSubject()); + + executor.setParameters(new ExecutorParameters()); + executor.setNext(nextExecutorMock); + assertEquals(nextExecutorMock, executor.getNext()); + executor.setNext(null); + assertEquals(null, executor.getNext()); + + try { + executor.cleanUp(); + fail("test should throw an exception"); + } catch (Exception ex) { + assertEquals("cleanUp() not implemented on class", ex.getMessage()); + } + + Mockito.doReturn(null).when(taskLogicMock).getLogic(); + + try { + executor.prepare(); + fail("test should throw an exception"); + } catch (Exception ex) { + assertEquals("task logic cannot be null.", ex.getMessage()); + } + + Mockito.doReturn("some task logic").when(taskLogicMock).getLogic(); + + try { + executor.prepare(); + } catch (StateMachineException e) { + fail("test should not throw an exception"); + } + + Map<String, Object> incomingFields = new LinkedHashMap<>(); + try { + executor.executePre(0, incomingFields); + } catch (Exception ex) { + assertEquals("task input fields \"[InField0]\" are missing for task \"Task0:0.0.1\"", ex.getMessage()); + } + + incomingFields.put("InField0", "A Value"); + try { + executor.executePre(0, incomingFields); + } catch (Exception e) { + fail("test should not throw an exception"); + } + + try { + executor.execute(0, incomingFields); + fail("test should throw an exception"); + } catch (Exception ex) { + assertEquals("execute() not implemented on abstract TaskExecutor class, only on its subclasses", + ex.getMessage()); + } + + try { + executor.executePost(false); + fail("test should throw an exception"); + } catch (Exception ex) { + assertEquals("execute-post: task logic execution failure on task \"Task0\" in model Context:0.0.1", + ex.getMessage()); + } + + executor.getExecutionContext().setMessage("Execution message"); + try { + executor.executePost(false); + fail("test should throw an exception"); + } catch (Exception ex) { + assertEquals("execute-post: task logic execution failure on task \"Task0\" in model Context:0.0.1, " + + "user message: Execution message", ex.getMessage()); + } + + try { + executor.executePost(true); + } catch (Exception e) { + fail("test should not throw an exception"); + } + + outFieldMap.put("MissingField", axMissingOutputFieldMock); + try { + executor.executePost(true); + fail("test should throw an exception"); + } catch (Exception ex) { + assertEquals("task output fields \"[MissingField]\" are missing for task \"Task0:0.0.1\"", ex.getMessage()); + } + + outFieldMap.remove("MissingField"); + executor.getExecutionContext().outFields.put("BadExtraField", "Howdy!"); + try { + executor.executePost(true); + fail("test should throw an exception"); + } catch (Exception ex) { + assertEquals("task output fields \"[BadExtraField]\" are unwanted for task \"Task0:0.0.1\"", + ex.getMessage()); + } + + executor.getExecutionContext().outFields.remove("BadExtraField"); + outFieldMap.put("InField1", axMissingOutputFieldMock); + try { + executor.executePost(true); + } catch (Exception ex) { + fail("test should not throw an exception"); + } + + outFieldMap.put("InField0", axMissingOutputFieldMock); + try { + executor.executePost(true); + } catch (Exception ex) { + fail("test should not throw an exception"); + } + + executor.getExecutionContext().outFields.put("InField0", "Output Value"); + try { + executor.executePost(true); + } catch (Exception ex) { + fail("test should not throw an exception"); + } + + executor.getExecutionContext().outFields.remove("InField0"); + try { + executor.executePost(true); + } catch (Exception ex) { + fail("test should not throw an exception"); + } + } +} diff --git a/core/core-engine/src/test/java/org/onap/policy/apex/core/engine/executor/TaskSelectExecutorTest.java b/core/core-engine/src/test/java/org/onap/policy/apex/core/engine/executor/TaskSelectExecutorTest.java new file mode 100644 index 000000000..b303df06a --- /dev/null +++ b/core/core-engine/src/test/java/org/onap/policy/apex/core/engine/executor/TaskSelectExecutorTest.java @@ -0,0 +1,208 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2018 Ericsson. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.core.engine.executor; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + +import java.util.LinkedHashMap; +import java.util.Map; + +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.MockitoAnnotations; +import org.onap.policy.apex.core.engine.ExecutorParameters; +import org.onap.policy.apex.core.engine.context.ApexInternalContext; +import org.onap.policy.apex.core.engine.event.EnEvent; +import org.onap.policy.apex.core.engine.executor.exception.StateMachineException; +import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey; +import org.onap.policy.apex.model.basicmodel.concepts.AxReferenceKey; +import org.onap.policy.apex.model.policymodel.concepts.AxState; +import org.onap.policy.apex.model.policymodel.concepts.AxStateTaskReference; +import org.onap.policy.apex.model.policymodel.concepts.AxTaskSelectionLogic; + +/** + * Test task executor. + */ +public class TaskSelectExecutorTest { + @Mock + private AxState axStateMock; + + @Mock + private ApexInternalContext internalContextMock; + + @Mock + private Executor<EnEvent, AxArtifactKey, AxState, ApexInternalContext> nextExecutorMock; + + @Mock + private AxTaskSelectionLogic taskSelectionLogicMock; + + @Mock + private EnEvent incomingEvent; + + /** + * Set up mocking. + */ + @Before + public void startMocking() { + MockitoAnnotations.initMocks(this); + + AxReferenceKey state0Key = new AxReferenceKey("State0Parent:0.0.1:Parent:State0"); + Mockito.doReturn(state0Key).when(axStateMock).getKey(); + Mockito.doReturn(state0Key.getId()).when(axStateMock).getId(); + + Map<AxArtifactKey, AxStateTaskReference> taskReferences = new LinkedHashMap<>(); + taskReferences.put(new AxArtifactKey("Task0:0.0.0"), null); + taskReferences.put(new AxArtifactKey("Task1:0.0.0"), null); + Mockito.doReturn(taskReferences).when(axStateMock).getTaskReferences(); + Mockito.doReturn(new AxArtifactKey("Task1:0.0.0")).when(axStateMock).getDefaultTask(); + + Mockito.doReturn(taskSelectionLogicMock).when(axStateMock).getTaskSelectionLogic(); + + Mockito.doReturn(new AxArtifactKey("Context:0.0.1")).when(internalContextMock).getKey(); + } + + @Test + public void testTaskSelectionExecutor() { + DummyTaskSelectExecutor executor = new DummyTaskSelectExecutor(); + + executor.setContext(null, axStateMock, internalContextMock); + assertEquals("State0Parent:0.0.1:Parent:State0", executor.getKey().getId()); + assertEquals(null, executor.getExecutionContext()); + assertEquals(null, executor.getParent()); + assertEquals(internalContextMock, executor.getContext()); + assertEquals(null, executor.getNext()); + assertEquals(null, executor.getIncoming()); + assertEquals(null, executor.getOutgoing()); + assertEquals(axStateMock, executor.getSubject()); + + executor.setParameters(new ExecutorParameters()); + executor.setNext(nextExecutorMock); + assertEquals(nextExecutorMock, executor.getNext()); + executor.setNext(null); + assertEquals(null, executor.getNext()); + + try { + executor.cleanUp(); + fail("test should throw an exception"); + } catch (Exception ex) { + assertEquals("cleanUp() not implemented on class", ex.getMessage()); + } + + Mockito.doReturn(null).when(taskSelectionLogicMock).getLogic(); + + try { + executor.prepare(); + fail("test should throw an exception"); + } catch (Exception ex) { + assertEquals("task selection logic cannot be null.", ex.getMessage()); + } + + Mockito.doReturn("some task logic").when(taskSelectionLogicMock).getLogic(); + + try { + executor.prepare(); + } catch (StateMachineException e) { + fail("test should not throw an exception"); + } + + try { + executor.executePre(0, incomingEvent); + } catch (Exception ex) { + assertEquals("task input fields \"[InField0]\" are missing for task \"Task0:0.0.1\"", ex.getMessage()); + } + + try { + executor.executePre(0, incomingEvent); + } catch (Exception e) { + fail("test should not throw an exception"); + } + + try { + executor.execute(0, incomingEvent); + fail("test should throw an exception"); + } catch (Exception ex) { + assertEquals("execute() not implemented on class", ex.getMessage()); + } + + try { + executor.executePost(false); + fail("test should throw an exception"); + } catch (Exception ex) { + assertEquals("execute-post: task selection logic failed on state \"State0Parent:0.0.1:Parent:State0\"", + ex.getMessage()); + } + + executor.getExecutionContext().setMessage("Execution message"); + try { + executor.executePost(false); + fail("test should throw an exception"); + } catch (Exception ex) { + assertEquals("execute-post: task selection logic failed on state \"State0Parent:0.0.1:Parent:State0\", " + + "user message: Execution message", ex.getMessage()); + } + + try { + executor.executePre(0, incomingEvent); + } catch (Exception e) { + fail("test should not throw an exception"); + } + + try { + executor.executePost(true); + assertEquals("Task1", executor.getOutgoing().getName()); + } catch (Exception e) { + fail("test should not throw an exception"); + } + + try { + executor.executePre(0, incomingEvent); + } catch (Exception e) { + fail("test should not throw an exception"); + } + + executor.getOutgoing().setName("IDontExist"); + try { + executor.executePost(true); + fail("test should throw an exception"); + } catch (Exception ex) { + assertEquals("task \"IDontExist:0.0.0\" returned by task selection logic not defined " + + "on state \"State0Parent:0.0.1:Parent:State0\"", ex.getMessage()); + } + + try { + executor.executePre(0, incomingEvent); + } catch (Exception e) { + fail("test should not throw an exception"); + } + + executor.getOutgoing().setName("Task0"); + + try { + executor.executePost(true); + assertEquals("Task0", executor.getOutgoing().getName()); + } catch (Exception e) { + fail("test should not throw an exception"); + } + } +} diff --git a/core/core-engine/src/test/java/org/onap/policy/apex/core/engine/executor/context/AxStateFacadeTest.java b/core/core-engine/src/test/java/org/onap/policy/apex/core/engine/executor/context/AxStateFacadeTest.java new file mode 100644 index 000000000..a35af534e --- /dev/null +++ b/core/core-engine/src/test/java/org/onap/policy/apex/core/engine/executor/context/AxStateFacadeTest.java @@ -0,0 +1,87 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2018 Ericsson. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.core.engine.executor.context; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; + +import java.util.LinkedHashMap; +import java.util.Map; + +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.MockitoAnnotations; +import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey; +import org.onap.policy.apex.model.basicmodel.concepts.AxReferenceKey; +import org.onap.policy.apex.model.basicmodel.service.ModelService; +import org.onap.policy.apex.model.policymodel.concepts.AxState; +import org.onap.policy.apex.model.policymodel.concepts.AxTask; +import org.onap.policy.apex.model.policymodel.concepts.AxTasks; + +/** + * Test the state facade. + */ +public class AxStateFacadeTest { + @Mock + private AxState axStateMock; + + @Mock + private AxTask axTaskMock; + + /** + * Set up mocking. + */ + @Before + public void startMocking() { + MockitoAnnotations.initMocks(this); + + AxReferenceKey stateKey = new AxReferenceKey("StateParent:0.0.1:ParentName:StateName"); + Mockito.doReturn(stateKey).when(axStateMock).getKey(); + + AxArtifactKey task0Key = new AxArtifactKey("Task0:0.0.1"); + Mockito.doReturn(task0Key).when(axStateMock).getDefaultTask(); + + Map<AxArtifactKey, Object> taskReferences = new LinkedHashMap<>();; + taskReferences.put(task0Key, null); + Mockito.doReturn(taskReferences).when(axStateMock).getTaskReferences(); + + AxTasks tasks = new AxTasks(); + tasks.getTaskMap().put(task0Key, axTaskMock); + + ModelService.registerModel(AxTasks.class, tasks); + Mockito.doReturn(task0Key).when(axTaskMock).getKey(); + } + + @Test + public void testAxStateFacade() { + AxStateFacade stateFacade = new AxStateFacade(axStateMock); + + assertEquals("StateName", stateFacade.getStateName()); + assertEquals("StateParent:0.0.1:ParentName:StateName", stateFacade.getId()); + + assertEquals("Task0", stateFacade.getDefaultTaskKey().getName()); + assertNull(stateFacade.getTaskKey(null)); + assertEquals("Task0", stateFacade.getTaskKey("Task0").getName()); + stateFacade.getTaskNames(); + } +} diff --git a/core/core-engine/src/test/java/org/onap/policy/apex/core/engine/executor/context/AxTaskFacadeTest.java b/core/core-engine/src/test/java/org/onap/policy/apex/core/engine/executor/context/AxTaskFacadeTest.java new file mode 100644 index 000000000..a18718cc5 --- /dev/null +++ b/core/core-engine/src/test/java/org/onap/policy/apex/core/engine/executor/context/AxTaskFacadeTest.java @@ -0,0 +1,155 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2018 Ericsson. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.core.engine.executor.context; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.fail; + +import java.util.LinkedHashMap; +import java.util.Map; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.MockitoAnnotations; +import org.onap.policy.apex.context.parameters.ContextParameterConstants; +import org.onap.policy.apex.context.parameters.SchemaParameters; +import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey; +import org.onap.policy.apex.model.basicmodel.concepts.AxReferenceKey; +import org.onap.policy.apex.model.basicmodel.service.ModelService; +import org.onap.policy.apex.model.contextmodel.concepts.AxContextSchema; +import org.onap.policy.apex.model.contextmodel.concepts.AxContextSchemas; +import org.onap.policy.apex.model.eventmodel.concepts.AxInputField; +import org.onap.policy.apex.model.eventmodel.concepts.AxOutputField; +import org.onap.policy.apex.model.policymodel.concepts.AxTask; +import org.onap.policy.common.parameters.ParameterService; + +/** + * Test the state facade. + */ +public class AxTaskFacadeTest { + @Mock + private AxTask axTaskMock; + + @Mock + private AxInputField axInputFieldMock; + + @Mock + private AxInputField axInputFieldBadMock; + + @Mock + private AxOutputField axOutputFieldMock; + + @Mock + private AxOutputField axOutputFieldBadMock; + + /** + * Set up mocking. + */ + @Before + public void startMocking() { + AxContextSchemas schemas = new AxContextSchemas(); + + AxArtifactKey stringTypeKey = new AxArtifactKey("StringType:0.0.1"); + AxContextSchema stringType = new AxContextSchema(stringTypeKey, "Java", "java.lang.String"); + schemas.getSchemasMap().put(stringTypeKey, stringType); + + ModelService.registerModel(AxContextSchemas.class, schemas); + + MockitoAnnotations.initMocks(this); + + AxArtifactKey task0Key = new AxArtifactKey("Task0:0.0.1"); + Mockito.doReturn(task0Key).when(axTaskMock).getKey(); + Mockito.doReturn(task0Key.getId()).when(axTaskMock).getId(); + + Map<String, AxInputField> inFieldMap = new LinkedHashMap<>(); + Map<String, AxOutputField> outFieldMap = new LinkedHashMap<>(); + + inFieldMap.put("InField0", axInputFieldMock); + inFieldMap.put("InFieldBad", axInputFieldBadMock); + outFieldMap.put("OutField0", axOutputFieldMock); + outFieldMap.put("OutFieldBad", axOutputFieldBadMock); + + Mockito.doReturn(inFieldMap).when(axTaskMock).getInputFields(); + Mockito.doReturn(outFieldMap).when(axTaskMock).getOutputFields(); + + Mockito.doReturn(new AxReferenceKey(task0Key, "InField0")).when(axInputFieldMock).getKey(); + Mockito.doReturn(stringTypeKey).when(axInputFieldMock).getSchema(); + + Mockito.doReturn(new AxReferenceKey(task0Key, "OutField0")).when(axOutputFieldMock).getKey(); + Mockito.doReturn(stringTypeKey).when(axOutputFieldMock).getSchema(); + + ParameterService.register(new SchemaParameters()); + } + + @After + public void teardown() { + ParameterService.deregister(ContextParameterConstants.SCHEMA_GROUP_NAME); + ModelService.clear(); + } + + @Test + public void testAxStateFacade() { + AxTaskFacade taskFacade = new AxTaskFacade(axTaskMock); + + assertEquals("Task0", taskFacade.getTaskName()); + assertEquals("Task0:0.0.1", taskFacade.getId()); + + try { + taskFacade.getInFieldSchemaHelper("InFieldDoesntExist"); + fail("test should throw an exception"); + } catch (Exception exc) { + assertEquals("no incoming field with name \"InFieldDoesntExist\" " + "defined on task \"Task0:0.0.1\"", + exc.getMessage()); + } + + try { + taskFacade.getOutFieldSchemaHelper("OutFieldDoesntExist"); + fail("test should throw an exception"); + } catch (Exception exc) { + assertEquals("no outgoing field with name \"OutFieldDoesntExist\" " + "defined on task \"Task0:0.0.1\"", + exc.getMessage()); + } + + assertNotNull(taskFacade.getInFieldSchemaHelper("InField0")); + assertNotNull(taskFacade.getOutFieldSchemaHelper("OutField0")); + + try { + taskFacade.getInFieldSchemaHelper("InFieldBad"); + fail("test should throw an exception"); + } catch (Exception exc) { + assertEquals("schema helper cannot be created for task field \"InFieldBad\" " + + "with key \"null\" with schema \"null\"", exc.getMessage()); + } + + try { + taskFacade.getOutFieldSchemaHelper("OutFieldBad"); + fail("test should throw an exception"); + } catch (Exception exc) { + assertEquals("schema helper cannot be created for task field \"OutFieldBad\" " + + "with key \"null\" with schema \"null\"", exc.getMessage()); + } + + } +} diff --git a/core/core-engine/src/test/java/org/onap/policy/apex/core/engine/executor/context/DummyContextAlbum.java b/core/core-engine/src/test/java/org/onap/policy/apex/core/engine/executor/context/DummyContextAlbum.java new file mode 100644 index 000000000..5d5583ff6 --- /dev/null +++ b/core/core-engine/src/test/java/org/onap/policy/apex/core/engine/executor/context/DummyContextAlbum.java @@ -0,0 +1,281 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2018 Ericsson. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.core.engine.executor.context; + +import java.util.Collection; +import java.util.Map; +import java.util.Set; + +import org.apache.commons.lang3.NotImplementedException; +import org.onap.policy.apex.context.ContextAlbum; +import org.onap.policy.apex.context.ContextException; +import org.onap.policy.apex.context.SchemaHelper; +import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey; +import org.onap.policy.apex.model.basicmodel.concepts.AxConcept; +import org.onap.policy.apex.model.contextmodel.concepts.AxContextAlbum; + +/** + * Dummy context album for testing. + */ +public class DummyContextAlbum implements ContextAlbum { + private final AxArtifactKey key; + + /** + * Constructor. + * @param key the key + */ + public DummyContextAlbum(AxArtifactKey key) { + super(); + this.key = key; + } + + /* + * (non-Javadoc) + * + * @see java.util.Map#clear() + */ + @Override + public void clear() { + throw new NotImplementedException("Not implemented on dummy class"); + } + + /* + * (non-Javadoc) + * + * @see java.util.Map#containsKey(java.lang.Object) + */ + @Override + public boolean containsKey(Object key) { + throw new NotImplementedException("Not implemented on dummy class"); + } + + /* + * (non-Javadoc) + * + * @see java.util.Map#containsValue(java.lang.Object) + */ + @Override + public boolean containsValue(Object value) { + throw new NotImplementedException("Not implemented on dummy class"); + } + + /* + * (non-Javadoc) + * + * @see java.util.Map#entrySet() + */ + @Override + public Set<Entry<String, Object>> entrySet() { + throw new NotImplementedException("Not implemented on dummy class"); + } + + /* + * (non-Javadoc) + * + * @see java.util.Map#get(java.lang.Object) + */ + @Override + public Object get(Object key) { + throw new NotImplementedException("Not implemented on dummy class"); + } + + /* + * (non-Javadoc) + * + * @see java.util.Map#isEmpty() + */ + @Override + public boolean isEmpty() { + throw new NotImplementedException("Not implemented on dummy class"); + } + + /* + * (non-Javadoc) + * + * @see java.util.Map#keySet() + */ + @Override + public Set<String> keySet() { + throw new NotImplementedException("Not implemented on dummy class"); + } + + /* + * (non-Javadoc) + * + * @see java.util.Map#put(java.lang.Object, java.lang.Object) + */ + @Override + public Object put(String key, Object value) { + throw new NotImplementedException("Not implemented on dummy class"); + } + + /* + * (non-Javadoc) + * + * @see java.util.Map#putAll(java.util.Map) + */ + @Override + public void putAll(Map<? extends String, ? extends Object> map) { + throw new NotImplementedException("Not implemented on dummy class"); + } + + /* + * (non-Javadoc) + * + * @see java.util.Map#remove(java.lang.Object) + */ + @Override + public Object remove(Object key) { + throw new NotImplementedException("Not implemented on dummy class"); + } + + /* + * (non-Javadoc) + * + * @see java.util.Map#size() + */ + @Override + public int size() { + throw new NotImplementedException("Not implemented on dummy class"); + } + + /* + * (non-Javadoc) + * + * @see java.util.Map#values() + */ + @Override + public Collection<Object> values() { + throw new NotImplementedException("Not implemented on dummy class"); + } + + /* + * (non-Javadoc) + * + * @see org.onap.policy.apex.context.ContextAlbum#getKey() + */ + @Override + public AxArtifactKey getKey() { + return key; + } + + /* + * (non-Javadoc) + * + * @see org.onap.policy.apex.context.ContextAlbum#getName() + */ + @Override + public String getName() { + throw new NotImplementedException("Not implemented on dummy class"); + } + + /* + * (non-Javadoc) + * + * @see org.onap.policy.apex.context.ContextAlbum#getAlbumDefinition() + */ + @Override + public AxContextAlbum getAlbumDefinition() { + throw new NotImplementedException("Not implemented on dummy class"); + } + + /* + * (non-Javadoc) + * + * @see org.onap.policy.apex.context.ContextAlbum#getSchemaHelper() + */ + @Override + public SchemaHelper getSchemaHelper() { + throw new NotImplementedException("Not implemented on dummy class"); + } + + /* + * (non-Javadoc) + * + * @see org.onap.policy.apex.context.ContextAlbum#lockForReading(java.lang.String) + */ + @Override + public void lockForReading(String key) throws ContextException { + throw new NotImplementedException("Not implemented on dummy class"); + } + + /* + * (non-Javadoc) + * + * @see org.onap.policy.apex.context.ContextAlbum#lockForWriting(java.lang.String) + */ + @Override + public void lockForWriting(String key) throws ContextException { + throw new NotImplementedException("Not implemented on dummy class"); + } + + /* + * (non-Javadoc) + * + * @see org.onap.policy.apex.context.ContextAlbum#unlockForReading(java.lang.String) + */ + @Override + public void unlockForReading(String key) throws ContextException { + throw new NotImplementedException("Not implemented on dummy class"); + } + + /* + * (non-Javadoc) + * + * @see org.onap.policy.apex.context.ContextAlbum#unlockForWriting(java.lang.String) + */ + @Override + public void unlockForWriting(String key) throws ContextException { + throw new NotImplementedException("Not implemented on dummy class"); + } + + /* + * (non-Javadoc) + * + * @see org.onap.policy.apex.context.ContextAlbum#getUserArtifactStack() + */ + @Override + public AxConcept[] getUserArtifactStack() { + throw new NotImplementedException("Not implemented on dummy class"); + } + + /* + * (non-Javadoc) + * + * @see + * org.onap.policy.apex.context.ContextAlbum#setUserArtifactStack(org.onap.policy.apex.model.basicmodel.concepts. + * AxConcept[]) + */ + @Override + public void setUserArtifactStack(AxConcept[] userArtifactStack) { + // Do nothing + } + + /* + * (non-Javadoc) + * + * @see org.onap.policy.apex.context.ContextAlbum#flush() + */ + @Override + public void flush() throws ContextException { + throw new NotImplementedException("Not implemented on dummy class"); + } +} diff --git a/core/core-engine/src/test/java/org/onap/policy/apex/core/engine/executor/context/StateFinalizerExecutionContextTest.java b/core/core-engine/src/test/java/org/onap/policy/apex/core/engine/executor/context/StateFinalizerExecutionContextTest.java new file mode 100644 index 000000000..8b0710ec7 --- /dev/null +++ b/core/core-engine/src/test/java/org/onap/policy/apex/core/engine/executor/context/StateFinalizerExecutionContextTest.java @@ -0,0 +1,113 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2018 Ericsson. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.core.engine.executor.context; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.fail; + +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.Map; +import java.util.Set; + +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.MockitoAnnotations; +import org.onap.policy.apex.context.ContextAlbum; +import org.onap.policy.apex.core.engine.context.ApexInternalContext; +import org.onap.policy.apex.core.engine.executor.StateFinalizerExecutor; +import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey; +import org.onap.policy.apex.model.basicmodel.concepts.AxReferenceKey; +import org.onap.policy.apex.model.policymodel.concepts.AxState; + +/** + * Test Task Execution Context. + */ +public class StateFinalizerExecutionContextTest { + @Mock + private StateFinalizerExecutor stateFinalizerExecutorMock; + + @Mock + private StateFinalizerExecutor parentExecutorMock; + + @Mock + private AxState axStateMock; + + @Mock + private ApexInternalContext internalContextMock; + + /** + * Set up mocking. + */ + @Before + public void startMocking() { + MockitoAnnotations.initMocks(this); + + Set<AxArtifactKey> contextAlbumReferences = new LinkedHashSet<>(); + contextAlbumReferences.add(new AxArtifactKey(("AlbumKey0:0.0.1"))); + contextAlbumReferences.add(new AxArtifactKey(("AlbumKey1:0.0.1"))); + + Mockito.doReturn(contextAlbumReferences).when(axStateMock).getContextAlbumReferences(); + Mockito.doReturn(new AxReferenceKey("Parent:0.0.1:ParentName:StateName")).when(axStateMock).getKey(); + + Map<AxArtifactKey, ContextAlbum> contextAlbumMap = new LinkedHashMap<>(); + AxArtifactKey album0Key = new AxArtifactKey("AlbumKey0:0.0.1"); + AxArtifactKey album1Key = new AxArtifactKey("AlbumKey1:0.0.1"); + + contextAlbumMap.put(album0Key, new DummyContextAlbum(album0Key)); + contextAlbumMap.put(album1Key, new DummyContextAlbum(album1Key)); + + Mockito.doReturn(contextAlbumMap).when(internalContextMock).getContextAlbums(); + + Mockito.doReturn(parentExecutorMock).when(stateFinalizerExecutorMock).getParent(); + Mockito.doReturn(new AxReferenceKey("Parent:0.0.1:ParentName:LocalName")).when(parentExecutorMock).getKey(); + } + + @Test + public void test() { + final Map<String, Object> fields = new LinkedHashMap<>(); + final Set<String> stateOutputNames = new LinkedHashSet<>(); + + StateFinalizerExecutionContext sfec = new StateFinalizerExecutionContext(stateFinalizerExecutorMock, 0, + axStateMock, fields, stateOutputNames, internalContextMock); + + assertNotNull(sfec); + sfec.setMessage("SFEC Message"); + assertEquals("SFEC Message", sfec.getMessage()); + + sfec.setSelectedStateOutputName("SomeOutput"); + assertEquals("SomeOutput", sfec.getSelectedStateOutputName()); + + ContextAlbum contextAlbum = sfec.getContextAlbum("AlbumKey0"); + assertEquals("AlbumKey0:0.0.1", contextAlbum.getKey().getId()); + + try { + sfec.getContextAlbum("AlbumKeyNonExistant"); + fail("test should throw an exception"); + } catch (Exception exc) { + assertEquals("cannot find definition of context album \"AlbumKeyNonExistant\" " + + "on state \"Parent:0.0.1:ParentName:StateName\"", exc.getMessage()); + } + } +} diff --git a/core/core-engine/src/test/java/org/onap/policy/apex/core/engine/executor/context/TaskExecutionContextTest.java b/core/core-engine/src/test/java/org/onap/policy/apex/core/engine/executor/context/TaskExecutionContextTest.java new file mode 100644 index 000000000..c6c196a01 --- /dev/null +++ b/core/core-engine/src/test/java/org/onap/policy/apex/core/engine/executor/context/TaskExecutionContextTest.java @@ -0,0 +1,108 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2018 Ericsson. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.core.engine.executor.context; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.fail; + +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.Map; +import java.util.Set; + +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.MockitoAnnotations; +import org.onap.policy.apex.context.ContextAlbum; +import org.onap.policy.apex.core.engine.context.ApexInternalContext; +import org.onap.policy.apex.core.engine.executor.TaskExecutor; +import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey; +import org.onap.policy.apex.model.policymodel.concepts.AxTask; + +/** + * Test Task Execution Context. + */ +public class TaskExecutionContextTest { + @Mock + private TaskExecutor taskExecutorMock; + + @Mock + private TaskExecutor parentExecutorMock; + + @Mock + private AxTask axTaskMock; + + @Mock + private ApexInternalContext internalContextMock; + + /** + * Set up mocking. + */ + @Before + public void startMocking() { + MockitoAnnotations.initMocks(this); + + Set<AxArtifactKey> contextAlbumReferences = new LinkedHashSet<>(); + contextAlbumReferences.add(new AxArtifactKey(("AlbumKey0:0.0.1"))); + contextAlbumReferences.add(new AxArtifactKey(("AlbumKey1:0.0.1"))); + + Mockito.doReturn(contextAlbumReferences).when(axTaskMock).getContextAlbumReferences(); + + Map<AxArtifactKey, ContextAlbum> contextAlbumMap = new LinkedHashMap<>(); + AxArtifactKey album0Key = new AxArtifactKey("AlbumKey0:0.0.1"); + AxArtifactKey album1Key = new AxArtifactKey("AlbumKey1:0.0.1"); + + contextAlbumMap.put(album0Key, new DummyContextAlbum(album0Key)); + contextAlbumMap.put(album1Key, new DummyContextAlbum(album1Key)); + + Mockito.doReturn(contextAlbumMap).when(internalContextMock).getContextAlbums(); + + Mockito.doReturn(parentExecutorMock).when(taskExecutorMock).getParent(); + Mockito.doReturn(new AxArtifactKey("Parent:0.0.1")).when(parentExecutorMock).getKey(); + } + + @Test + public void test() { + final Map<String, Object> inFields = new LinkedHashMap<>(); + final Map<String, Object> outFields = new LinkedHashMap<>(); + + TaskExecutionContext tec = new TaskExecutionContext(taskExecutorMock, 0, axTaskMock, inFields, outFields, + internalContextMock); + + assertNotNull(tec); + tec.setMessage("TEC Message"); + assertEquals("TEC Message", tec.getMessage()); + + ContextAlbum contextAlbum = tec.getContextAlbum("AlbumKey0"); + assertEquals("AlbumKey0:0.0.1", contextAlbum.getKey().getId()); + + try { + tec.getContextAlbum("AlbumKeyNonExistant"); + fail("test should throw an exception"); + } catch (Exception exc) { + assertEquals("cannot find definition of context album \"AlbumKeyNonExistant\" on task \"null\"", + exc.getMessage()); + } + } +} diff --git a/core/core-engine/src/test/java/org/onap/policy/apex/core/engine/executor/context/TaskSelectionExecutionContextTest.java b/core/core-engine/src/test/java/org/onap/policy/apex/core/engine/executor/context/TaskSelectionExecutionContextTest.java new file mode 100644 index 000000000..02e271717 --- /dev/null +++ b/core/core-engine/src/test/java/org/onap/policy/apex/core/engine/executor/context/TaskSelectionExecutionContextTest.java @@ -0,0 +1,113 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2018 Ericsson. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.core.engine.executor.context; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.fail; + +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.Map; +import java.util.Set; + +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.MockitoAnnotations; +import org.onap.policy.apex.context.ContextAlbum; +import org.onap.policy.apex.core.engine.context.ApexInternalContext; +import org.onap.policy.apex.core.engine.event.EnEvent; +import org.onap.policy.apex.core.engine.executor.TaskSelectExecutor; +import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey; +import org.onap.policy.apex.model.basicmodel.concepts.AxReferenceKey; +import org.onap.policy.apex.model.policymodel.concepts.AxState; + +/** + * Test Task Execution Context. + */ +public class TaskSelectionExecutionContextTest { + @Mock + private TaskSelectExecutor taskSelectExecutorMock; + + @Mock + private TaskSelectExecutor parentExecutorMock; + + @Mock + private AxState axStateMock; + + @Mock + private ApexInternalContext internalContextMock; + + @Mock + private EnEvent incomingEventMock; + + /** + * Set up mocking. + */ + @Before + public void startMocking() { + MockitoAnnotations.initMocks(this); + + Set<AxArtifactKey> contextAlbumReferences = new LinkedHashSet<>(); + contextAlbumReferences.add(new AxArtifactKey(("AlbumKey0:0.0.1"))); + contextAlbumReferences.add(new AxArtifactKey(("AlbumKey1:0.0.1"))); + + Mockito.doReturn(contextAlbumReferences).when(axStateMock).getContextAlbumReferences(); + Mockito.doReturn(new AxReferenceKey("Parent:0.0.1:ParentName:StateName")).when(axStateMock).getKey(); + + Map<AxArtifactKey, ContextAlbum> contextAlbumMap = new LinkedHashMap<>(); + AxArtifactKey album0Key = new AxArtifactKey("AlbumKey0:0.0.1"); + AxArtifactKey album1Key = new AxArtifactKey("AlbumKey1:0.0.1"); + + contextAlbumMap.put(album0Key, new DummyContextAlbum(album0Key)); + contextAlbumMap.put(album1Key, new DummyContextAlbum(album1Key)); + + Mockito.doReturn(contextAlbumMap).when(internalContextMock).getContextAlbums(); + + Mockito.doReturn(parentExecutorMock).when(taskSelectExecutorMock).getParent(); + Mockito.doReturn(new AxReferenceKey("Parent:0.0.1:ParentName:LocalName")).when(parentExecutorMock).getKey(); + } + + @Test + public void test() { + final AxArtifactKey outgoingEventKey = new AxArtifactKey("OutEvent:0.0.1"); + + TaskSelectionExecutionContext tsec = new TaskSelectionExecutionContext(taskSelectExecutorMock, 0, axStateMock, + incomingEventMock, outgoingEventKey, internalContextMock); + + assertNotNull(tsec); + tsec.setMessage("TSEC Message"); + assertEquals("TSEC Message", tsec.getMessage()); + + ContextAlbum contextAlbum = tsec.getContextAlbum("AlbumKey0"); + assertEquals("AlbumKey0:0.0.1", contextAlbum.getKey().getId()); + + try { + tsec.getContextAlbum("AlbumKeyNonExistant"); + fail("test should throw an exception"); + } catch (Exception exc) { + assertEquals("cannot find definition of context album \"AlbumKeyNonExistant\" " + + "on state \"Parent:0.0.1:ParentName:StateName\"", exc.getMessage()); + } + } +} diff --git a/core/core-engine/src/test/java/org/onap/policy/apex/core/engine/executor/exception/StateMachineRuntimeExceptionTest.java b/core/core-engine/src/test/java/org/onap/policy/apex/core/engine/executor/exception/StateMachineRuntimeExceptionTest.java new file mode 100644 index 000000000..e77002627 --- /dev/null +++ b/core/core-engine/src/test/java/org/onap/policy/apex/core/engine/executor/exception/StateMachineRuntimeExceptionTest.java @@ -0,0 +1,43 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2018 Ericsson. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.core.engine.executor.exception; + +import static org.junit.Assert.assertEquals; + +import java.io.IOException; + +import org.junit.Test; + +/** + * Test state machine runtime exception. + * + */ +public class StateMachineRuntimeExceptionTest { + + @Test + public void testException() { + StateMachineRuntimeException smre = new StateMachineRuntimeException("Exception Message"); + assertEquals("Exception Message", smre.getMessage()); + + smre = new StateMachineRuntimeException("Exception Message", new IOException()); + assertEquals("Exception Message", smre.getMessage()); + } +} diff --git a/core/core-engine/src/test/java/org/onap/policy/apex/core/engine/executor/impl/ExceutorFactoryImplTest.java b/core/core-engine/src/test/java/org/onap/policy/apex/core/engine/executor/impl/ExceutorFactoryImplTest.java new file mode 100644 index 000000000..7fe394758 --- /dev/null +++ b/core/core-engine/src/test/java/org/onap/policy/apex/core/engine/executor/impl/ExceutorFactoryImplTest.java @@ -0,0 +1,310 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2018 Ericsson. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.core.engine.executor.impl; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.fail; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.MockitoAnnotations; +import org.onap.policy.apex.core.engine.EngineParameters; +import org.onap.policy.apex.core.engine.ExecutorParameters; +import org.onap.policy.apex.core.engine.context.ApexInternalContext; +import org.onap.policy.apex.core.engine.executor.Executor; +import org.onap.policy.apex.core.engine.executor.exception.StateMachineException; +import org.onap.policy.apex.model.policymodel.concepts.AxState; +import org.onap.policy.apex.model.policymodel.concepts.AxStateFinalizerLogic; +import org.onap.policy.apex.model.policymodel.concepts.AxTask; +import org.onap.policy.apex.model.policymodel.concepts.AxTaskLogic; +import org.onap.policy.apex.model.policymodel.concepts.AxTaskSelectionLogic; +import org.onap.policy.common.parameters.ParameterService; + +/** + * Test the executor factory implementation. + * + */ +public class ExceutorFactoryImplTest { + @Mock + private ApexInternalContext internalContextMock; + + @Mock + private AxState stateMock; + + @Mock + private AxTaskSelectionLogic tslMock; + + @Mock + private AxTask taskMock; + + @Mock + private AxTaskLogic tlMock; + + @Mock + private AxStateFinalizerLogic sflMock; + + @Mock + private Executor<?, ?, ?, ?> parentMock; + + private ExecutorParameters executorPars; + + /** + * Set up mocking. + */ + @Before + public void startMocking() { + MockitoAnnotations.initMocks(this); + + Mockito.doReturn(tslMock).when(stateMock).getTaskSelectionLogic(); + Mockito.doReturn("Dummy").when(tslMock).getLogicFlavour(); + + Mockito.doReturn(tlMock).when(taskMock).getTaskLogic(); + Mockito.doReturn("Dummy").when(tlMock).getLogicFlavour(); + + Mockito.doReturn("Dummy").when(sflMock).getLogicFlavour(); + } + + @After + public void clearPars() { + ParameterService.clear(); + } + + @Test + public void testExecutorFactoryImplGood() { + setGoodPars(); + + ExecutorFactoryImpl factory = null; + + try { + factory = new ExecutorFactoryImpl(); + } catch (StateMachineException e) { + fail("test should not throw an exception"); + } + + Mockito.doReturn(true).when(stateMock).checkSetTaskSelectionLogic(); + assertNotNull(factory.getTaskSelectionExecutor(null, stateMock, internalContextMock)); + Mockito.doReturn(false).when(stateMock).checkSetTaskSelectionLogic(); + assertNull(factory.getTaskSelectionExecutor(null, stateMock, internalContextMock)); + + assertNotNull(factory.getTaskExecutor(null, taskMock, internalContextMock)); + + assertNotNull(factory.getStateFinalizerExecutor(parentMock, sflMock, internalContextMock)); + } + + @Test + public void testExecutorFactoryImplNonExistant() { + setNonExistantPars(); + + try { + new ExecutorFactoryImpl(); + fail("test should throw an exception"); + + } catch (StateMachineException ex) { + assertEquals("Apex executor class not found for executor plugin " + + "\"org.onap.policy.apex.core.engine.executor.BadTaskExecutor\"", ex.getMessage()); + } + + executorPars.setTaskExecutorPluginClass(null); + + try { + new ExecutorFactoryImpl(); + fail("test should throw an exception"); + } catch (StateMachineException ex) { + assertEquals("Apex executor class not found for executor plugin " + + "\"org.onap.policy.apex.core.engine.executor.BadTaskSelectExecutor\"", ex.getMessage()); + } + + executorPars.setTaskExecutorPluginClass("org.onap.policy.apex.core.engine.executor.DummyTaskExecutor"); + + try { + new ExecutorFactoryImpl(); + fail("test should throw an exception"); + } catch (StateMachineException ex) { + assertEquals("Apex executor class not found for executor plugin " + + "\"org.onap.policy.apex.core.engine.executor.BadTaskSelectExecutor\"", ex.getMessage()); + } + + executorPars.setTaskSelectionExecutorPluginClass( + "org.onap.policy.apex.core.engine.executor.DummyTaskSelectExecutor"); + + try { + new ExecutorFactoryImpl(); + fail("test should throw an exception"); + } catch (StateMachineException ex) { + assertEquals("Apex executor class not found for executor plugin " + + "\"org.onap.policy.apex.core.engine.executor.BadStateFinalizerExecutor\"", + ex.getMessage()); + } + } + + @Test + public void testExecutorFactoryImplBad() { + setBadPars(); + + try { + new ExecutorFactoryImpl(); + fail("test should throw an exception"); + + } catch (StateMachineException ex) { + assertEquals("Specified Apex executor plugin class \"java.lang.String\" " + + "does not implment the Executor interface", ex.getMessage()); + } + + executorPars.setTaskExecutorPluginClass("org.onap.policy.apex.core.engine.executor.DummyTaskExecutor"); + + try { + new ExecutorFactoryImpl(); + fail("test should throw an exception"); + } catch (StateMachineException ex) { + assertEquals("Specified Apex executor plugin class \"java.lang.String\" " + + "does not implment the Executor interface", ex.getMessage()); + } + + executorPars.setTaskSelectionExecutorPluginClass( + "org.onap.policy.apex.core.engine.executor.DummyTaskSelectExecutor"); + + try { + new ExecutorFactoryImpl(); + fail("test should throw an exception"); + } catch (StateMachineException ex) { + assertEquals("Specified Apex executor plugin class \"java.lang.String\" " + + "does not implment the Executor interface", ex.getMessage()); + } + } + + @Test + public void testExecutorFactoryCreateErrors() { + setGoodPars(); + + executorPars.setTaskExecutorPluginClass(null); + + ExecutorFactoryImpl factory = null; + + try { + factory = new ExecutorFactoryImpl(); + } catch (StateMachineException e) { + fail("test should not throw an exception"); + } + + Mockito.doReturn(true).when(stateMock).checkSetTaskSelectionLogic(); + + try { + factory.getTaskExecutor(null, taskMock, internalContextMock); + fail("test should throw an exception"); + } catch (Exception ex) { + assertEquals("Executor plugin class not defined for \"Dummy\" executor of type " + + "\"org.onap.policy.apex.core.engine.executor.TaskExecutor\"", ex.getMessage()); + } + + executorPars.setTaskExecutorPluginClass("org.onap.policy.apex.core.engine.executor.DummyFailingTaskExecutor"); + + try { + factory = new ExecutorFactoryImpl(); + } catch (StateMachineException e) { + fail("test should not throw an exception"); + } + + try { + factory.getTaskExecutor(null, taskMock, internalContextMock); + fail("test should throw an exception"); + } catch (Exception ex) { + assertEquals("Instantiation error on \"Dummy\" executor of type " + + "\"org.onap.policy.apex.core.engine.executor.DummyFailingTaskExecutor\"", + ex.getMessage()); + } + + executorPars.setTaskExecutorPluginClass( + "org.onap.policy.apex.core.engine.executor.DummyStateFinalizerExecutor"); + + try { + factory = new ExecutorFactoryImpl(); + } catch (StateMachineException e) { + fail("test should not throw an exception"); + } + + try { + factory.getTaskExecutor(null, taskMock, internalContextMock); + fail("test should throw an exception"); + } catch (Exception ex) { + assertEquals("Executor on \"Dummy\" " + + "of type \"class org.onap.policy.apex.core.engine.executor.DummyStateFinalizerExecutor\"" + + " is not an instance of \"org.onap.policy.apex.core.engine.executor.TaskExecutor\"", + ex.getMessage()); + } + } + + /** + * Set up good parameters. + */ + private void setGoodPars() { + executorPars = new ExecutorParameters(); + executorPars.setTaskExecutorPluginClass("org.onap.policy.apex.core.engine.executor.DummyTaskExecutor"); + executorPars.setTaskSelectionExecutorPluginClass( + "org.onap.policy.apex.core.engine.executor.DummyTaskSelectExecutor"); + executorPars.setStateFinalizerExecutorPluginClass( + "org.onap.policy.apex.core.engine.executor.DummyStateFinalizerExecutor"); + + EngineParameters enginePars = new EngineParameters(); + enginePars.getExecutorParameterMap().put("Dummy", executorPars); + + ParameterService.register(enginePars); + ParameterService.register(executorPars); + } + + /** + * Set up non existant parameters. + */ + private void setNonExistantPars() { + executorPars = new ExecutorParameters(); + executorPars.setTaskExecutorPluginClass("org.onap.policy.apex.core.engine.executor.BadTaskExecutor"); + executorPars.setTaskSelectionExecutorPluginClass( + "org.onap.policy.apex.core.engine.executor.BadTaskSelectExecutor"); + executorPars.setStateFinalizerExecutorPluginClass( + "org.onap.policy.apex.core.engine.executor.BadStateFinalizerExecutor"); + + EngineParameters enginePars = new EngineParameters(); + enginePars.getExecutorParameterMap().put("Dummy", executorPars); + + ParameterService.register(enginePars, true); + ParameterService.register(executorPars, true); + } + + /** + * Set up bad parameters. + */ + private void setBadPars() { + executorPars = new ExecutorParameters(); + executorPars.setTaskExecutorPluginClass("java.lang.String"); + executorPars.setTaskSelectionExecutorPluginClass("java.lang.String"); + executorPars.setStateFinalizerExecutorPluginClass("java.lang.String"); + + EngineParameters enginePars = new EngineParameters(); + enginePars.getExecutorParameterMap().put("Dummy", executorPars); + + ParameterService.register(enginePars, true); + ParameterService.register(executorPars, true); + } +} |