From 7860f047be25f99c4d1e83f9456c7eb245ad37dc Mon Sep 17 00:00:00 2001 From: "Damien F. Katz" Date: Sat, 30 May 2009 02:43:52 +0000 Subject: Test and fix for infinite loops in view_servers, fix for crashed OS processes causing leaked erlang processes and fix for view server crashing when view group process terminates. git-svn-id: https://svn.apache.org/repos/asf/couchdb/trunk@780165 13f79535-47bb-0310-9956-ffa450edef68 --- share/www/script/test/view_errors.js | 234 +++++++++++++++++++---------------- 1 file changed, 129 insertions(+), 105 deletions(-) (limited to 'share/www/script/test/view_errors.js') diff --git a/share/www/script/test/view_errors.js b/share/www/script/test/view_errors.js index 5d5223e8..c9ef6d0c 100644 --- a/share/www/script/test/view_errors.js +++ b/share/www/script/test/view_errors.js @@ -15,125 +15,149 @@ couchTests.view_errors = function(debug) { db.deleteDb(); db.createDb(); if (debug) debugger; + + - var doc = {integer: 1, string: "1", array: [1, 2, 3]}; - T(db.save(doc).ok); + run_on_modified_server( + [{section: "couchdb", + key: "os_process_timeout", + value: "500"}], + function() { + var doc = {integer: 1, string: "1", array: [1, 2, 3]}; + T(db.save(doc).ok); - // emitting a key value that is undefined should result in that row not - // being included in the view results - var results = db.query(function(doc) { - emit(doc.undef, null); - }); - T(results.total_rows == 0); + // emitting a key value that is undefined should result in that row not + // being included in the view results + var results = db.query(function(doc) { + emit(doc.undef, null); + }); + T(results.total_rows == 0); - // if a view function throws an exception, its results are not included in - // the view index, but the view does not itself raise an error - var results = db.query(function(doc) { - doc.undef(); // throws an error - }); - T(results.total_rows == 0); + // if a view function throws an exception, its results are not included in + // the view index, but the view does not itself raise an error + var results = db.query(function(doc) { + doc.undef(); // throws an error + }); + T(results.total_rows == 0); - // if a view function includes an undefined value in the emitted key or - // value, an error is logged and the result is not included in the view - // index, and the view itself does not raise an error - var results = db.query(function(doc) { - emit([doc._id, doc.undef], null); - }); - T(results.total_rows == 0); + // if a view function includes an undefined value in the emitted key or + // value, an error is logged and the result is not included in the view + // index, and the view itself does not raise an error + var results = db.query(function(doc) { + emit([doc._id, doc.undef], null); + }); + T(results.total_rows == 0); - // querying a view with invalid params should give a resonable error message - var xhr = CouchDB.request("POST", "/test_suite_db/_temp_view?startkey=foo", { - headers: {"Content-Type": "application/json"}, - body: JSON.stringify({language: "javascript", - map : "function(doc){emit(doc.integer)}" - }) - }); - T(JSON.parse(xhr.responseText).error == "invalid_json"); + // querying a view with invalid params should give a resonable error message + var xhr = CouchDB.request("POST", "/test_suite_db/_temp_view?startkey=foo", { + headers: {"Content-Type": "application/json"}, + body: JSON.stringify({language: "javascript", + map : "function(doc){emit(doc.integer)}" + }) + }); + T(JSON.parse(xhr.responseText).error == "invalid_json"); - // views should ignore Content-Type, like the rest of CouchDB - var xhr = CouchDB.request("POST", "/test_suite_db/_temp_view", { - headers: {"Content-Type": "application/x-www-form-urlencoded"}, - body: JSON.stringify({language: "javascript", - map : "function(doc){}" - }) - }); - T(xhr.status == 200); + // views should ignore Content-Type, like the rest of CouchDB + var xhr = CouchDB.request("POST", "/test_suite_db/_temp_view", { + headers: {"Content-Type": "application/x-www-form-urlencoded"}, + body: JSON.stringify({language: "javascript", + map : "function(doc){}" + }) + }); + T(xhr.status == 200); - var map = function (doc) {emit(doc.integer, doc.integer);}; + var map = function (doc) {emit(doc.integer, doc.integer);}; - try { - db.query(map, null, {group: true}); - T(0 == 1); - } catch(e) { - T(e.error == "query_parse_error"); - } + try { + db.query(map, null, {group: true}); + T(0 == 1); + } catch(e) { + T(e.error == "query_parse_error"); + } - // reduce=false on map views doesn't work, so group=true will - // never throw for temp reduce views. + // reduce=false on map views doesn't work, so group=true will + // never throw for temp reduce views. - var designDoc = { - _id:"_design/test", - language: "javascript", - views: { - "no_reduce": {map:"function(doc) {emit(doc._id, null);}"}, - "with_reduce": { - map:"function (doc) {emit(doc.integer, doc.integer)};", - reduce:"function (keys, values) { return sum(values); };"} - } - }; - T(db.save(designDoc).ok); + var designDoc = { + _id:"_design/test", + language: "javascript", + views: { + "no_reduce": {map:"function(doc) {emit(doc._id, null);}"}, + "with_reduce": { + map:"function (doc) {emit(doc.integer, doc.integer)};", + reduce:"function (keys, values) { return sum(values); };"} + } + }; + T(db.save(designDoc).ok); - var designDoc2 = { - _id:"_design/testbig", - language: "javascript", - views: { - "reduce_too_big" : { - map:"function (doc) {emit(doc.integer, doc.integer)};", - reduce:"function (keys, values) { var chars = []; for (var i=0; i < 1000; i++) {chars.push('wazzap');};return chars; };"} - } - }; - T(db.save(designDoc2).ok); + var designDoc2 = { + _id:"_design/testbig", + language: "javascript", + views: { + "reduce_too_big" : { + map:"function (doc) {emit(doc.integer, doc.integer)};", + reduce:"function (keys, values) { var chars = []; for (var i=0; i < 1000; i++) {chars.push('wazzap');};return chars; };"} + } + }; + T(db.save(designDoc2).ok); - try { - db.view("test/no_reduce", {group: true}); - T(0 == 1); - } catch(e) { - T(e.error == "query_parse_error"); - } + try { + db.view("test/no_reduce", {group: true}); + T(0 == 1); + } catch(e) { + T(e.error == "query_parse_error"); + } + + try { + db.view("test/no_reduce", {reduce: true}); + T(0 == 1); + } catch(e) { + T(db.last_req.status == 400); + T(e.error == "query_parse_error"); + } + + try { + db.view("test/with_reduce", {group: true, reduce: false}); + T(0 == 1); + } catch(e) { + T(e.error == "query_parse_error"); + } - try { - db.view("test/no_reduce", {reduce: true}); - T(0 == 1); - } catch(e) { - T(db.last_req.status == 400); - T(e.error == "query_parse_error"); - } + var designDoc3 = { + _id:"_design/infinite", + language: "javascript", + views: { + "infinite_loop" :{map:"function(doc) {while(true){emit(doc,doc);}};"} + } + }; + T(db.save(designDoc3).ok); - try { - db.view("test/with_reduce", {group: true, reduce: false}); - T(0 == 1); - } catch(e) { - T(e.error == "query_parse_error"); - } + try { + db.view("infinite/infinite_loop"); + T(0 == 1); + } catch(e) { + T(e.error == "os_process_error"); + } - // Check error responses for invalid multi-get bodies. - var path = "/test_suite_db/_design/test/_view/no_reduce"; - var xhr = CouchDB.request("POST", path, {body: "[]"}); - T(xhr.status == 400); - result = JSON.parse(xhr.responseText); - T(result.error == "bad_request"); - T(result.reason == "Request body must be a JSON object"); - var data = "{\"keys\": 1}"; - xhr = CouchDB.request("POST", path, {body:data}); - T(xhr.status == 400); - result = JSON.parse(xhr.responseText); - T(result.error == "bad_request"); - T(result.reason == "`keys` member must be a array."); + // Check error responses for invalid multi-get bodies. + var path = "/test_suite_db/_design/test/_view/no_reduce"; + var xhr = CouchDB.request("POST", path, {body: "[]"}); + T(xhr.status == 400); + result = JSON.parse(xhr.responseText); + T(result.error == "bad_request"); + T(result.reason == "Request body must be a JSON object"); + var data = "{\"keys\": 1}"; + xhr = CouchDB.request("POST", path, {body:data}); + T(xhr.status == 400); + result = JSON.parse(xhr.responseText); + T(result.error == "bad_request"); + T(result.reason == "`keys` member must be a array."); - // if the reduce grows to fast, throw an overflow error - var path = "/test_suite_db/_design/testbig/_view/reduce_too_big"; - xhr = CouchDB.request("GET", path); - T(xhr.status == 500); - result = JSON.parse(xhr.responseText); - T(result.error == "reduce_overflow_error"); + // if the reduce grows to fast, throw an overflow error + var path = "/test_suite_db/_design/testbig/_view/reduce_too_big"; + xhr = CouchDB.request("GET", path); + T(xhr.status == 500); + result = JSON.parse(xhr.responseText); + T(result.error == "reduce_overflow_error"); + }); }; -- cgit v1.2.3