diff options
author | Paul J. Davis <paul.joseph.davis@gmail.com> | 2020-01-06 11:06:40 -0600 |
---|---|---|
committer | Paul J. Davis <paul.joseph.davis@gmail.com> | 2020-01-06 12:50:27 -0600 |
commit | 641870ddbc184ffb6abbd877f81c0c99b9444b3f (patch) | |
tree | 1bef19783cffc41540b9f2fd949855407609bbb7 | |
parent | 05b5d063c93c1c7c73bbcb6af601b1a7f796233d (diff) | |
download | couchdb-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.js | 1 | ||||
-rw-r--r-- | share/server/views.js | 4 | ||||
-rw-r--r-- | src/couch/test/eunit/couch_js_tests.erl | 47 | ||||
-rw-r--r-- | test/javascript/tests/view_errors.js | 4 |
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. |