From 571edb05e32a2ae70ca7e1b1086ba937d2941a66 Mon Sep 17 00:00:00 2001 From: Robert Newson Date: Tue, 17 May 2011 19:13:42 +0000 Subject: port Filipe's fix and test for COUCHDB-885 to 1.1.x git-svn-id: https://svn.apache.org/repos/asf/couchdb/branches/1.1.x@1104475 13f79535-47bb-0310-9956-ffa450edef68 --- share/www/script/test/replication.js | 56 ++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) (limited to 'share/www/script') diff --git a/share/www/script/test/replication.js b/share/www/script/test/replication.js index 7f92891e..bde4ad11 100644 --- a/share/www/script/test/replication.js +++ b/share/www/script/test/replication.js @@ -785,6 +785,62 @@ couchTests.replication = function(debug) { TEquals('string', typeof repResult._local_id); + // COUCHDB-885 - push replication of a doc with attachment causes a + // conflict in the target. + dbA = new CouchDB("test_suite_db_a"); + dbB = new CouchDB("test_suite_db_b"); + + dbA.deleteDb(); + dbA.createDb(); + dbB.deleteDb(); + dbB.createDb(); + + var doc = { + _id: "doc1" + }; + TEquals(true, dbA.save(doc).ok); + + repResult = CouchDB.replicate( + dbA.name, + CouchDB.protocol + host + "/" + dbB.name + ); + TEquals(true, repResult.ok); + TEquals(true, repResult.history instanceof Array); + TEquals(1, repResult.history.length); + TEquals(1, repResult.history[0].docs_written); + TEquals(1, repResult.history[0].docs_read); + TEquals(0, repResult.history[0].doc_write_failures); + + doc["_attachments"] = { + "hello.txt": { + "content_type": "text/plain", + "data": "aGVsbG8gd29ybGQ=" // base64:encode("hello world") + }, + "foo.dat": { + "content_type": "not/compressible", + "data": "aSBhbSBub3QgZ3ppcGVk" // base64:encode("i am not gziped") + } + }; + + TEquals(true, dbA.save(doc).ok); + repResult = CouchDB.replicate( + dbA.name, + CouchDB.protocol + host + "/" + dbB.name + ); + TEquals(true, repResult.ok); + TEquals(true, repResult.history instanceof Array); + TEquals(2, repResult.history.length); + TEquals(1, repResult.history[0].docs_written); + TEquals(1, repResult.history[0].docs_read); + TEquals(0, repResult.history[0].doc_write_failures); + + var copy = dbB.open(doc._id, {conflicts: true, deleted_conflicts: true}); + T(copy !== null); + TEquals("undefined", typeof copy._conflicts); + TEquals("undefined", typeof copy._deleted_conflicts); + // end of test for COUCHDB-885 + + // cleanup dbA.deleteDb(); dbB.deleteDb(); -- cgit v1.2.3 From 589a5043e34c3bb98eb97b780fd015e0d1296152 Mon Sep 17 00:00:00 2001 From: Filipe David Borba Manana Date: Tue, 17 May 2011 19:18:57 +0000 Subject: Added extra assertions to the test for COUCHDB-885 This is to verify the attachments really exist in the target and have the right data and metadata. git-svn-id: https://svn.apache.org/repos/asf/couchdb/branches/1.1.x@1104478 13f79535-47bb-0310-9956-ffa450edef68 --- share/www/script/test/replication.js | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'share/www/script') diff --git a/share/www/script/test/replication.js b/share/www/script/test/replication.js index bde4ad11..ea6713e8 100644 --- a/share/www/script/test/replication.js +++ b/share/www/script/test/replication.js @@ -838,6 +838,12 @@ couchTests.replication = function(debug) { T(copy !== null); TEquals("undefined", typeof copy._conflicts); TEquals("undefined", typeof copy._deleted_conflicts); + TEquals("text/plain", copy._attachments["hello.txt"]["content_type"]); + TEquals("aGVsbG8gd29ybGQ=", copy._attachments["hello.txt"]["data"]); + TEquals("gzip", copy._attachments["hello.txt"]["encoding"]); + TEquals("not/compressible", copy._attachments["foo.dat"]["content_type"]); + TEquals("aSBhbSBub3QgZ3ppcGVk", copy._attachments["foo.dat"]["data"]); + TEquals("undefined", typeof copy._attachments["foo.dat"]["encoding"]); // end of test for COUCHDB-885 -- cgit v1.2.3 From 61c777b873004f795060b5f432cce02402bdf026 Mon Sep 17 00:00:00 2001 From: Filipe David Borba Manana Date: Tue, 17 May 2011 19:24:56 +0000 Subject: Add missing doc open option to the test for COUCHDB-885 These were forgotten when backporting the attachment related assertions from 1.0.x. git-svn-id: https://svn.apache.org/repos/asf/couchdb/branches/1.1.x@1104481 13f79535-47bb-0310-9956-ffa450edef68 --- share/www/script/test/replication.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'share/www/script') diff --git a/share/www/script/test/replication.js b/share/www/script/test/replication.js index ea6713e8..a08c0b66 100644 --- a/share/www/script/test/replication.js +++ b/share/www/script/test/replication.js @@ -834,7 +834,9 @@ couchTests.replication = function(debug) { TEquals(1, repResult.history[0].docs_read); TEquals(0, repResult.history[0].doc_write_failures); - var copy = dbB.open(doc._id, {conflicts: true, deleted_conflicts: true}); + var copy = dbB.open(doc._id, { + conflicts: true, deleted_conflicts: true, attachments: true, + att_encoding_info: true}); T(copy !== null); TEquals("undefined", typeof copy._conflicts); TEquals("undefined", typeof copy._deleted_conflicts); -- cgit v1.2.3 From a9ce63984c13d126f633a6ab8a243910feac6bc8 Mon Sep 17 00:00:00 2001 From: Filipe David Borba Manana Date: Wed, 18 May 2011 10:54:39 +0000 Subject: Avoid assertion failure in replication.js due to timing issues git-svn-id: https://svn.apache.org/repos/asf/couchdb/branches/1.1.x@1124185 13f79535-47bb-0310-9956-ffa450edef68 --- share/www/script/test/replication.js | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'share/www/script') diff --git a/share/www/script/test/replication.js b/share/www/script/test/replication.js index a08c0b66..5e85847e 100644 --- a/share/www/script/test/replication.js +++ b/share/www/script/test/replication.js @@ -12,6 +12,20 @@ couchTests.replication = function(debug) { if (debug) debugger; + + function waitForSeq(sourceDb, targetDb) { + var targetSeq, + sourceSeq = sourceDb.info().update_seq, + t0 = new Date(), + t1, + ms = 3000; + + do { + targetSeq = targetDb.info().update_seq; + t1 = new Date(); + } while (((t1 - t0) <= ms) && targetSeq < sourceSeq); + } + var host = CouchDB.host; var dbPairs = [ {source:"test_suite_db_a", @@ -768,6 +782,7 @@ couchTests.replication = function(debug) { var tasksAfter = JSON.parse(xhr.responseText); TEquals(tasks.length, tasksAfter.length); + waitForSeq(dbA, dbB); T(dbB.open("30") !== null); repResult = CouchDB.replicate( -- cgit v1.2.3 From 5b8d4522255662ce2b8637680ed1a3db24c2bcef Mon Sep 17 00:00:00 2001 From: Filipe David Borba Manana Date: Fri, 20 May 2011 10:57:28 +0000 Subject: Replication manager: allow edition of replication documents Replication documents that are not in the triggered state can now be edited by users. This is to make it simpler for Futon users to restart replications - they can just edit the document, remove its state field, and save it, instead of recreating it or adding a similar document but with a different _id. This is a backport of revision 1125319 (trunk). git-svn-id: https://svn.apache.org/repos/asf/couchdb/branches/1.1.x@1125321 13f79535-47bb-0310-9956-ffa450edef68 --- share/www/script/test/replicator_db.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'share/www/script') diff --git a/share/www/script/test/replicator_db.js b/share/www/script/test/replicator_db.js index 2810352c..48e5d5c6 100644 --- a/share/www/script/test/replicator_db.js +++ b/share/www/script/test/replicator_db.js @@ -676,7 +676,8 @@ couchTests.replicator_db = function(debug) { var repDoc = { _id: "foo_rep_doc", source: dbA.name, - target: dbB.name + target: dbB.name, + continuous: true }; T(CouchDB.login("fdmanana", "qwerty").ok); -- cgit v1.2.3 From 86c8ffc732052ba5eb942330ad431d1a42297034 Mon Sep 17 00:00:00 2001 From: Filipe David Borba Manana Date: Sat, 21 May 2011 12:29:38 +0000 Subject: Merged revision 1125680 from trunk Use RFC3339 timestamps in replication documents As recently proposed by Max Odgen, RFC3339 timestamps are now used instead of Unix timestamps. git-svn-id: https://svn.apache.org/repos/asf/couchdb/branches/1.1.x@1125682 13f79535-47bb-0310-9956-ffa450edef68 --- share/www/script/test/replicator_db.js | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'share/www/script') diff --git a/share/www/script/test/replicator_db.js b/share/www/script/test/replicator_db.js index 48e5d5c6..c28e067d 100644 --- a/share/www/script/test/replicator_db.js +++ b/share/www/script/test/replicator_db.js @@ -121,7 +121,7 @@ couchTests.replicator_db = function(debug) { T(repDoc1.source === repDoc.source); T(repDoc1.target === repDoc.target); T(repDoc1._replication_state === "completed", "simple"); - T(typeof repDoc1._replication_state_time === "number"); + T(typeof repDoc1._replication_state_time === "string"); T(typeof repDoc1._replication_id === "string"); } @@ -173,7 +173,7 @@ couchTests.replicator_db = function(debug) { T(repDoc1.source === repDoc.source); T(repDoc1.target === repDoc.target); T(repDoc1._replication_state === "completed", "filtered"); - T(typeof repDoc1._replication_state_time === "number"); + T(typeof repDoc1._replication_state_time === "string"); T(typeof repDoc1._replication_id === "string"); } @@ -217,7 +217,7 @@ couchTests.replicator_db = function(debug) { T(repDoc1.source === repDoc.source); T(repDoc1.target === repDoc.target); T(repDoc1._replication_state === "triggered"); - T(typeof repDoc1._replication_state_time === "number"); + T(typeof repDoc1._replication_state_time === "string"); T(typeof repDoc1._replication_id === "string"); // add a design doc to source, it will be replicated to target @@ -332,7 +332,7 @@ couchTests.replicator_db = function(debug) { T(repDoc1_copy.source === repDoc1.source); T(repDoc1_copy.target === repDoc1.target); T(repDoc1_copy._replication_state === "completed"); - T(typeof repDoc1_copy._replication_state_time === "number"); + T(typeof repDoc1_copy._replication_state_time === "string"); T(typeof repDoc1_copy._replication_id === "string"); var newDoc = { @@ -363,7 +363,7 @@ couchTests.replicator_db = function(debug) { T(repDoc2_copy.source === repDoc1.source); T(repDoc2_copy.target === repDoc1.target); T(repDoc2_copy._replication_state === "completed"); - T(typeof repDoc2_copy._replication_state_time === "number"); + T(typeof repDoc2_copy._replication_state_time === "string"); T(typeof repDoc2_copy._replication_id === "string"); T(repDoc2_copy._replication_id === repDoc1_copy._replication_id); } @@ -400,7 +400,7 @@ couchTests.replicator_db = function(debug) { repDoc1 = repDb.open("foo_dup_rep_doc_1"); T(repDoc1 !== null); T(repDoc1._replication_state === "completed", "identical"); - T(typeof repDoc1._replication_state_time === "number"); + T(typeof repDoc1._replication_state_time === "string"); T(typeof repDoc1._replication_id === "string"); repDoc2 = repDb.open("foo_dup_rep_doc_2"); @@ -444,7 +444,7 @@ couchTests.replicator_db = function(debug) { repDoc1 = repDb.open("foo_dup_cont_rep_doc_1"); T(repDoc1 !== null); T(repDoc1._replication_state === "triggered"); - T(typeof repDoc1._replication_state_time === "number"); + T(typeof repDoc1._replication_state_time === "string"); T(typeof repDoc1._replication_id === "string"); repDoc2 = repDb.open("foo_dup_cont_rep_doc_2"); @@ -470,7 +470,7 @@ couchTests.replicator_db = function(debug) { repDoc1 = repDb.open("foo_dup_cont_rep_doc_1"); T(repDoc1 !== null); T(repDoc1._replication_state === "triggered"); - T(typeof repDoc1._replication_state_time === "number"); + T(typeof repDoc1._replication_state_time === "string"); var newDoc2 = { _id: "foo5000", @@ -739,7 +739,7 @@ couchTests.replicator_db = function(debug) { T(repDoc1.target === repDoc.target); T(repDoc1._replication_state === "completed", "replication document with bad replication id failed"); - T(typeof repDoc1._replication_state_time === "number"); + T(typeof repDoc1._replication_state_time === "string"); T(typeof repDoc1._replication_id === "string"); T(repDoc1._replication_id !== "1234abc"); } @@ -930,7 +930,7 @@ couchTests.replicator_db = function(debug) { var repDoc1 = repDb.open(repDoc._id); T(repDoc1 !== null); T(repDoc1._replication_state === "error"); - T(typeof repDoc1._replication_state_time === "number"); + T(typeof repDoc1._replication_state_time === "string"); T(typeof repDoc1._replication_id === "string"); } -- cgit v1.2.3 From 6f2e87fb5a36bece84a9df3d0cd5c7b87ec60bce Mon Sep 17 00:00:00 2001 From: Filipe David Borba Manana Date: Sat, 21 May 2011 22:01:38 +0000 Subject: Merged revision 1125828 from trunk Add missing option to multipart/related GETs This is necessary as the client needs to be able to know if attachments are encoded or not. git-svn-id: https://svn.apache.org/repos/asf/couchdb/branches/1.1.x@1125830 13f79535-47bb-0310-9956-ffa450edef68 --- share/www/script/test/attachments_multipart.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'share/www/script') diff --git a/share/www/script/test/attachments_multipart.js b/share/www/script/test/attachments_multipart.js index 7f587357..13a5abf4 100644 --- a/share/www/script/test/attachments_multipart.js +++ b/share/www/script/test/attachments_multipart.js @@ -39,7 +39,7 @@ couchTests.attachments_multipart= function(debug) { }, "baz.txt": { "follows":true, - "content_type":"application/test", + "content_type":"text/plain", "length":19 } } @@ -78,12 +78,15 @@ couchTests.attachments_multipart= function(debug) { // now edit an attachment - var doc = db.open("multipart"); + var doc = db.open("multipart", {att_encoding_info: true}); var firstrev = doc._rev; T(doc._attachments["foo.txt"].stub == true); T(doc._attachments["bar.txt"].stub == true); T(doc._attachments["baz.txt"].stub == true); + TEquals("undefined", typeof doc._attachments["foo.txt"].encoding); + TEquals("undefined", typeof doc._attachments["bar.txt"].encoding); + TEquals("gzip", doc._attachments["baz.txt"].encoding); //lets change attachment bar delete doc._attachments["bar.txt"].stub; // remove stub member (or could set to false) -- cgit v1.2.3 From ee6bb16b53069e6b213d1314f78cde2bd648b069 Mon Sep 17 00:00:00 2001 From: Robert Newson Date: Mon, 23 May 2011 09:51:04 +0000 Subject: COUCHDB-1156 - send Accept header so Futon doesn't display HTML where it expects JSON (Thanks Dale Harvey for patch) git-svn-id: https://svn.apache.org/repos/asf/couchdb/branches/1.1.x@1126411 13f79535-47bb-0310-9956-ffa450edef68 --- share/www/script/jquery.couch.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'share/www/script') diff --git a/share/www/script/jquery.couch.js b/share/www/script/jquery.couch.js index edae18fc..9bc1363b 100644 --- a/share/www/script/jquery.couch.js +++ b/share/www/script/jquery.couch.js @@ -624,8 +624,14 @@ }; function ajax(obj, options, errorMessage, ajaxOptions) { + + var defaultAjaxOpts = { + contentType: "application/json", + headers:{"Accept": "application/json"} + }; + options = $.extend({successStatus: 200}, options); - ajaxOptions = $.extend({contentType: "application/json"}, ajaxOptions); + ajaxOptions = $.extend(defaultAjaxOpts, ajaxOptions); errorMessage = errorMessage || "Unknown error"; $.ajax($.extend($.extend({ type: "GET", dataType: "json", cache : !$.browser.msie, -- cgit v1.2.3 From 172a751ce84a46d2f121a1c57f6d5554447c7bee Mon Sep 17 00:00:00 2001 From: Filipe David Borba Manana Date: Wed, 25 May 2011 19:01:03 +0000 Subject: Backported revision 1127632 from trunk Force non admins to supply a user_ctx in replication documents This is to prevent users deleting replication documents added by other users and to make it clear who triggers which replications. git-svn-id: https://svn.apache.org/repos/asf/couchdb/branches/1.1.x@1127634 13f79535-47bb-0310-9956-ffa450edef68 --- share/www/script/test/replicator_db.js | 238 ++++++++++++++++++++++++++++++++- 1 file changed, 231 insertions(+), 7 deletions(-) (limited to 'share/www/script') diff --git a/share/www/script/test/replicator_db.js b/share/www/script/test/replicator_db.js index c28e067d..4434124e 100644 --- a/share/www/script/test/replicator_db.js +++ b/share/www/script/test/replicator_db.js @@ -186,7 +186,10 @@ couchTests.replicator_db = function(debug) { _id: "foo_cont_rep_doc", source: "http://" + host + "/" + dbA.name, target: dbB.name, - continuous: true + continuous: true, + user_ctx: { + roles: ["_admin"] + } }; T(repDb.save(repDoc).ok); @@ -220,10 +223,8 @@ couchTests.replicator_db = function(debug) { T(typeof repDoc1._replication_state_time === "string"); T(typeof repDoc1._replication_id === "string"); - // add a design doc to source, it will be replicated to target - // when the "user_ctx" property is not defined in the replication doc, - // the replication will be done under an _admin context, therefore - // design docs will be replicated + // Design documents are only replicated to local targets if the respective + // replication document has a user_ctx filed with the "_admin" role in it. var ddoc = { _id: "_design/foobar", language: "javascript" @@ -303,8 +304,7 @@ couchTests.replicator_db = function(debug) { T(copy === null); copy = dbB.open("_design/mydesign"); - T(copy !== null); - T(copy.language === "javascript"); + T(copy === null); } @@ -713,6 +713,225 @@ couchTests.replicator_db = function(debug) { } + function test_user_ctx_validation() { + populate_db(dbA, docs1); + populate_db(dbB, []); + populate_db(usersDb, []); + + var joeUserDoc = CouchDB.prepareUserDoc({ + name: "joe", + roles: ["erlanger", "bar"] + }, "erly"); + var fdmananaUserDoc = CouchDB.prepareUserDoc({ + name: "fdmanana", + roles: ["a", "b", "c"] + }, "qwerty"); + + TEquals(true, usersDb.save(joeUserDoc).ok); + TEquals(true, usersDb.save(fdmananaUserDoc).ok); + + T(dbB.setSecObj({ + admins: { + names: [], + roles: ["god"] + }, + readers: { + names: [], + roles: ["foo"] + } + }).ok); + + TEquals(true, CouchDB.login("joe", "erly").ok); + TEquals("joe", CouchDB.session().userCtx.name); + TEquals(-1, CouchDB.session().userCtx.roles.indexOf("_admin")); + + var repDoc = { + _id: "foo_rep", + source: CouchDB.protocol + host + "/" + dbA.name, + target: dbB.name + }; + + try { + repDb.save(repDoc); + T(false, "Should have failed, user_ctx missing."); + } catch (x) { + TEquals("forbidden", x.error); + } + + repDoc.user_ctx = { + name: "john", + roles: ["erlanger"] + }; + + try { + repDb.save(repDoc); + T(false, "Should have failed, wrong user_ctx.name."); + } catch (x) { + TEquals("forbidden", x.error); + } + + repDoc.user_ctx = { + name: "joe", + roles: ["bar", "god", "erlanger"] + }; + + try { + repDb.save(repDoc); + T(false, "Should have failed, a bad role in user_ctx.roles."); + } catch (x) { + TEquals("forbidden", x.error); + } + + // user_ctx.roles might contain only a subset of the user's roles + repDoc.user_ctx = { + name: "joe", + roles: ["erlanger"] + }; + + TEquals(true, repDb.save(repDoc).ok); + CouchDB.logout(); + + waitForRep(repDb, repDoc, "error"); + var repDoc1 = repDb.open(repDoc._id); + T(repDoc1 !== null); + TEquals(repDoc.source, repDoc1.source); + TEquals(repDoc.target, repDoc1.target); + TEquals("error", repDoc1._replication_state); + TEquals("string", typeof repDoc1._replication_id); + TEquals("string", typeof repDoc1._replication_state_time); + + TEquals(true, CouchDB.login("fdmanana", "qwerty").ok); + TEquals("fdmanana", CouchDB.session().userCtx.name); + TEquals(-1, CouchDB.session().userCtx.roles.indexOf("_admin")); + + try { + T(repDb.deleteDoc(repDoc1).ok); + T(false, "Shouldn't be able to delete replication document."); + } catch (x) { + TEquals("forbidden", x.error); + } + + CouchDB.logout(); + TEquals(true, CouchDB.login("joe", "erly").ok); + TEquals("joe", CouchDB.session().userCtx.name); + TEquals(-1, CouchDB.session().userCtx.roles.indexOf("_admin")); + + T(repDb.deleteDoc(repDoc1).ok); + CouchDB.logout(); + + for (var i = 0; i < docs1.length; i++) { + var doc = docs1[i]; + var copy = dbB.open(doc._id); + + TEquals(null, copy); + } + + T(dbB.setSecObj({ + admins: { + names: [], + roles: ["god", "erlanger"] + }, + readers: { + names: [], + roles: ["foo"] + } + }).ok); + + TEquals(true, CouchDB.login("joe", "erly").ok); + TEquals("joe", CouchDB.session().userCtx.name); + TEquals(-1, CouchDB.session().userCtx.roles.indexOf("_admin")); + + repDoc = { + _id: "foo_rep_2", + source: CouchDB.protocol + host + "/" + dbA.name, + target: dbB.name, + user_ctx: { + name: "joe", + roles: ["erlanger"] + } + }; + + TEquals(true, repDb.save(repDoc).ok); + CouchDB.logout(); + + waitForRep(repDb, repDoc, "complete"); + repDoc1 = repDb.open(repDoc._id); + T(repDoc1 !== null); + TEquals(repDoc.source, repDoc1.source); + TEquals(repDoc.target, repDoc1.target); + TEquals("completed", repDoc1._replication_state); + TEquals("string", typeof repDoc1._replication_id); + TEquals("string", typeof repDoc1._replication_state_time); + + for (var i = 0; i < docs1.length; i++) { + var doc = docs1[i]; + var copy = dbB.open(doc._id); + + T(copy !== null); + TEquals(doc.value, copy.value); + } + + // Admins don't need to supply a user_ctx property in replication docs. + // If they do not, the implicit user_ctx "user_ctx": {name: null, roles: []} + // is used, meaning that design documents will not be replicated into + // local targets + T(dbB.setSecObj({ + admins: { + names: [], + roles: [] + }, + readers: { + names: [], + roles: [] + } + }).ok); + + var ddoc = { _id: "_design/foo" }; + TEquals(true, dbA.save(ddoc).ok); + + repDoc = { + _id: "foo_rep_3", + source: CouchDB.protocol + host + "/" + dbA.name, + target: dbB.name + }; + + TEquals(true, repDb.save(repDoc).ok); + waitForRep(repDb, repDoc, "complete"); + repDoc1 = repDb.open(repDoc._id); + T(repDoc1 !== null); + TEquals(repDoc.source, repDoc1.source); + TEquals(repDoc.target, repDoc1.target); + TEquals("completed", repDoc1._replication_state); + TEquals("string", typeof repDoc1._replication_id); + TEquals("string", typeof repDoc1._replication_state_time); + + var ddoc_copy = dbB.open(ddoc._id); + T(ddoc_copy === null); + + repDoc = { + _id: "foo_rep_4", + source: CouchDB.protocol + host + "/" + dbA.name, + target: dbB.name, + user_ctx: { + roles: ["_admin"] + } + }; + + TEquals(true, repDb.save(repDoc).ok); + waitForRep(repDb, repDoc, "complete"); + repDoc1 = repDb.open(repDoc._id); + T(repDoc1 !== null); + TEquals(repDoc.source, repDoc1.source); + TEquals(repDoc.target, repDoc1.target); + TEquals("completed", repDoc1._replication_state); + TEquals("string", typeof repDoc1._replication_id); + TEquals("string", typeof repDoc1._replication_state_time); + + ddoc_copy = dbB.open(ddoc._id); + T(ddoc_copy !== null); + } + + function rep_doc_with_bad_rep_id() { populate_db(dbA, docs1); populate_db(dbB, []); @@ -1111,6 +1330,11 @@ couchTests.replicator_db = function(debug) { value: usersDb.name } ]); + + repDb.deleteDb(); + restartServer(); + run_on_modified_server(server_config_2, test_user_ctx_validation); + repDb.deleteDb(); restartServer(); run_on_modified_server(server_config_2, test_replication_credentials_delegation); -- cgit v1.2.3 From 7c719fe3b113f03e37aced91ab28957e2c4aeab3 Mon Sep 17 00:00:00 2001 From: Robert Newson Date: Thu, 26 May 2011 19:00:19 +0000 Subject: COUCHDB-1178 - fix make_first_doc_on_disk function_clause error git-svn-id: https://svn.apache.org/repos/asf/couchdb/branches/1.1.x@1128039 13f79535-47bb-0310-9956-ffa450edef68 --- share/www/script/couch_tests.js | 1 + share/www/script/test/regression.js | 48 +++++++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+) create mode 100644 share/www/script/test/regression.js (limited to 'share/www/script') diff --git a/share/www/script/couch_tests.js b/share/www/script/couch_tests.js index eb573526..4c5c00d6 100644 --- a/share/www/script/couch_tests.js +++ b/share/www/script/couch_tests.js @@ -76,6 +76,7 @@ loadTest("reduce.js"); loadTest("reduce_builtin.js"); loadTest("reduce_false.js"); loadTest("reduce_false_temp.js"); +loadTest("regression.js"); loadTest("replication.js"); loadTest("replicator_db.js"); loadTest("rev_stemming.js"); diff --git a/share/www/script/test/regression.js b/share/www/script/test/regression.js new file mode 100644 index 00000000..abe42b40 --- /dev/null +++ b/share/www/script/test/regression.js @@ -0,0 +1,48 @@ +// 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. + +couchTests.regression = function(debug) { + var db = new CouchDB("test_suite_db", {"X-Couch-Full-Commit":"false"}); + db.deleteDb(); + db.createDb(); + if (debug) debugger; + + // COUCHDB-1178 + { + var r1 = {"_id":"doc","foo":"bar"}; + var r2 = {"_id":"doc","foo":"baz","_rev":"1-4c6114c65e295552ab1019e2b046b10e"}; + var r3 = {"_id":"doc","foo":"bam","_rev":"2-cfcd6781f13994bde69a1c3320bfdadb"}; + var r4 = {"_id":"doc","foo":"bat","_rev":"3-cc2f3210d779aef595cd4738be0ef8ff"}; + + T(db.save({"_id":"_design/couchdb-1178","validate_doc_update":"function(){}"}).ok); + T(db.save(r1).ok); + T(db.save(r2).ok); + T(db.save(r3).ok); + + T(db.compact().ok); + while (db.info().compact_running) {}; + + TEquals({"_id":"doc", + "_rev":"3-cc2f3210d779aef595cd4738be0ef8ff", + "foo":"bam", + "_revisions":{"start":3, + "ids":["cc2f3210d779aef595cd4738be0ef8ff", + "cfcd6781f13994bde69a1c3320bfdadb", + "4c6114c65e295552ab1019e2b046b10e"]}}, + db.open("doc", {"revs": true})); + + TEquals([], db.bulkSave([r4, r3, r2], {"new_edits":false}), "no failures"); + } + + // cleanup + db.deleteDb(); +}; \ No newline at end of file -- cgit v1.2.3 From 66fa2a431d1ff3e01ff026d7e2daf7dcb1eb21d1 Mon Sep 17 00:00:00 2001 From: Robert Newson Date: Fri, 27 May 2011 08:12:47 +0000 Subject: COUCHDB-1074 - fix variable substitution in rewriter MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - key= ":key", startkey=[":a", ":b"] - variable substitution via query arguments - variable substituin via reversed path matching variables The variable substition is now a lot easier than the old one. Variables are decoded from the query if they are json, and we recode them only at the end. (Patch by BenoƮt Chesneau) git-svn-id: https://svn.apache.org/repos/asf/couchdb/branches/1.1.x@1128189 13f79535-47bb-0310-9956-ffa450edef68 --- share/www/script/test/rewrite.js | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) (limited to 'share/www/script') diff --git a/share/www/script/test/rewrite.js b/share/www/script/test/rewrite.js index 86905f8f..bb188773 100644 --- a/share/www/script/test/rewrite.js +++ b/share/www/script/test/rewrite.js @@ -119,6 +119,10 @@ couchTests.rewrite = function(debug) { "query": { "startkey": ":start", "endkey": ":end" + }, + "formats": { + "start": "int", + "end": "int" } }, { @@ -163,6 +167,18 @@ couchTests.rewrite = function(debug) { "key": [":a", ":b"] } }, + { + "from": "simpleForm/complexView7/:a/:b", + "to": "_view/complexView3", + "query": { + "key": [":a", ":b"], + "include_docs": ":doc" + }, + "format": { + "doc": "bool" + } + + }, { "from": "/", "to": "_view/basicView", @@ -348,14 +364,14 @@ couchTests.rewrite = function(debug) { T(!(/Key: 1/.test(xhr.responseText))); T(/FirstKey: 3/.test(xhr.responseText)); T(/LastKey: 8/.test(xhr.responseText)); - + // get with query params xhr = CouchDB.request("GET", "/test_suite_db/_design/test/_rewrite/simpleForm/basicViewPath/3/8"); T(xhr.status == 200, "with query params"); T(!(/Key: 1/.test(xhr.responseText))); T(/FirstKey: 3/.test(xhr.responseText)); T(/LastKey: 8/.test(xhr.responseText)); - + // get with query params xhr = CouchDB.request("GET", "/test_suite_db/_design/test/_rewrite/simpleForm/complexView"); T(xhr.status == 200, "with query params"); @@ -380,6 +396,11 @@ couchTests.rewrite = function(debug) { xhr = CouchDB.request("GET", "/test_suite_db/_design/test/_rewrite/simpleForm/complexView6?a=test&b=essai"); T(xhr.status == 200, "with query params"); T(/Value: doc 4/.test(xhr.responseText)); + + xhr = CouchDB.request("GET", "/test_suite_db/_design/test/_rewrite/simpleForm/complexView7/test/essai?doc=true"); + T(xhr.status == 200, "with query params"); + var result = JSON.parse(xhr.responseText); + T(typeof(result.rows[0].doc) === "object"); // test path relative to server designDoc.rewrites.push({ -- cgit v1.2.3 From 57bb30a736a7e0635c3cab394b946b1acbbed266 Mon Sep 17 00:00:00 2001 From: Robert Newson Date: Sat, 28 May 2011 16:15:14 +0000 Subject: COUCHDB-1173 - pass md5 in stub so replication verifies the transfer. git-svn-id: https://svn.apache.org/repos/asf/couchdb/branches/1.1.x@1128698 13f79535-47bb-0310-9956-ffa450edef68 --- share/www/script/test/attachments_multipart.js | 2 ++ 1 file changed, 2 insertions(+) (limited to 'share/www/script') diff --git a/share/www/script/test/attachments_multipart.js b/share/www/script/test/attachments_multipart.js index 13a5abf4..4f4590fc 100644 --- a/share/www/script/test/attachments_multipart.js +++ b/share/www/script/test/attachments_multipart.js @@ -90,6 +90,7 @@ couchTests.attachments_multipart= function(debug) { //lets change attachment bar delete doc._attachments["bar.txt"].stub; // remove stub member (or could set to false) + delete doc._attachments["bar.txt"].digest; // remove the digest (it's for the gzip form) doc._attachments["bar.txt"].length = 18; doc._attachments["bar.txt"].follows = true; //lets delete attachment baz: @@ -107,6 +108,7 @@ couchTests.attachments_multipart= function(debug) { "this is 18 chars l" + "\r\n--abc123--" }); + TEquals(201, xhr.status); xhr = CouchDB.request("GET", "/test_suite_db/multipart/bar.txt"); -- cgit v1.2.3 From 31e900ee642e672cec0b7b561c4bb596e1acf9a5 Mon Sep 17 00:00:00 2001 From: Robert Newson Date: Sat, 28 May 2011 16:50:10 +0000 Subject: COUCHDB-1171 Multiple requests to _changes feed causes {error, system_limit} "Too many processes" git-svn-id: https://svn.apache.org/repos/asf/couchdb/branches/1.1.x@1128704 13f79535-47bb-0310-9956-ffa450edef68 --- share/www/script/test/changes.js | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'share/www/script') diff --git a/share/www/script/test/changes.js b/share/www/script/test/changes.js index 5998f48c..ea22bfb3 100644 --- a/share/www/script/test/changes.js +++ b/share/www/script/test/changes.js @@ -503,6 +503,10 @@ couchTests.changes = function(debug) { TEquals("0", resp.results[0].id); TEquals("1", resp.results[1].id); + TEquals(0, CouchDB.requestStats('httpd', 'clients_requesting_changes').current); + CouchDB.request("GET", "/" + db.name + "/_changes"); + TEquals(0, CouchDB.requestStats('httpd', 'clients_requesting_changes').current); + // cleanup db.deleteDb(); }; -- cgit v1.2.3