Changes for checkstyle 8.32
[policy/apex-pdp.git] / plugins / plugins-executor / plugins-executor-javascript / src / test / java / org / onap / policy / apex / plugins / executor / javascript / JavascriptExecutorTest.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * Copyright (C) 2020 Nordix Foundation.
4  * ================================================================================
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  * SPDX-License-Identifier: Apache-2.0
18  * ============LICENSE_END=========================================================
19  */
20
21 package org.onap.policy.apex.plugins.executor.javascript;
22
23 import static org.assertj.core.api.Assertions.assertThatCode;
24 import static org.assertj.core.api.Assertions.assertThatThrownBy;
25 import static org.awaitility.Awaitility.await;
26 import static org.junit.Assert.assertFalse;
27 import static org.junit.Assert.assertTrue;
28
29 import java.io.IOException;
30 import java.util.concurrent.TimeUnit;
31 import java.util.concurrent.atomic.AtomicBoolean;
32 import org.junit.Before;
33 import org.junit.Test;
34 import org.onap.policy.apex.core.engine.executor.exception.StateMachineException;
35 import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
36 import org.slf4j.ext.XLogger;
37 import org.slf4j.ext.XLoggerFactory;
38
39 public class JavascriptExecutorTest {
40     private static final XLogger LOGGER = XLoggerFactory.getXLogger(JavascriptExecutorTest.class);
41
42     private AtomicBoolean concurrentResult = new AtomicBoolean();
43
44     @Before
45     public void beforeSetTimeouts() {
46         JavascriptExecutor.setTimeunit4Latches(TimeUnit.SECONDS);
47         JavascriptExecutor.setIntializationLatchTimeout(60);
48         JavascriptExecutor.setCleanupLatchTimeout(10);
49     }
50
51     @Test
52     public void testJavescriptExecutorConcurrencyNormal() throws StateMachineException, IOException {
53         JavascriptExecutor.setTimeunit4Latches(TimeUnit.SECONDS);
54         JavascriptExecutor.setIntializationLatchTimeout(60);
55         JavascriptExecutor.setCleanupLatchTimeout(10);
56
57         JavascriptExecutor executor = new JavascriptExecutor(new AxArtifactKey("executor:0.0.1"));
58
59         assertThatThrownBy(() -> {
60             executor.init(null);
61         }).hasMessageMatching("^javascriptCode is marked .*on.*ull but is null$");
62
63         assertThatThrownBy(() -> {
64             executor.init("   ");
65         }).hasMessage("initiation failed, no logic specified for executor executor:0.0.1");
66
67         assertThatCode(() -> {
68             executor.init("var x = 1;");
69         }).doesNotThrowAnyException();
70
71         assertThatThrownBy(() -> {
72             executor.init("var x = 1;");
73         }).hasMessage("initiation failed, executor executor:0.0.1 already initialized, run cleanUp to clear executor");
74
75         assertThatCode(() -> {
76             executor.cleanUp();
77         }).doesNotThrowAnyException();
78
79         assertThatThrownBy(() -> {
80             executor.cleanUp();
81         }).hasMessage("cleanup failed, executor executor:0.0.1 is not initialized");
82
83         assertThatThrownBy(() -> {
84             executor.execute("Hello");
85         }).hasMessage("execution failed, executor executor:0.0.1 is not initialized");
86
87         assertThatCode(() -> {
88             executor.init("var x = 1;");
89         }).doesNotThrowAnyException();
90
91         assertThatThrownBy(() -> {
92             executor.execute("Hello");
93         }).hasMessage(
94             "execute: logic for executor:0.0.1 returned a non-boolean value org.mozilla.javascript.Undefined@0");
95
96         assertThatThrownBy(() -> {
97             executor.execute("Hello");
98         }).hasMessage(
99             "execute: logic for executor:0.0.1 returned a non-boolean value org.mozilla.javascript.Undefined@0");
100
101         assertThatThrownBy(() -> {
102             executor.execute("Hello");
103         }).hasMessage(
104             "execute: logic for executor:0.0.1 returned a non-boolean value org.mozilla.javascript.Undefined@0");
105
106         assertThatThrownBy(() -> {
107             executor.execute("Hello");
108         }).hasMessage(
109             "execute: logic for executor:0.0.1 returned a non-boolean value org.mozilla.javascript.Undefined@0");
110
111         assertThatCode(() -> {
112             executor.cleanUp();
113         }).doesNotThrowAnyException();
114
115         assertThatThrownBy(() -> {
116             executor.cleanUp();
117         }).hasMessage("cleanup failed, executor executor:0.0.1 is not initialized");
118
119         assertThatThrownBy(() -> {
120             executor.execute("hello");
121         }).hasMessage("execution failed, executor executor:0.0.1 is not initialized");
122     }
123
124     @Test
125     public void testJavescriptExecutorConcurrencyLatchTimeout() throws StateMachineException, IOException {
126         JavascriptExecutor.setTimeunit4Latches(TimeUnit.MICROSECONDS);
127         JavascriptExecutor.setIntializationLatchTimeout(1);
128         JavascriptExecutor.setCleanupLatchTimeout(10000000);
129
130         JavascriptExecutor executor = new JavascriptExecutor(new AxArtifactKey("executor:0.0.1"));
131
132         assertThatThrownBy(() -> {
133             executor.init("var x = 1;");
134         }).hasMessage("JavascriptExecutor executor:0.0.1 initiation timed out after 1 MICROSECONDS");
135
136         assertThatCode(() -> {
137             executor.cleanUp();
138         }).doesNotThrowAnyException();
139
140         JavascriptExecutor.setTimeunit4Latches(TimeUnit.SECONDS);
141         JavascriptExecutor.setIntializationLatchTimeout(60);
142
143         assertThatCode(() -> {
144             executor.init("var x = 1;");
145         }).doesNotThrowAnyException();
146
147         assertThatCode(() -> {
148             executor.cleanUp();
149         }).doesNotThrowAnyException();
150
151         JavascriptExecutor.setTimeunit4Latches(TimeUnit.MICROSECONDS);
152         JavascriptExecutor.setIntializationLatchTimeout(60000000);
153         JavascriptExecutor.setCleanupLatchTimeout(1);
154
155         assertThatCode(() -> {
156             executor.init("var x = 1;");
157         }).doesNotThrowAnyException();
158
159         assertThatThrownBy(() -> {
160             executor.cleanUp();
161         }).hasMessage("JavascriptExecutor executor:0.0.1 cleanup timed out after 1 MICROSECONDS");
162
163         JavascriptExecutor.setCleanupLatchTimeout(10000000);
164         assertThatThrownBy(() -> {
165             executor.cleanUp();
166         }).hasMessage("cleanup failed, executor executor:0.0.1 is not initialized");
167
168         assertThatCode(() -> {
169             executor.init("var x = 1;");
170         }).doesNotThrowAnyException();
171
172         assertThatCode(() -> {
173             executor.cleanUp();
174         }).doesNotThrowAnyException();
175     }
176
177     @Test
178     public void testJavescriptExecutorBadStates() throws StateMachineException, IOException {
179         JavascriptExecutor executor = new JavascriptExecutor(new AxArtifactKey("executor:0.0.1"));
180
181         assertThatThrownBy(() -> {
182             executor.execute("hello");
183         }).hasMessage("execution failed, executor executor:0.0.1 is not initialized");
184
185         assertThatThrownBy(() -> {
186             executor.cleanUp();
187         }).hasMessage("cleanup failed, executor executor:0.0.1 is not initialized");
188
189         assertThatCode(() -> {
190             executor.init("var x = 1;");
191         }).doesNotThrowAnyException();
192
193         executor.getExecutorThread().interrupt();
194         await().atMost(10, TimeUnit.SECONDS).until(() -> !executor.getExecutorThread().isAlive());
195
196         assertThatThrownBy(() -> {
197             executor.execute("hello");
198         }).hasMessage("execution failed, executor executor:0.0.1 is not running, "
199             + "run cleanUp to clear executor and init to restart executor");
200
201         assertThatThrownBy(() -> {
202             executor.execute("hello");
203         }).hasMessage("execution failed, executor executor:0.0.1 is not running, "
204             + "run cleanUp to clear executor and init to restart executor");
205
206         assertThatCode(() -> {
207             executor.cleanUp();
208         }).doesNotThrowAnyException();
209     }
210
211     @Test
212     public void testJavescriptExecutorExecution() throws StateMachineException, IOException {
213         JavascriptExecutor executor = new JavascriptExecutor(new AxArtifactKey("executor:0.0.1"));
214
215         assertThatCode(() -> {
216             executor.init("true;");
217         }).doesNotThrowAnyException();
218
219         assertThatCode(() -> {
220             assertTrue(executor.execute("hello"));
221         }).doesNotThrowAnyException();
222
223         assertThatCode(() -> {
224             executor.cleanUp();
225         }).doesNotThrowAnyException();
226
227         assertThatCode(() -> {
228             executor.init("false;");
229         }).doesNotThrowAnyException();
230
231         assertThatCode(() -> {
232             assertFalse(executor.execute("hello"));
233         }).doesNotThrowAnyException();
234
235         assertThatCode(() -> {
236             executor.cleanUp();
237         }).doesNotThrowAnyException();
238
239         assertThatThrownBy(() -> {
240             executor.init("aaaaa = \"sss");
241         }).hasMessage(
242             "logic failed to compile for executor:0.0.1 with message: unterminated string literal (executor:0.0.1#1)");
243
244         assertThatCode(() -> {
245             executor.cleanUp();
246         }).doesNotThrowAnyException();
247
248         assertThatCode(() -> {
249             executor.init("true;");
250         }).doesNotThrowAnyException();
251
252         assertThatCode(() -> {
253             assertTrue(executor.execute("hello"));
254         }).doesNotThrowAnyException();
255
256         assertThatCode(() -> {
257             executor.cleanUp();
258         }).doesNotThrowAnyException();
259
260         assertThatCode(() -> {
261             executor.init("throw \"this is an error\";");
262         }).doesNotThrowAnyException();
263
264         assertThatThrownBy(() -> {
265             assertTrue(executor.execute("hello"));
266         }).hasMessage("logic failed to run for executor:0.0.1 with message: this is an error (executor:0.0.1#1)");
267
268         assertThatCode(() -> {
269             executor.cleanUp();
270         }).doesNotThrowAnyException();
271
272         assertThatCode(() -> {
273             executor.init("var x = 0; while (x < 100) { x++; }; true;");
274         }).doesNotThrowAnyException();
275
276         concurrentResult.set(true);
277
278         // Execute an infinite loop in Javascript
279         (new Thread() {
280             public void run() {
281                 try {
282                     while (executor.execute("hello")) {
283                         LOGGER.debug("test thread running . . .");
284                         // Loop until interrupted
285                     }
286                 } catch (StateMachineException e) {
287                     LOGGER.debug("test thread caught exception", e);
288                 }
289                 concurrentResult.set(false);
290                 LOGGER.debug("test thread exited");
291             }
292         }).start();
293
294         await().atMost(1000, TimeUnit.MILLISECONDS).until(() -> executor.getExecutorThread().isAlive());
295
296         executor.getExecutorThread().interrupt();
297
298         await().atMost(1000, TimeUnit.MILLISECONDS).until(() -> !concurrentResult.get());
299
300         assertThatCode(() -> {
301             executor.cleanUp();
302         }).doesNotThrowAnyException();
303
304         assertThatCode(() -> {
305             executor.init("true;");
306         }).doesNotThrowAnyException();
307
308         assertThatCode(() -> {
309             assertTrue(executor.execute("hello"));
310         }).doesNotThrowAnyException();
311
312         assertThatCode(() -> {
313             executor.cleanUp();
314         }).doesNotThrowAnyException();
315
316         assertThatCode(() -> {
317             executor.init("x = 1; true;");
318         }).doesNotThrowAnyException();
319
320         concurrentResult.set(true);
321
322         // Execute an infinite loop in Javascript
323         Thread executionThread = new Thread() {
324             public void run() {
325                 try {
326                     while (executor.execute("hello")) {
327                         ;
328                     }
329                 } catch (StateMachineException e) {
330                     ;
331                 }
332             }
333         };
334         executionThread.start();
335
336         executionThread.interrupt();
337
338         await().atMost(300, TimeUnit.MILLISECONDS).until(() -> !executionThread.isAlive());
339         await().atMost(300, TimeUnit.MILLISECONDS).until(() -> !executor.getExecutorThread().isAlive());
340
341         assertThatCode(() -> {
342             executor.cleanUp();
343         }).doesNotThrowAnyException();
344     }
345 }