2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2020 AT&T Intellectual Property. All rights reserved.
6 * ================================================================================
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 * ============LICENSE_END=========================================================
21 package org.onap.policy.controlloop.eventmanager;
23 import static org.assertj.core.api.Assertions.assertThat;
24 import static org.assertj.core.api.Assertions.assertThatCode;
25 import static org.junit.Assert.assertEquals;
26 import static org.junit.Assert.assertFalse;
27 import static org.junit.Assert.assertNotNull;
28 import static org.junit.Assert.assertSame;
29 import static org.junit.Assert.assertTrue;
30 import static org.mockito.Mockito.verify;
32 import java.io.IOException;
33 import java.util.ArrayList;
34 import java.util.List;
35 import java.util.UUID;
36 import java.util.concurrent.CompletableFuture;
37 import java.util.concurrent.ExecutorService;
38 import org.junit.Before;
39 import org.junit.Test;
40 import org.mockito.ArgumentCaptor;
41 import org.mockito.Mock;
42 import org.mockito.MockitoAnnotations;
43 import org.onap.policy.common.utils.coder.Coder;
44 import org.onap.policy.common.utils.coder.CoderException;
45 import org.onap.policy.common.utils.coder.StandardYamlCoder;
46 import org.onap.policy.common.utils.io.Serializer;
47 import org.onap.policy.common.utils.resources.ResourceUtils;
48 import org.onap.policy.controlloop.ControlLoopException;
49 import org.onap.policy.controlloop.actorserviceprovider.OperationOutcome;
50 import org.onap.policy.controlloop.drl.legacy.ControlLoopParams;
51 import org.onap.policy.controlloop.policy.PolicyResult;
52 import org.onap.policy.controlloop.policy.Target;
53 import org.onap.policy.controlloop.policy.TargetType;
54 import org.onap.policy.drools.core.lock.LockCallback;
55 import org.onap.policy.drools.core.lock.LockImpl;
56 import org.onap.policy.drools.core.lock.LockState;
57 import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicy;
58 import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate;
60 public class ControlLoopEventManagerTest {
61 private static final UUID REQ_ID = UUID.randomUUID();
62 private static final String CL_NAME = "my-closed-loop-name";
63 private static final String POLICY_NAME = "my-policy-name";
64 private static final String POLICY_SCOPE = "my-scope";
65 private static final String POLICY_VERSION = "1.2.3";
66 private static final String LOCK1 = "my-lock-A";
67 private static final String LOCK2 = "my-lock-B";
68 private static final Coder yamlCoder = new StandardYamlCoder();
69 private static final String MY_KEY = "def";
72 private ExecutorService executor;
74 private long preCreateTimeMs;
75 private List<LockImpl> locks;
76 private Target target;
77 private ToscaPolicy tosca;
78 private ControlLoopParams params;
79 private ControlLoopEventManager mgr;
85 public void setUp() throws ControlLoopException, CoderException {
86 MockitoAnnotations.initMocks(this);
88 target = new Target();
89 target.setType(TargetType.VNF);
91 params = new ControlLoopParams();
92 params.setClosedLoopControlName(CL_NAME);
93 params.setPolicyName(POLICY_NAME);
94 params.setPolicyScope(POLICY_SCOPE);
95 params.setPolicyVersion(POLICY_VERSION);
97 loadPolicy("eventManager/event-mgr-simple.yaml");
99 locks = new ArrayList<>();
101 preCreateTimeMs = System.currentTimeMillis();
103 MyManager.executor = executor;
104 MyManager.locks = locks;
106 mgr = new MyManager(params, REQ_ID);
110 public void testConstructor() {
111 assertEquals(POLICY_NAME, mgr.getPolicyName());
113 assertTrue(mgr.isActive());
114 assertEquals(CL_NAME, mgr.getClosedLoopControlName());
115 assertSame(REQ_ID, mgr.getRequestId());
116 assertEquals(POLICY_NAME, mgr.getPolicyName());
117 assertEquals(POLICY_VERSION, mgr.getPolicyVersion());
118 assertNotNull(mgr.getProcessor());
119 assertThat(mgr.getEndTimeMs()).isGreaterThanOrEqualTo(preCreateTimeMs);
123 public void testGetCreateCount() throws ControlLoopException {
124 long original = ControlLoopEventManager.getCreateCount();
126 new MyManager(params, REQ_ID);
127 assertEquals(original + 1, ControlLoopEventManager.getCreateCount());
129 new MyManager(params, REQ_ID);
130 assertEquals(original + 2, ControlLoopEventManager.getCreateCount());
134 public void testIsActive() throws Exception {
135 mgr = new ControlLoopEventManager(params, REQ_ID);
136 assertTrue(mgr.isActive());
138 ControlLoopEventManager mgr2 = Serializer.roundTrip(mgr);
139 assertFalse(mgr2.isActive());
143 public void testDestroy() throws IOException {
144 mgr.requestLock(LOCK1);
145 mgr.requestLock(LOCK2);
146 mgr.requestLock(LOCK1);
148 // ensure destroy() doesn't throw an exception if the object is deserialized
149 ControlLoopEventManager mgr2 = Serializer.roundTrip(mgr);
150 assertThatCode(() -> mgr2.destroy()).doesNotThrowAnyException();
152 // locks should not have been freed
153 for (LockImpl lock : locks) {
154 assertFalse(lock.isUnavailable());
161 for (LockImpl lock : locks) {
162 assertTrue(lock.isUnavailable());
167 public void testDetmControlLoopTimeoutMs() throws Exception {
168 long timeMs = 1200 * 1000L;
169 long end = mgr.getEndTimeMs();
170 assertThat(end).isGreaterThanOrEqualTo(preCreateTimeMs + timeMs);
171 assertThat(end).isLessThan(preCreateTimeMs + timeMs + 5000);
175 public void testRequestLock() {
176 final CompletableFuture<OperationOutcome> future1 = mgr.requestLock(LOCK1);
177 assertTrue(mgr.getOutcomes().isEmpty());
179 final CompletableFuture<OperationOutcome> future2 = mgr.requestLock(LOCK2);
180 assertTrue(mgr.getOutcomes().isEmpty());
182 assertSame(future1, mgr.requestLock(LOCK1));
183 assertTrue(mgr.getOutcomes().isEmpty());
185 assertEquals(2, locks.size());
187 assertTrue(future1.isDone());
188 assertTrue(future2.isDone());
190 // indicate that the first lock failed
191 locks.get(0).notifyUnavailable();
193 verifyLock(PolicyResult.FAILURE);
194 assertTrue(mgr.getOutcomes().isEmpty());
197 private void verifyLock(PolicyResult result) {
198 OperationOutcome outcome = mgr.getOutcomes().poll();
199 assertNotNull(outcome);
200 assertEquals(ActorConstants.LOCK_ACTOR, outcome.getActor());
201 assertEquals(ActorConstants.LOCK_OPERATION, outcome.getOperation());
202 assertNotNull(outcome.getEnd());
203 assertTrue(outcome.isFinalOutcome());
204 assertEquals(result, outcome.getResult());
208 public void testOnStart() {
209 OperationOutcome outcome1 = new OperationOutcome();
210 OperationOutcome outcome2 = new OperationOutcome();
212 mgr.onStart(outcome1);
213 mgr.onStart(outcome2);
215 assertSame(outcome1, mgr.getOutcomes().poll());
216 assertSame(outcome2, mgr.getOutcomes().poll());
217 assertTrue(mgr.getOutcomes().isEmpty());
221 public void testOnComplete() {
222 OperationOutcome outcome1 = new OperationOutcome();
223 OperationOutcome outcome2 = new OperationOutcome();
225 mgr.onComplete(outcome1);
226 mgr.onComplete(outcome2);
228 assertSame(outcome1, mgr.getOutcomes().poll());
229 assertSame(outcome2, mgr.getOutcomes().poll());
230 assertTrue(mgr.getOutcomes().isEmpty());
234 public void testContains_testGetProperty_testSetProperty_testRemoveProperty() {
235 mgr.setProperty("abc", "a string");
236 mgr.setProperty(MY_KEY, 100);
238 assertTrue(mgr.contains(MY_KEY));
239 assertFalse(mgr.contains("ghi"));
241 String strValue = mgr.getProperty("abc");
242 assertEquals("a string", strValue);
244 int intValue = mgr.getProperty(MY_KEY);
245 assertEquals(100, intValue);
247 mgr.removeProperty(MY_KEY);
248 assertFalse(mgr.contains(MY_KEY));
252 public void testToString() {
253 assertNotNull(mgr.toString());
256 private void loadPolicy(String fileName) throws CoderException {
257 ToscaServiceTemplate template =
258 yamlCoder.decode(ResourceUtils.getResourceAsString(fileName), ToscaServiceTemplate.class);
259 tosca = template.getToscaTopologyTemplate().getPolicies().get(0).values().iterator().next();
261 params.setToscaPolicy(tosca);
264 private void runExecutor() {
265 ArgumentCaptor<Runnable> runCaptor = ArgumentCaptor.forClass(Runnable.class);
266 verify(executor).execute(runCaptor.capture());
268 runCaptor.getValue().run();
272 private static class MyManager extends ControlLoopEventManager {
273 private static final long serialVersionUID = 1L;
275 private static ExecutorService executor;
276 private static List<LockImpl> locks;
278 public MyManager(ControlLoopParams params, UUID requestId)
279 throws ControlLoopException {
280 super(params, requestId);
284 protected ExecutorService getBlockingExecutor() {
289 protected void makeLock(String targetEntity, String requestId, int holdSec, LockCallback callback) {
290 LockImpl lock = new LockImpl(LockState.ACTIVE, targetEntity, requestId, holdSec, callback);
292 callback.lockAvailable(lock);