diff options
author | Pamela Dragosh <pdragosh@research.att.com> | 2018-10-08 11:59:25 +0000 |
---|---|---|
committer | Gerrit Code Review <gerrit@onap.org> | 2018-10-08 11:59:25 +0000 |
commit | fb0ea8cd5d4a7b4a1c9731b45839be1f291455bf (patch) | |
tree | 4674e4949b0c1379899dc38d23aa41513496c45b | |
parent | 5b416f07f49e719d1e0ad1f0830588c1d19a17dd (diff) | |
parent | 7a5e85e17d58e4d75812a3015adc7cbc06e4e49c (diff) |
Merge "Unit test for Apex engine"
34 files changed, 3715 insertions, 71 deletions
diff --git a/core/core-engine/pom.xml b/core/core-engine/pom.xml index f527d46c1..6e21cd444 100644 --- a/core/core-engine/pom.xml +++ b/core/core-engine/pom.xml @@ -51,9 +51,19 @@ <version>${project.version}</version> </dependency> <dependency> + <groupId>org.onap.policy.apex-pdp.core</groupId> + <artifactId>core-infrastructure</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> </dependency> + <dependency> + <groupId>org.mockito</groupId> + <artifactId>mockito-all</artifactId> + <scope>test</scope> + </dependency> </dependencies> <profiles> 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); + } +} diff --git a/services/services-engine/src/test/java/org/onap/policy/apex/service/engine/runtime/impl/EngineServiceImplTest.java b/services/services-engine/src/test/java/org/onap/policy/apex/service/engine/runtime/impl/EngineServiceImplTest.java index 582e61948..f68a4872b 100644 --- a/services/services-engine/src/test/java/org/onap/policy/apex/service/engine/runtime/impl/EngineServiceImplTest.java +++ b/services/services-engine/src/test/java/org/onap/policy/apex/service/engine/runtime/impl/EngineServiceImplTest.java @@ -171,7 +171,13 @@ public class EngineServiceImplTest { esImpl.registerActionListener(null, new DummyApexEventListener()); esImpl.registerActionListener("DummyListener", new DummyApexEventListener()); - esImpl.deregisterActionListener(null); + try { + esImpl.deregisterActionListener(null); + fail("test should throw an exception"); + } catch (Exception apEx) { + assertEquals("removeEventListener()<-Engine-0:0.0.1,STOPPED, listenerName is null", apEx.getMessage()); + } + esImpl.deregisterActionListener("DummyListener"); assertEquals(esImpl, esImpl.getEngineServiceEventInterface()); diff --git a/services/services-engine/src/test/java/org/onap/policy/apex/service/engine/runtime/impl/EngineWorkerTest.java b/services/services-engine/src/test/java/org/onap/policy/apex/service/engine/runtime/impl/EngineWorkerTest.java index 5ffda6ed6..1f8052d4a 100644 --- a/services/services-engine/src/test/java/org/onap/policy/apex/service/engine/runtime/impl/EngineWorkerTest.java +++ b/services/services-engine/src/test/java/org/onap/policy/apex/service/engine/runtime/impl/EngineWorkerTest.java @@ -143,7 +143,7 @@ public class EngineWorkerTest { ParameterService.deregister(ContextParameterConstants.MAIN_GROUP_NAME); ParameterService.deregister(EngineParameterConstants.MAIN_GROUP_NAME); } - + @After public void cleardownTest() { ModelService.clear(); @@ -155,12 +155,31 @@ public class EngineWorkerTest { EngineWorker worker = new EngineWorker(new AxArtifactKey("Worker", "0.0.1"), eventQueue, atFactory); - worker.registerActionListener(null, null); + try { + worker.registerActionListener(null, null); + fail("test should throw an exception"); + } catch (Exception apEx) { + assertEquals("addEventListener()<-Worker:0.0.1,STOPPED, listenerName is null", apEx.getMessage()); + } + worker.registerActionListener("DummyListener", null); - worker.registerActionListener(null, new DummyApexEventListener()); + + try { + worker.registerActionListener(null, new DummyApexEventListener()); + fail("test should throw an exception"); + } catch (Exception apEx) { + assertEquals("addEventListener()<-Worker:0.0.1,STOPPED, listenerName is null", apEx.getMessage()); + } worker.registerActionListener("DummyListener", new DummyApexEventListener()); - worker.deregisterActionListener(null); + + try { + worker.deregisterActionListener(null); + fail("test should throw an exception"); + } catch (Exception apEx) { + assertEquals("removeEventListener()<-Worker:0.0.1,STOPPED, listenerName is null", apEx.getMessage()); + } + worker.deregisterActionListener("DummyListener"); try { @@ -308,7 +327,6 @@ public class EngineWorkerTest { apEx.getMessage()); } } - @Test public void testApexImplModelWIthModel() throws ApexException { @@ -322,7 +340,7 @@ public class EngineWorkerTest { } catch (ApexException apEx) { fail("test should not throw an exception"); } - + eventQueue.add(new ApexEvent("SomeEvent", "0.0.1", "the.event.namespace", "EventSource", "EventTarget")); try { @@ -352,7 +370,7 @@ public class EngineWorkerTest { assertEquals(AxEngineState.STOPPED, worker.getState()); worker.startAll(); - + assertEquals(AxEngineState.READY, worker.getState()); String status = worker.getStatus(worker.getEngineKeys().iterator().next()); @@ -425,7 +443,7 @@ public class EngineWorkerTest { } catch (ApexException apEx) { fail("test should not throw an exception"); } - + assertNotNull(worker.getApexModelKey()); } } |