2 * ============LICENSE_START=======================================================
3 * Copyright (C) 2018 Ericsson. All rights reserved.
4 * Modifications Copyright (C) 2020 Nordix Foundation.
5 * ================================================================================
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
18 * SPDX-License-Identifier: Apache-2.0
19 * ============LICENSE_END=========================================================
22 package org.onap.policy.apex.core.engine.executor;
24 import static org.junit.Assert.assertEquals;
25 import static org.junit.Assert.assertNotNull;
26 import static org.junit.Assert.assertTrue;
27 import static org.junit.Assert.fail;
29 import java.util.LinkedHashMap;
32 import org.junit.After;
33 import org.junit.Before;
34 import org.junit.Test;
35 import org.mockito.Mock;
36 import org.mockito.Mockito;
37 import org.mockito.MockitoAnnotations;
38 import org.onap.policy.apex.context.parameters.SchemaParameters;
39 import org.onap.policy.apex.core.engine.ExecutorParameters;
40 import org.onap.policy.apex.core.engine.context.ApexInternalContext;
41 import org.onap.policy.apex.core.engine.event.EnEvent;
42 import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
43 import org.onap.policy.apex.model.basicmodel.concepts.AxReferenceKey;
44 import org.onap.policy.apex.model.basicmodel.service.ModelService;
45 import org.onap.policy.apex.model.contextmodel.concepts.AxContextSchema;
46 import org.onap.policy.apex.model.contextmodel.concepts.AxContextSchemas;
47 import org.onap.policy.apex.model.eventmodel.concepts.AxEvent;
48 import org.onap.policy.apex.model.eventmodel.concepts.AxEvents;
49 import org.onap.policy.apex.model.eventmodel.concepts.AxField;
50 import org.onap.policy.apex.model.policymodel.concepts.AxPolicy;
51 import org.onap.policy.apex.model.policymodel.concepts.AxState;
52 import org.onap.policy.apex.model.policymodel.concepts.AxStateFinalizerLogic;
53 import org.onap.policy.apex.model.policymodel.concepts.AxStateOutput;
54 import org.onap.policy.apex.model.policymodel.concepts.AxStateTaskOutputType;
55 import org.onap.policy.apex.model.policymodel.concepts.AxStateTaskReference;
56 import org.onap.policy.apex.model.policymodel.concepts.AxTask;
57 import org.onap.policy.apex.model.policymodel.concepts.AxTasks;
58 import org.onap.policy.common.parameters.ParameterService;
63 public class StateMachineExecutorTest {
65 private ApexInternalContext internalContextMock;
68 private Executor<EnEvent, EnEvent, AxPolicy, ApexInternalContext> nextExecutorMock;
71 private ExecutorFactory executorFactoryMock;
74 private EnEvent incomingEventMock;
76 private AxPolicy axPolicy = new AxPolicy();
78 private DummyTaskSelectExecutor dummyTsle;
80 private DummyStateFinalizerExecutor dummySfle;
86 public void startMocking() {
87 MockitoAnnotations.initMocks(this);
89 axPolicy.setKey(new AxArtifactKey("Policy:0.0.1"));
91 AxReferenceKey state0Key = new AxReferenceKey(axPolicy.getKey(), "state0");
92 AxState state0 = new AxState(state0Key);
94 AxReferenceKey state1Key = new AxReferenceKey(axPolicy.getKey(), "state1");
95 AxState state1 = new AxState(state1Key);
97 axPolicy.getStateMap().put("State0", state0);
98 axPolicy.getStateMap().put("State1", state1);
99 axPolicy.setFirstState("state0");
101 AxArtifactKey event0Key = new AxArtifactKey("Event0:0.0.1");
102 AxEvent event0 = new AxEvent(event0Key, "a.name.space", "source", "target");
103 AxArtifactKey event1Key = new AxArtifactKey("Event1:0.0.1");
104 AxEvent event1 = new AxEvent(event1Key, "a.name.space", "source", "target");
105 AxArtifactKey event2Key = new AxArtifactKey("Event2:0.0.1");
106 AxEvent event2 = new AxEvent(event2Key, "a.name.space", "source", "target");
107 AxEvents events = new AxEvents();
108 events.getEventMap().put(event0Key, event0);
109 events.getEventMap().put(event1Key, event1);
110 events.getEventMap().put(event2Key, event2);
111 ModelService.registerModel(AxEvents.class, events);
113 AxReferenceKey fieldKey = new AxReferenceKey("Event1:0.0.1:event:Field0");
114 AxArtifactKey stringSchemaKey = new AxArtifactKey("StringSchema:0.0.1");
115 AxContextSchema stringSchema = new AxContextSchema(stringSchemaKey, "Java", "java.lang.String");
116 AxContextSchemas schemas = new AxContextSchemas();
117 schemas.getSchemasMap().put(stringSchemaKey, stringSchema);
118 ModelService.registerModel(AxContextSchemas.class, schemas);
120 AxField event1Field0Definition = new AxField(fieldKey, stringSchemaKey);
121 event1.getParameterMap().put("Event1Field0", event1Field0Definition);
123 event0.getParameterMap().put("Event1Field0", event1Field0Definition);
124 event0.getParameterMap().put("UnusedField", event1Field0Definition);
126 Mockito.doReturn(event0Key).when(incomingEventMock).getKey();
127 Mockito.doReturn(event0).when(incomingEventMock).getAxEvent();
129 state0.setTrigger(event0Key);
130 state1.setTrigger(event1Key);
132 AxArtifactKey task0Key = new AxArtifactKey("task0:0.0.1");
133 AxTask task0 = new AxTask(task0Key);
135 AxArtifactKey task1Key = new AxArtifactKey("task1:0.0.1");
136 AxTask task1 = new AxTask(task1Key);
138 AxTasks tasks = new AxTasks();
139 tasks.getTaskMap().put(task0Key, task0);
140 tasks.getTaskMap().put(task1Key, task1);
141 ModelService.registerModel(AxTasks.class, tasks);
143 ParameterService.register(new SchemaParameters());
145 AxReferenceKey stateOutput0Key = new AxReferenceKey("Policy:0.0.1:state0:stateOutput0");
146 AxStateOutput stateOutput0 = new AxStateOutput(stateOutput0Key, event1Key, state1.getKey());
148 state0.getStateOutputs().put(stateOutput0Key.getLocalName(), stateOutput0);
150 AxReferenceKey stateOutput1Key = new AxReferenceKey("Policy:0.0.1:state0:stateOutput1");
151 AxStateOutput stateOutput1 = new AxStateOutput(stateOutput1Key, event2Key, AxReferenceKey.getNullKey());
153 state1.getStateOutputs().put(stateOutput1Key.getLocalName(), stateOutput1);
155 AxReferenceKey str0Key = new AxReferenceKey("Policy:0.0.1:state0:str0");
156 AxStateTaskReference str0 = new AxStateTaskReference(str0Key, AxStateTaskOutputType.DIRECT, stateOutput0Key);
157 state0.getTaskReferences().put(task0Key, str0);
159 AxReferenceKey sflKey = new AxReferenceKey("Policy:0.0.1:state1:sfl");
160 AxStateFinalizerLogic sfl = new AxStateFinalizerLogic(sflKey, "Java", "State fianlizer logic");
161 state1.getStateFinalizerLogicMap().put("sfl", sfl);
163 AxReferenceKey str1Key = new AxReferenceKey("Policy:0.0.1:state1:str1");
164 AxStateTaskReference str1 = new AxStateTaskReference(str1Key, AxStateTaskOutputType.LOGIC, sflKey);
165 state1.getTaskReferences().put(task1Key, str1);
167 Mockito.doReturn(new DummyTaskExecutor(true)).when(executorFactoryMock).getTaskExecutor(Mockito.anyObject(),
168 Mockito.anyObject(), Mockito.anyObject());
170 dummyTsle = new DummyTaskSelectExecutor(true);
171 Mockito.doReturn(dummyTsle).when(executorFactoryMock).getTaskSelectionExecutor(Mockito.anyObject(),
172 Mockito.anyObject(), Mockito.anyObject());
174 dummySfle = new DummyStateFinalizerExecutor(true);
175 Mockito.doReturn(dummySfle).when(executorFactoryMock).getStateFinalizerExecutor(Mockito.anyObject(),
176 Mockito.anyObject(), Mockito.anyObject());
180 public void cleardown() {
181 ParameterService.clear();
182 ModelService.clear();
186 public void testStateMachineExecutor() {
187 StateMachineExecutor executor =
188 new StateMachineExecutor(executorFactoryMock, new AxArtifactKey("OwnerKey:0.0.1"));
191 executor.execute(0, null, incomingEventMock);
192 fail("test should throw an exception");
193 } catch (Exception ex) {
194 assertEquals("no states defined on state machine", ex.getMessage());
197 executor.setContext(null, axPolicy, internalContextMock);
198 assertEquals("Policy:0.0.1", executor.getKey().getId());
199 assertEquals(null, executor.getParent());
200 assertEquals(internalContextMock, executor.getContext());
201 assertEquals(null, executor.getNext());
202 assertEquals(null, executor.getIncoming());
203 assertEquals(null, executor.getOutgoing());
204 assertEquals(axPolicy, executor.getSubject());
206 executor.setParameters(new ExecutorParameters());
207 executor.setNext(nextExecutorMock);
208 assertEquals(nextExecutorMock, executor.getNext());
209 executor.setNext(null);
210 assertEquals(null, executor.getNext());
213 executor.executePre(0, null, null);
214 fail("test should throw an exception");
215 } catch (Exception ex) {
216 assertEquals("execution pre work not implemented on class", ex.getMessage());
220 executor.executePost(false);
221 fail("test should throw an exception");
222 } catch (Exception ex) {
223 assertEquals("execution post work not implemented on class", ex.getMessage());
228 fail("test should throw an exception");
229 } catch (Exception e) {
230 assertTrue(e instanceof NullPointerException);
233 axPolicy.setFirstState("BadState");
234 executor.setContext(null, axPolicy, internalContextMock);
236 executor.execute(0, null, incomingEventMock);
237 fail("test should throw an exception");
238 } catch (Exception ex) {
239 assertEquals("first state not defined on state machine", ex.getMessage());
242 axPolicy.setFirstState("state0");
243 executor.setContext(null, axPolicy, internalContextMock);
245 executor.execute(0, null, incomingEventMock);
246 } catch (Exception ex) {
247 fail("test should not throw an exception");
250 dummyTsle.setTaskNo(0);
252 executor.execute(0, null, incomingEventMock);
253 } catch (Exception ex) {
254 fail("test should not throw an exception");
257 AxReferenceKey badStateKey = new AxReferenceKey("Policy:0.0.1:PName:BadState");
258 axPolicy.getStateMap().get("State1").getStateOutputs().get("stateOutput1").setNextState(badStateKey);
259 dummyTsle.setTaskNo(0);
261 executor.execute(0, null, incomingEventMock);
262 fail("test should throw an exception");
263 } catch (Exception ex) {
264 assertEquals("state execution failed, next state \"Policy:0.0.1:PName:BadState\" not found",
268 axPolicy.getStateMap().get("State1").getStateOutputs().get("stateOutput1")
269 .setNextState(AxReferenceKey.getNullKey());
270 dummyTsle.setTaskNo(0);
272 executor.execute(0, null, incomingEventMock);
273 } catch (Exception ex) {
274 fail("test should not throw an exception");
277 axPolicy.getStateMap().get("State1").setTrigger(new AxArtifactKey("BadTrigger:0.0.1"));
278 dummyTsle.setTaskNo(0);
280 executor.execute(0, null, incomingEventMock);
281 fail("test should throw an exception");
282 } catch (Exception ex) {
283 assertEquals("incoming event \"Event1:0.0.1\" does not match trigger \"BadTrigger:0.0.1\" "
284 + "of state \"Policy:0.0.1:NULL:state1\"", ex.getMessage());
287 axPolicy.getStateMap().get("State1").setTrigger(new AxArtifactKey("Event1:0.0.1"));
288 dummyTsle.setTaskNo(0);
290 executor.execute(0, null, incomingEventMock);
291 } catch (Exception ex) {
292 fail("test should not throw an exception");
295 AxStateFinalizerLogic savedSfl = axPolicy.getStateMap().get("State1").getStateFinalizerLogicMap().get("sfl");
296 axPolicy.getStateMap().get("State1").getStateFinalizerLogicMap().put("sfl", null);
298 executor.setContext(null, axPolicy, internalContextMock);
299 fail("test should throw an exception");
300 } catch (Exception ex) {
301 assertEquals("state finalizer logic on task reference "
302 + "\"AxStateTaskReference:(stateKey=AxReferenceKey:(parentKeyName=Policy,"
303 + "parentKeyVersion=0.0.1,parentLocalName=state1,localName=str1),"
304 + "outputType=LOGIC,output=AxReferenceKey:(parentKeyName=Policy,parentKeyVersion=0.0.1,"
305 + "parentLocalName=state1,localName=sfl))\" on state \"Policy:0.0.1:NULL:state1\" " + "does not exist",
309 axPolicy.getStateMap().get("State1").getStateFinalizerLogicMap().put("sfl", savedSfl);
310 executor.setContext(null, axPolicy, internalContextMock);
312 dummyTsle.setTaskNo(0);
314 executor.execute(0, null, incomingEventMock);
315 } catch (Exception ex) {
316 fail("test should not throw an exception");
319 AxArtifactKey task1Key = new AxArtifactKey("task1:0.0.1");
321 axPolicy.getStateMap().get("State1").getTaskReferences().get(task1Key)
322 .setStateTaskOutputType(AxStateTaskOutputType.UNDEFINED);
323 executor.setContext(null, axPolicy, internalContextMock);
324 fail("test should throw an exception");
325 } catch (Exception ex) {
326 assertEquals("invalid state output type on task reference \"AxStateTaskReference:(stateKey=AxReferenceKey:"
327 + "(parentKeyName=Policy,parentKeyVersion=0.0.1,parentLocalName=state1,localName=str1),"
328 + "outputType=UNDEFINED,output=AxReferenceKey:(parentKeyName=Policy,"
329 + "parentKeyVersion=0.0.1,parentLocalName=state1,localName=sfl))\" "
330 + "on state \"Policy:0.0.1:NULL:state1\"", ex.getMessage());
333 axPolicy.getStateMap().get("State1").getTaskReferences().get(task1Key)
334 .setStateTaskOutputType(AxStateTaskOutputType.LOGIC);
335 executor.setContext(null, axPolicy, internalContextMock);
337 dummyTsle.setTaskNo(0);
339 executor.execute(0, null, incomingEventMock);
340 } catch (Exception ex) {
341 fail("test should not throw an exception");
344 dummyTsle.setTaskNo(0);
345 dummySfle.setReturnBad(true);
347 executor.execute(0, null, incomingEventMock);
348 fail("test should throw an exception");
349 } catch (Exception ex) {
350 assertEquals("State execution of state \"Policy:0.0.1:NULL:state1\" on task \"task1:0.0.1\" failed: "
351 + "state output definition for state output \"stateOutputBad\" not found for "
352 + "state \"Policy:0.0.1:NULL:state1\"", ex.getMessage());
355 dummyTsle.setTaskNo(0);
356 dummySfle.setReturnBad(false);
358 executor.execute(0, null, incomingEventMock);
359 } catch (Exception ex) {
360 fail("test should not throw an exception");
365 fail("test should throw an exception");
366 } catch (Exception ex) {
367 assertEquals("cleanUp() not implemented on class", ex.getMessage());
372 public void testStateOutput() {
374 new StateOutput(axPolicy.getStateMap().get("State0").getStateOutputs().get("stateOutput0"));
375 assertNotNull(output);
377 assertEquals("stateOutput0", output.getStateOutputDefinition().getKey().getLocalName());
380 output.setEventFields(null, null);
381 fail("test should throw an exception");
382 } catch (Exception ex) {
383 assertEquals("incomingFieldDefinitionMap may not be null", ex.getMessage());
386 Map<String, AxField> incomingFieldDefinitionMap = new LinkedHashMap<>();
388 output.setEventFields(incomingFieldDefinitionMap, null);
389 fail("test should throw an exception");
390 } catch (Exception ex) {
391 assertEquals("eventFieldMap may not be null", ex.getMessage());
394 Map<String, Object> eventFieldMap = new LinkedHashMap<>();
396 output.setEventFields(incomingFieldDefinitionMap, eventFieldMap);
397 } catch (Exception ex) {
398 fail("test should not throw an exception");
401 eventFieldMap.put("key", "Value");
403 output.setEventFields(incomingFieldDefinitionMap, eventFieldMap);
404 fail("test should throw an exception");
405 } catch (Exception ex) {
406 assertEquals("field definitions and values do not match for event Event1:0.0.1\n[]\n[key]",
410 AxField axBadFieldDefinition = new AxField();
411 incomingFieldDefinitionMap.put("key", axBadFieldDefinition);
413 output.setEventFields(incomingFieldDefinitionMap, eventFieldMap);
414 fail("test should throw an exception");
415 } catch (Exception ex) {
416 assertEquals("field \"key\" does not exist on event \"Event1:0.0.1\"", ex.getMessage());
419 incomingFieldDefinitionMap.clear();
420 eventFieldMap.clear();
421 AxArtifactKey stringSchemaKey = new AxArtifactKey("StringSchema:0.0.1");
422 AxReferenceKey fieldKey = new AxReferenceKey("Event1:0.0.1:event:Field0");
423 AxField event1Field0Definition = new AxField(fieldKey, stringSchemaKey);
424 incomingFieldDefinitionMap.put("Event1Field0", event1Field0Definition);
425 eventFieldMap.put("Event1Field0", "Value");
427 output.setEventFields(incomingFieldDefinitionMap, eventFieldMap);
428 } catch (Exception ex) {
429 fail("test should not throw an exception");
432 output = new StateOutput(axPolicy.getStateMap().get("State0").getStateOutputs().get("stateOutput0"));
434 EnEvent incomingEvent = new EnEvent(new AxArtifactKey("Event0:0.0.1"));
435 output.copyUnsetFields(incomingEvent);
437 incomingEvent.put("Event1Field0", "Hello");
438 output.copyUnsetFields(incomingEvent);