summaryrefslogtreecommitdiff
path: root/share/www/script/test/replication.js
diff options
context:
space:
mode:
Diffstat (limited to 'share/www/script/test/replication.js')
-rw-r--r--share/www/script/test/replication.js467
1 files changed, 447 insertions, 20 deletions
diff --git a/share/www/script/test/replication.js b/share/www/script/test/replication.js
index 78678937..5acff4ab 100644
--- a/share/www/script/test/replication.js
+++ b/share/www/script/test/replication.js
@@ -17,19 +17,19 @@ couchTests.replication = function(debug) {
{source:"test_suite_db_a",
target:"test_suite_db_b"},
{source:"test_suite_db_a",
- target:"http://" + host + "/test_suite_db_b"},
- {source:"http://" + host + "/test_suite_db_a",
+ target:CouchDB.protocol + host + "/test_suite_db_b"},
+ {source:CouchDB.protocol + host + "/test_suite_db_a",
target:"test_suite_db_b"},
- {source:"http://" + host + "/test_suite_db_a",
- target:"http://" + host + "/test_suite_db_b"}
- ]
+ {source:CouchDB.protocol + host + "/test_suite_db_a",
+ target:CouchDB.protocol + host + "/test_suite_db_b"}
+ ];
var dbA = new CouchDB("test_suite_db_a", {"X-Couch-Full-Commit":"false"});
var dbB = new CouchDB("test_suite_db_b", {"X-Couch-Full-Commit":"false"});
var numDocs = 10;
var xhr;
for (var testPair = 0; testPair < dbPairs.length; testPair++) {
- var A = dbPairs[testPair].source
- var B = dbPairs[testPair].target
+ var A = dbPairs[testPair].source;
+ var B = dbPairs[testPair].target;
dbA.deleteDb();
dbA.createDb();
@@ -41,7 +41,7 @@ couchTests.replication = function(debug) {
test_template: new function () {
this.init = function(dbA, dbB) {
// before anything has happened
- }
+ };
this.afterAB1 = function(dbA, dbB) {
// called after replicating src=A tgt=B first time.
};
@@ -165,20 +165,20 @@ couchTests.replication = function(debug) {
this.afterAB1 = function(dbA, dbB) {
var xhr = CouchDB.request("GET",
"/test_suite_db_a/bin_doc/foo%2Bbar.txt");
- T(xhr.responseText == "This is a base64 encoded text")
+ T(xhr.responseText == "This is a base64 encoded text");
xhr = CouchDB.request("GET",
"/test_suite_db_b/bin_doc/foo%2Bbar.txt");
- T(xhr.responseText == "This is a base64 encoded text")
+ T(xhr.responseText == "This is a base64 encoded text");
// and the design-doc
xhr = CouchDB.request("GET",
"/test_suite_db_a/_design/with_bin/foo%2Bbar.txt");
- T(xhr.responseText == "This is a base64 encoded text")
+ T(xhr.responseText == "This is a base64 encoded text");
xhr = CouchDB.request("GET",
"/test_suite_db_b/_design/with_bin/foo%2Bbar.txt");
- T(xhr.responseText == "This is a base64 encoded text")
+ T(xhr.responseText == "This is a base64 encoded text");
};
},
@@ -209,8 +209,8 @@ couchTests.replication = function(debug) {
var docB = dbB.open("foo", {conflicts: true, deleted_conflicts: true});
// We should have no conflicts this time
- T(docA._conflicts === undefined)
- T(docB._conflicts === undefined);
+ T(typeof docA._conflicts === "undefined");
+ T(typeof docB._conflicts === "undefined");
// They show up as deleted conflicts instead
T(docA._deleted_conflicts[0] == docB._deleted_conflicts[0]);
@@ -229,7 +229,7 @@ couchTests.replication = function(debug) {
var seqA = result.source_last_seq;
T(0 == result.history[0].start_last_seq);
- T(result.history[1] === undefined)
+ T(typeof result.history[1] === "undefined");
for(test in repTests) {
if(repTests[test].afterAB1) repTests[test].afterAB1(dbA, dbB);
@@ -239,7 +239,7 @@ couchTests.replication = function(debug) {
var seqB = result.source_last_seq;
T(0 == result.history[0].start_last_seq);
- T(result.history[1] === undefined)
+ T(typeof result.history[1] === "undefined");
for(test in repTests) {
if(repTests[test].afterBA1) repTests[test].afterBA1(dbA, dbB);
@@ -252,7 +252,7 @@ couchTests.replication = function(debug) {
T(seqA < result2.source_last_seq);
T(seqA == result2.history[0].start_last_seq);
- T(result2.history[1].end_last_seq == seqA)
+ T(result2.history[1].end_last_seq == seqA);
seqA = result2.source_last_seq;
@@ -260,11 +260,11 @@ couchTests.replication = function(debug) {
if(repTests[test].afterAB2) repTests[test].afterAB2(dbA, dbB);
}
- result = CouchDB.replicate(B, A)
+ result = CouchDB.replicate(B, A);
T(seqB < result.source_last_seq);
T(seqB == result.history[0].start_last_seq);
- T(result.history[1].end_last_seq == seqB)
+ T(result.history[1].end_last_seq == seqB);
seqB = result.source_last_seq;
@@ -296,9 +296,436 @@ couchTests.replication = function(debug) {
// remote
dbB.deleteDb();
- CouchDB.replicate(dbA.name, "http://" + CouchDB.host + "/test_suite_db_b", {
+ CouchDB.replicate(dbA.name, CouchDB.protocol + CouchDB.host + "/test_suite_db_b", {
body: {"create_target": true}
});
TEquals("test_suite_db_b", dbB.info().db_name,
"Target database should exist");
+
+ // continuous
+ var continuousResult = CouchDB.replicate(dbA.name, "test_suite_db_b", {
+ body: {"continuous": true}
+ });
+ T(continuousResult.ok);
+ T(continuousResult._local_id);
+
+ var cancelResult = CouchDB.replicate(dbA.name, "test_suite_db_b", {
+ body: {"cancel": true}
+ });
+ T(cancelResult.ok);
+ T(continuousResult._local_id == cancelResult._local_id);
+
+ try {
+ var cancelResult2 = CouchDB.replicate(dbA.name, "test_suite_db_b", {
+ body: {"cancel": true}
+ });
+ } catch (e) {
+ T(e.error == "not_found");
+ }
+ // test replication object option doc_ids
+
+ var dbA = new CouchDB("test_suite_rep_docs_db_a", {"X-Couch-Full-Commit":"false"});
+ var dbB = new CouchDB("test_suite_rep_docs_db_b", {"X-Couch-Full-Commit":"false"});
+
+ dbA.deleteDb();
+ dbA.createDb();
+
+ var all_docs = [
+ {
+ _id: "foo1",
+ value: "a"
+ },
+ {
+ _id: "foo2",
+ value: "b"
+ },
+ {
+ _id: "foo3",
+ value: "c"
+ },
+ {
+ _id: "slashed/foo",
+ value: "s"
+ },
+ {
+ _id: "_design/foobar",
+ language: "javascript",
+ value: "I am a design doc",
+ filters: {
+ idfilter: (function(doc, req) {
+ return doc.value == Number(req.filter_value);
+ }).toString()
+ },
+ views: {
+ countview: (function(doc) {
+ emit(doc.value, 1);
+ }).toString()
+ }
+ }
+ ];
+
+ for (var i = 0; i < all_docs.length; i++) {
+ T(dbA.save(all_docs[i]).ok);
+ }
+
+ var dbPairs = [
+ {source:"test_suite_rep_docs_db_a",
+ target:"test_suite_rep_docs_db_b"},
+ {source:"test_suite_rep_docs_db_a",
+ target:CouchDB.protocol + host + "/test_suite_rep_docs_db_b"},
+ {source:CouchDB.protocol + host + "/test_suite_rep_docs_db_a",
+ target:"test_suite_rep_docs_db_b"},
+ {source:CouchDB.protocol + host + "/test_suite_rep_docs_db_a",
+ target:CouchDB.protocol + host + "/test_suite_rep_docs_db_b"}
+ ];
+
+ var target_doc_ids = [
+ ["foo1", "foo3", "foo666"],
+ ["foo1", "foo666"],
+ ["foo666", "foo2"],
+ ["foo2", "foo9999", "foo1"],
+ ["foo3", "slashed/foo"],
+ ["foo3", "slashed%2Ffoo"],
+ ["foo1", "_design/foobar"],
+ ["foo1", "foo1001", "_design%2Ffoobar"]
+ ];
+
+ for (var i = 0; i < dbPairs.length; i++) {
+ var src_db = dbPairs[i].source;
+ var tgt_db = dbPairs[i].target;
+
+ for (var j = 0; j < target_doc_ids.length; j++) {
+ var doc_ids = target_doc_ids[j];
+ var valid_doc_ids = [];
+ var invalid_doc_ids = [];
+
+ for (var p = 0; p < doc_ids.length; p++) {
+ var id = doc_ids[p];
+ var found = false;
+
+ for (var k = 0; k < all_docs.length; k++) {
+ var doc = all_docs[k];
+
+ if (id === doc._id) {
+ found = true;
+ break;
+ }
+ }
+
+ if (found) {
+ valid_doc_ids.push(id);
+ } else {
+ invalid_doc_ids.push(id);
+ }
+ };
+
+ dbB.deleteDb();
+ dbB.createDb();
+
+ var repResult = CouchDB.replicate(src_db, tgt_db, {
+ body: {"doc_ids": doc_ids}
+ });
+
+ T(repResult.ok);
+ T(repResult.docs_written === valid_doc_ids.length);
+ T(repResult.docs_read === valid_doc_ids.length);
+ T(repResult.doc_write_failures === 0);
+
+ for (var k = 0; k < all_docs.length; k++) {
+ var doc = all_docs[k];
+ var tgt_doc = dbB.open(doc._id);
+
+ if (doc_ids.indexOf(doc._id) >= 0) {
+ T(tgt_doc !== null);
+ T(tgt_doc.value === doc.value);
+ } else {
+ T(tgt_doc === null);
+ }
+ }
+
+ for (var k = 0; k < invalid_doc_ids.length; k++) {
+ var tgt_doc = dbB.open(invalid_doc_ids[k]);
+
+ T(tgt_doc === null);
+ }
+ }
+ }
+
+ // test filtered replication
+ var filterFun1 = (function(doc, req) {
+ if (doc.value < Number(req.query.maxvalue)) {
+ return true;
+ } else {
+ return false;
+ }
+ }).toString();
+
+ var filterFun2 = (function(doc, req) {
+ return true;
+ }).toString();
+
+ var dbPairs = [
+ {source:"test_suite_filtered_rep_db_a",
+ target:"test_suite_filtered_rep_db_b"},
+ {source:"test_suite_filtered_rep_db_a",
+ target:CouchDB.protocol + host + "/test_suite_filtered_rep_db_b"},
+ {source:CouchDB.protocol + host + "/test_suite_filtered_rep_db_a",
+ target:"test_suite_filtered_rep_db_b"},
+ {source:CouchDB.protocol + host + "/test_suite_filtered_rep_db_a",
+ target:CouchDB.protocol + host + "/test_suite_filtered_rep_db_b"}
+ ];
+ var sourceDb = new CouchDB("test_suite_filtered_rep_db_a");
+ var targetDb = new CouchDB("test_suite_filtered_rep_db_b");
+
+ for (var i = 0; i < dbPairs.length; i++) {
+ sourceDb.deleteDb();
+ sourceDb.createDb();
+
+ T(sourceDb.save({_id: "foo1", value: 1}).ok);
+ T(sourceDb.save({_id: "foo2", value: 2}).ok);
+ T(sourceDb.save({_id: "foo3", value: 3}).ok);
+ T(sourceDb.save({_id: "foo4", value: 4}).ok);
+
+ var ddoc = {
+ "_id": "_design/mydesign",
+ "language": "javascript",
+ "filters": {
+ "myfilter": filterFun1
+ }
+ };
+
+ T(sourceDb.save(ddoc).ok);
+
+ targetDb.deleteDb();
+ targetDb.createDb();
+
+ var dbA = dbPairs[i].source;
+ var dbB = dbPairs[i].target;
+
+ var repResult = CouchDB.replicate(dbA, dbB, {
+ body: {
+ "filter" : "mydesign/myfilter",
+ "query_params" : {
+ "maxvalue": "3"
+ }
+ }
+ });
+
+ T(repResult.ok);
+ T(repResult.history instanceof Array);
+ T(repResult.history.length === 1);
+ T(repResult.history[0].docs_written === 2);
+ T(repResult.history[0].docs_read === 2);
+ T(repResult.history[0].doc_write_failures === 0);
+
+ var docFoo1 = targetDb.open("foo1");
+ T(docFoo1 !== null);
+ T(docFoo1.value === 1);
+
+ var docFoo2 = targetDb.open("foo2");
+ T(docFoo2 !== null);
+ T(docFoo2.value === 2);
+
+ var docFoo3 = targetDb.open("foo3");
+ T(docFoo3 === null);
+
+ var docFoo4 = targetDb.open("foo4");
+ T(docFoo4 === null);
+
+ // replication should start from scratch after the filter's code changed
+
+ ddoc.filters.myfilter = filterFun2;
+ T(sourceDb.save(ddoc).ok);
+
+ repResult = CouchDB.replicate(dbA, dbB, {
+ body: {
+ "filter" : "mydesign/myfilter",
+ "query_params" : {
+ "maxvalue": "3"
+ }
+ }
+ });
+
+ T(repResult.ok);
+ T(repResult.history instanceof Array);
+ T(repResult.history.length === 1);
+ T(repResult.history[0].docs_written === 3);
+ T(repResult.history[0].docs_read === 3);
+ T(repResult.history[0].doc_write_failures === 0);
+
+ docFoo1 = targetDb.open("foo1");
+ T(docFoo1 !== null);
+ T(docFoo1.value === 1);
+
+ docFoo2 = targetDb.open("foo2");
+ T(docFoo2 !== null);
+ T(docFoo2.value === 2);
+
+ docFoo3 = targetDb.open("foo3");
+ T(docFoo3 !== null);
+ T(docFoo3.value === 3);
+
+ docFoo4 = targetDb.open("foo4");
+ T(docFoo4 !== null);
+ T(docFoo4.value === 4);
+
+ T(targetDb.open("_design/mydesign") !== null);
+ }
+
+ // test for COUCHDB-868 - design docs' attachments not getting replicated
+ // when doing a pull replication with HTTP basic auth
+ dbA = new CouchDB("test_suite_db_a");
+ dbB = new CouchDB("test_suite_db_b");
+ var usersDb = new CouchDB("test_suite_auth");
+ var lorem = CouchDB.request(
+ "GET", "/_utils/script/test/lorem.txt").responseText;
+ var lorem_b64 = CouchDB.request(
+ "GET", "/_utils/script/test/lorem_b64.txt").responseText;
+
+ usersDb.deleteDb();
+ usersDb.createDb();
+ dbA.deleteDb();
+ dbA.createDb();
+ dbB.deleteDb();
+ dbB.createDb();
+
+ var atts_ddoc = {
+ _id: "_design/i_have_atts",
+ language: "javascript"
+ };
+ T(dbA.save(atts_ddoc).ok);
+
+ var rev = atts_ddoc._rev;
+ var att_1_name = "lorem.txt";
+ var att_2_name = "lorem.dat";
+ var xhr = CouchDB.request(
+ "PUT", "/" + dbA.name + "/" + atts_ddoc._id + "/" + att_1_name + "?rev=" + rev, {
+ headers: {"Content-Type": "text/plain;charset=utf-8"},
+ body: lorem
+ });
+ rev = JSON.parse(xhr.responseText).rev;
+ T(xhr.status === 201);
+ xhr = CouchDB.request(
+ "PUT", "/" + dbA.name + "/" + atts_ddoc._id + "/" + att_2_name + "?rev=" + rev, {
+ headers: {"Content-Type": "application/data"},
+ body: lorem_b64
+ });
+ T(xhr.status === 201);
+
+ var fdmananaUserDoc = CouchDB.prepareUserDoc({
+ name: "fdmanana",
+ roles: ["reader"]
+ }, "qwerty");
+ T(usersDb.save(fdmananaUserDoc).ok);
+
+ T(dbA.setSecObj({
+ admins: {
+ names: [],
+ roles: ["admin"]
+ },
+ readers: {
+ names: [],
+ roles: ["reader"]
+ }
+ }).ok);
+ T(dbB.setSecObj({
+ admins: {
+ names: ["fdmanana"],
+ roles: []
+ }
+ }).ok);
+
+ var server_config = [
+ {
+ section: "couch_httpd_auth",
+ key: "authentication_db",
+ value: usersDb.name
+ },
+ // to prevent admin party mode
+ {
+ section: "admins",
+ key: "joe",
+ value: "erlang"
+ }
+ ];
+
+ var test_fun = function() {
+ T(CouchDB.login("fdmanana", "qwerty").ok);
+ T(CouchDB.session().userCtx.name === "fdmanana");
+ T(CouchDB.session().userCtx.roles.indexOf("_admin") === -1);
+
+ var repResult = CouchDB.replicate(
+ CouchDB.protocol + "fdmanana:qwerty@" + host + "/" + dbA.name,
+ dbB.name
+ );
+ T(repResult.ok === true);
+ T(repResult.history instanceof Array);
+ T(repResult.history.length === 1);
+ T(repResult.history[0].docs_written === 1);
+ T(repResult.history[0].docs_read === 1);
+ T(repResult.history[0].doc_write_failures === 0);
+
+ var atts_ddoc_copy = dbB.open(atts_ddoc._id);
+ T(atts_ddoc_copy !== null);
+ T(typeof atts_ddoc_copy._attachments === "object");
+ T(atts_ddoc_copy._attachments !== null);
+ T(att_1_name in atts_ddoc_copy._attachments);
+ T(att_2_name in atts_ddoc_copy._attachments);
+
+ var xhr = CouchDB.request("GET", "/" + dbB.name + "/" + atts_ddoc._id + "/" + att_1_name);
+ T(xhr.status === 200);
+ T(xhr.responseText === lorem);
+
+ xhr = CouchDB.request("GET", "/" + dbB.name + "/" + atts_ddoc._id + "/" + att_2_name);
+ T(xhr.status === 200);
+ T(xhr.responseText === lorem_b64);
+
+ CouchDB.logout();
+ T(CouchDB.login("joe", "erlang").ok);
+ T(dbA.setSecObj({
+ admins: {
+ names: [],
+ roles: ["bar"]
+ },
+ readers: {
+ names: [],
+ roles: ["foo"]
+ }
+ }).ok);
+ T(dbB.deleteDb().ok === true);
+ T(dbB.createDb().ok === true);
+ T(dbB.setSecObj({
+ admins: {
+ names: ["fdmanana"],
+ roles: []
+ }
+ }).ok);
+ CouchDB.logout();
+
+ T(CouchDB.login("fdmanana", "qwerty").ok);
+ T(CouchDB.session().userCtx.name === "fdmanana");
+ T(CouchDB.session().userCtx.roles.indexOf("_admin") === -1);
+ try {
+ repResult = CouchDB.replicate(
+ CouchDB.protocol + "fdmanana:qwerty@" + host + "/" + dbA.name,
+ dbB.name
+ );
+ T(false, "replication should have failed");
+ } catch(x) {
+ T(x.error === "unauthorized");
+ }
+
+ atts_ddoc_copy = dbB.open(atts_ddoc._id);
+ T(atts_ddoc_copy === null);
+
+ CouchDB.logout();
+ T(CouchDB.login("joe", "erlang").ok);
+ };
+
+ run_on_modified_server(server_config, test_fun);
+
+ // cleanup
+ dbA.deleteDb();
+ dbB.deleteDb();
+ usersDb.deleteDb();
};