summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul J. Davis <paul.joseph.davis@gmail.com>2020-01-06 11:06:40 -0600
committerPaul J. Davis <paul.joseph.davis@gmail.com>2020-01-06 12:50:27 -0600
commit641870ddbc184ffb6abbd877f81c0c99b9444b3f (patch)
tree1bef19783cffc41540b9f2fd949855407609bbb7
parent05b5d063c93c1c7c73bbcb6af601b1a7f796233d (diff)
downloadcouchdb-641870ddbc184ffb6abbd877f81c0c99b9444b3f.tar.gz
Fix JS tests on SpiderMonkey 60
It turns out the infinite loop can now run fast enough that we exhaust the stack space in a given couchjs process. This ends up leaving a couchjs process that can't be used for other things as the `map_results` buffer doesn't get reset inbetween calls.
-rw-r--r--share/server/state.js1
-rw-r--r--share/server/views.js4
-rw-r--r--src/couch/test/eunit/couch_js_tests.erl47
-rw-r--r--test/javascript/tests/view_errors.js4
4 files changed, 54 insertions, 2 deletions
diff --git a/share/server/state.js b/share/server/state.js
index ff553dd57..76fb68b79 100644
--- a/share/server/state.js
+++ b/share/server/state.js
@@ -16,6 +16,7 @@ var State = {
State.funs = [];
State.lib = null;
State.query_config = config || {};
+ Views.reset();
gc();
print("true"); // indicates success
},
diff --git a/share/server/views.js b/share/server/views.js
index 7c9953d83..623f47d5e 100644
--- a/share/server/views.js
+++ b/share/server/views.js
@@ -56,6 +56,7 @@ var Views = (function() {
};
function handleViewError(err, doc) {
+ map_results = [];
if (err == "fatal_error") {
// Only if it's a "fatal_error" do we exit. What's a fatal error?
// That's for the query to decide.
@@ -82,6 +83,9 @@ var Views = (function() {
return {
// view helper functions
+ reset : function() {
+ map_results = [];
+ },
emit : function(key, value) {
map_results.push([key, value]);
},
diff --git a/src/couch/test/eunit/couch_js_tests.erl b/src/couch/test/eunit/couch_js_tests.erl
new file mode 100644
index 000000000..540d8b197
--- /dev/null
+++ b/src/couch/test/eunit/couch_js_tests.erl
@@ -0,0 +1,47 @@
+% 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.
+
+-module(couch_js_tests).
+-include_lib("eunit/include/eunit.hrl").
+
+
+-define(FUNC, <<
+ "function(doc) {\n"
+ " var val = \"0123456789ABCDEF\";\n"
+ " while(true) {emit(val, val);}\n"
+ "}\n"
+>>).
+
+
+couch_js_test_() ->
+ {
+ "Test couchjs",
+ {
+ setup,
+ fun test_util:start_couch/0,
+ fun test_util:stop_couch/1,
+ [
+ fun should_recover_from_oom/0
+ ]
+ }
+ }.
+
+
+should_recover_from_oom() ->
+ Proc = couch_query_servers:get_os_process(<<"javascript">>),
+ R1 = couch_query_servers:proc_prompt(Proc, [<<"add_fun">>, ?FUNC]),
+ R2 = couch_query_servers:proc_prompt(Proc, [<<"map_doc">>, <<"{}">>]),
+ R3 = couch_query_servers:proc_prompt(Proc, [<<"add_fun">>, ?FUNC]),
+
+ ?assertEqual(true, R1),
+ ?assertEqual([[]], R2),
+ ?assertEqual(true, R3).
diff --git a/test/javascript/tests/view_errors.js b/test/javascript/tests/view_errors.js
index 7577b8086..43db3c820 100644
--- a/test/javascript/tests/view_errors.js
+++ b/test/javascript/tests/view_errors.js
@@ -145,7 +145,7 @@ couchTests.view_errors = function(debug) {
_id:"_design/infinite",
language: "javascript",
views: {
- "infinite_loop" :{map:"function(doc) {while(true){emit(doc,doc);}};"}
+ "infinite_loop" :{map:"function(doc) {while(true){};}"}
}
};
T(db.save(designDoc3).ok);
@@ -154,7 +154,7 @@ couchTests.view_errors = function(debug) {
db.view("infinite/infinite_loop");
T(0 == 1);
} catch(e) {
- T(e.error == "os_process_error" || e.error == "unnamed_error");
+ T(e.error == "os_process_error");
}
// Check error responses for invalid multi-get bodies.