aboutsummaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorhannesw <none@none>2014-03-12 11:26:00 +0100
committerhannesw <none@none>2014-03-12 11:26:00 +0100
commit88255f8931b252105c2e1b9886783b33b834d2af (patch)
tree8e99b4f8b13da4c893ab76fd7c5d8280e26c5e44 /test
parent7b7176399812992b93f01a7bb93a43d049a612c2 (diff)
downloadnashorn-88255f8931b252105c2e1b9886783b33b834d2af.tar.gz
8021350: Share script classes between threads/globals within context
Reviewed-by: lagergren, sundar
Diffstat (limited to 'test')
-rw-r--r--test/src/jdk/nashorn/api/scripting/ScopeTest.java316
-rw-r--r--test/src/jdk/nashorn/api/scripting/resources/func.js42
-rw-r--r--test/src/jdk/nashorn/api/scripting/resources/gettersetter.js38
-rw-r--r--test/src/jdk/nashorn/api/scripting/resources/witheval.js60
4 files changed, 456 insertions, 0 deletions
diff --git a/test/src/jdk/nashorn/api/scripting/ScopeTest.java b/test/src/jdk/nashorn/api/scripting/ScopeTest.java
index a18055bb..dc27d826 100644
--- a/test/src/jdk/nashorn/api/scripting/ScopeTest.java
+++ b/test/src/jdk/nashorn/api/scripting/ScopeTest.java
@@ -245,4 +245,320 @@ public class ScopeTest {
sb.put("x", "newX");
assertTrue(e.eval("x", ctx).equals("newX"));
}
+
+ /**
+ * Test multi-threaded access to defined global variables for shared script classes with multiple globals.
+ */
+ @Test
+ public static void multiThreadedVarTest() throws ScriptException, InterruptedException {
+ final ScriptEngineManager m = new ScriptEngineManager();
+ final ScriptEngine e = m.getEngineByName("nashorn");
+ final Bindings b = e.createBindings();
+ final ScriptContext origContext = e.getContext();
+ final ScriptContext newCtxt = new SimpleScriptContext();
+ newCtxt.setBindings(b, ScriptContext.ENGINE_SCOPE);
+ final String sharedScript = "foo";
+
+ assertEquals(e.eval("var foo = 'original context';", origContext), null);
+ assertEquals(e.eval("var foo = 'new context';", newCtxt), null);
+
+ final Thread t1 = new Thread(new ScriptRunner(e, origContext, sharedScript, "original context", 1000));
+ final Thread t2 = new Thread(new ScriptRunner(e, newCtxt, sharedScript, "new context", 1000));
+ t1.start();
+ t2.start();
+ t1.join();
+ t2.join();
+
+ assertEquals(e.eval("var foo = 'newer context';", newCtxt), null);
+ final Thread t3 = new Thread(new ScriptRunner(e, origContext, sharedScript, "original context", 1000));
+ final Thread t4 = new Thread(new ScriptRunner(e, newCtxt, sharedScript, "newer context", 1000));
+
+ t3.start();
+ t4.start();
+ t3.join();
+ t4.join();
+
+ assertEquals(e.eval(sharedScript), "original context");
+ assertEquals(e.eval(sharedScript, newCtxt), "newer context");
+ }
+
+ /**
+ * Test multi-threaded access to undefined global variables for shared script classes with multiple globals.
+ */
+ @Test
+ public static void multiThreadedGlobalTest() throws ScriptException, InterruptedException {
+ final ScriptEngineManager m = new ScriptEngineManager();
+ final ScriptEngine e = m.getEngineByName("nashorn");
+ final Bindings b = e.createBindings();
+ final ScriptContext origContext = e.getContext();
+ final ScriptContext newCtxt = new SimpleScriptContext();
+ newCtxt.setBindings(b, ScriptContext.ENGINE_SCOPE);
+
+ assertEquals(e.eval("foo = 'original context';", origContext), "original context");
+ assertEquals(e.eval("foo = 'new context';", newCtxt), "new context");
+ final String sharedScript = "foo";
+
+ final Thread t1 = new Thread(new ScriptRunner(e, origContext, sharedScript, "original context", 1000));
+ final Thread t2 = new Thread(new ScriptRunner(e, newCtxt, sharedScript, "new context", 1000));
+ t1.start();
+ t2.start();
+ t1.join();
+ t2.join();
+
+ Object obj3 = e.eval("delete foo; foo = 'newer context';", newCtxt);
+ assertEquals(obj3, "newer context");
+ final Thread t3 = new Thread(new ScriptRunner(e, origContext, sharedScript, "original context", 1000));
+ final Thread t4 = new Thread(new ScriptRunner(e, newCtxt, sharedScript, "newer context", 1000));
+
+ t3.start();
+ t4.start();
+ t3.join();
+ t4.join();
+
+ Assert.assertEquals(e.eval(sharedScript), "original context");
+ Assert.assertEquals(e.eval(sharedScript, newCtxt), "newer context");
+ }
+
+ /**
+ * Test multi-threaded access using the postfix ++ operator for shared script classes with multiple globals.
+ */
+ @Test
+ public static void multiThreadedIncTest() throws ScriptException, InterruptedException {
+ final ScriptEngineManager m = new ScriptEngineManager();
+ final ScriptEngine e = m.getEngineByName("nashorn");
+ final Bindings b = e.createBindings();
+ final ScriptContext origContext = e.getContext();
+ final ScriptContext newCtxt = new SimpleScriptContext();
+ newCtxt.setBindings(b, ScriptContext.ENGINE_SCOPE);
+
+ assertEquals(e.eval("var x = 0;", origContext), null);
+ assertEquals(e.eval("var x = 2;", newCtxt), null);
+ final String sharedScript = "x++;";
+
+ final Thread t1 = new Thread(new Runnable() {
+ @Override
+ public void run() {
+ try {
+ for (int i = 0; i < 1000; i++) {
+ assertEquals(e.eval(sharedScript, origContext), (double)i);
+ }
+ } catch (ScriptException se) {
+ fail(se.toString());
+ }
+ }
+ });
+ final Thread t2 = new Thread(new Runnable() {
+ @Override
+ public void run() {
+ try {
+ for (int i = 2; i < 1000; i++) {
+ assertEquals(e.eval(sharedScript, newCtxt), (double)i);
+ }
+ } catch (ScriptException se) {
+ fail(se.toString());
+ }
+ }
+ });
+ t1.start();
+ t2.start();
+ t1.join();
+ t2.join();
+ }
+
+ /**
+ * Test multi-threaded access to primitive prototype properties for shared script classes with multiple globals.
+ */
+ @Test
+ public static void multiThreadedPrimitiveTest() throws ScriptException, InterruptedException {
+ final ScriptEngineManager m = new ScriptEngineManager();
+ final ScriptEngine e = m.getEngineByName("nashorn");
+ final Bindings b = e.createBindings();
+ final ScriptContext origContext = e.getContext();
+ final ScriptContext newCtxt = new SimpleScriptContext();
+ newCtxt.setBindings(b, ScriptContext.ENGINE_SCOPE);
+
+ Object obj1 = e.eval("String.prototype.foo = 'original context';", origContext);
+ Object obj2 = e.eval("String.prototype.foo = 'new context';", newCtxt);
+ assertEquals(obj1, "original context");
+ assertEquals(obj2, "new context");
+ final String sharedScript = "''.foo";
+
+ final Thread t1 = new Thread(new ScriptRunner(e, origContext, sharedScript, "original context", 1000));
+ final Thread t2 = new Thread(new ScriptRunner(e, newCtxt, sharedScript, "new context", 1000));
+ t1.start();
+ t2.start();
+ t1.join();
+ t2.join();
+
+ Object obj3 = e.eval("delete String.prototype.foo; Object.prototype.foo = 'newer context';", newCtxt);
+ assertEquals(obj3, "newer context");
+ final Thread t3 = new Thread(new ScriptRunner(e, origContext, sharedScript, "original context", 1000));
+ final Thread t4 = new Thread(new ScriptRunner(e, newCtxt, sharedScript, "newer context", 1000));
+
+ t3.start();
+ t4.start();
+ t3.join();
+ t4.join();
+
+ Assert.assertEquals(e.eval(sharedScript), "original context");
+ Assert.assertEquals(e.eval(sharedScript, newCtxt), "newer context");
+ }
+
+ /**
+ * Test multi-threaded scope function invocation for shared script classes with multiple globals.
+ */
+ @Test
+ public static void multiThreadedFunctionTest() throws ScriptException, InterruptedException {
+ final ScriptEngineManager m = new ScriptEngineManager();
+ final ScriptEngine e = m.getEngineByName("nashorn");
+ final Bindings b = e.createBindings();
+ final ScriptContext origContext = e.getContext();
+ final ScriptContext newCtxt = new SimpleScriptContext();
+ newCtxt.setBindings(b, ScriptContext.ENGINE_SCOPE);
+
+ e.eval(new URLReader(ScopeTest.class.getResource("resources/func.js")), origContext);
+ assertEquals(origContext.getAttribute("scopeVar"), 1);
+ assertEquals(e.eval("scopeTest()"), 1);
+
+ e.eval(new URLReader(ScopeTest.class.getResource("resources/func.js")), newCtxt);
+ assertEquals(newCtxt.getAttribute("scopeVar"), 1);
+ assertEquals(e.eval("scopeTest();", newCtxt), 1);
+
+ assertEquals(e.eval("scopeVar = 3;", newCtxt), 3);
+ assertEquals(newCtxt.getAttribute("scopeVar"), 3);
+
+
+ final Thread t1 = new Thread(new ScriptRunner(e, origContext, "scopeTest()", 1, 1000));
+ final Thread t2 = new Thread(new ScriptRunner(e, newCtxt, "scopeTest()", 3, 1000));
+
+ t1.start();
+ t2.start();
+ t1.join();
+ t2.join();
+
+ }
+
+ /**
+ * Test multi-threaded access to global getters and setters for shared script classes with multiple globals.
+ */
+ @Test
+ public static void getterSetterTest() throws ScriptException, InterruptedException {
+ final ScriptEngineManager m = new ScriptEngineManager();
+ final ScriptEngine e = m.getEngineByName("nashorn");
+ final Bindings b = e.createBindings();
+ final ScriptContext origContext = e.getContext();
+ final ScriptContext newCtxt = new SimpleScriptContext();
+ newCtxt.setBindings(b, ScriptContext.ENGINE_SCOPE);
+ final String sharedScript = "accessor1";
+
+ e.eval(new URLReader(ScopeTest.class.getResource("resources/gettersetter.js")), origContext);
+ assertEquals(e.eval("accessor1 = 1;"), 1);
+ assertEquals(e.eval(sharedScript), 1);
+
+ e.eval(new URLReader(ScopeTest.class.getResource("resources/gettersetter.js")), newCtxt);
+ assertEquals(e.eval("accessor1 = 2;", newCtxt), 2);
+ assertEquals(e.eval(sharedScript, newCtxt), 2);
+
+
+ final Thread t1 = new Thread(new ScriptRunner(e, origContext, sharedScript, 1, 1000));
+ final Thread t2 = new Thread(new ScriptRunner(e, newCtxt, sharedScript, 2, 1000));
+
+ t1.start();
+ t2.start();
+ t1.join();
+ t2.join();
+
+ assertEquals(e.eval(sharedScript), 1);
+ assertEquals(e.eval(sharedScript, newCtxt), 2);
+ assertEquals(e.eval("v"), 1);
+ assertEquals(e.eval("v", newCtxt), 2);
+ }
+
+ /**
+ * Test multi-threaded access to global getters and setters for shared script classes with multiple globals.
+ */
+ @Test
+ public static void getterSetter2Test() throws ScriptException, InterruptedException {
+ final ScriptEngineManager m = new ScriptEngineManager();
+ final ScriptEngine e = m.getEngineByName("nashorn");
+ final Bindings b = e.createBindings();
+ final ScriptContext origContext = e.getContext();
+ final ScriptContext newCtxt = new SimpleScriptContext();
+ newCtxt.setBindings(b, ScriptContext.ENGINE_SCOPE);
+ final String sharedScript = "accessor2";
+
+ e.eval(new URLReader(ScopeTest.class.getResource("resources/gettersetter.js")), origContext);
+ assertEquals(e.eval("accessor2 = 1;"), 1);
+ assertEquals(e.eval(sharedScript), 1);
+
+ e.eval(new URLReader(ScopeTest.class.getResource("resources/gettersetter.js")), newCtxt);
+ assertEquals(e.eval("accessor2 = 2;", newCtxt), 2);
+ assertEquals(e.eval(sharedScript, newCtxt), 2);
+
+
+ final Thread t1 = new Thread(new ScriptRunner(e, origContext, sharedScript, 1, 1000));
+ final Thread t2 = new Thread(new ScriptRunner(e, newCtxt, sharedScript, 2, 1000));
+
+ t1.start();
+ t2.start();
+ t1.join();
+ t2.join();
+
+ assertEquals(e.eval(sharedScript), 1);
+ assertEquals(e.eval(sharedScript, newCtxt), 2);
+ assertEquals(e.eval("x"), 1);
+ assertEquals(e.eval("x", newCtxt), 2);
+ }
+
+ /**
+ * Test "slow" scopes involving {@code with} and {@code eval} statements for shared script classes with multiple globals.
+ */
+ @Test
+ public static void testSlowScope() throws ScriptException, InterruptedException {
+ final ScriptEngineManager m = new ScriptEngineManager();
+ final ScriptEngine e = m.getEngineByName("nashorn");
+
+ for (int i = 0; i < 100; i++) {
+ final Bindings b = e.createBindings();
+ final ScriptContext ctxt = new SimpleScriptContext();
+ ctxt.setBindings(b, ScriptContext.ENGINE_SCOPE);
+
+ e.eval(new URLReader(ScopeTest.class.getResource("resources/witheval.js")), ctxt);
+ assertEquals(e.eval("a", ctxt), 1);
+ assertEquals(b.get("a"), 1);
+ assertEquals(e.eval("b", ctxt), 3);
+ assertEquals(b.get("b"), 3);
+ assertEquals(e.eval("c", ctxt), 10);
+ assertEquals(b.get("c"), 10);
+ }
+ }
+
+ private static class ScriptRunner implements Runnable {
+
+ final ScriptEngine engine;
+ final ScriptContext context;
+ final String source;
+ final Object expected;
+ final int iterations;
+
+ ScriptRunner(final ScriptEngine engine, final ScriptContext context, final String source, final Object expected, final int iterations) {
+ this.engine = engine;
+ this.context = context;
+ this.source = source;
+ this.expected = expected;
+ this.iterations = iterations;
+ }
+
+ @Override
+ public void run() {
+ try {
+ for (int i = 0; i < iterations; i++) {
+ assertEquals(engine.eval(source, context), expected);
+ }
+ } catch (ScriptException se) {
+ throw new RuntimeException(se);
+ }
+ }
+ }
+
}
diff --git a/test/src/jdk/nashorn/api/scripting/resources/func.js b/test/src/jdk/nashorn/api/scripting/resources/func.js
new file mode 100644
index 00000000..477bd1a6
--- /dev/null
+++ b/test/src/jdk/nashorn/api/scripting/resources/func.js
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// This script is loaded from jdk.nashorn.api.scripting.ScopeTest to test script class sharing and reuse.
+
+var scopeVar = 1;
+var global = this;
+undefGlobal = this;
+
+function scopeTest() {
+ if (this !== global) {
+ throw new Error("this !== global");
+ }
+ if (this !== undefGlobal) {
+ throw new Error("this !== undefinedGlobal")
+ }
+ return scopeVar;
+}
+
+scopeTest();
diff --git a/test/src/jdk/nashorn/api/scripting/resources/gettersetter.js b/test/src/jdk/nashorn/api/scripting/resources/gettersetter.js
new file mode 100644
index 00000000..51e24727
--- /dev/null
+++ b/test/src/jdk/nashorn/api/scripting/resources/gettersetter.js
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// This script is loaded from jdk.nashorn.api.scripting.ScopeTest to test script class sharing and reuse.
+
+var v;
+
+Object.defineProperty(this, "accessor1", {
+ get: function() { return v; },
+ set: function(n) { v = n; }
+});
+
+Object.defineProperty(this, "accessor2", {
+ get: function() { return x; },
+ set: function(n) { x = n; }
+});
diff --git a/test/src/jdk/nashorn/api/scripting/resources/witheval.js b/test/src/jdk/nashorn/api/scripting/resources/witheval.js
new file mode 100644
index 00000000..6041d5b4
--- /dev/null
+++ b/test/src/jdk/nashorn/api/scripting/resources/witheval.js
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// This script is loaded from jdk.nashorn.api.scripting.ScopeTest to test script class sharing and reuse.
+
+var a;
+
+function outer(p, e) {
+ eval(e);
+ with(p) {
+ function inner() {
+ a = 1;
+ c = 10;
+ if (a !== 1) {
+ throw new Error("a !== 1");
+ }
+ if (b !== 3) {
+ throw new Error("b !== 3");
+ }
+ if (c !== 10) {
+ throw new Error("c !== 10");
+ }
+ }
+ inner();
+ }
+}
+
+outer({}, "b = 3;");
+
+if (a !== 1) {
+ throw new Error("a !== 1");
+}
+if (b !== 3) {
+ throw new Error("b !== 3");
+}
+if (c !== 10) {
+ throw new Error("c !== 10");
+}