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
9 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 * SPDX-License-Identifier: Apache-2.0
18 * ============LICENSE_END=========================================================
21 package org.onap.policy.apex.plugins.executor.javascript;
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;
29 import java.io.IOException;
30 import java.util.concurrent.TimeUnit;
31 import java.util.concurrent.atomic.AtomicBoolean;
33 import org.junit.Before;
34 import org.junit.Test;
35 import org.onap.policy.apex.core.engine.executor.exception.StateMachineException;
36 import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
38 public class JavascriptExecutorTest {
39 private AtomicBoolean concurrentResult = new AtomicBoolean();
42 public void beforeSetTimeouts() {
43 JavascriptExecutor.setTimeunit4Latches(TimeUnit.SECONDS);
44 JavascriptExecutor.setIntializationLatchTimeout(60);
45 JavascriptExecutor.setCleanupLatchTimeout(10);
49 public void testJavescriptExecutorConcurrencyNormal() throws StateMachineException, IOException {
50 JavascriptExecutor.setTimeunit4Latches(TimeUnit.SECONDS);
51 JavascriptExecutor.setIntializationLatchTimeout(60);
52 JavascriptExecutor.setCleanupLatchTimeout(10);
54 JavascriptExecutor executor = new JavascriptExecutor(new AxArtifactKey("executor:0.0.1"));
56 assertThatThrownBy(() -> {
58 }).hasMessageMatching("^javascriptCode is marked .*on.*ull but is null$");
60 assertThatThrownBy(() -> {
62 }).hasMessage("initiation failed, no logic specified for executor executor:0.0.1");
64 assertThatCode(() -> {
65 executor.init("var x = 1;");
66 }).doesNotThrowAnyException();
68 assertThatThrownBy(() -> {
69 executor.init("var x = 1;");
70 }).hasMessage("initiation failed, executor executor:0.0.1 already initialized, run cleanUp to clear executor");
72 assertThatCode(() -> {
74 }).doesNotThrowAnyException();
76 assertThatThrownBy(() -> {
78 }).hasMessage("cleanup failed, executor executor:0.0.1 is not initialized");
80 assertThatThrownBy(() -> {
81 executor.execute("Hello");
82 }).hasMessage("execution failed, executor executor:0.0.1 is not initialized");
84 assertThatCode(() -> {
85 executor.init("var x = 1;");
86 }).doesNotThrowAnyException();
88 assertThatThrownBy(() -> {
89 executor.execute("Hello");
91 "execute: logic for executor:0.0.1 returned a non-boolean value org.mozilla.javascript.Undefined@0");
93 assertThatThrownBy(() -> {
94 executor.execute("Hello");
96 "execute: logic for executor:0.0.1 returned a non-boolean value org.mozilla.javascript.Undefined@0");
98 assertThatThrownBy(() -> {
99 executor.execute("Hello");
101 "execute: logic for executor:0.0.1 returned a non-boolean value org.mozilla.javascript.Undefined@0");
103 assertThatThrownBy(() -> {
104 executor.execute("Hello");
106 "execute: logic for executor:0.0.1 returned a non-boolean value org.mozilla.javascript.Undefined@0");
108 assertThatCode(() -> {
110 }).doesNotThrowAnyException();
112 assertThatThrownBy(() -> {
114 }).hasMessage("cleanup failed, executor executor:0.0.1 is not initialized");
116 assertThatThrownBy(() -> {
117 executor.execute("hello");
118 }).hasMessage("execution failed, executor executor:0.0.1 is not initialized");
122 public void testJavescriptExecutorConcurrencyLatchTimeout() throws StateMachineException, IOException {
123 JavascriptExecutor.setTimeunit4Latches(TimeUnit.MICROSECONDS);
124 JavascriptExecutor.setIntializationLatchTimeout(1);
125 JavascriptExecutor.setCleanupLatchTimeout(10000000);
127 JavascriptExecutor executor = new JavascriptExecutor(new AxArtifactKey("executor:0.0.1"));
129 assertThatThrownBy(() -> {
130 executor.init("var x = 1;");
131 }).hasMessage("JavascriptExecutor executor:0.0.1 initiation timed out after 1 MICROSECONDS");
133 assertThatCode(() -> {
135 }).doesNotThrowAnyException();
137 JavascriptExecutor.setTimeunit4Latches(TimeUnit.SECONDS);
138 JavascriptExecutor.setIntializationLatchTimeout(60);
140 assertThatCode(() -> {
141 executor.init("var x = 1;");
142 }).doesNotThrowAnyException();
144 assertThatCode(() -> {
146 }).doesNotThrowAnyException();
148 JavascriptExecutor.setTimeunit4Latches(TimeUnit.MICROSECONDS);
149 JavascriptExecutor.setIntializationLatchTimeout(60000000);
150 JavascriptExecutor.setCleanupLatchTimeout(1);
152 assertThatCode(() -> {
153 executor.init("var x = 1;");
154 }).doesNotThrowAnyException();
156 assertThatThrownBy(() -> {
158 }).hasMessage("JavascriptExecutor executor:0.0.1 cleanup timed out after 1 MICROSECONDS");
160 JavascriptExecutor.setCleanupLatchTimeout(10000000);
161 assertThatThrownBy(() -> {
163 }).hasMessage("cleanup failed, executor executor:0.0.1 is not initialized");
165 assertThatCode(() -> {
166 executor.init("var x = 1;");
167 }).doesNotThrowAnyException();
169 assertThatCode(() -> {
171 }).doesNotThrowAnyException();
175 public void testJavescriptExecutorBadStates() throws StateMachineException, IOException {
176 JavascriptExecutor executor = new JavascriptExecutor(new AxArtifactKey("executor:0.0.1"));
178 assertThatThrownBy(() -> {
179 executor.execute("hello");
180 }).hasMessage("execution failed, executor executor:0.0.1 is not initialized");
182 assertThatThrownBy(() -> {
184 }).hasMessage("cleanup failed, executor executor:0.0.1 is not initialized");
186 assertThatCode(() -> {
187 executor.init("var x = 1;");
188 }).doesNotThrowAnyException();
190 executor.getExecutorThread().interrupt();
191 await().atMost(10, TimeUnit.SECONDS).until(() -> !executor.getExecutorThread().isAlive());
193 assertThatThrownBy(() -> {
194 executor.execute("hello");
195 }).hasMessage("execution failed, executor executor:0.0.1 is not running, "
196 + "run cleanUp to clear executor and init to restart executor");
198 assertThatThrownBy(() -> {
199 executor.execute("hello");
200 }).hasMessage("execution failed, executor executor:0.0.1 is not running, "
201 + "run cleanUp to clear executor and init to restart executor");
203 assertThatCode(() -> {
205 }).doesNotThrowAnyException();
209 public void testJavescriptExecutorExecution() throws StateMachineException, IOException {
210 JavascriptExecutor executor = new JavascriptExecutor(new AxArtifactKey("executor:0.0.1"));
212 assertThatCode(() -> {
213 executor.init("true;");
214 }).doesNotThrowAnyException();
216 assertThatCode(() -> {
217 assertTrue(executor.execute("hello"));
218 }).doesNotThrowAnyException();
220 assertThatCode(() -> {
222 }).doesNotThrowAnyException();
224 assertThatCode(() -> {
225 executor.init("false;");
226 }).doesNotThrowAnyException();
228 assertThatCode(() -> {
229 assertFalse(executor.execute("hello"));
230 }).doesNotThrowAnyException();
232 assertThatCode(() -> {
234 }).doesNotThrowAnyException();
236 assertThatThrownBy(() -> {
237 executor.init("aaaaa = \"sss");
239 "logic failed to compile for executor:0.0.1 with message: unterminated string literal (executor:0.0.1#1)");
241 assertThatCode(() -> {
243 }).doesNotThrowAnyException();
245 assertThatCode(() -> {
246 executor.init("true;");
247 }).doesNotThrowAnyException();
249 assertThatCode(() -> {
250 assertTrue(executor.execute("hello"));
251 }).doesNotThrowAnyException();
253 assertThatCode(() -> {
255 }).doesNotThrowAnyException();
257 assertThatCode(() -> {
258 executor.init("throw \"this is an error\";");
259 }).doesNotThrowAnyException();
261 assertThatThrownBy(() -> {
262 assertTrue(executor.execute("hello"));
263 }).hasMessage("logic failed to run for executor:0.0.1 with message: this is an error (executor:0.0.1#1)");
265 assertThatCode(() -> {
267 }).doesNotThrowAnyException();
269 assertThatCode(() -> {
270 executor.init("var x = 0; while (x < 100) { x++; }; true;");
271 }).doesNotThrowAnyException();
273 concurrentResult.set(true);
275 // Execute an infinite loop in Javascript
279 while (executor.execute("hello")) {
280 // Loop until interrupted
282 concurrentResult.set(false);
283 } catch (StateMachineException e) {
289 await().atMost(1000, TimeUnit.MILLISECONDS).until(() -> executor.getExecutorThread().isAlive());
291 executor.getExecutorThread().interrupt();
293 await().atMost(1000, TimeUnit.MILLISECONDS).until(() -> !concurrentResult.get());
295 assertThatCode(() -> {
297 }).doesNotThrowAnyException();
299 assertThatCode(() -> {
300 executor.init("true;");
301 }).doesNotThrowAnyException();
303 assertThatCode(() -> {
304 assertTrue(executor.execute("hello"));
305 }).doesNotThrowAnyException();
307 assertThatCode(() -> {
309 }).doesNotThrowAnyException();
311 assertThatCode(() -> {
312 executor.init("x = 1; true;");
313 }).doesNotThrowAnyException();
315 concurrentResult.set(true);
317 // Execute an infinite loop in Javascript
318 Thread executionThread = new Thread() {
321 while (executor.execute("hello")) {
324 } catch (StateMachineException e) {
329 executionThread.start();
331 executionThread.interrupt();
333 await().atMost(300, TimeUnit.MILLISECONDS).until(() -> !executionThread.isAlive());
334 await().atMost(300, TimeUnit.MILLISECONDS).until(() -> !executor.getExecutorThread().isAlive());
336 assertThatCode(() -> {
338 }).doesNotThrowAnyException();