diff options
author | Robert Newson <robert.newson@cloudant.com> | 2011-09-28 11:18:06 +0100 |
---|---|---|
committer | Robert Newson <robert.newson@cloudant.com> | 2011-09-28 11:32:50 +0100 |
commit | 954ddf0fca558f17f39e68df8311ee9057beb390 (patch) | |
tree | 2542c112210363076be1a8bc7b24e13bfaf1c055 /rel | |
parent | c8d7b6d8c3cb881d525be80bc6b16bc08822df65 (diff) | |
parent | befbdfb11f45bd2a5ccffb6b0d5ac04435ac9e55 (diff) |
Merge 1.1.x changes
Conflicts:
apps/couch/include/couch_db.hrl
apps/couch/src/couch_db.erl
apps/couch/src/couch_os_process.erl
apps/couch/src/couch_query_servers.erl
apps/couch/src/couch_rep.erl
apps/couch/src/couch_replication_manager.erl
apps/couch/src/couch_view_compactor.erl
apps/couch/src/couch_view_group.erl
apps/couch/src/couch_view_updater.erl
configure.ac
couchjs/c_src/http.c
couchjs/c_src/main.c
couchjs/c_src/utf8.c
etc/windows/couchdb.iss.tpl
src/couchdb/priv/Makefile.am
src/couchdb/priv/couch_js/main.c
test/etap/160-vhosts.t
test/etap/200-view-group-no-db-leaks.t
test/etap/Makefile.am
BugzID: 12645
Diffstat (limited to 'rel')
-rw-r--r-- | rel/overlay/etc/default.ini | 1 | ||||
-rw-r--r-- | rel/overlay/share/www/script/couch_test_runner.js | 15 | ||||
-rw-r--r-- | rel/overlay/share/www/script/futon.browse.js | 3 | ||||
-rw-r--r-- | rel/overlay/share/www/script/test/all_docs.js | 7 | ||||
-rw-r--r-- | rel/overlay/share/www/script/test/basics.js | 19 | ||||
-rw-r--r-- | rel/overlay/share/www/script/test/changes.js | 26 | ||||
-rw-r--r-- | rel/overlay/share/www/script/test/design_docs.js | 39 | ||||
-rw-r--r-- | rel/overlay/share/www/script/test/etags_views.js | 8 | ||||
-rw-r--r-- | rel/overlay/share/www/script/test/jsonp.js | 2 | ||||
-rw-r--r-- | rel/overlay/share/www/script/test/recreate_doc.js | 41 | ||||
-rw-r--r-- | rel/overlay/share/www/script/test/show_documents.js | 26 | ||||
-rw-r--r-- | rel/overlay/share/www/script/test/update_documents.js | 14 | ||||
-rw-r--r-- | rel/overlay/share/www/script/test/view_collation_raw.js | 9 |
13 files changed, 206 insertions, 4 deletions
diff --git a/rel/overlay/etc/default.ini b/rel/overlay/etc/default.ini index cb032152..55371083 100644 --- a/rel/overlay/etc/default.ini +++ b/rel/overlay/etc/default.ini @@ -51,6 +51,7 @@ allow_jsonp = false ;server_options = [{backlog, 128}, {acceptor_pool_size, 16}] ; For more socket options, consult Erlang's module 'inet' man page. ;socket_options = [{recbuf, 262144}, {sndbuf, 262144}, {nodelay, true}] +log_max_chunk_size = 1000000 [ssl] port = 6984 diff --git a/rel/overlay/share/www/script/couch_test_runner.js b/rel/overlay/share/www/script/couch_test_runner.js index 55a6533f..e14640b6 100644 --- a/rel/overlay/share/www/script/couch_test_runner.js +++ b/rel/overlay/share/www/script/couch_test_runner.js @@ -414,9 +414,22 @@ function waitForSuccess(fun, tag) { function waitForRestart() { var waiting = true; - while (waiting) { + // Wait for the server to go down but don't + // wait too long because we might miss the + // unavailable period. + var count = 25; + while (waiting && count > 0) { + count--; try { CouchDB.request("GET", "/"); + } catch(e) { + waiting = false; + } + } + // Wait for it to come back up + waiting = true; + while (waiting) { + try { CouchDB.request("GET", "/"); waiting = false; } catch(e) { diff --git a/rel/overlay/share/www/script/futon.browse.js b/rel/overlay/share/www/script/futon.browse.js index b981feec..faacc64e 100644 --- a/rel/overlay/share/www/script/futon.browse.js +++ b/rel/overlay/share/www/script/futon.browse.js @@ -1275,8 +1275,7 @@ return false; }).prependTo($("a", li)); } - }, - + } }); function encodeAttachment(name) { diff --git a/rel/overlay/share/www/script/test/all_docs.js b/rel/overlay/share/www/script/test/all_docs.js index 1d83aa95..1afe701d 100644 --- a/rel/overlay/share/www/script/test/all_docs.js +++ b/rel/overlay/share/www/script/test/all_docs.js @@ -41,6 +41,13 @@ couchTests.all_docs = function(debug) { var all = db.allDocs({startkey:"2"}); T(all.offset == 2); + // Confirm that queries may assume raw collation. + var raw = db.allDocs({ + startkey: "org.couchdb.user:", + endkey: "org.couchdb.user;" + }); + TEquals(0, raw.rows.length); + // check that the docs show up in the seq view in the order they were created var changes = db.changes(); var ids = ["0","3","1","2"]; diff --git a/rel/overlay/share/www/script/test/basics.js b/rel/overlay/share/www/script/test/basics.js index 30c27c11..5dcf9fa9 100644 --- a/rel/overlay/share/www/script/test/basics.js +++ b/rel/overlay/share/www/script/test/basics.js @@ -246,4 +246,23 @@ couchTests.basics = function(debug) { result = JSON.parse(xhr.responseText); TEquals("bad_request", result.error); TEquals("You tried to DELETE a database with a ?=rev parameter. Did you mean to DELETE a document instead?", result.reason); + + // On restart, a request for creating a database that already exists can + // not override the existing database file + db = new CouchDB("test_suite_foobar"); + db.deleteDb(); + xhr = CouchDB.request("PUT", "/" + db.name); + TEquals(201, xhr.status); + + TEquals(true, db.save({"_id": "doc1"}).ok); + TEquals(true, db.ensureFullCommit().ok); + + TEquals(1, db.info().doc_count); + + restartServer(); + + xhr = CouchDB.request("PUT", "/" + db.name); + TEquals(412, xhr.status); + + TEquals(1, db.info().doc_count); }; diff --git a/rel/overlay/share/www/script/test/changes.js b/rel/overlay/share/www/script/test/changes.js index ea22bfb3..284f1985 100644 --- a/rel/overlay/share/www/script/test/changes.js +++ b/rel/overlay/share/www/script/test/changes.js @@ -507,6 +507,32 @@ couchTests.changes = function(debug) { CouchDB.request("GET", "/" + db.name + "/_changes"); TEquals(0, CouchDB.requestStats('httpd', 'clients_requesting_changes').current); + // COUCHDB-1256 + T(db.deleteDb()); + T(db.createDb()); + + T(db.save({"_id":"foo", "a" : 123}).ok); + T(db.save({"_id":"bar", "a" : 456}).ok); + + options = { + headers: {"Content-Type": "application/json"}, + body: JSON.stringify({"_rev":"1-cc609831f0ca66e8cd3d4c1e0d98108a", "a":456}) + }; + req = CouchDB.request("PUT", "/" + db.name + "/foo?new_edits=false", options); + + req = CouchDB.request("GET", "/" + db.name + "/_changes?style=all_docs"); + resp = JSON.parse(req.responseText); + + TEquals(3, resp.last_seq); + TEquals(2, resp.results.length); + + req = CouchDB.request("GET", "/" + db.name + "/_changes?style=all_docs&since=2"); + resp = JSON.parse(req.responseText); + + TEquals(3, resp.last_seq); + TEquals(1, resp.results.length); + TEquals(2, resp.results[0].changes.length); + // cleanup db.deleteDb(); }; diff --git a/rel/overlay/share/www/script/test/design_docs.js b/rel/overlay/share/www/script/test/design_docs.js index 702f0441..dd38858a 100644 --- a/rel/overlay/share/www/script/test/design_docs.js +++ b/rel/overlay/share/www/script/test/design_docs.js @@ -421,6 +421,45 @@ couchTests.design_docs = function(debug) { run_on_modified_server(server_config, testFun); + // COUCHDB-1227 - if a design document is deleted, by adding a "_deleted" + // field with the boolean value true, its validate_doc_update functions + // should no longer have effect. + db.deleteDb(); + db.createDb(); + var ddoc = { + _id: "_design/test", + language: "javascript", + validate_doc_update: (function(newDoc, oldDoc, userCtx, secObj) { + if (newDoc.value % 2 == 0) { + throw({forbidden: "dont like even numbers"}); + } + return true; + }).toString() + }; + + TEquals(true, db.save(ddoc).ok); + try { + db.save({_id: "doc1", value: 4}); + T(false, "doc insertion should have failed"); + } catch (x) { + TEquals("forbidden", x.error); + } + + var doc = db.open("doc1"); + TEquals(null, doc); + ddoc._deleted = true; + TEquals(true, db.save(ddoc).ok); + + try { + TEquals(true, db.save({_id: "doc1", value: 4}).ok); + } catch (x) { + T(false, "doc insertion should have succeeded"); + } + + doc = db.open("doc1"); + TEquals(true, doc !== null, "doc was not persisted"); + TEquals(4, doc.value); + // cleanup db.deleteDb(); db2.deleteDb(); diff --git a/rel/overlay/share/www/script/test/etags_views.js b/rel/overlay/share/www/script/test/etags_views.js index 34116f71..f6a4e1a5 100644 --- a/rel/overlay/share/www/script/test/etags_views.js +++ b/rel/overlay/share/www/script/test/etags_views.js @@ -70,6 +70,14 @@ couchTests.etags_views = function(debug) { xhr = CouchDB.request("GET", "/test_suite_db/_design/etags/_view/basicView"); var etag1 = xhr.getResponseHeader("etag"); T(etag1 == etag); + + // verify ETag always changes for include_docs=true on update + xhr = CouchDB.request("GET", "/test_suite_db/_design/etags/_view/basicView?include_docs=true"); + var etag1 = xhr.getResponseHeader("etag"); + T(db.save({"_id":"doc2", "foo":"bar"}).ok); + xhr = CouchDB.request("GET", "/test_suite_db/_design/etags/_view/basicView?include_docs=true"); + var etag2 = xhr.getResponseHeader("etag"); + T(etag1 != etag2); // Verify that purges affect etags xhr = CouchDB.request("GET", "/test_suite_db/_design/etags/_view/fooView"); diff --git a/rel/overlay/share/www/script/test/jsonp.js b/rel/overlay/share/www/script/test/jsonp.js index 9aba7189..d1bca94a 100644 --- a/rel/overlay/share/www/script/test/jsonp.js +++ b/rel/overlay/share/www/script/test/jsonp.js @@ -48,6 +48,7 @@ couchTests.jsonp = function(debug) { // Test unchunked callbacks. var xhr = CouchDB.request("GET", "/test_suite_db/0?callback=jsonp_no_chunk"); + TEquals("text/javascript", xhr.getResponseHeader("Content-Type")); T(xhr.status == 200); jsonp_flag = 0; eval(xhr.responseText); @@ -70,6 +71,7 @@ couchTests.jsonp = function(debug) { var url = "/test_suite_db/_design/test/_view/all_docs?callback=jsonp_chunk"; xhr = CouchDB.request("GET", url); + TEquals("text/javascript", xhr.getResponseHeader("Content-Type")); T(xhr.status == 200); jsonp_flag = 0; eval(xhr.responseText); diff --git a/rel/overlay/share/www/script/test/recreate_doc.js b/rel/overlay/share/www/script/test/recreate_doc.js index 05843558..a1cfb8f8 100644 --- a/rel/overlay/share/www/script/test/recreate_doc.js +++ b/rel/overlay/share/www/script/test/recreate_doc.js @@ -77,4 +77,45 @@ couchTests.recreate_doc = function(debug) { } catch (e) { T(e.error == "conflict"); } + + db.deleteDb(); + db.createDb(); + + // COUCHDB-1265 + // Resuscitate an unavailable old revision and make sure that it + // doesn't introduce duplicates into the _changes feed. + + var doc = {_id: "bar", count: 0}; + T(db.save(doc).ok); + var ghost = {_id: "bar", _rev: doc._rev, count: doc.count}; + for(var i = 0; i < 2; i++) { + doc.count += 1; + T(db.save(doc).ok); + } + + // Compact so that the old revision to be resuscitated will be + // in the rev_tree as ?REV_MISSING + db.compact(); + while(db.info().compact_running) {} + + // Saving the ghost here puts it back in the rev_tree in such + // a way as to create a new update_seq but without changing a + // leaf revision. This would cause the #full_doc_info{} and + // #doc_info{} records to diverge in their idea of what the + // doc's update_seq is and end up introducing a duplicate in + // the _changes feed the next time this doc is updated. + T(db.save(ghost, {new_edits: false}).ok); + + // The duplicate would have been introduce here becuase the #doc_info{} + // would not have been removed correctly. + T(db.save(doc).ok); + + // And finally assert that there are no duplicates in _changes. + var req = CouchDB.request("GET", "/test_suite_db/_changes"); + var resp = JSON.parse(req.responseText); + var docids = {}; + for(var i = 0; i < resp.results.length; i++) { + T(docids[resp.results[i].id] === undefined, "Duplicates in _changes feed."); + docids[resp.results[i].id] = true; + } }; diff --git a/rel/overlay/share/www/script/test/show_documents.js b/rel/overlay/share/www/script/test/show_documents.js index 55ed9698..cf73ed57 100644 --- a/rel/overlay/share/www/script/test/show_documents.js +++ b/rel/overlay/share/www/script/test/show_documents.js @@ -90,6 +90,24 @@ couchTests.show_documents = function(debug) { start({"X-Couch-Test-Header": "Yeah"}); send("Hey"); }), + "list-api-provides" : stringFun(function(doc, req) { + provides("text", function(){ + send("foo, "); + send("bar, "); + send("baz!"); + }) + }), + "list-api-provides-and-return" : stringFun(function(doc, req) { + provides("text", function(){ + send("4, "); + send("5, "); + send("6, "); + return "7!"; + }) + send("1, "); + send("2, "); + return "3, "; + }), "list-api-mix" : stringFun(function(doc, req) { start({"X-Couch-Test-Header": "Yeah"}); send("Hey "); @@ -395,6 +413,14 @@ couchTests.show_documents = function(debug) { T(xhr.responseText == "Hey"); TEquals("Yeah", xhr.getResponseHeader("X-Couch-Test-Header"), "header should be cool"); + // test list() compatible API with provides function + xhr = CouchDB.request("GET", "/test_suite_db/_design/template/_show/list-api-provides/foo?format=text"); + TEquals(xhr.responseText, "foo, bar, baz!", "should join chunks to response body"); + + // should keep next result order: chunks + return value + provided chunks + provided return value + xhr = CouchDB.request("GET", "/test_suite_db/_design/template/_show/list-api-provides-and-return/foo?format=text"); + TEquals(xhr.responseText, "1, 2, 3, 4, 5, 6, 7!", "should not break 1..7 range"); + xhr = CouchDB.request("GET", "/test_suite_db/_design/template/_show/list-api-mix/foo"); T(xhr.responseText == "Hey Dude"); TEquals("Yeah", xhr.getResponseHeader("X-Couch-Test-Header"), "header should be cool"); diff --git a/rel/overlay/share/www/script/test/update_documents.js b/rel/overlay/share/www/script/test/update_documents.js index 49d3b68a..4d2b29fc 100644 --- a/rel/overlay/share/www/script/test/update_documents.js +++ b/rel/overlay/share/www/script/test/update_documents.js @@ -165,4 +165,18 @@ couchTests.update_documents = function(debug) { T(xhr.status == 200); T(xhr.responseText.length == 32); + // COUCHDB-1229 - allow slashes in doc ids for update handlers + // /db/_design/doc/_update/handler/doc/id + + var doc = { + _id:"with/slash", + counter:1 + }; + db.save(doc); + xhr = CouchDB.request("PUT", "/test_suite_db/_design/update/_update/bump-counter/with/slash"); + TEquals(201, xhr.status, "should return a 200 status"); + TEquals("<h1>bumped it!</h1>", xhr.responseText, "should report bumping"); + + var doc = db.open("with/slash"); + TEquals(2, doc.counter, "counter should be 2"); }; diff --git a/rel/overlay/share/www/script/test/view_collation_raw.js b/rel/overlay/share/www/script/test/view_collation_raw.js index 31624cdb..779f7eb8 100644 --- a/rel/overlay/share/www/script/test/view_collation_raw.js +++ b/rel/overlay/share/www/script/test/view_collation_raw.js @@ -76,12 +76,19 @@ couchTests.view_collation_raw = function(debug) { } } T(db.save(designDoc).ok); + + // Confirm that everything collates correctly. var rows = db.view("test/test").rows; for (i=0; i<values.length; i++) { T(equals(rows[i].key, values[i])); } - // everything has collated correctly. Now to check the descending output + // Confirm that couch allows raw semantics in key ranges. + rows = db.view("test/test", {startkey:"Z", endkey:"a"}).rows; + TEquals(1, rows.length); + TEquals("a", rows[0].key); + + // Check the descending output. rows = db.view("test/test", {descending: true}).rows; for (i=0; i<values.length; i++) { T(equals(rows[i].key, values[values.length - 1 -i])); |