summaryrefslogtreecommitdiff
path: root/rel
diff options
context:
space:
mode:
Diffstat (limited to 'rel')
-rw-r--r--rel/overlay/etc/default.ini1
-rw-r--r--rel/overlay/share/www/script/couch_test_runner.js15
-rw-r--r--rel/overlay/share/www/script/futon.browse.js3
-rw-r--r--rel/overlay/share/www/script/test/all_docs.js7
-rw-r--r--rel/overlay/share/www/script/test/basics.js19
-rw-r--r--rel/overlay/share/www/script/test/changes.js26
-rw-r--r--rel/overlay/share/www/script/test/design_docs.js39
-rw-r--r--rel/overlay/share/www/script/test/etags_views.js8
-rw-r--r--rel/overlay/share/www/script/test/jsonp.js2
-rw-r--r--rel/overlay/share/www/script/test/recreate_doc.js41
-rw-r--r--rel/overlay/share/www/script/test/show_documents.js26
-rw-r--r--rel/overlay/share/www/script/test/update_documents.js14
-rw-r--r--rel/overlay/share/www/script/test/view_collation_raw.js9
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]));