aboutsummaryrefslogtreecommitdiffstats
path: root/core/src/test/java/org
diff options
context:
space:
mode:
Diffstat (limited to 'core/src/test/java/org')
-rw-r--r--core/src/test/java/org/onap/policy/apex/core/engine/EngineParametersTest.java94
-rw-r--r--core/src/test/java/org/onap/policy/apex/core/engine/ExecutorParametersTest.java60
-rw-r--r--core/src/test/java/org/onap/policy/apex/core/engine/context/ApexInternalContextTest.java174
-rw-r--r--core/src/test/java/org/onap/policy/apex/core/engine/engine/impl/ApexEngineImplTest.java521
-rw-r--r--core/src/test/java/org/onap/policy/apex/core/engine/engine/impl/DummyEnEventListener.java40
-rw-r--r--core/src/test/java/org/onap/policy/apex/core/engine/engine/impl/DummyListener.java40
-rw-r--r--core/src/test/java/org/onap/policy/apex/core/engine/engine/impl/DummySlowEnEventListener.java56
-rw-r--r--core/src/test/java/org/onap/policy/apex/core/engine/engine/impl/DummySmExecutor.java85
-rw-r--r--core/src/test/java/org/onap/policy/apex/core/engine/event/DummyAxKey.java131
-rw-r--r--core/src/test/java/org/onap/policy/apex/core/engine/event/EnEventTest.java170
-rw-r--r--core/src/test/java/org/onap/policy/apex/core/engine/event/EnExceptionTest.java41
-rw-r--r--core/src/test/java/org/onap/policy/apex/core/engine/event/EnFieldTest.java93
-rw-r--r--core/src/test/java/org/onap/policy/apex/core/engine/executor/DummyFailingTaskExecutor.java30
-rw-r--r--core/src/test/java/org/onap/policy/apex/core/engine/executor/DummyStateFinalizerExecutor.java65
-rw-r--r--core/src/test/java/org/onap/policy/apex/core/engine/executor/DummyTaskExecutor.java91
-rw-r--r--core/src/test/java/org/onap/policy/apex/core/engine/executor/DummyTaskSelectExecutor.java74
-rw-r--r--core/src/test/java/org/onap/policy/apex/core/engine/executor/StateExecutorTest.java88
-rw-r--r--core/src/test/java/org/onap/policy/apex/core/engine/executor/StateFinalizerExecutorTest.java139
-rw-r--r--core/src/test/java/org/onap/policy/apex/core/engine/executor/StateMachineExecutorTest.java336
-rw-r--r--core/src/test/java/org/onap/policy/apex/core/engine/executor/TaskExecutorTest.java240
-rw-r--r--core/src/test/java/org/onap/policy/apex/core/engine/executor/TaskSelectExecutorTest.java148
-rw-r--r--core/src/test/java/org/onap/policy/apex/core/engine/executor/context/AxStateFacadeTest.java86
-rw-r--r--core/src/test/java/org/onap/policy/apex/core/engine/executor/context/AxTaskFacadeTest.java140
-rw-r--r--core/src/test/java/org/onap/policy/apex/core/engine/executor/context/DummyContextAlbum.java226
-rw-r--r--core/src/test/java/org/onap/policy/apex/core/engine/executor/context/StateFinalizerExecutionContextTest.java109
-rw-r--r--core/src/test/java/org/onap/policy/apex/core/engine/executor/context/TaskExecutionContextTest.java118
-rw-r--r--core/src/test/java/org/onap/policy/apex/core/engine/executor/context/TaskSelectionExecutionContextTest.java109
-rw-r--r--core/src/test/java/org/onap/policy/apex/core/engine/executor/exception/StateMachineRuntimeExceptionTest.java42
-rw-r--r--core/src/test/java/org/onap/policy/apex/core/engine/executor/impl/ExceutorFactoryImplTest.java240
-rw-r--r--core/src/test/java/org/onap/policy/apex/core/infrastructure/threading/ThreadingTest.java86
30 files changed, 3872 insertions, 0 deletions
diff --git a/core/src/test/java/org/onap/policy/apex/core/engine/EngineParametersTest.java b/core/src/test/java/org/onap/policy/apex/core/engine/EngineParametersTest.java
new file mode 100644
index 000000000..5427c3515
--- /dev/null
+++ b/core/src/test/java/org/onap/policy/apex/core/engine/EngineParametersTest.java
@@ -0,0 +1,94 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2020 Nordix Foundation.
+ * Modifications Copyright (C) 2021 AT&T Intellectual Property. 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;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import org.junit.Test;
+import org.onap.policy.apex.context.parameters.ContextParameters;
+import org.onap.policy.common.parameters.ParameterService;
+
+/**
+ * Test the executor parameters.
+ *
+ */
+public class EngineParametersTest {
+
+ @Test
+ public void test() {
+ EngineParameters pars = new EngineParameters();
+ pars.setName("Name");
+ assertEquals("Name", pars.getName());
+
+ ContextParameters contextPars = new ContextParameters();
+
+ pars.setContextParameters(contextPars);
+ assertEquals(contextPars, pars.getContextParameters());
+
+ Map<String, ExecutorParameters> executorParameterMap = new LinkedHashMap<>();
+ executorParameterMap.put("Executor", new ExecutorParameters());
+ pars.setExecutorParameterMap(executorParameterMap);
+ assertEquals(executorParameterMap, pars.getExecutorParameterMap());
+
+ List<TaskParameters> taskParameters = new ArrayList<>();
+ taskParameters.add(new TaskParameters("param1key", "param1value", "param1taskId"));
+ taskParameters.add(new TaskParameters("param1key", "param1value", null));
+ pars.setTaskParameters(taskParameters);
+
+ assertThat(pars.validate().getResult()).isNull();
+ assertTrue(pars.validate().isValid());
+
+ ParameterService.register(pars);
+ ParameterService.deregister(pars);
+ }
+
+ @Test
+ public void test_invalid() {
+ EngineParameters pars = new EngineParameters();
+ pars.setName("Name");
+ assertEquals("Name", pars.getName());
+
+ ContextParameters contextPars = new ContextParameters();
+
+ pars.setContextParameters(contextPars);
+ assertEquals(contextPars, pars.getContextParameters());
+
+ Map<String, ExecutorParameters> executorParameterMap = Map.of("Executor", new ExecutorParameters());
+ pars.setExecutorParameterMap(executorParameterMap);
+ assertEquals(executorParameterMap, pars.getExecutorParameterMap());
+
+ pars.setTaskParameters(List.of(new TaskParameters(null, "param1value", "param1taskId")));
+ assertFalse(pars.validate().isValid());
+ pars.setTaskParameters(List.of(new TaskParameters(" ", "param1value", "param1taskId")));
+ assertFalse(pars.validate().isValid());
+ pars.setTaskParameters(List.of(new TaskParameters("param1key", "", "param1taskId")));
+ assertFalse(pars.validate().isValid());
+ }
+}
diff --git a/core/src/test/java/org/onap/policy/apex/core/engine/ExecutorParametersTest.java b/core/src/test/java/org/onap/policy/apex/core/engine/ExecutorParametersTest.java
new file mode 100644
index 000000000..784580422
--- /dev/null
+++ b/core/src/test/java/org/onap/policy/apex/core/engine/ExecutorParametersTest.java
@@ -0,0 +1,60 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2021 AT&T Intellectual Property. 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;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+import org.onap.policy.common.parameters.ParameterService;
+
+/**
+ * Test the executor parameters.
+ *
+ */
+public class ExecutorParametersTest {
+
+ @Test
+ public void test() {
+ ExecutorParameters pars = new ExecutorParameters();
+ pars.setName("Name");
+ assertEquals("Name", pars.getName());
+ pars.setStateFinalizerExecutorPluginClass("some.state.finalizer.plugin.class");
+ assertEquals("some.state.finalizer.plugin.class", pars.getStateFinalizerExecutorPluginClass());
+ pars.setTaskExecutorPluginClass("some.task.executor.plugin.class");
+ assertEquals("some.task.executor.plugin.class", pars.getTaskExecutorPluginClass());
+ pars.setTaskSelectionExecutorPluginClass("some.task.selection.executor.plugin.class");
+ assertEquals("some.task.selection.executor.plugin.class", pars.getTaskSelectionExecutorPluginClass());
+
+ assertEquals("ExecutorParameters [name=Name, taskExecutorPluginClass=some.task.executor.plugin.class, "
+ + "taskSelectionExecutorPluginClass=some.task.selection.executor.plugin.class, "
+ + "stateFinalizerExecutorPluginClass=some.state.finalizer.plugin.class]", pars.toString());
+
+ assertThat(pars.validate().getResult()).isNull();
+ assertTrue(pars.validate().isValid());
+
+
+ ParameterService.register(pars);
+ ParameterService.deregister(pars);
+ }
+}
diff --git a/core/src/test/java/org/onap/policy/apex/core/engine/context/ApexInternalContextTest.java b/core/src/test/java/org/onap/policy/apex/core/engine/context/ApexInternalContextTest.java
new file mode 100644
index 000000000..19828f6e2
--- /dev/null
+++ b/core/src/test/java/org/onap/policy/apex/core/engine/context/ApexInternalContextTest.java
@@ -0,0 +1,174 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2019-2020 Nordix Foundation.
+ * ================================================================================
+ * 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.context;
+
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.junit.Assert.assertEquals;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onap.policy.apex.context.ContextException;
+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.model.basicmodel.concepts.AxArtifactKey;
+import org.onap.policy.apex.model.contextmodel.concepts.AxContextAlbum;
+import org.onap.policy.apex.model.contextmodel.concepts.AxContextSchema;
+import org.onap.policy.apex.model.policymodel.concepts.AxPolicyModel;
+import org.onap.policy.common.parameters.ParameterService;
+
+/**
+ * Test the Apex engine internal context class.
+ */
+public class ApexInternalContextTest {
+
+ private AxPolicyModel policyModel;
+ private AxPolicyModel newVersionPolicyModel;
+ private AxPolicyModel newPolicyModel;
+ private AxContextAlbum album;
+ private AxContextAlbum newAlbum;
+ private AxPolicyModel incompatiblePolicyModel;
+
+ /**
+ * Initialize parameters.
+ */
+ @Before
+ public void registerParameters() {
+ ParameterService.register(new SchemaParameters());
+ ParameterService.register(new DistributorParameters());
+ ParameterService.register(new LockManagerParameters());
+ ParameterService.register(new PersistorParameters());
+ }
+
+ /**
+ * Create policy model.
+ */
+ @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");
+ album = new AxContextAlbum(albumKey, "Policy", true, schemaKey);
+
+ policyModel.getAlbums().getAlbumsMap().put(albumKey, album);
+
+ AxArtifactKey newVersionModelKey = new AxArtifactKey("PolicyModel:0.0.2");
+ newVersionPolicyModel = new AxPolicyModel(newVersionModelKey);
+
+ newVersionPolicyModel.getSchemas().getSchemasMap().put(schemaKey, schema);
+ AxContextAlbum compatibleAlbum = new AxContextAlbum(albumKey, "Global", true, schemaKey);
+ newVersionPolicyModel.getAlbums().getAlbumsMap().put(albumKey, compatibleAlbum);
+
+ AxArtifactKey anotherAlbumKey = new AxArtifactKey("AnotherAlbum:0.0.1");
+ AxContextAlbum anotherAlbum = new AxContextAlbum(anotherAlbumKey, "Policy", true, schemaKey);
+
+ newVersionPolicyModel.getAlbums().getAlbumsMap().put(anotherAlbumKey, anotherAlbum);
+
+ 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 newModelKey = new AxArtifactKey("NewPolicyModel:0.0.1");
+ newPolicyModel = new AxPolicyModel(newModelKey);
+
+ AxArtifactKey newSchemaKey = new AxArtifactKey("NewSchema:0.0.1");
+ AxContextSchema newSchema = new AxContextSchema(newSchemaKey, "Java", "java.lang.Integer");
+ newPolicyModel.getSchemas().getSchemasMap().put(newSchemaKey, newSchema);
+
+ AxArtifactKey newAlbumKey = new AxArtifactKey("NewAlbum:0.0.1");
+ newAlbum = new AxContextAlbum(newAlbumKey, "Policy", true, newSchemaKey);
+
+ newPolicyModel.getAlbums().getAlbumsMap().put(newAlbumKey, newAlbum);
+ }
+
+ /**
+ * Deregister parameters.
+ */
+ @After
+ public void deregisterParameters() {
+ ParameterService.deregister(ContextParameterConstants.DISTRIBUTOR_GROUP_NAME);
+ ParameterService.deregister(ContextParameterConstants.LOCKING_GROUP_NAME);
+ ParameterService.deregister(ContextParameterConstants.PERSISTENCE_GROUP_NAME);
+ ParameterService.deregister(ContextParameterConstants.SCHEMA_GROUP_NAME);
+ }
+
+ @Test
+ public void testAlbumInit() throws ContextException {
+ assertThatThrownBy(() -> new ApexInternalContext(null))
+ .hasMessage("internal context update failed, supplied model is null");
+ ApexInternalContext context = new ApexInternalContext(policyModel);
+
+ assertEquals(policyModel.getKey(), context.getKey());
+ assertEquals(1, context.getContextAlbums().size());
+
+ AxArtifactKey albumKey = new AxArtifactKey("Album:0.0.1");
+ assertEquals(album.getId(), context.get(albumKey).getKey().getId());
+ assertEquals(album.getId(), context.get(albumKey.getName()).getKey().getId());
+ assertEquals(album.getId(), context.get(albumKey.getName(), albumKey.getVersion()).getKey().getId());
+ assertEquals(album.getId(), context.getAll(albumKey.getName()).iterator().next().getKey().getId());
+ assertEquals(album.getId(),
+ context.getAll(albumKey.getName(), albumKey.getVersion()).iterator().next().getKey().getId());
+
+ context.clear();
+ assertEquals(1, context.getContextAlbums().size());
+
+ assertEquals("ApexInternalContext [contextAlbums={AxArtifactKey:(name=Album,version=0.0.1)",
+ context.toString().substring(0, 76));
+ }
+
+ @Test
+ public void testAlbumUpdate() throws ContextException {
+ ApexInternalContext context = new ApexInternalContext(policyModel);
+ assertThatThrownBy(() -> context.update(null, false))
+ .hasMessage("internal context update failed, supplied model is null");
+
+ assertEquals(policyModel.getKey().getId(), context.getKey().getId());
+ assertEquals(1, context.getContextAlbums().size());
+
+ assertThatThrownBy(() -> context.update(incompatiblePolicyModel, false)).hasMessage(
+ "internal context update failed on context album \"Album:0.0.1\" " + "in model \"PolicyModel:0.0.1\", "
+ + "schema \"Schema:0.0.1\" on existing context model does not equal "
+ + "schema \"IncompatibleSchema:0.0.1\" on incoming model");
+
+ assertEquals(policyModel.getKey().getId(), context.getKey().getId());
+
+ context.update(newVersionPolicyModel, false);
+ assertEquals(newVersionPolicyModel.getKey().getId(), context.getKey().getId());
+
+ context.update(newPolicyModel, true);
+ assertEquals(newPolicyModel.getKey().getId(), context.getKey().getId());
+ }
+}
diff --git a/core/src/test/java/org/onap/policy/apex/core/engine/engine/impl/ApexEngineImplTest.java b/core/src/test/java/org/onap/policy/apex/core/engine/engine/impl/ApexEngineImplTest.java
new file mode 100644
index 000000000..3b682acd6
--- /dev/null
+++ b/core/src/test/java/org/onap/policy/apex/core/engine/engine/impl/ApexEngineImplTest.java
@@ -0,0 +1,521 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2019-2021 Nordix Foundation.
+ * Modifications Copyright (C) 2021 AT&T Intellectual Property. 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.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.awaitility.Awaitility.await;
+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 io.prometheus.client.CollectorRegistry;
+import java.io.IOException;
+import java.lang.reflect.Field;
+import java.util.HashMap;
+import java.util.concurrent.TimeUnit;
+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.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 static final String ENGINE_ID = "Engine:0.0.1";
+
+ 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() throws ApexException {
+ AxArtifactKey engineKey = new AxArtifactKey(ENGINE_ID);
+ ApexEngineImpl engine = (ApexEngineImpl) new ApexEngineFactory().createApexEngine(engineKey);
+ assertNotNull(engine);
+ assertEquals(engineKey, engine.getKey());
+
+ assertThatThrownBy(engine::start).hasMessage("start()<-Engine:0.0.1,STOPPED, cannot start engine, "
+ + "engine has not been initialized, its model is not loaded");
+
+ assertThatThrownBy(engine::stop)
+ .hasMessage("stop()<-Engine:0.0.1,STOPPED, cannot stop engine, " + "engine is already stopped");
+
+ assertEquals(AxEngineState.STOPPED, engine.getState());
+ checkAxEngineStateMetric(AxEngineState.STOPPED);
+ assertEquals(0, engine.getEngineContext().size());
+ assertEquals(engineKey, engine.getEngineStatus().getKey());
+ assertNull(engine.getInternalContext());
+
+ engine.clear();
+
+ assertThatThrownBy(() -> engine.addEventListener(null, null))
+ .hasMessage("addEventListener()<-Engine:0.0.1,STOPPED, listenerName is null");
+
+ assertThatThrownBy(() -> engine.addEventListener("myListener", null))
+ .hasMessage("addEventListener()<-Engine:0.0.1,STOPPED, listener is null");
+
+ assertThatThrownBy(() -> engine.removeEventListener(null))
+ .hasMessage("removeEventListener()<-Engine:0.0.1,STOPPED, listenerName is null");
+ }
+
+ @Test
+ public void testListener() throws ApexException {
+ AxArtifactKey engineKey = new AxArtifactKey(ENGINE_ID);
+ ApexEngineImpl engine = (ApexEngineImpl) new ApexEngineFactory().createApexEngine(engineKey);
+
+ engine.addEventListener("myListener", new DummyListener());
+ engine.removeEventListener("myListener");
+
+ assertNull(engine.createEvent(null));
+
+ assertFalse(engine.handleEvent(null));
+
+ assertThatThrownBy(() -> engine.updateModel(null, false))
+ .hasMessage("updateModel()<-Engine:0.0.1, Apex model is not defined, it has a null value");
+
+ engine.updateModel(policyModel, false);
+
+ // Force a context exception
+ ModelService.registerModel(AxPolicyModel.class, new AxPolicyModel());
+ assertThatThrownBy(() -> engine.updateModel(incompatiblePolicyModel, false))
+ .hasMessage("updateModel()<-Engine:0.0.1, error setting the context for engine \"Engine:0.0.1\"");
+
+ engine.updateModel(policyModel, false);
+
+ assertNotNull(engine.getInternalContext());
+ assertEquals(1, engine.getEngineContext().size());
+
+ engine.start();
+ assertEquals(AxEngineState.READY, engine.getState());
+ checkAxEngineStateMetric(AxEngineState.READY);
+
+ assertThatThrownBy(engine::start)
+ .hasMessage("start()<-Engine:0.0.1,READY, cannot start engine, engine not in state STOPPED");
+
+ assertThatThrownBy(engine::clear)
+ .hasMessage("clear()<-Engine:0.0.1,READY, cannot clear engine, engine is not stopped");
+
+ engine.stop();
+ assertEquals(AxEngineState.STOPPED, engine.getState());
+ checkAxEngineStateMetric(AxEngineState.STOPPED);
+
+ engine.clear();
+ assertEquals(AxEngineState.STOPPED, engine.getState());
+ checkAxEngineStateMetric(AxEngineState.STOPPED);
+
+ assertThatThrownBy(engine::start).hasMessage("start()<-Engine:0.0.1,STOPPED, cannot start engine, "
+ + "engine has not been initialized, its model is not loaded");
+
+ engine.updateModel(policyModel, false);
+ assertEquals(AxEngineState.STOPPED, engine.getState());
+ checkAxEngineStateMetric(AxEngineState.STOPPED);
+
+ engine.start();
+ assertEquals(AxEngineState.READY, engine.getState());
+ checkAxEngineStateMetric(AxEngineState.READY);
+
+ assertNull(engine.createEvent(null));
+ }
+
+ @Test
+ public void testEventKey() throws ApexException {
+ AxArtifactKey engineKey = new AxArtifactKey(ENGINE_ID);
+ ApexEngineImpl engine = (ApexEngineImpl) new ApexEngineFactory().createApexEngine(engineKey);
+ engine.updateModel(policyModel, false);
+ engine.start();
+
+ 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());
+ checkAxEngineStateMetric(AxEngineState.READY);
+
+ engine.stop();
+ assertEquals(AxEngineState.STOPPED, engine.getState());
+ checkAxEngineStateMetric(AxEngineState.STOPPED);
+
+ engine.addEventListener("myListener", new DummyListener());
+
+ engine.start();
+ assertEquals(AxEngineState.READY, engine.getState());
+ checkAxEngineStateMetric(AxEngineState.READY);
+
+ assertThatThrownBy(() -> engine.updateModel(policyModel, false)).hasMessage(
+ "updateModel()<-Engine:0.0.1, cannot update model, engine should be stopped but is in state READY");
+
+ assertTrue(engine.handleEvent(event));
+ assertEquals(AxEngineState.READY, engine.getState());
+ checkAxEngineStateMetric(AxEngineState.READY);
+
+ engine.stop();
+ assertEquals(AxEngineState.STOPPED, engine.getState());
+ checkAxEngineStateMetric(AxEngineState.STOPPED);
+
+ engine.addEventListener("badListener", new DummyEnEventListener());
+
+ engine.start();
+ assertEquals(AxEngineState.READY, engine.getState());
+ checkAxEngineStateMetric(AxEngineState.READY);
+
+ assertFalse(engine.handleEvent(event));
+ assertEquals(AxEngineState.READY, engine.getState());
+ checkAxEngineStateMetric(AxEngineState.READY);
+ engine.stop();
+ assertEquals(AxEngineState.STOPPED, engine.getState());
+ checkAxEngineStateMetric(AxEngineState.STOPPED);
+
+ engine.removeEventListener("badListener");
+ engine.addEventListener("slowListener", new DummySlowEnEventListener());
+ }
+
+ @Test
+ public void testState() throws InterruptedException, ApexException {
+ AxArtifactKey engineKey = new AxArtifactKey(ENGINE_ID);
+ ApexEngineImpl engine = (ApexEngineImpl) new ApexEngineFactory().createApexEngine(engineKey);
+ assertNotNull(engine);
+ assertEquals(engineKey, engine.getKey());
+
+ engine.updateModel(policyModel, false);
+ assertEquals(AxEngineState.STOPPED, engine.getState());
+ checkAxEngineStateMetric(AxEngineState.STOPPED);
+
+ DummySlowEnEventListener slowListener = new DummySlowEnEventListener();
+ engine.addEventListener("slowListener", slowListener);
+
+ engine.start();
+ assertEquals(AxEngineState.READY, engine.getState());
+ checkAxEngineStateMetric(AxEngineState.READY);
+
+ assertEquals(AxEngineState.READY, engine.getState());
+ checkAxEngineStateMetric(AxEngineState.READY);
+
+ 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() {
+ @Override
+ public void run() {
+ engine.handleEvent(event);
+ }
+ }).start();
+ await().atLeast(50, TimeUnit.MILLISECONDS).until(() -> engine.getState().equals(AxEngineState.EXECUTING));
+ assertEquals(AxEngineState.EXECUTING, engine.getState());
+ checkAxEngineStateMetric(AxEngineState.EXECUTING);
+
+ assertFalse(engine.handleEvent(event));
+ assertNotNull(engine.createEvent(eventKey));
+
+ engine.stop();
+ assertEquals(AxEngineState.STOPPED, engine.getState());
+ checkAxEngineStateMetric(AxEngineState.STOPPED);
+
+ engine.start();
+ assertEquals(AxEngineState.READY, engine.getState());
+ checkAxEngineStateMetric(AxEngineState.READY);
+
+ // 4 seconds is more than the 3 second wait on engine stopping
+ slowListener.setWaitTime(4000);
+ (new Thread() {
+ @Override
+ public void run() {
+ engine.handleEvent(event);
+ }
+ }).start();
+
+ await().atLeast(50, TimeUnit.MILLISECONDS).until(() -> engine.getState().equals(AxEngineState.EXECUTING));
+ assertEquals(AxEngineState.EXECUTING, engine.getState());
+ checkAxEngineStateMetric(AxEngineState.EXECUTING);
+ assertThatThrownBy(engine::stop)
+ .hasMessage("stop()<-Engine:0.0.1,STOPPED, error stopping engine, engine stop timed out");
+ assertEquals(AxEngineState.STOPPED, engine.getState());
+ checkAxEngineStateMetric(AxEngineState.STOPPED);
+ engine.clear();
+ assertEquals(AxEngineState.STOPPED, engine.getState());
+ checkAxEngineStateMetric(AxEngineState.STOPPED);
+ }
+
+ @Test
+ public void testStateMachineError() throws InterruptedException, IllegalArgumentException, IllegalAccessException,
+ NoSuchFieldException, SecurityException, ApexException {
+
+ AxArtifactKey engineKey = new AxArtifactKey(ENGINE_ID);
+ ApexEngineImpl engine = (ApexEngineImpl) new ApexEngineFactory().createApexEngine(engineKey);
+ assertNotNull(engine);
+ assertEquals(engineKey, engine.getKey());
+
+ engine.updateModel(policyModel, false);
+ assertEquals(AxEngineState.STOPPED, engine.getState());
+ checkAxEngineStateMetric(AxEngineState.STOPPED);
+
+ final Field smHandlerField = engine.getClass().getDeclaredField("stateMachineHandler");
+ smHandlerField.setAccessible(true);
+ smHandlerField.set(engine, smHandlerMock);
+
+ engine.start();
+ assertEquals(AxEngineState.READY, engine.getState());
+ checkAxEngineStateMetric(AxEngineState.READY);
+
+ assertEquals(AxEngineState.READY, engine.getState());
+ checkAxEngineStateMetric(AxEngineState.READY);
+
+ 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());
+ checkAxEngineStateMetric(AxEngineState.READY);
+
+ engine.stop();
+ assertEquals(AxEngineState.STOPPED, engine.getState());
+ checkAxEngineStateMetric(AxEngineState.STOPPED);
+ Mockito.doThrow(new StateMachineException("mocked state machine exception",
+ new IOException("nexted exception"))).when(smHandlerMock).start();
+ assertThatThrownBy(engine::start).hasMessage("updateModel()<-Engine:0.0.1, error starting the engine state "
+ + "machines \"Engine:0.0.1\"");
+ assertEquals(AxEngineState.STOPPED, engine.getState());
+ checkAxEngineStateMetric(AxEngineState.STOPPED);
+
+ engine.clear();
+ assertEquals(AxEngineState.STOPPED, engine.getState());
+ checkAxEngineStateMetric(AxEngineState.STOPPED);
+ }
+
+ @Test
+ public void testStateMachineHandler() throws InterruptedException, IllegalArgumentException, IllegalAccessException,
+ NoSuchFieldException, SecurityException, ApexException {
+ AxArtifactKey engineKey = new AxArtifactKey(ENGINE_ID);
+ ApexEngineImpl engine = (ApexEngineImpl) new ApexEngineFactory().createApexEngine(engineKey);
+ assertNotNull(engine);
+ assertEquals(engineKey, engine.getKey());
+
+ engine.updateModel(policyModelWithStates, false);
+ assertEquals(AxEngineState.STOPPED, engine.getState());
+ checkAxEngineStateMetric(AxEngineState.STOPPED);
+
+ engine.start();
+ assertEquals(AxEngineState.READY, engine.getState());
+ checkAxEngineStateMetric(AxEngineState.READY);
+
+ AxArtifactKey eventKey = new AxArtifactKey("Event:0.0.1");
+ EnEvent event = engine.createEvent(eventKey);
+ assertEquals(eventKey, event.getKey());
+
+ engine.stop();
+ assertEquals(AxEngineState.STOPPED, engine.getState());
+ checkAxEngineStateMetric(AxEngineState.STOPPED);
+
+ assertEquals(AxEngineState.STOPPED, engine.getState());
+ checkAxEngineStateMetric(AxEngineState.STOPPED);
+
+ engine.start();
+ assertEquals(AxEngineState.READY, engine.getState());
+ checkAxEngineStateMetric(AxEngineState.READY);
+
+ assertEquals(AxEngineState.READY, engine.getState());
+ checkAxEngineStateMetric(AxEngineState.READY);
+
+ // Can't work, state is not fully defined
+ assertFalse(engine.handleEvent(event));
+ assertEquals(AxEngineState.READY, engine.getState());
+ checkAxEngineStateMetric(AxEngineState.READY);
+
+ 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);
+ ApexInternalContext internalContext = new ApexInternalContext(policyModelWithStates);
+ assertThatThrownBy(() -> dummyExecutor.setContext(null, null, internalContext))
+ .isInstanceOf(NullPointerException.class);
+
+ engine.stop();
+ assertEquals(AxEngineState.STOPPED, engine.getState());
+ checkAxEngineStateMetric(AxEngineState.STOPPED);
+
+ assertThatThrownBy(engine::start).hasMessageContaining("updateModel()<-Engine:0.0.1, error starting the "
+ + "engine state machines \"Engine:0.0.1\"");
+ assertEquals(AxEngineState.STOPPED, engine.getState());
+ checkAxEngineStateMetric(AxEngineState.STOPPED);
+
+ engine.start();
+ assertEquals(AxEngineState.READY, engine.getState());
+ checkAxEngineStateMetric(AxEngineState.READY);
+
+ // Works, Dummy executor fakes event execution
+ assertTrue(engine.handleEvent(event));
+ assertEquals(AxEngineState.READY, engine.getState());
+ checkAxEngineStateMetric(AxEngineState.READY);
+
+ engine.stop();
+ assertEquals(AxEngineState.STOPPED, engine.getState());
+ checkAxEngineStateMetric(AxEngineState.STOPPED);
+
+ engine.clear();
+ assertEquals(AxEngineState.STOPPED, engine.getState());
+ checkAxEngineStateMetric(AxEngineState.STOPPED);
+ }
+
+ private void checkAxEngineStateMetric(AxEngineState state) {
+ Double stateMetric = CollectorRegistry.defaultRegistry
+ .getSampleValue("pdpa_engine_state", new String[]{"engine_instance_id"}, new String[]{ENGINE_ID});
+ assertEquals(stateMetric.intValue(), state.getStateIdentifier());
+ }
+} \ No newline at end of file
diff --git a/core/src/test/java/org/onap/policy/apex/core/engine/engine/impl/DummyEnEventListener.java b/core/src/test/java/org/onap/policy/apex/core/engine/engine/impl/DummyEnEventListener.java
new file mode 100644
index 000000000..b429295ad
--- /dev/null
+++ b/core/src/test/java/org/onap/policy/apex/core/engine/engine/impl/DummyEnEventListener.java
@@ -0,0 +1,40 @@
+/*-
+ * ============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 DummyEnEventListener implements EnEventListener {
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public void onEnEvent(EnEvent enEvent) throws ApexException {
+ throw new ApexException("not implemented on dummy class");
+ }
+}
diff --git a/core/src/test/java/org/onap/policy/apex/core/engine/engine/impl/DummyListener.java b/core/src/test/java/org/onap/policy/apex/core/engine/engine/impl/DummyListener.java
new file mode 100644
index 000000000..6256ff498
--- /dev/null
+++ b/core/src/test/java/org/onap/policy/apex/core/engine/engine/impl/DummyListener.java
@@ -0,0 +1,40 @@
+/*-
+ * ============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 {
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public void onEnEvent(EnEvent enEvent) throws ApexException {
+ // Do nothing
+ }
+}
diff --git a/core/src/test/java/org/onap/policy/apex/core/engine/engine/impl/DummySlowEnEventListener.java b/core/src/test/java/org/onap/policy/apex/core/engine/engine/impl/DummySlowEnEventListener.java
new file mode 100644
index 000000000..e794a7d04
--- /dev/null
+++ b/core/src/test/java/org/onap/policy/apex/core/engine/engine/impl/DummySlowEnEventListener.java
@@ -0,0 +1,56 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2019-2021 Nordix Foundation.
+ * ================================================================================
+ * 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.
+ * Thread.sleep is used to simulate a slow event listener.
+ *
+ */
+public class DummySlowEnEventListener implements EnEventListener {
+
+ private long waitTime;
+
+ /**
+ * {@inheritDoc}.
+ */
+ @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/src/test/java/org/onap/policy/apex/core/engine/engine/impl/DummySmExecutor.java b/core/src/test/java/org/onap/policy/apex/core/engine/engine/impl/DummySmExecutor.java
new file mode 100644
index 000000000..df4d9279e
--- /dev/null
+++ b/core/src/test/java/org/onap/policy/apex/core/engine/engine/impl/DummySmExecutor.java
@@ -0,0 +1,85 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2019 Nordix Foundation.
+ * Modifications Copyright (C) 2021 Bell Canada. 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 java.util.Collection;
+import java.util.List;
+import java.util.Properties;
+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);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public void prepare() throws StateMachineException {
+ if (prepareWorks) {
+ prepareWorks = false;
+ } else {
+ prepareWorks = true;
+ throw new StateMachineException("dummy state machine executor exception");
+ }
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public Collection<EnEvent> execute(final long executionId, final Properties executionProperties,
+ final EnEvent incomingEvent) {
+ return List.of(incomingEvent);
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @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/src/test/java/org/onap/policy/apex/core/engine/event/DummyAxKey.java b/core/src/test/java/org/onap/policy/apex/core/engine/event/DummyAxKey.java
new file mode 100644
index 000000000..eafa7f419
--- /dev/null
+++ b/core/src/test/java/org/onap/policy/apex/core/engine/event/DummyAxKey.java
@@ -0,0 +1,131 @@
+/*-
+ * ============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.event;
+
+import java.util.List;
+import org.apache.commons.lang3.NotImplementedException;
+import org.onap.policy.apex.model.basicmodel.concepts.AxConcept;
+import org.onap.policy.apex.model.basicmodel.concepts.AxKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult;
+
+/**
+ * Dummy Key Class.
+ */
+public class DummyAxKey extends AxKey {
+ private static final long serialVersionUID = 964899169013353800L;
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public int compareTo(AxConcept concept) {
+ throw new NotImplementedException("Not implemented on dummy class");
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public String getId() {
+ throw new NotImplementedException("Not implemented on dummy class");
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public Compatibility getCompatibility(AxKey otherKey) {
+ throw new NotImplementedException("Not implemented on dummy class");
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public boolean isCompatible(AxKey otherKey) {
+ throw new NotImplementedException("Not implemented on dummy class");
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public AxKey getKey() {
+ throw new NotImplementedException("Not implemented on dummy class");
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public List<AxKey> getKeys() {
+ throw new NotImplementedException("Not implemented on dummy class");
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public AxValidationResult validate(AxValidationResult result) {
+ throw new NotImplementedException("Not implemented on dummy class");
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public void clean() {
+ throw new NotImplementedException("Not implemented on dummy class");
+
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public boolean equals(Object otherObject) {
+ throw new NotImplementedException("Not implemented on dummy class");
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public String toString() {
+ return "Dummy Key";
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public int hashCode() {
+ throw new NotImplementedException("Not implemented on dummy class");
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public AxConcept copyTo(AxConcept target) {
+ throw new NotImplementedException("Not implemented on dummy class");
+ }
+}
diff --git a/core/src/test/java/org/onap/policy/apex/core/engine/event/EnEventTest.java b/core/src/test/java/org/onap/policy/apex/core/engine/event/EnEventTest.java
new file mode 100644
index 000000000..49b4f80d2
--- /dev/null
+++ b/core/src/test/java/org/onap/policy/apex/core/engine/event/EnEventTest.java
@@ -0,0 +1,170 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2020-2021 Nordix Foundation
+ * Modifications Copyright (C) 2022 Bell Canada. 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.event;
+
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+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.AxConcept;
+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.common.parameters.ParameterService;
+
+/**
+ * Test the engine event class.
+ */
+public class EnEventTest {
+ /**
+ * Set up the services.
+ */
+ @Before
+ public void setupServices() {
+ ModelService.registerModel(AxContextSchemas.class, new AxContextSchemas());
+ ModelService.registerModel(AxEvents.class, new AxEvents());
+ ParameterService.register(new SchemaParameters());
+ }
+
+ /**
+ * Tear down the services.
+ */
+ @After
+ public void teardownServices() {
+ ModelService.deregisterModel(AxContextSchema.class);
+ ModelService.deregisterModel(AxEvents.class);
+ ParameterService.deregister(ContextParameterConstants.SCHEMA_GROUP_NAME);
+ }
+
+ @Test
+ public void testEnEvent() {
+ AxArtifactKey eventKey = new AxArtifactKey("Event:0.0.1");
+ assertThatThrownBy(() -> new EnEvent(eventKey))
+ .hasMessage("event definition is null or was not found in model service");
+ assertThatThrownBy(() -> new EnEvent((AxEvent) null))
+ .hasMessage("event definition is null or was not found in model service");
+ AxEvent axEvent = new AxEvent(eventKey, "a.name.space", "some source", "some target");
+ ModelService.getModel(AxEvents.class).getEventMap().put(eventKey, axEvent);
+
+ EnEvent event = new EnEvent(eventKey);
+ assertEquals(eventKey, event.getKey());
+ assertEquals("Event:0.0.1", event.getId());
+ assertEquals("Event", event.getName());
+ assertEquals(axEvent, event.getAxEvent());
+ event.setExecutionId(123454321L);
+ assertEquals(123454321L, event.getExecutionId());
+ event.setExceptionMessage("Something happened");
+ assertEquals("Something happened", event.getExceptionMessage());
+ AxConcept[] usedArtifactStackArray =
+ { eventKey };
+ event.setUserArtifactStack(usedArtifactStackArray);
+ assertEquals(usedArtifactStackArray.length, event.getUserArtifactStack().length);
+ assertEquals("EnEvent [axEvent=AxEvent:(key=AxArtifactKey:(name=Event,version=0.0.1),nameSpace=a.name.space,"
+ + "source=some source,target=some target,parameter={},toscaPolicyState=), "
+ + "userArtifactStack=[AxArtifactKey:(name=Event,version=0.0.1)], map={}]", event.toString());
+ assertThatThrownBy(() -> event.put(null, null))
+ .hasMessage("null keys are illegal on method parameter \"key\"");
+ assertThatThrownBy(() -> event.put("NonField", null))
+ .hasMessage("parameter with key \"NonField\" not defined on event \"Event\"");
+ }
+
+ @Test
+ public void testAxEvent() {
+ AxArtifactKey eventKey = new AxArtifactKey("Event:0.0.1");
+ AxEvent axEvent = new AxEvent(eventKey, "a.name.space", "some source", "some target");
+ ModelService.getModel(AxEvents.class).getEventMap().put(eventKey, axEvent);
+ EnEvent event = new EnEvent(eventKey);
+
+ AxReferenceKey fieldKey = new AxReferenceKey("Parent", "0.0.1", "MyParent", "MyField");
+ AxArtifactKey fieldSchemaKey = new AxArtifactKey("FieldSchema:0.0.1");
+ AxField axField = new AxField(fieldKey, fieldSchemaKey);
+
+ AxConcept[] usedArtifactStackArrayMultiple =
+ { eventKey, fieldKey, new DummyAxKey() };
+ event.setUserArtifactStack(usedArtifactStackArrayMultiple);
+
+ AxContextSchema schema = new AxContextSchema(fieldSchemaKey, "Java", "java.lang.Integer");
+ ModelService.getModel(AxContextSchemas.class).getSchemasMap().put(fieldSchemaKey, schema);
+
+ Map<String, AxField> parameterMap = new LinkedHashMap<>();
+ parameterMap.put("MyField", axField);
+ ModelService.getModel(AxEvents.class).get(eventKey).setParameterMap(parameterMap);
+
+ event.put("MyField", null);
+ assertNull(event.get("MyField"));
+
+ assertThatThrownBy(() -> event.put("MyField", "Hello"))
+ .hasMessage("Parent:0.0.1:MyParent:MyField: object \"Hello\" of class \"java.lang.String\" "
+ + "not compatible with class \"java.lang.Integer\"");
+ event.put("MyField", 123);
+ assertEquals(123, event.get("MyField"));
+
+ assertTrue(event.keySet().contains("MyField"));
+ assertTrue(event.values().contains(123));
+ assertEquals("MyField", event.entrySet().iterator().next().getKey());
+
+ event.putAll(event);
+
+ assertThatThrownBy(() -> event.get(null))
+ .hasMessage("null values are illegal on method parameter \"key\"");
+ assertThatThrownBy(() -> event.get("NonField"))
+ .hasMessage("parameter with key NonField not defined on this event");
+ assertThatThrownBy(() -> event.remove(null))
+ .hasMessage("null keys are illegal on method parameter \"key\"");
+ assertThatThrownBy(() -> event.remove("NonField"))
+ .hasMessage("parameter with key NonField not defined on this event");
+ event.remove("MyField");
+ assertNull(event.get("MyField"));
+
+ event.put("MyField", 123);
+ assertEquals(123, event.get("MyField"));
+ event.clear();
+ assertNull(event.get("MyField"));
+
+ assertNotEquals(0, event.hashCode());
+ // disabling sonar because this code tests the equals() method
+ assertEquals(event, event); // NOSONAR
+ assertNotNull(event);
+ Map<String, Object> hashMap = new HashMap<>();
+ assertNotEquals(event, hashMap);
+
+ EnEvent otherEvent = new EnEvent(eventKey);
+ assertEquals(event, otherEvent);
+ }
+} \ No newline at end of file
diff --git a/core/src/test/java/org/onap/policy/apex/core/engine/event/EnExceptionTest.java b/core/src/test/java/org/onap/policy/apex/core/engine/event/EnExceptionTest.java
new file mode 100644
index 000000000..5ca49e479
--- /dev/null
+++ b/core/src/test/java/org/onap/policy/apex/core/engine/event/EnExceptionTest.java
@@ -0,0 +1,41 @@
+/*-
+ * ============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.event;
+
+import static org.junit.Assert.assertEquals;
+
+import java.io.IOException;
+import org.junit.Test;
+
+/**
+ * Test the event exception class.
+ */
+public class EnExceptionTest {
+
+ @Test
+ public void testEnException() {
+ EnException ene = new EnException("Message");
+ assertEquals("Message", ene.getMessage());
+
+ ene = new EnException("Message", new IOException());
+ assertEquals("Message", ene.getMessage());
+ }
+}
diff --git a/core/src/test/java/org/onap/policy/apex/core/engine/event/EnFieldTest.java b/core/src/test/java/org/onap/policy/apex/core/engine/event/EnFieldTest.java
new file mode 100644
index 000000000..dbe2fa3c8
--- /dev/null
+++ b/core/src/test/java/org/onap/policy/apex/core/engine/event/EnFieldTest.java
@@ -0,0 +1,93 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2020 Nordix Foundation
+ * ================================================================================
+ * 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.event;
+
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+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.AxField;
+import org.onap.policy.common.parameters.ParameterService;
+
+/**
+ * Test the EnField class.
+ */
+public class EnFieldTest {
+ /**
+ * Set up the services.
+ */
+ @Before
+ public void setupServices() {
+ AxContextSchemas schemas = new AxContextSchemas();
+ ModelService.registerModel(AxContextSchemas.class, schemas);
+ ParameterService.register(new SchemaParameters());
+ }
+
+ /**
+ * Tear down the services.
+ */
+ @After
+ public void teardownServices() {
+ ModelService.deregisterModel(AxContextSchemas.class);
+ ParameterService.deregister(ContextParameterConstants.SCHEMA_GROUP_NAME);
+ }
+
+ @Test
+ public void testEnField() {
+ AxReferenceKey fieldKey = new AxReferenceKey("Parent", "0.0.1", "MyParent", "MyField");
+ AxArtifactKey fieldSchemaKey = new AxArtifactKey("FieldSchema:0.0.1");
+ AxField axField = new AxField(fieldKey, fieldSchemaKey);
+
+ assertThatThrownBy(() -> new EnField(axField, null))
+ .hasMessage("schema helper cannot be created for parameter with key \"Parent:0.0.1:MyParent:My"
+ + "Field\" with schema \"AxArtifactKey:(name=FieldSchema,version=0.0.1)\"");
+ AxContextSchema schema = new AxContextSchema(fieldSchemaKey, "Java", "java.lang.Integer");
+ ModelService.getModel(AxContextSchemas.class).getSchemasMap().put(fieldSchemaKey, schema);
+ EnField field = new EnField(axField, 123);
+
+ assertEquals(axField, field.getAxField());
+ assertEquals(123, field.getValue());
+ assertEquals(fieldKey, field.getKey());
+ assertEquals("MyField", field.getName());
+ assertEquals("org.onap.policy.apex.context.impl.schema.java.JavaSchemaHelper",
+ field.getSchemaHelper().getClass().getName());
+ assertEquals(123, field.getAssignableValue());
+ assertEquals("EnField [axField=AxField:(key=AxReferenceKey:(parentKeyName=Parent,parentKeyVersion=0.0.1,"
+ + "parentLocalName=MyParent,localName=MyField),fieldSchemaKey=AxArtifactKey:"
+ + "(name=FieldSchema,version=0.0.1),optional=false), value=123]", field.toString());
+ assertTrue(field.isAssignableValue());
+
+ field = new EnField(axField, "Hello");
+ assertFalse(field.isAssignableValue());
+ }
+}
diff --git a/core/src/test/java/org/onap/policy/apex/core/engine/executor/DummyFailingTaskExecutor.java b/core/src/test/java/org/onap/policy/apex/core/engine/executor/DummyFailingTaskExecutor.java
new file mode 100644
index 000000000..4d4fb639f
--- /dev/null
+++ b/core/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/src/test/java/org/onap/policy/apex/core/engine/executor/DummyStateFinalizerExecutor.java b/core/src/test/java/org/onap/policy/apex/core/engine/executor/DummyStateFinalizerExecutor.java
new file mode 100644
index 000000000..e4e3ddf0d
--- /dev/null
+++ b/core/src/test/java/org/onap/policy/apex/core/engine/executor/DummyStateFinalizerExecutor.java
@@ -0,0 +1,65 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2019 Nordix Foundation.
+ * Modifications Copyright (C) 2021 AT&T Intellectual Property. 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 java.util.Properties;
+import lombok.NoArgsConstructor;
+import org.onap.policy.apex.context.ContextException;
+import org.onap.policy.apex.core.engine.executor.exception.StateMachineException;
+
+/**
+ * Dummy state finalizer executor for testing.
+ */
+@NoArgsConstructor
+public class DummyStateFinalizerExecutor extends StateFinalizerExecutor {
+ private boolean override;
+
+ private boolean returnBad;
+
+ public DummyStateFinalizerExecutor(final boolean override) {
+ this.override = override;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public String execute(final long executionId, final Properties executionProperties,
+ final Map<String, Object> newIncomingFields) throws StateMachineException, ContextException {
+
+ if (!override) {
+ super.execute(executionId, executionProperties, newIncomingFields);
+ }
+
+ if (returnBad) {
+ return "stateOutputBad";
+ } else {
+ return "stateOutput1";
+ }
+ }
+
+ public void setReturnBad(boolean returnBad) {
+ this.returnBad = returnBad;
+ }
+}
diff --git a/core/src/test/java/org/onap/policy/apex/core/engine/executor/DummyTaskExecutor.java b/core/src/test/java/org/onap/policy/apex/core/engine/executor/DummyTaskExecutor.java
new file mode 100644
index 000000000..8172eefcc
--- /dev/null
+++ b/core/src/test/java/org/onap/policy/apex/core/engine/executor/DummyTaskExecutor.java
@@ -0,0 +1,91 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2019-2020 Nordix Foundation.
+ * Modifications Copyright (C) 2021 Bell Canada. All rights reserved.
+ * Modifications Copyright (C) 2021 AT&T Intellectual Property. 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 java.util.Properties;
+import lombok.AllArgsConstructor;
+import lombok.NoArgsConstructor;
+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.eventmodel.concepts.AxEvent;
+import org.onap.policy.apex.model.policymodel.concepts.AxTask;
+
+/**
+ * Dummy task executor for testing.
+ */
+@NoArgsConstructor
+@AllArgsConstructor
+public class DummyTaskExecutor extends TaskExecutor {
+ private static final String EVENT_KEY = "Event1:0.0.1";
+ private boolean override;
+
+ @Override
+ public void prepare() throws StateMachineException {
+ if (!override) {
+ super.prepare();
+ }
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public Map<String, Map<String, Object>> execute(final long executionId, final Properties executionProperties,
+ final Map<String, Object> newIncomingFields) throws StateMachineException, ContextException {
+ if (!override) {
+ super.execute(executionId, executionProperties, newIncomingFields);
+ }
+
+ AxArtifactKey eventKey = new AxArtifactKey(EVENT_KEY);
+ return Map.of(eventKey.getName(), new EnEvent(eventKey));
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public AxTask getSubject() {
+ if (!override) {
+ return super.getSubject();
+ }
+
+ AxArtifactKey taskKey = new AxArtifactKey("FirstTask:0.0.1");
+ AxTask task = new AxTask(taskKey);
+ task.setOutputEvents(Map.of("Event1", new AxEvent(new AxArtifactKey(EVENT_KEY))));
+ return task;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public void cleanUp() throws StateMachineException {
+ if (!override) {
+ super.cleanUp();
+ }
+ }
+}
diff --git a/core/src/test/java/org/onap/policy/apex/core/engine/executor/DummyTaskSelectExecutor.java b/core/src/test/java/org/onap/policy/apex/core/engine/executor/DummyTaskSelectExecutor.java
new file mode 100644
index 000000000..a5525ac83
--- /dev/null
+++ b/core/src/test/java/org/onap/policy/apex/core/engine/executor/DummyTaskSelectExecutor.java
@@ -0,0 +1,74 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2019 Nordix Foundation.
+ * Modifications Copyright (C) 2021 AT&T Intellectual Property. 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.Properties;
+import lombok.AllArgsConstructor;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+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.
+ */
+@NoArgsConstructor
+@AllArgsConstructor
+public class DummyTaskSelectExecutor extends TaskSelectExecutor {
+ private boolean override;
+
+ @Setter
+ private static int taskNo;
+
+ @Override
+ public void prepare() throws StateMachineException {
+ if (!override) {
+ super.prepare();
+ }
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public AxArtifactKey execute(final long executionId, final Properties executionProperties,
+ final EnEvent newIncomingEvent) throws StateMachineException, ContextException {
+ if (!override) {
+ return super.execute(executionId, executionProperties, newIncomingEvent);
+ }
+
+ return new AxArtifactKey("task" + (taskNo++) + ":0.0.1");
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public void cleanUp() throws StateMachineException {
+ if (!override) {
+ super.cleanUp();
+ }
+ }
+}
diff --git a/core/src/test/java/org/onap/policy/apex/core/engine/executor/StateExecutorTest.java b/core/src/test/java/org/onap/policy/apex/core/engine/executor/StateExecutorTest.java
new file mode 100644
index 000000000..f3e12cc1f
--- /dev/null
+++ b/core/src/test/java/org/onap/policy/apex/core/engine/executor/StateExecutorTest.java
@@ -0,0 +1,88 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2020 Nordix Foundation
+ * ================================================================================
+ * 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.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.junit.Assert.assertEquals;
+
+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());
+
+ assertThatThrownBy(() -> executor.executePre(0, null, null))
+ .hasMessage("execution pre work not implemented on class");
+ assertThatThrownBy(() -> executor.executePost(false))
+ .hasMessage("execution post work not implemented on class");
+ }
+}
diff --git a/core/src/test/java/org/onap/policy/apex/core/engine/executor/StateFinalizerExecutorTest.java b/core/src/test/java/org/onap/policy/apex/core/engine/executor/StateFinalizerExecutorTest.java
new file mode 100644
index 000000000..8f6544497
--- /dev/null
+++ b/core/src/test/java/org/onap/policy/apex/core/engine/executor/StateFinalizerExecutorTest.java
@@ -0,0 +1,139 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2020 Nordix Foundation.
+ * ================================================================================
+ * 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.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.junit.Assert.assertEquals;
+
+import java.util.Map;
+import java.util.Properties;
+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.ContextException;
+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() throws StateMachineException, ContextException {
+ 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());
+
+ assertThatThrownBy(executor::cleanUp)
+ .hasMessage("cleanUp() not implemented on class");
+ Mockito.doReturn(null).when(stateFinalizerLogicMock).getLogic();
+
+ assertThatThrownBy(executor::prepare)
+ .hasMessage("state finalizer logic cannot be null.");
+ Mockito.doReturn("some task logic").when(stateFinalizerLogicMock).getLogic();
+
+ executor.prepare();
+
+ executor.executePre(0, new Properties(), incomingEvent);
+ assertThatThrownBy(() -> executor.executePre(0, null, incomingEvent))
+ .hasMessageMatching("^executionProperties is marked .*on.*ull but is null$");
+
+ executor.executePre(0, new Properties(), incomingEvent);
+
+ assertThatThrownBy(() -> executor.execute(0, new Properties(), incomingEvent))
+ .hasMessage("execute() not implemented on abstract StateFinalizerExecutionContext class, "
+ + "only on its subclasses");
+ assertThatThrownBy(() -> executor.executePost(false))
+ .hasMessage("execute-post: state finalizer logic execution failure on state \"NULL:0.0.0:"
+ + "NULL:NULL\" on finalizer logic null");
+ executor.getExecutionContext().setMessage("Execution message");
+ assertThatThrownBy(() -> executor.executePost(false))
+ .hasMessage("execute-post: state finalizer logic execution failure on state \"NULL:0.0.0:"
+ + "NULL:NULL\" on finalizer logic null, user message: Execution message");
+ executor.executePre(0, new Properties(), incomingEvent);
+
+ assertThatThrownBy(() -> executor.executePost(true))
+ .hasMessage("execute-post: state finalizer logic \"null\" did not select an output state");
+ executor.executePre(0, new Properties(), incomingEvent);
+
+ executor.getExecutionContext().setSelectedStateOutputName("ThisOutputDoesNotExist");
+ assertThatThrownBy(() -> executor.executePost(true))
+ .hasMessage("execute-post: state finalizer logic \"null\" selected output state "
+ + "\"ThisOutputDoesNotExist\" that does not exsist on state \"NULL:0.0.0:NULL:NULL\"");
+ executor.executePre(0, new Properties(), incomingEvent);
+
+ executor.getExecutionContext().setSelectedStateOutputName("ValidOutput");
+ executor.executePost(true);
+
+ }
+}
diff --git a/core/src/test/java/org/onap/policy/apex/core/engine/executor/StateMachineExecutorTest.java b/core/src/test/java/org/onap/policy/apex/core/engine/executor/StateMachineExecutorTest.java
new file mode 100644
index 000000000..5d91bd2b3
--- /dev/null
+++ b/core/src/test/java/org/onap/policy/apex/core/engine/executor/StateMachineExecutorTest.java
@@ -0,0 +1,336 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2020 Nordix Foundation.
+ * Modifications Copyright (C) 2021 Bell Canada. All rights reserved.
+ * Modifications Copyright (C) 2021 AT&T Intellectual Property. 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.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Collection;
+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.ContextException;
+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, Collection<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() throws StateMachineException, ContextException {
+ StateMachineExecutor executor =
+ new StateMachineExecutor(executorFactoryMock, new AxArtifactKey("OwnerKey:0.0.1"));
+
+ assertThatThrownBy(() -> executor.execute(0, null, incomingEventMock))
+ .hasMessage("no states defined on state machine");
+ executor.setContext(null, axPolicy, internalContextMock);
+ assertEquals("Policy:0.0.1", executor.getKey().getId());
+ assertNull(executor.getParent());
+ assertEquals(internalContextMock, executor.getContext());
+ assertNull(executor.getNext());
+ assertNull(executor.getIncoming());
+ assertTrue(executor.getOutgoing().isEmpty());
+ assertEquals(axPolicy, executor.getSubject());
+
+ executor.setParameters(new ExecutorParameters());
+ executor.setNext(nextExecutorMock);
+ assertEquals(nextExecutorMock, executor.getNext());
+ executor.setNext(null);
+ assertNull(executor.getNext());
+
+ assertThatThrownBy(() -> executor.executePre(0, null, null))
+ .hasMessage("execution pre work not implemented on class");
+ assertThatThrownBy(() -> executor.executePost(false))
+ .hasMessage("execution post work not implemented on class");
+ assertThatThrownBy(executor::prepare)
+ .isInstanceOf(NullPointerException.class);
+ axPolicy.setFirstState("BadState");
+ executor.setContext(null, axPolicy, internalContextMock);
+ assertThatThrownBy(() -> executor.execute(0, null, incomingEventMock))
+ .hasMessage("first state not defined on state machine");
+ axPolicy.setFirstState("state0");
+ executor.setContext(null, axPolicy, internalContextMock);
+ executor.execute(0, null, incomingEventMock);
+
+ DummyTaskSelectExecutor.setTaskNo(0);
+ executor.execute(0, null, incomingEventMock);
+
+ AxReferenceKey badStateKey = new AxReferenceKey("Policy:0.0.1:PName:BadState");
+ axPolicy.getStateMap().get("State1").getStateOutputs().get("stateOutput1").setNextState(badStateKey);
+ DummyTaskSelectExecutor.setTaskNo(0);
+ assertThatThrownBy(() -> executor.execute(0, null, incomingEventMock))
+ .hasMessage("state execution failed, next state \"Policy:0.0.1:PName:BadState\" not found");
+ axPolicy.getStateMap().get("State1").getStateOutputs().get("stateOutput1")
+ .setNextState(AxReferenceKey.getNullKey());
+ DummyTaskSelectExecutor.setTaskNo(0);
+ executor.execute(0, null, incomingEventMock);
+
+ axPolicy.getStateMap().get("State1").setTrigger(new AxArtifactKey("BadTrigger:0.0.1"));
+ DummyTaskSelectExecutor.setTaskNo(0);
+ assertThatThrownBy(() -> executor.execute(0, null, incomingEventMock))
+ .hasMessage("incoming event \"Event1:0.0.1\" does not match trigger \"BadTrigger:0.0.1\" "
+ + "of state \"Policy:0.0.1:NULL:state1\"");
+ axPolicy.getStateMap().get("State1").setTrigger(new AxArtifactKey("Event1:0.0.1"));
+ DummyTaskSelectExecutor.setTaskNo(0);
+ executor.execute(0, null, incomingEventMock);
+
+ AxStateFinalizerLogic savedSfl = axPolicy.getStateMap().get("State1").getStateFinalizerLogicMap().get("sfl");
+ axPolicy.getStateMap().get("State1").getStateFinalizerLogicMap().put("sfl", null);
+ assertThatThrownBy(() -> executor.setContext(null, axPolicy, internalContextMock))
+ .hasMessage("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");
+ axPolicy.getStateMap().get("State1").getStateFinalizerLogicMap().put("sfl", savedSfl);
+ executor.setContext(null, axPolicy, internalContextMock);
+
+ DummyTaskSelectExecutor.setTaskNo(0);
+ executor.execute(0, null, incomingEventMock);
+
+ AxArtifactKey task1Key = new AxArtifactKey("task1:0.0.1");
+ axPolicy.getStateMap().get("State1").getTaskReferences().get(task1Key)
+ .setStateTaskOutputType(AxStateTaskOutputType.UNDEFINED);
+ assertThatThrownBy(() -> executor.setContext(null, axPolicy, internalContextMock))
+ .hasMessage("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\"");
+ axPolicy.getStateMap().get("State1").getTaskReferences().get(task1Key)
+ .setStateTaskOutputType(AxStateTaskOutputType.LOGIC);
+ executor.setContext(null, axPolicy, internalContextMock);
+
+ DummyTaskSelectExecutor.setTaskNo(0);
+ executor.execute(0, null, incomingEventMock);
+
+ DummyTaskSelectExecutor.setTaskNo(0);
+ dummySfle.setReturnBad(true);
+ assertThatThrownBy(() -> executor.execute(0, null, incomingEventMock))
+ .hasMessage("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\"");
+ DummyTaskSelectExecutor.setTaskNo(0);
+ dummySfle.setReturnBad(false);
+ executor.execute(0, null, incomingEventMock);
+
+ assertThatThrownBy(executor::cleanUp)
+ .hasMessage("cleanUp() not implemented on class");
+ }
+
+ @Test
+ public void testStateOutput() throws StateMachineException {
+ final StateOutput output =
+ new StateOutput(axPolicy.getStateMap().get("State0").getStateOutputs().get("stateOutput0"));
+ assertNotNull(output);
+
+ assertEquals("stateOutput0", output.getStateOutputDefinition().getKey().getLocalName());
+
+ assertThatThrownBy(() -> output.setEventFields(null, null))
+ .hasMessage("incomingFieldDefinitionMap may not be null");
+ Map<String, AxEvent> incomingFieldDefinitionMap = new LinkedHashMap<>();
+ assertThatThrownBy(() -> output.setEventFields(incomingFieldDefinitionMap, null))
+ .hasMessage("eventFieldMaps may not be null");
+ Map<String, Map<String, Object>> eventFieldMaps = new LinkedHashMap<>();
+ output.setEventFields(incomingFieldDefinitionMap, eventFieldMaps);
+ AxEvent event = new AxEvent(new AxArtifactKey("Event1", "0.0.1"));
+ event.setParameterMap(Map.of("key", new AxField()));
+ incomingFieldDefinitionMap.put("Event1", event);
+ eventFieldMaps.put("Event1", Map.of("key2", "value"));
+ assertThatThrownBy(() -> output.setEventFields(incomingFieldDefinitionMap, eventFieldMaps))
+ .hasMessage("field definitions and values do not match for event Event1:0.0.1\n[key]\n[key2]");
+
+ eventFieldMaps.put("Event1", Map.of("key", "value"));
+ assertThatThrownBy(() -> output.setEventFields(incomingFieldDefinitionMap, eventFieldMaps))
+ .hasMessage("field \"key\" does not exist on event \"Event1:0.0.1\"");
+
+ incomingFieldDefinitionMap.clear();
+ eventFieldMaps.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);
+ event.setParameterMap(Map.of("Event1Field0", event1Field0Definition));
+ incomingFieldDefinitionMap.put("Event1", event);
+ eventFieldMaps.put("Event1", Map.of("Event1Field0", "Value"));
+ output.setEventFields(incomingFieldDefinitionMap, eventFieldMaps);
+
+ StateOutput outputCopy = new StateOutput(axPolicy.getStateMap().get("State0")
+ .getStateOutputs().get("stateOutput0"));
+
+ EnEvent incomingEvent = new EnEvent(new AxArtifactKey("Event0:0.0.1"));
+ outputCopy.copyUnsetFields(incomingEvent);
+ incomingEvent.put("Event1Field0", "Hello");
+ outputCopy.copyUnsetFields(incomingEvent);
+ }
+}
diff --git a/core/src/test/java/org/onap/policy/apex/core/engine/executor/TaskExecutorTest.java b/core/src/test/java/org/onap/policy/apex/core/engine/executor/TaskExecutorTest.java
new file mode 100644
index 000000000..4160a9f19
--- /dev/null
+++ b/core/src/test/java/org/onap/policy/apex/core/engine/executor/TaskExecutorTest.java
@@ -0,0 +1,240 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2020 Nordix Foundation.
+ * Modifications Copyright (C) 2021 Bell Canada. 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.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.TreeMap;
+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.ContextException;
+import org.onap.policy.apex.core.engine.ExecutorParameters;
+import org.onap.policy.apex.core.engine.TaskParameters;
+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.basicmodel.concepts.AxReferenceKey;
+import org.onap.policy.apex.model.eventmodel.concepts.AxEvent;
+import org.onap.policy.apex.model.eventmodel.concepts.AxField;
+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;
+import org.onap.policy.apex.model.policymodel.concepts.AxTaskParameter;
+
+/**
+ * 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, Map<String, Object>>, AxTask,
+ ApexInternalContext> nextExecutorMock;
+
+ @Mock
+ private AxTaskLogic taskLogicMock;
+
+ private Map<String, AxField> inFieldMap;
+ private Map<String, AxField> outFieldMap;
+ private List<TaskParameters> taskParametersFromConfig;
+ private Map<String, AxEvent> outEvents = new TreeMap<>();
+
+ /**
+ * 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 = Map.of("InField0", axInputFieldMock, "InField1", axOptionalInputFieldMock);
+ outFieldMap = new LinkedHashMap<>();
+
+ outFieldMap.put("OutField0", axOutputFieldMock);
+ outFieldMap.put("OutField1", axOptionalOutputFieldMock);
+
+ AxEvent inEvent = new AxEvent();
+ inEvent.setParameterMap(inFieldMap);
+ AxEvent outEvent = new AxEvent(new AxArtifactKey("outputEvent:1.0.0"));
+ outEvent.setParameterMap(outFieldMap);
+ outEvents.put(outEvent.getKey().getName(), outEvent);
+
+ 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(taskLogicMock).when(axTaskMock).getTaskLogic();
+
+ Mockito.doReturn(inEvent).when(axTaskMock).getInputEvent();
+ Mockito.doReturn(outEvents).when(axTaskMock).getOutputEvents();
+
+ Mockito.doReturn(new AxArtifactKey("Context:0.0.1")).when(internalContextMock).getKey();
+
+ Map<String, AxTaskParameter> taskParameters = new HashMap<>();
+ taskParameters.put("parameterKey2", new AxTaskParameter(new AxReferenceKey(), "parameterOriginalValue2"));
+ Mockito.doReturn(taskParameters).when(axTaskMock).getTaskParameters();
+
+ taskParametersFromConfig = new ArrayList<>();
+ taskParametersFromConfig.add(new TaskParameters("parameterKey0", "parameterNewValue0", "Task0:0.0.1"));
+ taskParametersFromConfig.add(new TaskParameters("parameterKey1", "parameterNewValue1", "Task1:0.0.1"));
+ taskParametersFromConfig.add(new TaskParameters("parameterKey2", "parameterNewValue2", null));
+ }
+
+ @Test
+ public void testTaskExecutor() throws StateMachineException, ContextException {
+ final 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());
+
+ assertThatThrownBy(() -> executor.cleanUp()).hasMessageContaining("cleanUp() not implemented on class");
+
+ Mockito.doReturn(null).when(taskLogicMock).getLogic();
+
+ assertThatThrownBy(() -> executor.prepare()).hasMessageContaining("task logic cannot be null.");
+
+ Mockito.doReturn("some task logic").when(taskLogicMock).getLogic();
+
+ executor.prepare();
+
+ Map<String, Object> incomingFields = new LinkedHashMap<>();
+
+ incomingFields.put("InField0", "A Value");
+
+ executor.executePre(0, new Properties(), incomingFields);
+
+ assertThatThrownBy(() -> executor.execute(0, new Properties(), incomingFields))
+ .hasMessageContaining("execute() not implemented on abstract TaskExecutor class, only on its subclasses");
+
+ assertThatThrownBy(() -> executor.executePost(false)).hasMessageContaining(
+ "execute-post: task logic execution failure on task \"Task0\" in model Context:0.0.1");
+
+ executor.getExecutionContext().setMessage("Execution message");
+
+ assertThatThrownBy(() -> executor.executePost(false)).hasMessageContaining(
+ "execute-post: task logic execution failure on task \"Task0\" in model Context:0.0.1, "
+ + "user message: Execution message");
+
+ executor.executePost(true);
+
+ outFieldMap.put("MissingField", axMissingOutputFieldMock);
+ outEvents.get("outputEvent").getParameterMap().put("MissingField", axMissingOutputFieldMock);
+ assertThatThrownBy(() -> executor.executePost(true)).hasMessageContaining(
+ "Fields for task output events \"[outputEvent]\" are missing for task \"Task0:0.0.1\"");
+
+ outFieldMap.remove("MissingField");
+ outEvents.get("outputEvent").getParameterMap().remove("MissingField");
+ executor.getExecutionContext().outFields.put("BadExtraField", "Howdy!");
+
+ assertThatThrownBy(() -> executor.executePost(true)).hasMessageContaining(
+ "task output event \"[outputEvent]\" contains fields that are unwanted for task \"Task0:0.0.1\"");
+
+ executor.getExecutionContext().outFields.remove("BadExtraField");
+ outFieldMap.put("InField1", axMissingOutputFieldMock);
+ executor.executePost(true);
+
+ outFieldMap.put("InField0", axMissingOutputFieldMock);
+ executor.executePost(true);
+
+ executor.getExecutionContext().outFields.put("InField0", "Output Value");
+ outEvents.get("outputEvent").getParameterMap().put("InField0", axMissingOutputFieldMock);
+ executor.executePost(true);
+
+ executor.getExecutionContext().outFields.remove("InField0");
+ executor.executePost(true);
+
+ assertThatThrownBy(() -> executor.executePre(0, null, incomingFields))
+ .hasMessageMatching("^executionProperties is marked .*on.*ull but is null$");
+ }
+
+ @Test
+ public void testTaskExecutorForTaskParameters() {
+ DummyTaskExecutor executorForParmeterTest = new DummyTaskExecutor(false);
+
+ executorForParmeterTest.setContext(null, axTaskMock, internalContextMock);
+ executorForParmeterTest.updateTaskParameters(taskParametersFromConfig);
+ assertNotNull(executorForParmeterTest.getSubject().getTaskParameters());
+ // taskId matched, parameter value updated with the new value
+ assertEquals("parameterNewValue0",
+ executorForParmeterTest.getSubject().getTaskParameters().get("parameterKey0").getTaskParameterValue());
+ // taskId mismatch, so the parameter is not updated in the task
+ assertNull(executorForParmeterTest.getSubject().getTaskParameters().get("parameterKey1"));
+ // taskId is not available, so parameter is updated in the task
+ assertEquals("parameterNewValue2",
+ executorForParmeterTest.getSubject().getTaskParameters().get("parameterKey2").getTaskParameterValue());
+ }
+}
diff --git a/core/src/test/java/org/onap/policy/apex/core/engine/executor/TaskSelectExecutorTest.java b/core/src/test/java/org/onap/policy/apex/core/engine/executor/TaskSelectExecutorTest.java
new file mode 100644
index 000000000..613d1ae01
--- /dev/null
+++ b/core/src/test/java/org/onap/policy/apex/core/engine/executor/TaskSelectExecutorTest.java
@@ -0,0 +1,148 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2020 Nordix Foundation.
+ * ================================================================================
+ * 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.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.junit.Assert.assertEquals;
+
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.Properties;
+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() throws StateMachineException {
+ 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());
+
+ assertThatThrownBy(executor::cleanUp)
+ .hasMessage("cleanUp() not implemented on class");
+ Mockito.doReturn(null).when(taskSelectionLogicMock).getLogic();
+
+ assertThatThrownBy(executor::prepare)
+ .hasMessage("task selection logic cannot be null.");
+ Mockito.doReturn("some task logic").when(taskSelectionLogicMock).getLogic();
+
+ executor.prepare();
+
+ executor.executePre(0, new Properties(), incomingEvent);
+
+ assertThatThrownBy(() -> executor.execute(0, new Properties(), incomingEvent))
+ .hasMessage("execute() not implemented on class");
+ assertThatThrownBy(() -> executor.executePost(false))
+ .hasMessage("execute-post: task selection logic failed on state \"State0Parent:0.0.1:Parent:State0\"");
+
+ executor.getExecutionContext().setMessage("Execution message");
+ assertThatThrownBy(() -> executor.executePost(false))
+ .hasMessageContaining("execute-post: task selection logic failed on state \""
+ + "State0Parent:0.0.1:Parent:State0\", user message: Execution message");
+ executor.executePre(0, new Properties(), incomingEvent);
+
+ executor.executePost(true);
+ assertEquals("Task1", executor.getOutgoing().getName());
+
+ executor.executePre(0, new Properties(), incomingEvent);
+
+ executor.getOutgoing().setName("IDontExist");
+ assertThatThrownBy(() -> executor.executePost(true))
+ .hasMessageContaining("task \"IDontExist:0.0.0\" returned by task selection logic not defined "
+ + "on state \"State0Parent:0.0.1:Parent:State0\"");
+ executor.executePre(0, new Properties(), incomingEvent);
+
+ executor.getOutgoing().setName("Task0");
+
+ executor.executePost(true);
+ assertEquals("Task0", executor.getOutgoing().getName());
+
+ assertThatThrownBy(() -> executor.executePre(0, null, incomingEvent))
+ .hasMessageMatching("^executionProperties is marked .*on.*ull but is null$");
+ }
+}
diff --git a/core/src/test/java/org/onap/policy/apex/core/engine/executor/context/AxStateFacadeTest.java b/core/src/test/java/org/onap/policy/apex/core/engine/executor/context/AxStateFacadeTest.java
new file mode 100644
index 000000000..68d478877
--- /dev/null
+++ b/core/src/test/java/org/onap/policy/apex/core/engine/executor/context/AxStateFacadeTest.java
@@ -0,0 +1,86 @@
+/*-
+ * ============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/src/test/java/org/onap/policy/apex/core/engine/executor/context/AxTaskFacadeTest.java b/core/src/test/java/org/onap/policy/apex/core/engine/executor/context/AxTaskFacadeTest.java
new file mode 100644
index 000000000..9da8ecfad
--- /dev/null
+++ b/core/src/test/java/org/onap/policy/apex/core/engine/executor/context/AxTaskFacadeTest.java
@@ -0,0 +1,140 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2020 Nordix Foundation
+ * Modifications Copyright (C) 2021 Bell Canada. 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.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import java.util.Map;
+import java.util.TreeMap;
+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.AxEvent;
+import org.onap.policy.apex.model.eventmodel.concepts.AxField;
+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, AxField> inFieldMap = Map.of("InField0", axInputFieldMock, "InFieldBad", axInputFieldBadMock);
+ Map<String, AxField> outFieldMap = Map.of("OutField0", axOutputFieldMock, "OutFieldBad", axOutputFieldBadMock);
+
+ AxEvent inEvent = new AxEvent();
+ inEvent.setParameterMap(inFieldMap);
+ AxEvent outEvent = new AxEvent(new AxArtifactKey("outputEvent:1.0.0"));
+ outEvent.setParameterMap(outFieldMap);
+ Map<String, AxEvent> outEvents = new TreeMap<>();
+ outEvents.put(outEvent.getKey().getName(), outEvent);
+
+ Mockito.doReturn(inEvent).when(axTaskMock).getInputEvent();
+ Mockito.doReturn(outEvents).when(axTaskMock).getOutputEvents();
+
+ 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());
+
+ assertThatThrownBy(() -> taskFacade.getInFieldSchemaHelper("InFieldDoesntExist"))
+ .hasMessage("no incoming field with name \"InFieldDoesntExist\" " + "defined on task "
+ + "\"Task0:0.0.1\"");
+ assertThatThrownBy(() -> taskFacade.getOutFieldSchemaHelper("OutFieldDoesntExist"))
+ .hasMessage("no outgoing field with name \"OutFieldDoesntExist\" " + "defined on task "
+ + "\"Task0:0.0.1\"");
+ assertNotNull(taskFacade.getInFieldSchemaHelper("InField0"));
+ assertNotNull(taskFacade.getOutFieldSchemaHelper("OutField0"));
+
+ assertThatThrownBy(() -> taskFacade.getInFieldSchemaHelper("InFieldBad"))
+ .hasMessage("schema helper cannot be created for task field \"InFieldBad\" "
+ + "with key \"null\" with schema \"null\"");
+ assertThatThrownBy(() -> taskFacade.getOutFieldSchemaHelper("OutFieldBad"))
+ .hasMessage("schema helper cannot be created for task field \"OutFieldBad\" "
+ + "with key \"null\" with schema \"null\"");
+ }
+}
diff --git a/core/src/test/java/org/onap/policy/apex/core/engine/executor/context/DummyContextAlbum.java b/core/src/test/java/org/onap/policy/apex/core/engine/executor/context/DummyContextAlbum.java
new file mode 100644
index 000000000..efb53a682
--- /dev/null
+++ b/core/src/test/java/org/onap/policy/apex/core/engine/executor/context/DummyContextAlbum.java
@@ -0,0 +1,226 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2021 AT&T Intellectual Property. 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 lombok.AllArgsConstructor;
+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.
+ */
+@AllArgsConstructor
+public class DummyContextAlbum implements ContextAlbum {
+ private final AxArtifactKey key;
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public void clear() {
+ throw new NotImplementedException("Not implemented on dummy class");
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public boolean containsKey(Object key) {
+ throw new NotImplementedException("Not implemented on dummy class");
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public boolean containsValue(Object value) {
+ throw new NotImplementedException("Not implemented on dummy class");
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public Set<Entry<String, Object>> entrySet() {
+ throw new NotImplementedException("Not implemented on dummy class");
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public Object get(Object key) {
+ throw new NotImplementedException("Not implemented on dummy class");
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public boolean isEmpty() {
+ throw new NotImplementedException("Not implemented on dummy class");
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public Set<String> keySet() {
+ throw new NotImplementedException("Not implemented on dummy class");
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public Object put(String key, Object value) {
+ throw new NotImplementedException("Not implemented on dummy class");
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public void putAll(Map<? extends String, ? extends Object> map) {
+ throw new NotImplementedException("Not implemented on dummy class");
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public Object remove(Object key) {
+ throw new NotImplementedException("Not implemented on dummy class");
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public int size() {
+ throw new NotImplementedException("Not implemented on dummy class");
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public Collection<Object> values() {
+ throw new NotImplementedException("Not implemented on dummy class");
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public AxArtifactKey getKey() {
+ return key;
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public String getName() {
+ throw new NotImplementedException("Not implemented on dummy class");
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public AxContextAlbum getAlbumDefinition() {
+ throw new NotImplementedException("Not implemented on dummy class");
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public SchemaHelper getSchemaHelper() {
+ throw new NotImplementedException("Not implemented on dummy class");
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public void lockForReading(String key) throws ContextException {
+ throw new NotImplementedException("Not implemented on dummy class");
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public void lockForWriting(String key) throws ContextException {
+ throw new NotImplementedException("Not implemented on dummy class");
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public void unlockForReading(String key) throws ContextException {
+ throw new NotImplementedException("Not implemented on dummy class");
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public void unlockForWriting(String key) throws ContextException {
+ throw new NotImplementedException("Not implemented on dummy class");
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public AxConcept[] getUserArtifactStack() {
+ throw new NotImplementedException("Not implemented on dummy class");
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public void setUserArtifactStack(AxConcept[] userArtifactStack) {
+ // Do nothing
+ }
+
+ /**
+ * {@inheritDoc}.
+ */
+ @Override
+ public void flush() throws ContextException {
+ throw new NotImplementedException("Not implemented on dummy class");
+ }
+}
diff --git a/core/src/test/java/org/onap/policy/apex/core/engine/executor/context/StateFinalizerExecutionContextTest.java b/core/src/test/java/org/onap/policy/apex/core/engine/executor/context/StateFinalizerExecutionContextTest.java
new file mode 100644
index 000000000..c540f51ad
--- /dev/null
+++ b/core/src/test/java/org/onap/policy/apex/core/engine/executor/context/StateFinalizerExecutionContextTest.java
@@ -0,0 +1,109 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2020 Nordix Foundation
+ * ================================================================================
+ * 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.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+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, null,
+ 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());
+
+ assertThatThrownBy(() -> sfec.getContextAlbum("AlbumKeyNonExistant"))
+ .hasMessage("cannot find definition of context album \"AlbumKeyNonExistant\" "
+ + "on state \"Parent:0.0.1:ParentName:StateName\"");
+ }
+}
diff --git a/core/src/test/java/org/onap/policy/apex/core/engine/executor/context/TaskExecutionContextTest.java b/core/src/test/java/org/onap/policy/apex/core/engine/executor/context/TaskExecutionContextTest.java
new file mode 100644
index 000000000..24c504822
--- /dev/null
+++ b/core/src/test/java/org/onap/policy/apex/core/engine/executor/context/TaskExecutionContextTest.java
@@ -0,0 +1,118 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2020 Nordix Foundation.
+ * Modifications Copyright (C) 2021 Bell Canada. 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.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.LinkedList;
+import java.util.List;
+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.basicmodel.concepts.AxReferenceKey;
+import org.onap.policy.apex.model.policymodel.concepts.AxTask;
+import org.onap.policy.apex.model.policymodel.concepts.AxTaskParameter;
+
+/**
+ * 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<String, AxTaskParameter> taskParameters = new HashMap<>();
+ taskParameters.put("parameterKey1", new AxTaskParameter(new AxReferenceKey(), "parameterValue1"));
+ taskParameters.put("parameterKey2", new AxTaskParameter(new AxReferenceKey(), "parameterValue2"));
+ Mockito.doReturn(taskParameters).when(axTaskMock).getTaskParameters();
+
+ 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 List<Map<String, Object>> outFieldsList = new LinkedList<>();
+
+ TaskExecutionContext tec = new TaskExecutionContext(taskExecutorMock, 0, null, axTaskMock, inFields,
+ outFieldsList, 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());
+
+ Map<String, String> parameters = tec.getParameters();
+ assertEquals("parameterValue1", parameters.get("parameterKey1"));
+ assertEquals("parameterValue2", parameters.get("parameterKey2"));
+
+ assertThatThrownBy(() -> tec.getContextAlbum("AlbumKeyNonExistant"))
+ .hasMessageContaining("cannot find definition of context album \"AlbumKeyNonExistant\" on task \"null\"");
+ }
+}
diff --git a/core/src/test/java/org/onap/policy/apex/core/engine/executor/context/TaskSelectionExecutionContextTest.java b/core/src/test/java/org/onap/policy/apex/core/engine/executor/context/TaskSelectionExecutionContextTest.java
new file mode 100644
index 000000000..5857e0513
--- /dev/null
+++ b/core/src/test/java/org/onap/policy/apex/core/engine/executor/context/TaskSelectionExecutionContextTest.java
@@ -0,0 +1,109 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2020 Nordix Foundation
+ * ================================================================================
+ * 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.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+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());
+
+ assertThatThrownBy(() -> tsec.getContextAlbum("AlbumKeyNonExistant"))
+ .hasMessage("cannot find definition of context album \"AlbumKeyNonExistant\" "
+ + "on state \"Parent:0.0.1:ParentName:StateName\"");
+ }
+}
diff --git a/core/src/test/java/org/onap/policy/apex/core/engine/executor/exception/StateMachineRuntimeExceptionTest.java b/core/src/test/java/org/onap/policy/apex/core/engine/executor/exception/StateMachineRuntimeExceptionTest.java
new file mode 100644
index 000000000..84f330308
--- /dev/null
+++ b/core/src/test/java/org/onap/policy/apex/core/engine/executor/exception/StateMachineRuntimeExceptionTest.java
@@ -0,0 +1,42 @@
+/*-
+ * ============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/src/test/java/org/onap/policy/apex/core/engine/executor/impl/ExceutorFactoryImplTest.java b/core/src/test/java/org/onap/policy/apex/core/engine/executor/impl/ExceutorFactoryImplTest.java
new file mode 100644
index 000000000..5957ff347
--- /dev/null
+++ b/core/src/test/java/org/onap/policy/apex/core/engine/executor/impl/ExceutorFactoryImplTest.java
@@ -0,0 +1,240 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2020 Nordix Foundation
+ * ================================================================================
+ * 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.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+
+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() throws StateMachineException {
+ setGoodPars();
+
+ ExecutorFactoryImpl factory = null;
+
+ factory = new ExecutorFactoryImpl();
+
+ 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();
+
+ assertThatThrownBy(() -> new ExecutorFactoryImpl())
+ .hasMessage("Apex executor class not found for executor plugin "
+ + "\"org.onap.policy.apex.core.engine.executor.BadTaskExecutor\"");
+ executorPars.setTaskExecutorPluginClass(null);
+
+ assertThatThrownBy(() -> new ExecutorFactoryImpl())
+ .hasMessage("Apex executor class not found for executor plugin "
+ + "\"org.onap.policy.apex.core.engine.executor.BadTaskSelectExecutor\"");
+ executorPars.setTaskExecutorPluginClass("org.onap.policy.apex.core.engine.executor.DummyTaskExecutor");
+
+ assertThatThrownBy(() -> new ExecutorFactoryImpl())
+ .hasMessage("Apex executor class not found for executor plugin "
+ + "\"org.onap.policy.apex.core.engine.executor.BadTaskSelectExecutor\"");
+ executorPars.setTaskSelectionExecutorPluginClass(
+ "org.onap.policy.apex.core.engine.executor.DummyTaskSelectExecutor");
+
+ assertThatThrownBy(() -> new ExecutorFactoryImpl())
+ .hasMessage("Apex executor class not found for executor plugin "
+ + "\"org.onap.policy.apex.core.engine.executor.BadStateFinalizerExecutor\"");
+ }
+
+ @Test
+ public void testExecutorFactoryImplBad() {
+ setBadPars();
+
+ assertThatThrownBy(() -> new ExecutorFactoryImpl())
+ .hasMessage("Specified Apex executor plugin class \"java.lang.String\" "
+ + "does not implment the Executor interface");
+ executorPars.setTaskExecutorPluginClass("org.onap.policy.apex.core.engine.executor.DummyTaskExecutor");
+
+ assertThatThrownBy(() -> new ExecutorFactoryImpl())
+ .hasMessage("Specified Apex executor plugin class \"java.lang.String\" "
+ + "does not implment the Executor interface");
+ executorPars.setTaskSelectionExecutorPluginClass(
+ "org.onap.policy.apex.core.engine.executor.DummyTaskSelectExecutor");
+
+ assertThatThrownBy(() -> new ExecutorFactoryImpl())
+ .hasMessage("Specified Apex executor plugin class \"java.lang.String\" "
+ + "does not implment the Executor interface");
+ }
+
+ @Test
+ public void testExecutorFactoryCreateErrors() throws StateMachineException {
+ setGoodPars();
+
+ executorPars.setTaskExecutorPluginClass(null);
+
+ final ExecutorFactoryImpl factory = new ExecutorFactoryImpl();
+
+ Mockito.doReturn(true).when(stateMock).checkSetTaskSelectionLogic();
+
+ assertThatThrownBy(() -> factory.getTaskExecutor(null, taskMock, internalContextMock))
+ .hasMessage("Executor plugin class not defined for \"Dummy\" executor of type "
+ + "\"org.onap.policy.apex.core.engine.executor.TaskExecutor\"");
+ executorPars.setTaskExecutorPluginClass("org.onap.policy.apex.core.engine.executor.DummyFailingTaskExecutor");
+
+ ExecutorFactoryImpl factoryInitError = new ExecutorFactoryImpl();
+
+ assertThatThrownBy(() -> factoryInitError.getTaskExecutor(null, taskMock, internalContextMock))
+ .hasMessage("Instantiation error on \"Dummy\" executor of type "
+ + "\"org.onap.policy.apex.core.engine.executor.DummyFailingTaskExecutor\"");
+ executorPars.setTaskExecutorPluginClass(
+ "org.onap.policy.apex.core.engine.executor.DummyStateFinalizerExecutor");
+
+ ExecutorFactoryImpl factoryDummyError = new ExecutorFactoryImpl();
+
+ assertThatThrownBy(() -> factoryDummyError.getTaskExecutor(null, taskMock, internalContextMock))
+ .hasMessage("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\"");
+ }
+
+ /**
+ * 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/core/src/test/java/org/onap/policy/apex/core/infrastructure/threading/ThreadingTest.java b/core/src/test/java/org/onap/policy/apex/core/infrastructure/threading/ThreadingTest.java
new file mode 100644
index 000000000..35ad9386a
--- /dev/null
+++ b/core/src/test/java/org/onap/policy/apex/core/infrastructure/threading/ThreadingTest.java
@@ -0,0 +1,86 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2020 Nordix Foundation.
+ * ================================================================================
+ * 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.infrastructure.threading;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.junit.Test;
+import org.slf4j.ext.XLogger;
+import org.slf4j.ext.XLoggerFactory;
+
+/**
+ * The Class ThreadingTest.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class ThreadingTest {
+
+ private static final String LOCAL_NAME = "localName";
+ // Logger for this class
+ private static final XLogger logger = XLoggerFactory.getXLogger(ThreadingTest.class);
+
+ /**
+ * Test thread factory initialization.
+ */
+ @Test
+ public void testThreadFactoryInitialization() {
+ final ApplicationThreadFactory objUnderTest = new ApplicationThreadFactory(LOCAL_NAME, 0);
+ assertNotNull("Failed to create ApplicationThreadFactory threadFactory0", objUnderTest);
+ logger.debug(objUnderTest.toString());
+ assertTrue("Failed to name ApplicationThreadFactory threadFactory0",
+ objUnderTest.getName().startsWith("Apex-" + LOCAL_NAME));
+
+ final ApplicationThreadFactory objUnderTest1 = new ApplicationThreadFactory(LOCAL_NAME, 0);
+ assertNotNull("Failed to create ApplicationThreadFactory threadFactory1", objUnderTest1);
+ logger.debug(objUnderTest1.toString());
+ assertTrue("Failed to name ApplicationThreadFactory threadFactory1",
+ objUnderTest1.getName().startsWith("Apex-" + LOCAL_NAME));
+
+ testThreadFactory(objUnderTest);
+ testThreadFactory(objUnderTest1);
+ }
+
+ /**
+ * Test thread factory.
+ *
+ * @param threadFactory the thread factory
+ */
+ private void testThreadFactory(final ApplicationThreadFactory threadFactory) {
+ final List<Thread> threadList = new ArrayList<>();
+
+ for (int i = 0; i < 5; i++) {
+ final Thread thread = threadFactory.newThread(() -> {
+ });
+ threadList.add(thread);
+ thread.start();
+ }
+
+ for (int i = 0; i < 5; i++) {
+ Thread thread = threadList.get(i);
+ assertTrue(thread.getName().startsWith("Apex-" + LOCAL_NAME));
+ assertTrue(thread.getName().contains(":" + i));
+ }
+ }
+}