From d1c16ec2feba9cfba637287b31e2d5881e68a5af Mon Sep 17 00:00:00 2001 From: liamfallon Date: Fri, 27 Mar 2020 17:24:18 +0000 Subject: Fix hanging tests in JavascritExecutor Added tests to check threads start, execute, and stop correctly and fixed JavescriptExecutor class to handle startup and shutdown correctly without hanging. Issue-ID: POLICY-2106 Change-Id: I9ab41023aae2ab1cbcaea53fdf5d48eccd90a2f1 Signed-off-by: liamfallon --- .../javascript/JavascriptExecutorFullApexTest.java | 2 - .../javascript/JavascriptExecutorTest.java | 335 +++++++++++++++++++++ .../JavascriptStateFinalizerExecutorTest.java | 12 +- .../javascript/JavascriptTaskExecutorTest.java | 5 +- .../JavascriptTaskSelectExecutorTest.java | 13 +- 5 files changed, 350 insertions(+), 17 deletions(-) create mode 100644 plugins/plugins-executor/plugins-executor-javascript/src/test/java/org/onap/policy/apex/plugins/executor/javascript/JavascriptExecutorTest.java (limited to 'plugins/plugins-executor/plugins-executor-javascript/src/test/java/org/onap') diff --git a/plugins/plugins-executor/plugins-executor-javascript/src/test/java/org/onap/policy/apex/plugins/executor/javascript/JavascriptExecutorFullApexTest.java b/plugins/plugins-executor/plugins-executor-javascript/src/test/java/org/onap/policy/apex/plugins/executor/javascript/JavascriptExecutorFullApexTest.java index 9a6b8c7a6..5078c9730 100644 --- a/plugins/plugins-executor/plugins-executor-javascript/src/test/java/org/onap/policy/apex/plugins/executor/javascript/JavascriptExecutorFullApexTest.java +++ b/plugins/plugins-executor/plugins-executor-javascript/src/test/java/org/onap/policy/apex/plugins/executor/javascript/JavascriptExecutorFullApexTest.java @@ -28,7 +28,6 @@ import java.io.IOException; import java.util.concurrent.TimeUnit; import org.apache.commons.lang3.StringUtils; -import org.junit.Ignore; import org.junit.Test; import org.onap.policy.apex.model.basicmodel.concepts.ApexException; import org.onap.policy.apex.service.engine.main.ApexMain; @@ -36,7 +35,6 @@ import org.onap.policy.common.utils.resources.TextFileUtils; public class JavascriptExecutorFullApexTest { - @Ignore @Test public void testFullApexPolicy() throws ApexException { final String[] args = {"src/test/resources/prodcons/File2File.json"}; diff --git a/plugins/plugins-executor/plugins-executor-javascript/src/test/java/org/onap/policy/apex/plugins/executor/javascript/JavascriptExecutorTest.java b/plugins/plugins-executor/plugins-executor-javascript/src/test/java/org/onap/policy/apex/plugins/executor/javascript/JavascriptExecutorTest.java new file mode 100644 index 000000000..53781e870 --- /dev/null +++ b/plugins/plugins-executor/plugins-executor-javascript/src/test/java/org/onap/policy/apex/plugins/executor/javascript/JavascriptExecutorTest.java @@ -0,0 +1,335 @@ +/*- + * ============LICENSE_START======================================================= + * 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.plugins.executor.javascript; + +import static org.assertj.core.api.Assertions.assertThatCode; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.awaitility.Awaitility.await; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.io.IOException; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; + +import org.junit.Before; +import org.junit.Test; +import org.onap.policy.apex.core.engine.executor.exception.StateMachineException; +import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey; + +public class JavascriptExecutorTest { + private AtomicBoolean concurrentResult = new AtomicBoolean(); + + @Before + public void beforeSetTimeouts() { + JavascriptExecutor.setTimeunit4Latches(TimeUnit.SECONDS); + JavascriptExecutor.setIntializationLatchTimeout(60); + JavascriptExecutor.setCleanupLatchTimeout(10); + } + + @Test + public void testJavescriptExecutorConcurrencyNormal() throws StateMachineException, IOException { + JavascriptExecutor.setTimeunit4Latches(TimeUnit.SECONDS); + JavascriptExecutor.setIntializationLatchTimeout(60); + JavascriptExecutor.setCleanupLatchTimeout(10); + + JavascriptExecutor executor = new JavascriptExecutor(new AxArtifactKey("executor:0.0.1")); + + assertThatThrownBy(() -> { + executor.init(null); + }).hasMessageMatching("^javascriptCode is marked .*on.*ull but is null$"); + + assertThatThrownBy(() -> { + executor.init(" "); + }).hasMessage("initiation failed, no logic specified for executor executor:0.0.1"); + + assertThatCode(() -> { + executor.init("var x = 1;"); + }).doesNotThrowAnyException(); + + assertThatThrownBy(() -> { + executor.init("var x = 1;"); + }).hasMessage("initiation failed, executor executor:0.0.1 already initialized, run cleanUp to clear executor"); + + assertThatCode(() -> { + executor.cleanUp(); + }).doesNotThrowAnyException(); + + assertThatThrownBy(() -> { + executor.cleanUp(); + }).hasMessage("cleanup failed, executor executor:0.0.1 is not initialized"); + + assertThatThrownBy(() -> { + executor.execute("Hello"); + }).hasMessage("execution failed, executor executor:0.0.1 is not initialized"); + + assertThatCode(() -> { + executor.init("var x = 1;"); + }).doesNotThrowAnyException(); + + assertThatThrownBy(() -> { + executor.execute("Hello"); + }).hasMessage( + "execute: logic for executor:0.0.1 returned a non-boolean value org.mozilla.javascript.Undefined@0"); + + assertThatThrownBy(() -> { + executor.execute("Hello"); + }).hasMessage( + "execute: logic for executor:0.0.1 returned a non-boolean value org.mozilla.javascript.Undefined@0"); + + assertThatThrownBy(() -> { + executor.execute("Hello"); + }).hasMessage( + "execute: logic for executor:0.0.1 returned a non-boolean value org.mozilla.javascript.Undefined@0"); + + assertThatThrownBy(() -> { + executor.execute("Hello"); + }).hasMessage( + "execute: logic for executor:0.0.1 returned a non-boolean value org.mozilla.javascript.Undefined@0"); + + assertThatCode(() -> { + executor.cleanUp(); + }).doesNotThrowAnyException(); + + assertThatThrownBy(() -> { + executor.cleanUp(); + }).hasMessage("cleanup failed, executor executor:0.0.1 is not initialized"); + + assertThatThrownBy(() -> { + executor.execute("hello"); + }).hasMessage("execution failed, executor executor:0.0.1 is not initialized"); + } + + @Test + public void testJavescriptExecutorConcurrencyLatchTimeout() throws StateMachineException, IOException { + JavascriptExecutor.setTimeunit4Latches(TimeUnit.MICROSECONDS); + JavascriptExecutor.setIntializationLatchTimeout(1); + JavascriptExecutor.setCleanupLatchTimeout(10000000); + + JavascriptExecutor executor = new JavascriptExecutor(new AxArtifactKey("executor:0.0.1")); + + assertThatThrownBy(() -> { + executor.init("var x = 1;"); + }).hasMessage("JavascriptExecutor executor:0.0.1 initiation timed out after 1 MICROSECONDS"); + + assertThatCode(() -> { + executor.cleanUp(); + }).doesNotThrowAnyException(); + + JavascriptExecutor.setTimeunit4Latches(TimeUnit.SECONDS); + JavascriptExecutor.setIntializationLatchTimeout(60); + + assertThatCode(() -> { + executor.init("var x = 1;"); + }).doesNotThrowAnyException(); + + assertThatCode(() -> { + executor.cleanUp(); + }).doesNotThrowAnyException(); + + JavascriptExecutor.setTimeunit4Latches(TimeUnit.MICROSECONDS); + JavascriptExecutor.setIntializationLatchTimeout(60000000); + JavascriptExecutor.setCleanupLatchTimeout(1); + + assertThatCode(() -> { + executor.init("var x = 1;"); + }).doesNotThrowAnyException(); + + assertThatThrownBy(() -> { + executor.cleanUp(); + }).hasMessage("JavascriptExecutor executor:0.0.1 cleanup timed out after 1 MICROSECONDS"); + + JavascriptExecutor.setCleanupLatchTimeout(10000000); + assertThatThrownBy(() -> { + executor.cleanUp(); + }).hasMessage("cleanup failed, executor executor:0.0.1 is not initialized"); + + assertThatCode(() -> { + executor.init("var x = 1;"); + }).doesNotThrowAnyException(); + + assertThatCode(() -> { + executor.cleanUp(); + }).doesNotThrowAnyException(); + } + + @Test + public void testJavescriptExecutorBadStates() throws StateMachineException, IOException { + JavascriptExecutor executor = new JavascriptExecutor(new AxArtifactKey("executor:0.0.1")); + + assertThatThrownBy(() -> { + executor.execute("hello"); + }).hasMessage("execution failed, executor executor:0.0.1 is not initialized"); + + assertThatThrownBy(() -> { + executor.cleanUp(); + }).hasMessage("cleanup failed, executor executor:0.0.1 is not initialized"); + + assertThatCode(() -> { + executor.init("var x = 1;"); + }).doesNotThrowAnyException(); + + executor.getExecutorThread().interrupt(); + await().atMost(10, TimeUnit.SECONDS).until(() -> !executor.getExecutorThread().isAlive()); + + assertThatThrownBy(() -> { + executor.execute("hello"); + }).hasMessage("execution failed, executor executor:0.0.1 is not running, " + + "run cleanUp to clear executor and init to restart executor"); + + assertThatThrownBy(() -> { + executor.execute("hello"); + }).hasMessage("execution failed, executor executor:0.0.1 is not running, " + + "run cleanUp to clear executor and init to restart executor"); + + assertThatCode(() -> { + executor.cleanUp(); + }).doesNotThrowAnyException(); + } + + @Test + public void testJavescriptExecutorExecution() throws StateMachineException, IOException { + JavascriptExecutor executor = new JavascriptExecutor(new AxArtifactKey("executor:0.0.1")); + + assertThatCode(() -> { + executor.init("true;"); + }).doesNotThrowAnyException(); + + assertThatCode(() -> { + assertTrue(executor.execute("hello")); + }).doesNotThrowAnyException(); + + assertThatCode(() -> { + executor.cleanUp(); + }).doesNotThrowAnyException(); + + assertThatCode(() -> { + executor.init("false;"); + }).doesNotThrowAnyException(); + + assertThatCode(() -> { + assertFalse(executor.execute("hello")); + }).doesNotThrowAnyException(); + + assertThatCode(() -> { + executor.cleanUp(); + }).doesNotThrowAnyException(); + + assertThatThrownBy(() -> { + executor.init("aaaaa = \"sss"); + }).hasMessage( + "logic failed to compile for executor:0.0.1 with message: unterminated string literal (executor:0.0.1#1)"); + + assertThatCode(() -> { + executor.cleanUp(); + }).doesNotThrowAnyException(); + + assertThatCode(() -> { + executor.init("true;"); + }).doesNotThrowAnyException(); + + assertThatCode(() -> { + assertTrue(executor.execute("hello")); + }).doesNotThrowAnyException(); + + assertThatCode(() -> { + executor.cleanUp(); + }).doesNotThrowAnyException(); + + assertThatCode(() -> { + executor.init("throw \"this is an error\";"); + }).doesNotThrowAnyException(); + + assertThatThrownBy(() -> { + assertTrue(executor.execute("hello")); + }).hasMessage("logic failed to run for executor:0.0.1 with message: this is an error (executor:0.0.1#1)"); + + assertThatCode(() -> { + executor.cleanUp(); + }).doesNotThrowAnyException(); + + assertThatCode(() -> { + executor.init("while (true) { x = 1; }; true;"); + }).doesNotThrowAnyException(); + + concurrentResult.set(true); + + // Execute an infinite loop in Javascript + (new Thread() { + public void run() { + try { + concurrentResult.set(executor.execute("hello")); + } catch (StateMachineException e) { + e.printStackTrace(); + } + } + }).start(); + + executor.getExecutorThread().interrupt(); + + await().atMost(1000, TimeUnit.MILLISECONDS).until(() -> !concurrentResult.get()); + + assertThatCode(() -> { + executor.cleanUp(); + }).doesNotThrowAnyException(); + + assertThatCode(() -> { + executor.init("true;"); + }).doesNotThrowAnyException(); + + assertThatCode(() -> { + assertTrue(executor.execute("hello")); + }).doesNotThrowAnyException(); + + assertThatCode(() -> { + executor.cleanUp(); + }).doesNotThrowAnyException(); + + assertThatCode(() -> { + executor.init("x = 1; true;"); + }).doesNotThrowAnyException(); + + concurrentResult.set(true); + + // Execute an infinite loop in Javascript + Thread executionThread = new Thread() { + public void run() { + try { + while (executor.execute("hello")) { + ; + } + } catch (StateMachineException e) { + ; + } + } + }; + executionThread.start(); + + executionThread.interrupt(); + + await().atMost(300, TimeUnit.MILLISECONDS).until(() -> !executionThread.isAlive()); + await().atMost(300, TimeUnit.MILLISECONDS).until(() -> !executor.getExecutorThread().isAlive()); + + assertThatCode(() -> { + executor.cleanUp(); + }).doesNotThrowAnyException(); + } +} diff --git a/plugins/plugins-executor/plugins-executor-javascript/src/test/java/org/onap/policy/apex/plugins/executor/javascript/JavascriptStateFinalizerExecutorTest.java b/plugins/plugins-executor/plugins-executor-javascript/src/test/java/org/onap/policy/apex/plugins/executor/javascript/JavascriptStateFinalizerExecutorTest.java index 62471797f..243a1d977 100644 --- a/plugins/plugins-executor/plugins-executor-javascript/src/test/java/org/onap/policy/apex/plugins/executor/javascript/JavascriptStateFinalizerExecutorTest.java +++ b/plugins/plugins-executor/plugins-executor-javascript/src/test/java/org/onap/policy/apex/plugins/executor/javascript/JavascriptStateFinalizerExecutorTest.java @@ -31,7 +31,6 @@ import java.util.Properties; import org.junit.After; import org.junit.Before; -import org.junit.Ignore; import org.junit.Test; import org.onap.policy.apex.context.parameters.ContextParameterConstants; import org.onap.policy.apex.context.parameters.DistributorParameters; @@ -77,7 +76,6 @@ public class JavascriptStateFinalizerExecutorTest { ParameterService.deregister(EngineParameterConstants.MAIN_GROUP_NAME); } - @Ignore @Test public void testJavaStateFinalizerExecutor() throws Exception { JavascriptStateFinalizerExecutor jsfe = new JavascriptStateFinalizerExecutor(); @@ -104,15 +102,17 @@ public class JavascriptStateFinalizerExecutorTest { Map incomingParameters1 = new HashMap<>(); assertThatThrownBy(() -> { jsfe.execute(-1, new Properties(), incomingParameters1); - }).hasMessage("execution failed, executor NULL:0.0.0:NULL:NULL is not running"); + }).hasMessage("execution failed, executor NULL:0.0.0:NULL:NULL is not running, " + + "run cleanUp to clear executor and init to restart executor"); assertThatThrownBy(() -> { jsfe.prepare(); - }).hasMessage("initiation failed, executor NULL:0.0.0:NULL:NULL failed to start"); + }).hasMessage( + "initiation failed, executor NULL:0.0.0:NULL:NULL already initialized, run cleanUp to clear executor"); - assertThatThrownBy(() -> { + assertThatCode(() -> { jsfe.cleanUp(); - }).hasMessage("cleanup failed, executor NULL:0.0.0:NULL:NULL is not running"); + }).doesNotThrowAnyException(); JavascriptStateFinalizerExecutor jsfe1 = new JavascriptStateFinalizerExecutor(); stateFinalizerLogic.setLogic("java.lang.String"); diff --git a/plugins/plugins-executor/plugins-executor-javascript/src/test/java/org/onap/policy/apex/plugins/executor/javascript/JavascriptTaskExecutorTest.java b/plugins/plugins-executor/plugins-executor-javascript/src/test/java/org/onap/policy/apex/plugins/executor/javascript/JavascriptTaskExecutorTest.java index fe71d3c0e..4fc7507ed 100644 --- a/plugins/plugins-executor/plugins-executor-javascript/src/test/java/org/onap/policy/apex/plugins/executor/javascript/JavascriptTaskExecutorTest.java +++ b/plugins/plugins-executor/plugins-executor-javascript/src/test/java/org/onap/policy/apex/plugins/executor/javascript/JavascriptTaskExecutorTest.java @@ -32,7 +32,6 @@ import java.util.Properties; import org.junit.AfterClass; import org.junit.BeforeClass; -import org.junit.Ignore; import org.junit.Test; import org.onap.policy.apex.context.ContextAlbum; import org.onap.policy.apex.context.ContextException; @@ -98,7 +97,6 @@ public class JavascriptTaskExecutorTest { ParameterService.clear(); } - @Ignore @Test public void testJavascriptTaskExecutor() throws Exception { assertThatThrownBy(() -> { @@ -129,7 +127,7 @@ public class JavascriptTaskExecutorTest { assertThatThrownBy(() -> { jte.prepare(); - }).hasMessage("initiation failed, executor TestTask:0.0.1 is already running"); + }).hasMessage("initiation failed, executor TestTask:0.0.1 already initialized, run cleanUp to clear executor"); assertThatThrownBy(() -> { jte.execute(-1, new Properties(), null); @@ -166,7 +164,6 @@ public class JavascriptTaskExecutorTest { }).doesNotThrowAnyException(); } - @Ignore @Test public void testJavascriptTaskExecutorLogic() throws Exception { JavascriptTaskExecutor jte = new JavascriptTaskExecutor(); diff --git a/plugins/plugins-executor/plugins-executor-javascript/src/test/java/org/onap/policy/apex/plugins/executor/javascript/JavascriptTaskSelectExecutorTest.java b/plugins/plugins-executor/plugins-executor-javascript/src/test/java/org/onap/policy/apex/plugins/executor/javascript/JavascriptTaskSelectExecutorTest.java index de5df5787..fa494ced9 100644 --- a/plugins/plugins-executor/plugins-executor-javascript/src/test/java/org/onap/policy/apex/plugins/executor/javascript/JavascriptTaskSelectExecutorTest.java +++ b/plugins/plugins-executor/plugins-executor-javascript/src/test/java/org/onap/policy/apex/plugins/executor/javascript/JavascriptTaskSelectExecutorTest.java @@ -30,7 +30,6 @@ import java.util.Properties; import org.junit.After; import org.junit.Before; -import org.junit.Ignore; import org.junit.Test; import org.onap.policy.apex.context.parameters.ContextParameterConstants; import org.onap.policy.apex.context.parameters.DistributorParameters; @@ -69,7 +68,6 @@ public class JavascriptTaskSelectExecutorTest { ParameterService.deregister(ContextParameterConstants.PERSISTENCE_GROUP_NAME); } - @Ignore @Test public void testJavascriptTaskSelectExecutor() throws Exception { JavascriptTaskSelectExecutor jtse = new JavascriptTaskSelectExecutor(); @@ -86,14 +84,18 @@ public class JavascriptTaskSelectExecutorTest { assertThatThrownBy(() -> { jtse.prepare(); - }).hasMessage("no logic specified for NULL:0.0.0:NULL:NULL"); + }).hasMessage("initiation failed, no logic specified for executor NULL:0.0.0:NULL:NULL"); AxEvent axEvent1 = new AxEvent(new AxArtifactKey("Event", "0.0.1")); EnEvent event1 = new EnEvent(axEvent1); assertThatThrownBy(() -> { jtse.execute(-1, new Properties(), event1); - }).hasMessage("execution failed, executor NULL:0.0.0:NULL:NULL is not running"); + }).hasMessage("execution failed, executor NULL:0.0.0:NULL:NULL is not initialized"); + + assertThatThrownBy(() -> { + jtse.cleanUp(); + }).hasMessage("cleanup failed, executor NULL:0.0.0:NULL:NULL is not initialized"); state.getTaskSelectionLogic().setLogic("java.lang.String"); jtse.prepare(); @@ -119,7 +121,8 @@ public class JavascriptTaskSelectExecutorTest { assertThatThrownBy(() -> { jtse.prepare(); - }).hasMessage("initiation failed, executor NULL:0.0.0:NULL:NULL is already running"); + }).hasMessage( + "initiation failed, executor NULL:0.0.0:NULL:NULL already initialized, run cleanUp to clear executor"); assertThatCode(() -> { jtse.cleanUp(); -- cgit 1.2.3-korg