Return-Path: X-Original-To: apmail-couchdb-commits-archive@www.apache.org Delivered-To: apmail-couchdb-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id E134617A09 for ; Wed, 28 Jan 2015 15:51:54 +0000 (UTC) Received: (qmail 75097 invoked by uid 500); 28 Jan 2015 15:51:50 -0000 Delivered-To: apmail-couchdb-commits-archive@couchdb.apache.org Received: (qmail 74981 invoked by uid 500); 28 Jan 2015 15:51:50 -0000 Mailing-List: contact commits-help@couchdb.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@couchdb.apache.org Delivered-To: mailing list commits@couchdb.apache.org Received: (qmail 74528 invoked by uid 99); 28 Jan 2015 15:51:50 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 28 Jan 2015 15:51:50 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id 9A056E0EFA; Wed, 28 Jan 2015 15:51:48 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: kxepal@apache.org To: commits@couchdb.apache.org Date: Wed, 28 Jan 2015 15:52:02 -0000 Message-Id: In-Reply-To: <106b99bb3f2f4447ba7d6a797d24f3d4@git.apache.org> References: <106b99bb3f2f4447ba7d6a797d24f3d4@git.apache.org> X-Mailer: ASF-Git Admin Mailer Subject: [15/46] couchdb commit: updated refs/heads/master to 6f41698 http://git-wip-us.apache.org/repos/asf/couchdb/blob/e2d9c9b1/share/www/script/test/replication.js ---------------------------------------------------------------------- diff --git a/share/www/script/test/replication.js b/share/www/script/test/replication.js deleted file mode 100644 index 21a4304..0000000 --- a/share/www/script/test/replication.js +++ /dev/null @@ -1,1795 +0,0 @@ -// 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.replication = function(debug) { - - if (debug) debugger; - - var host = CouchDB.host; - var sourceDb = new CouchDB("test_suite_db_a",{"X-Couch-Full-Commit":"false"}); - var targetDb = new CouchDB("test_suite_db_b",{"X-Couch-Full-Commit":"false"}); - - var dbPairs = [ - { - source: sourceDb.name, - target: targetDb.name - }, - { - source: CouchDB.protocol + host + "/" + sourceDb.name, - target: targetDb.name - }, - { - source: sourceDb.name, - target: CouchDB.protocol + host + "/" + targetDb.name - }, - { - source: CouchDB.protocol + host + "/" + sourceDb.name, - target: CouchDB.protocol + host + "/" + targetDb.name - } - ]; - - var att1_data = CouchDB.request("GET", "/_utils/script/test/lorem.txt"); - att1_data = att1_data.responseText; - - var att2_data = CouchDB.request("GET", "/_utils/script/test/lorem_b64.txt"); - att2_data = att2_data.responseText; - - var sourceInfo, targetInfo; - var docs, doc, copy; - var repResult; - var i, j, k; - - - function makeAttData(minSize) { - var data = att1_data; - - while (data.length < minSize) { - data = data + att1_data; - } - return data; - } - - - function enableAttCompression(level, types) { - var xhr = CouchDB.request( - "PUT", - "/_config/attachments/compression_level", - { - body: JSON.stringify(level), - headers: {"X-Couch-Persist": "false"} - } - ); - T(xhr.status === 200); - xhr = CouchDB.request( - "PUT", - "/_config/attachments/compressible_types", - { - body: JSON.stringify(types), - headers: {"X-Couch-Persist": "false"} - } - ); - T(xhr.status === 200); - } - - - function disableAttCompression() { - var xhr = CouchDB.request( - "PUT", - "/_config/attachments/compression_level", - { - body: JSON.stringify("0"), - headers: {"X-Couch-Persist": "false"} - } - ); - T(xhr.status === 200); - } - - - function populateDb(db, docs, dontRecreateDb) { - if (dontRecreateDb !== true) { - db.deleteDb(); - db.createDb(); - } - for (var i = 0; i < docs.length; i++) { - var doc = docs[i]; - delete doc._rev; - } - if (docs.length > 0) { - db.bulkSave(docs); - } - } - - - function addAtt(db, doc, attName, attData, type) { - var uri = "/" + db.name + "/" + encodeURIComponent(doc._id) + "/" + attName; - - if (doc._rev) { - uri += "?rev=" + doc._rev; - } - - var xhr = CouchDB.request("PUT", uri, { - headers: { - "Content-Type": type - }, - body: attData - }); - - T(xhr.status === 201); - doc._rev = JSON.parse(xhr.responseText).rev; - } - - - function compareObjects(o1, o2) { - for (var p in o1) { - if (o1[p] === null && o2[p] !== null) { - return false; - } else if (typeof o1[p] === "object") { - if ((typeof o2[p] !== "object") || o2[p] === null) { - return false; - } - if (!arguments.callee(o1[p], o2[p])) { - return false; - } - } else { - if (o1[p] !== o2[p]) { - return false; - } - } - } - return true; - } - - - function getTask(rep_id, delay) { - var t0 = new Date(); - var t1; - do { - var xhr = CouchDB.request("GET", "/_active_tasks"); - var tasks = JSON.parse(xhr.responseText); - for(var i = 0; i < tasks.length; i++) { - if(tasks[i].replication_id == repResult._local_id) { - return tasks[i]; - } - } - t1 = new Date(); - } while((t1 - t0) <= delay); - - return null; - } - - - function waitForSeq(sourceDb, targetDb, rep_id) { - var sourceSeq = sourceDb.info().update_seq, - t0 = new Date(), - t1, - ms = 3000; - - do { - var task = getTask(rep_id, 0); - if(task && task["through_seq"] == sourceSeq) { - return; - } - t1 = new Date(); - } while (((t1 - t0) <= ms)); - } - - - // test simple replications (not continuous, not filtered), including - // conflict creation - docs = makeDocs(1, 21); - docs.push({ - _id: "_design/foo", - language: "javascript", - value: "ddoc" - }); - - for (i = 0; i < dbPairs.length; i++) { - populateDb(sourceDb, docs); - populateDb(targetDb, []); - - // add some attachments - for (j = 10; j < 15; j++) { - addAtt(sourceDb, docs[j], "readme.txt", att1_data, "text/plain"); - } - - repResult = CouchDB.replicate(dbPairs[i].source, dbPairs[i].target); - TEquals(true, repResult.ok); - - sourceInfo = sourceDb.info(); - targetInfo = targetDb.info(); - - TEquals(sourceInfo.doc_count, targetInfo.doc_count); - - TEquals('string', typeof repResult.session_id); - TEquals(repResult.source_last_seq, sourceInfo.update_seq); - TEquals(true, repResult.history instanceof Array); - TEquals(1, repResult.history.length); - TEquals(repResult.history[0].session_id, repResult.session_id); - TEquals('string', typeof repResult.history[0].start_time); - TEquals('string', typeof repResult.history[0].end_time); - TEquals(0, repResult.history[0].start_last_seq); - TEquals(sourceInfo.update_seq, repResult.history[0].end_last_seq); - TEquals(sourceInfo.update_seq, repResult.history[0].recorded_seq); - TEquals(sourceInfo.doc_count, repResult.history[0].missing_checked); - TEquals(sourceInfo.doc_count, repResult.history[0].missing_found); - TEquals(sourceInfo.doc_count, repResult.history[0].docs_read); - TEquals(sourceInfo.doc_count, repResult.history[0].docs_written); - TEquals(0, repResult.history[0].doc_write_failures); - - for (j = 0; j < docs.length; j++) { - doc = docs[j]; - copy = targetDb.open(doc._id); - - T(copy !== null); - TEquals(true, compareObjects(doc, copy)); - - if (j >= 10 && j < 15) { - var atts = copy._attachments; - TEquals('object', typeof atts); - TEquals('object', typeof atts["readme.txt"]); - TEquals(2, atts["readme.txt"].revpos); - TEquals(0, atts["readme.txt"].content_type.indexOf("text/plain")); - TEquals(true, atts["readme.txt"].stub); - - var att_copy = CouchDB.request( - "GET", "/" + targetDb.name + "/" + copy._id + "/readme.txt" - ).responseText; - TEquals(att1_data.length, att_copy.length); - TEquals(att1_data, att_copy); - } - } - - - // add one more doc to source, more attachments to some existing docs - // and replicate again - var newDoc = { - _id: "foo666", - value: "d" - }; - TEquals(true, sourceDb.save(newDoc).ok); - - // add some more attachments - for (j = 10; j < 15; j++) { - addAtt(sourceDb, docs[j], "data.dat", att2_data, "application/binary"); - } - - repResult = CouchDB.replicate(dbPairs[i].source, dbPairs[i].target); - TEquals(true, repResult.ok); - - sourceInfo = sourceDb.info(); - targetInfo = targetDb.info(); - - TEquals(targetInfo.doc_count, sourceInfo.doc_count); - - TEquals('string', typeof repResult.session_id); - TEquals(sourceInfo.update_seq, repResult.source_last_seq); - TEquals(true, repResult.history instanceof Array); - TEquals(2, repResult.history.length); - TEquals(repResult.history[0].session_id, repResult.session_id); - TEquals('string', typeof repResult.history[0].start_time); - TEquals('string', typeof repResult.history[0].end_time); - TEquals((sourceInfo.update_seq - 6), repResult.history[0].start_last_seq); - TEquals(sourceInfo.update_seq, repResult.history[0].end_last_seq); - TEquals(sourceInfo.update_seq, repResult.history[0].recorded_seq); - TEquals(6, repResult.history[0].missing_checked); - TEquals(6, repResult.history[0].missing_found); - TEquals(6, repResult.history[0].docs_read); - TEquals(6, repResult.history[0].docs_written); - TEquals(0, repResult.history[0].doc_write_failures); - - copy = targetDb.open(newDoc._id); - T(copy !== null); - TEquals(newDoc._id, copy._id); - TEquals(newDoc.value, copy.value); - - for (j = 10; j < 15; j++) { - doc = docs[j]; - copy = targetDb.open(doc._id); - - T(copy !== null); - TEquals(true, compareObjects(doc, copy)); - - var atts = copy._attachments; - TEquals('object', typeof atts); - TEquals('object', typeof atts["readme.txt"]); - TEquals(2, atts["readme.txt"].revpos); - TEquals(0, atts["readme.txt"].content_type.indexOf("text/plain")); - TEquals(true, atts["readme.txt"].stub); - - var att1_copy = CouchDB.request( - "GET", "/" + targetDb.name + "/" + copy._id + "/readme.txt" - ).responseText; - TEquals(att1_data.length, att1_copy.length); - TEquals(att1_data, att1_copy); - - TEquals('object', typeof atts["data.dat"]); - TEquals(3, atts["data.dat"].revpos); - TEquals(0, atts["data.dat"].content_type.indexOf("application/binary")); - TEquals(true, atts["data.dat"].stub); - - var att2_copy = CouchDB.request( - "GET", "/" + targetDb.name + "/" + copy._id + "/data.dat" - ).responseText; - TEquals(att2_data.length, att2_copy.length); - TEquals(att2_data, att2_copy); - } - - // test deletion is replicated - doc = sourceDb.open(docs[1]._id); - TEquals(true, sourceDb.deleteDoc(doc).ok); - - repResult = CouchDB.replicate(dbPairs[i].source, dbPairs[i].target); - TEquals(true, repResult.ok); - - sourceInfo = sourceDb.info(); - targetInfo = targetDb.info(); - - TEquals(targetInfo.doc_count, sourceInfo.doc_count); - TEquals(targetInfo.doc_del_count, sourceInfo.doc_del_count); - TEquals(1, targetInfo.doc_del_count); - - TEquals(true, repResult.history instanceof Array); - TEquals(3, repResult.history.length); - TEquals((sourceInfo.update_seq - 1), repResult.history[0].start_last_seq); - TEquals(sourceInfo.update_seq, repResult.history[0].end_last_seq); - TEquals(sourceInfo.update_seq, repResult.history[0].recorded_seq); - TEquals(1, repResult.history[0].missing_checked); - TEquals(1, repResult.history[0].missing_found); - TEquals(1, repResult.history[0].docs_read); - TEquals(1, repResult.history[0].docs_written); - TEquals(0, repResult.history[0].doc_write_failures); - - copy = targetDb.open(docs[1]._id); - TEquals(null, copy); - - var changes = targetDb.changes({since: 0}); - var idx = changes.results.length - 1; - TEquals(docs[1]._id, changes.results[idx].id); - TEquals(true, changes.results[idx].deleted); - - // test conflict - doc = sourceDb.open(docs[0]._id); - doc.value = "white"; - TEquals(true, sourceDb.save(doc).ok); - - copy = targetDb.open(docs[0]._id); - copy.value = "black"; - TEquals(true, targetDb.save(copy).ok); - - repResult = CouchDB.replicate(dbPairs[i].source, dbPairs[i].target); - TEquals(true, repResult.ok); - - sourceInfo = sourceDb.info(); - targetInfo = targetDb.info(); - - TEquals(sourceInfo.doc_count, targetInfo.doc_count); - - TEquals(true, repResult.history instanceof Array); - TEquals(4, repResult.history.length); - TEquals((sourceInfo.update_seq - 1), repResult.history[0].start_last_seq); - TEquals(sourceInfo.update_seq, repResult.history[0].end_last_seq); - TEquals(sourceInfo.update_seq, repResult.history[0].recorded_seq); - TEquals(1, repResult.history[0].missing_checked); - TEquals(1, repResult.history[0].missing_found); - TEquals(1, repResult.history[0].docs_read); - TEquals(1, repResult.history[0].docs_written); - TEquals(0, repResult.history[0].doc_write_failures); - - copy = targetDb.open(docs[0]._id, {conflicts: true}); - - TEquals(0, copy._rev.indexOf("2-")); - TEquals(true, copy._conflicts instanceof Array); - TEquals(1, copy._conflicts.length); - TEquals(0, copy._conflicts[0].indexOf("2-")); - - // replicate again with conflict - doc.value = "yellow"; - TEquals(true, sourceDb.save(doc).ok); - - repResult = CouchDB.replicate(dbPairs[i].source, dbPairs[i].target); - TEquals(true, repResult.ok); - - sourceInfo = sourceDb.info(); - targetInfo = targetDb.info(); - - TEquals(sourceInfo.doc_count, targetInfo.doc_count); - - TEquals(true, repResult.history instanceof Array); - TEquals(5, repResult.history.length); - TEquals((sourceInfo.update_seq - 1), repResult.history[0].start_last_seq); - TEquals(sourceInfo.update_seq, repResult.history[0].end_last_seq); - TEquals(sourceInfo.update_seq, repResult.history[0].recorded_seq); - TEquals(1, repResult.history[0].missing_checked); - TEquals(1, repResult.history[0].missing_found); - TEquals(1, repResult.history[0].docs_read); - TEquals(1, repResult.history[0].docs_written); - TEquals(0, repResult.history[0].doc_write_failures); - - copy = targetDb.open(docs[0]._id, {conflicts: true}); - - TEquals(0, copy._rev.indexOf("3-")); - TEquals(true, copy._conflicts instanceof Array); - TEquals(1, copy._conflicts.length); - TEquals(0, copy._conflicts[0].indexOf("2-")); - - // resolve the conflict - TEquals(true, targetDb.deleteDoc({_id: copy._id, _rev: copy._conflicts[0]}).ok); - - // replicate again, check there are no more conflicts - doc.value = "rainbow"; - TEquals(true, sourceDb.save(doc).ok); - - repResult = CouchDB.replicate(dbPairs[i].source, dbPairs[i].target); - TEquals(true, repResult.ok); - - sourceInfo = sourceDb.info(); - targetInfo = targetDb.info(); - - TEquals(sourceInfo.doc_count, targetInfo.doc_count); - - TEquals(true, repResult.history instanceof Array); - TEquals(6, repResult.history.length); - TEquals((sourceInfo.update_seq - 1), repResult.history[0].start_last_seq); - TEquals(sourceInfo.update_seq, repResult.history[0].end_last_seq); - TEquals(sourceInfo.update_seq, repResult.history[0].recorded_seq); - TEquals(1, repResult.history[0].missing_checked); - TEquals(1, repResult.history[0].missing_found); - TEquals(1, repResult.history[0].docs_read); - TEquals(1, repResult.history[0].docs_written); - TEquals(0, repResult.history[0].doc_write_failures); - - copy = targetDb.open(docs[0]._id, {conflicts: true}); - - TEquals(0, copy._rev.indexOf("4-")); - TEquals('undefined', typeof copy._conflicts); - - // test that revisions already in a target are not copied - TEquals(true, sourceDb.save({_id: "foo1", value: 111}).ok); - TEquals(true, targetDb.save({_id: "foo1", value: 111}).ok); - TEquals(true, sourceDb.save({_id: "foo2", value: 222}).ok); - TEquals(true, sourceDb.save({_id: "foo3", value: 333}).ok); - TEquals(true, targetDb.save({_id: "foo3", value: 333}).ok); - - repResult = CouchDB.replicate(dbPairs[i].source, dbPairs[i].target); - TEquals(true, repResult.ok); - - sourceInfo = sourceDb.info(); - TEquals(sourceInfo.update_seq, repResult.source_last_seq); - TEquals(sourceInfo.update_seq - 3, repResult.history[0].start_last_seq); - TEquals(sourceInfo.update_seq, repResult.history[0].end_last_seq); - TEquals(sourceInfo.update_seq, repResult.history[0].recorded_seq); - TEquals(3, repResult.history[0].missing_checked); - TEquals(1, repResult.history[0].missing_found); - TEquals(1, repResult.history[0].docs_read); - TEquals(1, repResult.history[0].docs_written); - TEquals(0, repResult.history[0].doc_write_failures); - - TEquals(true, sourceDb.save({_id: "foo4", value: 444}).ok); - TEquals(true, targetDb.save({_id: "foo4", value: 444}).ok); - TEquals(true, sourceDb.save({_id: "foo5", value: 555}).ok); - TEquals(true, targetDb.save({_id: "foo5", value: 555}).ok); - - repResult = CouchDB.replicate(dbPairs[i].source, dbPairs[i].target); - TEquals(true, repResult.ok); - - sourceInfo = sourceDb.info(); - TEquals(sourceInfo.update_seq, repResult.source_last_seq); - TEquals(sourceInfo.update_seq - 2, repResult.history[0].start_last_seq); - TEquals(sourceInfo.update_seq, repResult.history[0].end_last_seq); - TEquals(sourceInfo.update_seq, repResult.history[0].recorded_seq); - TEquals(2, repResult.history[0].missing_checked); - TEquals(0, repResult.history[0].missing_found); - TEquals(0, repResult.history[0].docs_read); - TEquals(0, repResult.history[0].docs_written); - TEquals(0, repResult.history[0].doc_write_failures); - - repResult = CouchDB.replicate(dbPairs[i].source, dbPairs[i].target); - TEquals(true, repResult.ok); - TEquals(true, repResult.no_changes); - sourceInfo = sourceDb.info(); - TEquals(sourceInfo.update_seq, repResult.source_last_seq); - } - - - // test error when source database does not exist - try { - CouchDB.replicate("foobar", "test_suite_db"); - T(false, "should have failed with db_not_found error"); - } catch (x) { - TEquals("db_not_found", x.error); - } - - // validate COUCHDB-317 - try { - CouchDB.replicate("/foobar", "test_suite_db"); - T(false, "should have failed with db_not_found error"); - } catch (x) { - TEquals("db_not_found", x.error); - } - - try { - CouchDB.replicate(CouchDB.protocol + host + "/foobar", "test_suite_db"); - T(false, "should have failed with db_not_found error"); - } catch (x) { - TEquals("db_not_found", x.error); - } - - - // test since_seq parameter - docs = makeDocs(1, 6); - - for (i = 0; i < dbPairs.length; i++) { - var since_seq = 3; - populateDb(sourceDb, docs); - populateDb(targetDb, []); - - var expected_ids = []; - var changes = sourceDb.changes({since: since_seq}); - for (j = 0; j < changes.results.length; j++) { - expected_ids.push(changes.results[j].id); - } - TEquals(2, expected_ids.length, "2 documents since since_seq"); - - // For OTP < R14B03, temporary child specs are kept in the supervisor - // after the child terminates, so cancel the replication to delete the - // child spec in those OTP releases, otherwise since_seq will have no - // effect. - try { - CouchDB.replicate( - dbPairs[i].source, - dbPairs[i].target, - {body: {cancel: true}} - ); - } catch (x) { - // OTP R14B03 onwards - TEquals("not found", x.error); - } - repResult = CouchDB.replicate( - dbPairs[i].source, - dbPairs[i].target, - {body: {since_seq: since_seq}} - ); - // Same reason as before. But here we don't want since_seq to affect - // subsequent replications, so we need to delete the child spec from the - // supervisor (since_seq is not used to calculate the replication ID). - try { - CouchDB.replicate( - dbPairs[i].source, - dbPairs[i].target, - {body: {cancel: true}} - ); - } catch (x) { - // OTP R14B03 onwards - TEquals("not found", x.error); - } - TEquals(true, repResult.ok); - TEquals(2, repResult.history[0].missing_checked); - TEquals(2, repResult.history[0].missing_found); - TEquals(2, repResult.history[0].docs_read); - TEquals(2, repResult.history[0].docs_written); - TEquals(0, repResult.history[0].doc_write_failures); - - for (j = 0; j < docs.length; j++) { - doc = docs[j]; - copy = targetDb.open(doc._id); - - if (expected_ids.indexOf(doc._id) === -1) { - T(copy === null); - } else { - T(copy !== null); - TEquals(true, compareObjects(doc, copy)); - } - } - } - - - // test errors due to doc validate_doc_update functions in the target endpoint - docs = makeDocs(1, 8); - docs[2]["_attachments"] = { - "hello.txt": { - "content_type": "text/plain", - "data": "aGVsbG8gd29ybGQ=" // base64:encode("hello world") - } - }; - var ddoc = { - _id: "_design/test", - language: "javascript", - validate_doc_update: (function(newDoc, oldDoc, userCtx, secObj) { - if ((newDoc.integer % 2) !== 0) { - throw {forbidden: "I only like multiples of 2."}; - } - }).toString() - }; - - for (i = 0; i < dbPairs.length; i++) { - populateDb(sourceDb, docs); - populateDb(targetDb, [ddoc]); - - repResult = CouchDB.replicate( - dbPairs[i].source, - dbPairs[i].target - ); - TEquals(true, repResult.ok); - TEquals(7, repResult.history[0].missing_checked); - TEquals(7, repResult.history[0].missing_found); - TEquals(7, repResult.history[0].docs_read); - TEquals(3, repResult.history[0].docs_written); - TEquals(4, repResult.history[0].doc_write_failures); - - for (j = 0; j < docs.length; j++) { - doc = docs[j]; - copy = targetDb.open(doc._id); - - if (doc.integer % 2 === 0) { - T(copy !== null); - TEquals(copy.integer, doc.integer); - } else { - T(copy === null); - } - } - } - - - // test create_target option - docs = makeDocs(1, 2); - - for (i = 0; i < dbPairs.length; i++) { - populateDb(sourceDb, docs); - targetDb.deleteDb(); - - repResult = CouchDB.replicate( - dbPairs[i].source, - dbPairs[i].target, - {body: {create_target: true}} - ); - TEquals(true, repResult.ok); - - sourceInfo = sourceDb.info(); - targetInfo = targetDb.info(); - - TEquals(sourceInfo.doc_count, targetInfo.doc_count); - TEquals(sourceInfo.update_seq, targetInfo.update_seq); - } - - - // test filtered replication - docs = makeDocs(1, 31); - docs.push({ - _id: "_design/mydesign", - language: "javascript", - filters: { - myfilter: (function(doc, req) { - var modulus = Number(req.query.modulus); - var special = req.query.special; - return (doc.integer % modulus === 0) || (doc.string === special); - }).toString() - } - }); - - for (i = 0; i < dbPairs.length; i++) { - populateDb(sourceDb, docs); - populateDb(targetDb, []); - - repResult = CouchDB.replicate( - dbPairs[i].source, - dbPairs[i].target, - { - body: { - filter: "mydesign/myfilter", - query_params: { - modulus: "2", - special: "7" - } - } - } - ); - - TEquals(true, repResult.ok); - - for (j = 0; j < docs.length; j++) { - doc = docs[j]; - copy = targetDb.open(doc._id); - - if ((doc.integer && (doc.integer % 2 === 0)) || (doc.string === "7")) { - - T(copy !== null); - TEquals(true, compareObjects(doc, copy)); - } else { - TEquals(null, copy); - } - } - - TEquals(true, repResult.history instanceof Array); - TEquals(1, repResult.history.length); - // We (incorrectly) don't record update sequences for things - // that don't pass the changse feed filter. Historically the - // last document to pass was the second to last doc which has - // an update sequence of 30. Work that has been applied to avoid - // conflicts from duplicate IDs breaking _bulk_docs updates added - // a sort to the logic which changes this. Now the last document - // to pass has an doc id of "8" and is at update_seq 29 (because only - // "9" and the design doc are after it). - // - // In the future the fix ought to be that we record that update - // sequence of the database. BigCouch has some existing work on - // this in the clustered case because if you have very few documents - // that pass the filter then (given single node's behavior) you end - // up having to rescan a large portion of the database. - TEquals(29, repResult.source_last_seq); - TEquals(0, repResult.history[0].start_last_seq); - TEquals(29, repResult.history[0].end_last_seq); - TEquals(29, repResult.history[0].recorded_seq); - // 16 => 15 docs with even integer field + 1 doc with string field "7" - TEquals(16, repResult.history[0].missing_checked); - TEquals(16, repResult.history[0].missing_found); - TEquals(16, repResult.history[0].docs_read); - TEquals(16, repResult.history[0].docs_written); - TEquals(0, repResult.history[0].doc_write_failures); - - - // add new docs to source and resume the same replication - var newDocs = makeDocs(50, 56); - populateDb(sourceDb, newDocs, true); - - repResult = CouchDB.replicate( - dbPairs[i].source, - dbPairs[i].target, - { - body: { - filter: "mydesign/myfilter", - query_params: { - modulus: "2", - special: "7" - } - } - } - ); - - TEquals(true, repResult.ok); - - for (j = 0; j < newDocs.length; j++) { - doc = newDocs[j]; - copy = targetDb.open(doc._id); - - if (doc.integer && (doc.integer % 2 === 0)) { - - T(copy !== null); - TEquals(true, compareObjects(doc, copy)); - } else { - TEquals(null, copy); - } - } - - // last doc has even integer field, so last replicated seq is 36 - TEquals(36, repResult.source_last_seq); - TEquals(true, repResult.history instanceof Array); - TEquals(2, repResult.history.length); - TEquals(29, repResult.history[0].start_last_seq); - TEquals(36, repResult.history[0].end_last_seq); - TEquals(36, repResult.history[0].recorded_seq); - TEquals(3, repResult.history[0].missing_checked); - TEquals(3, repResult.history[0].missing_found); - TEquals(3, repResult.history[0].docs_read); - TEquals(3, repResult.history[0].docs_written); - TEquals(0, repResult.history[0].doc_write_failures); - } - - - // test filtered replication works as expected after changing the filter's - // code (ticket COUCHDB-892) - 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(); - - for (i = 0; i < dbPairs.length; i++) { - populateDb(targetDb, []); - populateDb(sourceDb, []); - - TEquals(true, sourceDb.save({_id: "foo1", value: 1}).ok); - TEquals(true, sourceDb.save({_id: "foo2", value: 2}).ok); - TEquals(true, sourceDb.save({_id: "foo3", value: 3}).ok); - TEquals(true, sourceDb.save({_id: "foo4", value: 4}).ok); - - var ddoc = { - "_id": "_design/mydesign", - "language": "javascript", - "filters": { - "myfilter": filterFun1 - } - }; - - TEquals(true, sourceDb.save(ddoc).ok); - - repResult = CouchDB.replicate( - dbPairs[i].source, - dbPairs[i].target, - { - body: { - filter: "mydesign/myfilter", - query_params: { - maxvalue: "3" - } - } - } - ); - - TEquals(true, repResult.ok); - TEquals(true, repResult.history instanceof Array); - TEquals(1, repResult.history.length); - TEquals(2, repResult.history[0].docs_written); - TEquals(2, repResult.history[0].docs_read); - TEquals(0, repResult.history[0].doc_write_failures); - - var docFoo1 = targetDb.open("foo1"); - T(docFoo1 !== null); - TEquals(1, docFoo1.value); - - var docFoo2 = targetDb.open("foo2"); - T(docFoo2 !== null); - TEquals(2, docFoo2.value); - - var docFoo3 = targetDb.open("foo3"); - TEquals(null, docFoo3); - - var docFoo4 = targetDb.open("foo4"); - TEquals(null, docFoo4); - - // replication should start from scratch after the filter's code changed - - ddoc.filters.myfilter = filterFun2; - TEquals(true, sourceDb.save(ddoc).ok); - - repResult = CouchDB.replicate( - dbPairs[i].source, - dbPairs[i].target, - { - body: { - filter: "mydesign/myfilter", - query_params : { - maxvalue: "3" - } - } - } - ); - - TEquals(true, repResult.ok); - TEquals(true, repResult.history instanceof Array); - TEquals(1, repResult.history.length); - TEquals(3, repResult.history[0].docs_written); - TEquals(3, repResult.history[0].docs_read); - TEquals(0, repResult.history[0].doc_write_failures); - - docFoo1 = targetDb.open("foo1"); - T(docFoo1 !== null); - TEquals(1, docFoo1.value); - - docFoo2 = targetDb.open("foo2"); - T(docFoo2 !== null); - TEquals(2, docFoo2.value); - - docFoo3 = targetDb.open("foo3"); - T(docFoo3 !== null); - TEquals(3, docFoo3.value); - - docFoo4 = targetDb.open("foo4"); - T(docFoo4 !== null); - TEquals(4, docFoo4.value); - - T(targetDb.open("_design/mydesign") !== null); - } - - - // test replication by doc IDs - docs = makeDocs(1, 11); - docs.push({ - _id: "_design/foo", - language: "javascript", - integer: 1 - }); - - var target_doc_ids = [ - { initial: ["1", "2", "10"], after: [], conflict_id: "2" }, - { initial: ["1", "2"], after: ["7"], conflict_id: "1" }, - { initial: ["1", "foo_666", "10"], after: ["7"], conflict_id: "10" }, - { initial: ["_design/foo", "8"], after: ["foo_5"], conflict_id: "8" }, - { initial: ["_design%2Ffoo", "8"], after: ["foo_5"], conflict_id: "8" }, - { initial: [], after: ["foo_1000", "_design/foo", "1"], conflict_id: "1" } - ]; - var doc_ids, after_doc_ids; - var id, num_inexistent_docs, after_num_inexistent_docs; - var total, after_total; - - for (i = 0; i < dbPairs.length; i++) { - - for (j = 0; j < target_doc_ids.length; j++) { - doc_ids = target_doc_ids[j].initial; - num_inexistent_docs = 0; - - for (k = 0; k < doc_ids.length; k++) { - id = doc_ids[k]; - if (id.indexOf("foo_") === 0) { - num_inexistent_docs += 1; - } - } - - populateDb(sourceDb, docs); - populateDb(targetDb, []); - - repResult = CouchDB.replicate( - dbPairs[i].source, - dbPairs[i].target, - { - body: { - doc_ids: doc_ids - } - } - ); - - total = doc_ids.length - num_inexistent_docs; - TEquals(true, repResult.ok); - if (total === 0) { - TEquals(true, repResult.no_changes); - } else { - TEquals('string', typeof repResult.start_time); - TEquals('string', typeof repResult.end_time); - TEquals(total, repResult.docs_read); - TEquals(total, repResult.docs_written); - TEquals(0, repResult.doc_write_failures); - } - - for (k = 0; k < doc_ids.length; k++) { - id = decodeURIComponent(doc_ids[k]); - doc = sourceDb.open(id); - copy = targetDb.open(id); - - if (id.indexOf("foo_") === 0) { - TEquals(null, doc); - TEquals(null, copy); - } else { - T(doc !== null); - T(copy !== null); - TEquals(true, compareObjects(doc, copy)); - } - } - - // be absolutely sure that other docs were not replicated - for (k = 0; k < docs.length; k++) { - var base_id = docs[k]._id; - id = encodeURIComponent(base_id); - doc = targetDb.open(base_id); - - if ((doc_ids.indexOf(id) >= 0) || (doc_ids.indexOf(base_id) >= 0)) { - T(doc !== null); - } else { - TEquals(null, doc); - } - } - - targetInfo = targetDb.info(); - TEquals(total, targetInfo.doc_count); - - - // add more docs throught replication by doc IDs - after_doc_ids = target_doc_ids[j].after; - after_num_inexistent_docs = 0; - - for (k = 0; k < after_doc_ids.length; k++) { - id = after_doc_ids[k]; - if (id.indexOf("foo_") === 0) { - after_num_inexistent_docs += 1; - } - } - - repResult = CouchDB.replicate( - dbPairs[i].source, - dbPairs[i].target, - { - body: { - doc_ids: after_doc_ids - } - } - ); - - after_total = after_doc_ids.length - after_num_inexistent_docs; - TEquals(true, repResult.ok); - if (after_total === 0) { - TEquals(true, repResult.no_changes); - } else { - TEquals('string', typeof repResult.start_time); - TEquals('string', typeof repResult.end_time); - TEquals(after_total, repResult.docs_read); - TEquals(after_total, repResult.docs_written); - TEquals(0, repResult.doc_write_failures); - } - - for (k = 0; k < after_doc_ids.length; k++) { - id = after_doc_ids[k]; - doc = sourceDb.open(id); - copy = targetDb.open(id); - - if (id.indexOf("foo_") === 0) { - TEquals(null, doc); - TEquals(null, copy); - } else { - T(doc !== null); - T(copy !== null); - TEquals(true, compareObjects(doc, copy)); - } - } - - // be absolutely sure that other docs were not replicated - for (k = 0; k < docs.length; k++) { - var base_id = docs[k]._id; - id = encodeURIComponent(base_id); - doc = targetDb.open(base_id); - - if ((doc_ids.indexOf(id) >= 0) || (after_doc_ids.indexOf(id) >= 0) || - (doc_ids.indexOf(base_id) >= 0) || - (after_doc_ids.indexOf(base_id) >= 0)) { - T(doc !== null); - } else { - TEquals(null, doc); - } - } - - targetInfo = targetDb.info(); - TEquals((total + after_total), targetInfo.doc_count); - - - // replicate again the same doc after updated on source (no conflict) - id = target_doc_ids[j].conflict_id; - doc = sourceDb.open(id); - T(doc !== null); - doc.integer = 666; - TEquals(true, sourceDb.save(doc).ok); - addAtt(sourceDb, doc, "readme.txt", att1_data, "text/plain"); - addAtt(sourceDb, doc, "data.dat", att2_data, "application/binary"); - - repResult = CouchDB.replicate( - dbPairs[i].source, - dbPairs[i].target, - { - body: { - doc_ids: [id] - } - } - ); - - TEquals(true, repResult.ok); - TEquals(1, repResult.docs_read); - TEquals(1, repResult.docs_written); - TEquals(0, repResult.doc_write_failures); - - copy = targetDb.open(id, {conflicts: true}); - - TEquals(666, copy.integer); - TEquals(0, copy._rev.indexOf("4-")); - TEquals('undefined', typeof copy._conflicts); - - var atts = copy._attachments; - TEquals('object', typeof atts); - TEquals('object', typeof atts["readme.txt"]); - TEquals(3, atts["readme.txt"].revpos); - TEquals(0, atts["readme.txt"].content_type.indexOf("text/plain")); - TEquals(true, atts["readme.txt"].stub); - - var att1_copy = CouchDB.request( - "GET", "/" + targetDb.name + "/" + copy._id + "/readme.txt" - ).responseText; - TEquals(att1_data.length, att1_copy.length); - TEquals(att1_data, att1_copy); - - TEquals('object', typeof atts["data.dat"]); - TEquals(4, atts["data.dat"].revpos); - TEquals(0, atts["data.dat"].content_type.indexOf("application/binary")); - TEquals(true, atts["data.dat"].stub); - - var att2_copy = CouchDB.request( - "GET", "/" + targetDb.name + "/" + copy._id + "/data.dat" - ).responseText; - TEquals(att2_data.length, att2_copy.length); - TEquals(att2_data, att2_copy); - - - // generate a conflict throught replication by doc IDs - id = target_doc_ids[j].conflict_id; - doc = sourceDb.open(id); - copy = targetDb.open(id); - T(doc !== null); - T(copy !== null); - doc.integer += 100; - copy.integer += 1; - TEquals(true, sourceDb.save(doc).ok); - TEquals(true, targetDb.save(copy).ok); - - repResult = CouchDB.replicate( - dbPairs[i].source, - dbPairs[i].target, - { - body: { - doc_ids: [id] - } - } - ); - - TEquals(true, repResult.ok); - TEquals(1, repResult.docs_read); - TEquals(1, repResult.docs_written); - TEquals(0, repResult.doc_write_failures); - - copy = targetDb.open(id, {conflicts: true}); - - TEquals(0, copy._rev.indexOf("5-")); - TEquals(true, copy._conflicts instanceof Array); - TEquals(1, copy._conflicts.length); - TEquals(0, copy._conflicts[0].indexOf("5-")); - } - } - - - docs = makeDocs(1, 25); - docs.push({ - _id: "_design/foo", - language: "javascript", - filters: { - myfilter: (function(doc, req) { return true; }).toString() - } - }); - - for (i = 0; i < dbPairs.length; i++) { - populateDb(sourceDb, docs); - populateDb(targetDb, []); - - // add some attachments - for (j = 10; j < 15; j++) { - addAtt(sourceDb, docs[j], "readme.txt", att1_data, "text/plain"); - } - - repResult = CouchDB.replicate( - dbPairs[i].source, - dbPairs[i].target, - { - body: { - continuous: true - } - } - ); - TEquals(true, repResult.ok); - TEquals('string', typeof repResult._local_id); - - var rep_id = repResult._local_id; - - waitForSeq(sourceDb, targetDb, rep_id); - - for (j = 0; j < docs.length; j++) { - doc = docs[j]; - copy = targetDb.open(doc._id); - - T(copy !== null); - TEquals(true, compareObjects(doc, copy)); - - if (j >= 10 && j < 15) { - var atts = copy._attachments; - TEquals('object', typeof atts); - TEquals('object', typeof atts["readme.txt"]); - TEquals(2, atts["readme.txt"].revpos); - TEquals(0, atts["readme.txt"].content_type.indexOf("text/plain")); - TEquals(true, atts["readme.txt"].stub); - - var att_copy = CouchDB.request( - "GET", "/" + targetDb.name + "/" + copy._id + "/readme.txt" - ).responseText; - TEquals(att1_data.length, att_copy.length); - TEquals(att1_data, att_copy); - } - } - - sourceInfo = sourceDb.info(); - targetInfo = targetDb.info(); - - TEquals(sourceInfo.doc_count, targetInfo.doc_count); - - // add attachments to docs in source - for (j = 10; j < 15; j++) { - addAtt(sourceDb, docs[j], "data.dat", att2_data, "application/binary"); - } - - var ddoc = docs[docs.length - 1]; // design doc - addAtt(sourceDb, ddoc, "readme.txt", att1_data, "text/plain"); - - waitForSeq(sourceDb, targetDb, rep_id); - - var modifDocs = docs.slice(10, 15).concat([ddoc]); - for (j = 0; j < modifDocs.length; j++) { - doc = modifDocs[j]; - copy = targetDb.open(doc._id); - - T(copy !== null); - TEquals(true, compareObjects(doc, copy)); - - var atts = copy._attachments; - TEquals('object', typeof atts); - TEquals('object', typeof atts["readme.txt"]); - TEquals(2, atts["readme.txt"].revpos); - TEquals(0, atts["readme.txt"].content_type.indexOf("text/plain")); - TEquals(true, atts["readme.txt"].stub); - - var att1_copy = CouchDB.request( - "GET", "/" + targetDb.name + "/" + copy._id + "/readme.txt" - ).responseText; - TEquals(att1_data.length, att1_copy.length); - TEquals(att1_data, att1_copy); - - if (doc._id.indexOf("_design/") === -1) { - TEquals('object', typeof atts["data.dat"]); - TEquals(3, atts["data.dat"].revpos); - TEquals(0, atts["data.dat"].content_type.indexOf("application/binary")); - TEquals(true, atts["data.dat"].stub); - - var att2_copy = CouchDB.request( - "GET", "/" + targetDb.name + "/" + copy._id + "/data.dat" - ).responseText; - TEquals(att2_data.length, att2_copy.length); - TEquals(att2_data, att2_copy); - } - } - - sourceInfo = sourceDb.info(); - targetInfo = targetDb.info(); - - TEquals(sourceInfo.doc_count, targetInfo.doc_count); - - // add another attachment to the ddoc on source - addAtt(sourceDb, ddoc, "data.dat", att2_data, "application/binary"); - - waitForSeq(sourceDb, targetDb, rep_id); - - copy = targetDb.open(ddoc._id); - var atts = copy._attachments; - TEquals('object', typeof atts); - TEquals('object', typeof atts["readme.txt"]); - TEquals(2, atts["readme.txt"].revpos); - TEquals(0, atts["readme.txt"].content_type.indexOf("text/plain")); - TEquals(true, atts["readme.txt"].stub); - - var att1_copy = CouchDB.request( - "GET", "/" + targetDb.name + "/" + copy._id + "/readme.txt" - ).responseText; - TEquals(att1_data.length, att1_copy.length); - TEquals(att1_data, att1_copy); - - TEquals('object', typeof atts["data.dat"]); - TEquals(3, atts["data.dat"].revpos); - TEquals(0, atts["data.dat"].content_type.indexOf("application/binary")); - TEquals(true, atts["data.dat"].stub); - - var att2_copy = CouchDB.request( - "GET", "/" + targetDb.name + "/" + copy._id + "/data.dat" - ).responseText; - TEquals(att2_data.length, att2_copy.length); - TEquals(att2_data, att2_copy); - - sourceInfo = sourceDb.info(); - targetInfo = targetDb.info(); - - TEquals(sourceInfo.doc_count, targetInfo.doc_count); - - - // add more docs to source - var newDocs = makeDocs(25, 35); - populateDb(sourceDb, newDocs, true); - - waitForSeq(sourceDb, targetDb, rep_id); - - for (j = 0; j < newDocs.length; j++) { - doc = newDocs[j]; - copy = targetDb.open(doc._id); - - T(copy !== null); - TEquals(true, compareObjects(doc, copy)); - } - - sourceInfo = sourceDb.info(); - targetInfo = targetDb.info(); - - TEquals(sourceInfo.doc_count, targetInfo.doc_count); - - // delete docs from source - TEquals(true, sourceDb.deleteDoc(newDocs[0]).ok); - TEquals(true, sourceDb.deleteDoc(newDocs[6]).ok); - - waitForSeq(sourceDb, targetDb, rep_id); - - copy = targetDb.open(newDocs[0]._id); - TEquals(null, copy); - copy = targetDb.open(newDocs[6]._id); - TEquals(null, copy); - - var changes = targetDb.changes({since: targetInfo.update_seq}); - var line1 = changes.results[changes.results.length - 2]; - var line2 = changes.results[changes.results.length - 1]; - TEquals(newDocs[0]._id, line1.id); - TEquals(true, line1.deleted); - TEquals(newDocs[6]._id, line2.id); - TEquals(true, line2.deleted); - - // cancel the replication - repResult = CouchDB.replicate( - dbPairs[i].source, - dbPairs[i].target, - { - body: { - continuous: true, - cancel: true - } - } - ); - TEquals(true, repResult.ok); - TEquals(rep_id, repResult._local_id); - - doc = { - _id: 'foobar', - value: 666 - }; - TEquals(true, sourceDb.save(doc).ok); - - waitForSeq(sourceDb, targetDb, rep_id); - copy = targetDb.open(doc._id); - TEquals(null, copy); - } - - // COUCHDB-1093 - filtered and continuous _changes feed dies when the - // database is compacted - docs = makeDocs(1, 10); - docs.push({ - _id: "_design/foo", - language: "javascript", - filters: { - myfilter: (function(doc, req) { return true; }).toString() - } - }); - populateDb(sourceDb, docs); - populateDb(targetDb, []); - - repResult = CouchDB.replicate( - CouchDB.protocol + host + "/" + sourceDb.name, - targetDb.name, - { - body: { - continuous: true, - filter: "foo/myfilter" - } - } - ); - TEquals(true, repResult.ok); - TEquals('string', typeof repResult._local_id); - - TEquals(true, sourceDb.compact().ok); - while (sourceDb.info().compact_running) {}; - - TEquals(true, sourceDb.save(makeDocs(30, 31)[0]).ok); - - var task = getTask(repResult._local_id, 1000); - T(task != null); - - waitForSeq(sourceDb, targetDb, repResult._local_id); - T(sourceDb.open("30") !== null); - - // cancel replication - repResult = CouchDB.replicate( - CouchDB.protocol + host + "/" + sourceDb.name, - targetDb.name, - { - body: { - continuous: true, - filter: "foo/myfilter", - cancel: true - } - } - ); - TEquals(true, repResult.ok); - TEquals('string', typeof repResult._local_id); - - - // - // test replication of compressed attachments - // - doc = { - _id: "foobar" - }; - var bigTextAtt = makeAttData(128 * 1024); - var attName = "readme.txt"; - var xhr = CouchDB.request("GET", "/_config/attachments/compression_level"); - var compressionLevel = JSON.parse(xhr.responseText); - xhr = CouchDB.request("GET", "/_config/attachments/compressible_types"); - var compressibleTypes = JSON.parse(xhr.responseText); - - for (i = 0; i < dbPairs.length; i++) { - populateDb(sourceDb, [doc]); - populateDb(targetDb, []); - - // enable compression of text types - enableAttCompression("8", "text/*"); - - // add text attachment to foobar doc - xhr = CouchDB.request( - "PUT", - "/" + sourceDb.name + "/" + doc._id + "/" + attName + "?rev=" + doc._rev, - { - body: bigTextAtt, - headers: {"Content-Type": "text/plain"} - } - ); - TEquals(201, xhr.status); - - // disable compression and replicate - disableAttCompression(); - - repResult = CouchDB.replicate(dbPairs[i].source, dbPairs[i].target); - TEquals(true, repResult.ok); - TEquals(true, repResult.history instanceof Array); - TEquals(1, repResult.history.length); - TEquals(1, repResult.history[0].missing_checked); - TEquals(1, repResult.history[0].missing_found); - TEquals(1, repResult.history[0].docs_read); - TEquals(1, repResult.history[0].docs_written); - TEquals(0, repResult.history[0].doc_write_failures); - - copy = targetDb.open( - doc._id, - {att_encoding_info: true, bypass_cache: Math.round(Math.random() * 1000)} - ); - T(copy !== null); - T(attName in copy._attachments); - TEquals("gzip", copy._attachments[attName].encoding); - TEquals("number", typeof copy._attachments[attName].length); - TEquals("number", typeof copy._attachments[attName].encoded_length); - T(copy._attachments[attName].encoded_length < copy._attachments[attName].length); - } - - delete bigTextAtt; - // restore original settings - enableAttCompression(compressionLevel, compressibleTypes); - - - // - // test replication triggered by non admins - // - - // case 1) user triggering the replication is not a DB admin of the target DB - var joeUserDoc = CouchDB.prepareUserDoc({ - name: "joe", - roles: ["erlanger"] - }, "erly"); - var usersDb = new CouchDB("test_suite_auth", {"X-Couch-Full-Commit":"false"}); - var server_config = [ - { - section: "couch_httpd_auth", - key: "authentication_db", - value: usersDb.name - } - ]; - - docs = makeDocs(1, 6); - docs.push({ - _id: "_design/foo", - language: "javascript" - }); - - dbPairs = [ - { - source: sourceDb.name, - target: targetDb.name - }, - { - source: CouchDB.protocol + host + "/" + sourceDb.name, - target: targetDb.name - }, - { - source: sourceDb.name, - target: CouchDB.protocol + "joe:erly@" + host + "/" + targetDb.name - }, - { - source: CouchDB.protocol + host + "/" + sourceDb.name, - target: CouchDB.protocol + "joe:erly@" + host + "/" + targetDb.name - } - ]; - - for (i = 0; i < dbPairs.length; i++) { - usersDb.deleteDb(); - populateDb(sourceDb, docs); - populateDb(targetDb, []); - - TEquals(true, targetDb.setSecObj({ - admins: { - names: ["superman"], - roles: ["god"] - } - }).ok); - - run_on_modified_server(server_config, function() { - delete joeUserDoc._rev; - TEquals(true, usersDb.save(joeUserDoc).ok); - - TEquals(true, CouchDB.login("joe", "erly").ok); - TEquals('joe', CouchDB.session().userCtx.name); - - repResult = CouchDB.replicate(dbPairs[i].source, dbPairs[i].target); - - TEquals(true, CouchDB.logout().ok); - - TEquals(true, repResult.ok); - TEquals(docs.length, repResult.history[0].docs_read); - TEquals((docs.length - 1), repResult.history[0].docs_written); // 1 ddoc - TEquals(1, repResult.history[0].doc_write_failures); - }); - - for (j = 0; j < docs.length; j++) { - doc = docs[j]; - copy = targetDb.open(doc._id); - - if (doc._id.indexOf("_design/") === 0) { - TEquals(null, copy); - } else { - T(copy !== null); - TEquals(true, compareObjects(doc, copy)); - } - } - } - - // case 2) user triggering the replication is not a reader (nor admin) of the - // source DB - dbPairs = [ - { - source: sourceDb.name, - target: targetDb.name - }, - { - source: CouchDB.protocol + "joe:erly@" + host + "/" + sourceDb.name, - target: targetDb.name - }, - { - source: sourceDb.name, - target: CouchDB.protocol + host + "/" + targetDb.name - }, - { - source: CouchDB.protocol + "joe:erly@" + host + "/" + sourceDb.name, - target: CouchDB.protocol + host + "/" + targetDb.name - } - ]; - - for (i = 0; i < dbPairs.length; i++) { - usersDb.deleteDb(); - populateDb(sourceDb, docs); - populateDb(targetDb, []); - - TEquals(true, sourceDb.setSecObj({ - admins: { - names: ["superman"], - roles: ["god"] - }, - readers: { - names: ["john"], - roles: ["secret"] - } - }).ok); - - run_on_modified_server(server_config, function() { - delete joeUserDoc._rev; - TEquals(true, usersDb.save(joeUserDoc).ok); - - TEquals(true, CouchDB.login("joe", "erly").ok); - TEquals('joe', CouchDB.session().userCtx.name); - - try { - CouchDB.replicate(dbPairs[i].source, dbPairs[i].target); - T(false, "should have raised an exception"); - } catch (x) { - TEquals("unauthorized", x.error); - } - - TEquals(true, CouchDB.logout().ok); - }); - - for (j = 0; j < docs.length; j++) { - doc = docs[j]; - copy = targetDb.open(doc._id); - TEquals(null, copy); - } - } - - - // COUCHDB-885 - push replication of a doc with attachment causes a - // conflict in the target. - sourceDb = new CouchDB("test_suite_db_a"); - targetDb = new CouchDB("test_suite_db_b"); - - sourceDb.deleteDb(); - sourceDb.createDb(); - targetDb.deleteDb(); - targetDb.createDb(); - - doc = { - _id: "doc1" - }; - TEquals(true, sourceDb.save(doc).ok); - - repResult = CouchDB.replicate( - sourceDb.name, - CouchDB.protocol + host + "/" + targetDb.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, sourceDb.save(doc).ok); - repResult = CouchDB.replicate( - sourceDb.name, - CouchDB.protocol + host + "/" + targetDb.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); - - copy = targetDb.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); - 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 - - // Test for COUCHDB-1242 (reject non-string query_params) - try { - CouchDB.replicate(sourceDb, targetDb, { - body: { - filter : "mydesign/myfilter", - query_params : { - "maxvalue": 4 - } - } - }); - } catch (e) { - TEquals("bad_request", e.error); - } - - - // Test that we can cancel a replication just by POSTing an object - // like {"replication_id": Id, "cancel": true}. The replication ID - // can be obtained from a continuous replication request response - // (_local_id field), from _active_tasks or from the log - populateDb(sourceDb, makeDocs(1, 6)); - populateDb(targetDb, []); - - repResult = CouchDB.replicate( - CouchDB.protocol + host + "/" + sourceDb.name, - targetDb.name, - { - body: { - continuous: true, - create_target: true - } - } - ); - TEquals(true, repResult.ok); - TEquals('string', typeof repResult._local_id); - var repId = repResult._local_id; - - var task = getTask(repId, 3000); - T(task != null); - - TEquals(task["replication_id"], repId, "Replication found in _active_tasks"); - xhr = CouchDB.request( - "POST", "/_replicate", { - body: JSON.stringify({"replication_id": repId, "cancel": true}), - headers: {"Content-Type": "application/json"} - }); - TEquals(200, xhr.status, "Replication cancel request success"); - - task = getTask(repId); - TEquals(null, task, "Replication was canceled"); - - xhr = CouchDB.request( - "POST", "/_replicate", { - body: JSON.stringify({"replication_id": repId, "cancel": true}), - headers: {"Content-Type": "application/json"} - }); - TEquals(404, xhr.status, "2nd replication cancel failed"); - - // Non-admin user can not cancel replications triggered by other users - var userDoc = CouchDB.prepareUserDoc({ - name: "tony", - roles: ["mafia"] - }, "soprano"); - usersDb = new CouchDB("test_suite_auth", {"X-Couch-Full-Commit":"false"}); - server_config = [ - { - section: "couch_httpd_auth", - key: "authentication_db", - value: usersDb.name - } - ]; - - run_on_modified_server(server_config, function() { - populateDb(sourceDb, makeDocs(1, 6)); - populateDb(targetDb, []); - TEquals(true, usersDb.save(userDoc).ok); - - repResult = CouchDB.replicate( - CouchDB.protocol + host + "/" + sourceDb.name, - targetDb.name, - { - body: { - continuous: true - } - } - ); - TEquals(true, repResult.ok); - TEquals('string', typeof repResult._local_id); - - TEquals(true, CouchDB.login("tony", "soprano").ok); - TEquals('tony', CouchDB.session().userCtx.name); - - xhr = CouchDB.request( - "POST", "/_replicate", { - body: JSON.stringify({"replication_id": repResult._local_id, "cancel": true}), - headers: {"Content-Type": "application/json"} - }); - TEquals(401, xhr.status, "Unauthorized to cancel replication"); - TEquals("unauthorized", JSON.parse(xhr.responseText).error); - - TEquals(true, CouchDB.logout().ok); - - xhr = CouchDB.request( - "POST", "/_replicate", { - body: JSON.stringify({"replication_id": repResult._local_id, "cancel": true}), - headers: {"Content-Type": "application/json"} - }); - TEquals(200, xhr.status, "Authorized to cancel replication"); - }); - - // cleanup - usersDb.deleteDb(); - sourceDb.deleteDb(); - targetDb.deleteDb(); -}; http://git-wip-us.apache.org/repos/asf/couchdb/blob/e2d9c9b1/share/www/script/test/replicator_db_bad_rep_id.js ---------------------------------------------------------------------- diff --git a/share/www/script/test/replicator_db_bad_rep_id.js b/share/www/script/test/replicator_db_bad_rep_id.js deleted file mode 100644 index 285b863..0000000 --- a/share/www/script/test/replicator_db_bad_rep_id.js +++ /dev/null @@ -1,77 +0,0 @@ -// 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.replicator_db_bad_rep_id = function(debug) { - - if (debug) debugger; - - var populate_db = replicator_db.populate_db; - var docs1 = replicator_db.docs1; - var dbA = replicator_db.dbA; - var dbB = replicator_db.dbB; - var repDb = replicator_db.repDb; - var wait = replicator_db.wait; - var waitForRep = replicator_db.waitForRep; - var waitForSeq = replicator_db.waitForSeq; - - function rep_doc_with_bad_rep_id() { - populate_db(dbA, docs1); - populate_db(dbB, []); - - var repDoc = { - _id: "foo_rep", - source: dbA.name, - target: dbB.name, - replication_id: "1234abc" - }; - T(repDb.save(repDoc).ok); - - waitForRep(repDb, repDoc, "completed"); - for (var i = 0; i < docs1.length; i++) { - var doc = docs1[i]; - var copy = dbB.open(doc._id); - T(copy !== null); - T(copy.value === doc.value); - } - - var repDoc1 = repDb.open(repDoc._id); - T(repDoc1 !== null); - T(repDoc1.source === repDoc.source); - T(repDoc1.target === repDoc.target); - T(repDoc1._replication_state === "completed", - "replication document with bad replication id failed"); - T(typeof repDoc1._replication_state_time === "string"); - T(typeof repDoc1._replication_id === "string"); - T(repDoc1._replication_id !== "1234abc"); - } - - var server_config = [ - { - section: "couch_httpd_auth", - key: "iterations", - value: "1" - }, - { - section: "replicator", - key: "db", - value: repDb.name - } - ]; - - repDb.deleteDb(); - run_on_modified_server(server_config, rep_doc_with_bad_rep_id); - - // cleanup - repDb.deleteDb(); - dbA.deleteDb(); - dbB.deleteDb(); -} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/couchdb/blob/e2d9c9b1/share/www/script/test/replicator_db_by_doc_id.js ---------------------------------------------------------------------- diff --git a/share/www/script/test/replicator_db_by_doc_id.js b/share/www/script/test/replicator_db_by_doc_id.js deleted file mode 100644 index 1e1a385..0000000 --- a/share/www/script/test/replicator_db_by_doc_id.js +++ /dev/null @@ -1,99 +0,0 @@ -// 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.replicator_db_by_doc_id = function(debug) { - - if (debug) debugger; - - var populate_db = replicator_db.populate_db; - var docs1 = replicator_db.docs1; - var dbA = replicator_db.dbA; - var dbB = replicator_db.dbB; - var repDb = replicator_db.repDb; - var wait = replicator_db.wait; - var waitForRep = replicator_db.waitForRep; - var waitForSeq = replicator_db.waitForSeq; - - function by_doc_ids_replication() { - // to test that we can replicate docs with slashes in their IDs - var docs2 = docs1.concat([ - { - _id: "_design/mydesign", - language : "javascript" - } - ]); - - populate_db(dbA, docs2); - populate_db(dbB, []); - - var repDoc = { - _id: "foo_cont_rep_doc", - source: "http://" + CouchDB.host + "/" + dbA.name, - target: dbB.name, - doc_ids: ["foo666", "foo3", "_design/mydesign", "foo999", "foo1"] - }; - T(repDb.save(repDoc).ok); - - waitForRep(repDb, repDoc, "completed"); - var copy = dbB.open("foo1"); - T(copy !== null); - T(copy.value === 11); - - copy = dbB.open("foo2"); - T(copy === null); - - copy = dbB.open("foo3"); - T(copy !== null); - T(copy.value === 33); - - copy = dbB.open("foo666"); - T(copy === null); - - copy = dbB.open("foo999"); - T(copy === null); - - copy = dbB.open("_design/mydesign"); - T(copy === null); - - repDoc = repDb.open(repDoc._id); - T(typeof repDoc._replication_stats === "object", "doc has stats"); - var stats = repDoc._replication_stats; - TEquals(3, stats.revisions_checked, "right # of revisions_checked"); - TEquals(3, stats.missing_revisions_found, "right # of missing_revisions_found"); - TEquals(3, stats.docs_read, "right # of docs_read"); - TEquals(2, stats.docs_written, "right # of docs_written"); - TEquals(1, stats.doc_write_failures, "right # of doc_write_failures"); - TEquals(dbA.info().update_seq, stats.checkpointed_source_seq, - "right checkpointed_source_seq"); - } - - var server_config = [ - { - section: "couch_httpd_auth", - key: "iterations", - value: "1" - }, - { - section: "replicator", - key: "db", - value: repDb.name - } - ]; - - repDb.deleteDb(); - run_on_modified_server(server_config, by_doc_ids_replication); - - // cleanup - repDb.deleteDb(); - dbA.deleteDb(); - dbB.deleteDb(); -} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/couchdb/blob/e2d9c9b1/share/www/script/test/replicator_db_compact_rep_db.js ---------------------------------------------------------------------- diff --git a/share/www/script/test/replicator_db_compact_rep_db.js b/share/www/script/test/replicator_db_compact_rep_db.js deleted file mode 100644 index 0dea0ed..0000000 --- a/share/www/script/test/replicator_db_compact_rep_db.js +++ /dev/null @@ -1,119 +0,0 @@ -// 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.replicator_db_compact_rep_db = function(debug) { - - if (debug) debugger; - - var populate_db = replicator_db.populate_db; - var docs1 = replicator_db.docs1; - var dbA = replicator_db.dbA; - var dbB = replicator_db.dbB; - var repDb = replicator_db.repDb; - var usersDb = replicator_db.usersDb; - var wait = replicator_db.wait; - var waitForRep = replicator_db.waitForRep; - var waitForSeq = replicator_db.waitForSeq; - var wait_rep_doc = replicator_db.wait_rep_doc; - - function compact_rep_db() { - var dbA_copy = new CouchDB("test_suite_rep_db_a_copy"); - var dbB_copy = new CouchDB("test_suite_rep_db_b_copy"); - var repDoc1, repDoc2; - var xhr, i, doc, copy, new_doc; - var docs = makeDocs(1, 50); - - populate_db(dbA, docs); - populate_db(dbB, docs); - populate_db(dbA_copy, []); - populate_db(dbB_copy, []); - - repDoc1 = { - _id: "rep1", - source: CouchDB.protocol + CouchDB.host + "/" + dbA.name, - target: dbA_copy.name, - continuous: true - }; - repDoc2 = { - _id: "rep2", - source: CouchDB.protocol + CouchDB.host + "/" + dbB.name, - target: dbB_copy.name, - continuous: true - }; - - TEquals(true, repDb.save(repDoc1).ok); - TEquals(true, repDb.save(repDoc2).ok); - - TEquals(true, repDb.compact().ok); - TEquals(202, repDb.last_req.status); - - waitForSeq(dbA, dbA_copy); - waitForSeq(dbB, dbB_copy); - - while (repDb.info().compact_running) {}; - - for (i = 0; i < docs.length; i++) { - copy = dbA_copy.open(docs[i]._id); - T(copy !== null); - copy = dbB_copy.open(docs[i]._id); - T(copy !== null); - } - - new_doc = { - _id: "foo666", - value: 666 - }; - - TEquals(true, dbA.save(new_doc).ok); - TEquals(true, dbB.save(new_doc).ok); - - waitForSeq(dbA, dbA_copy); - waitForSeq(dbB, dbB_copy); - - copy = dbA.open(new_doc._id); - T(copy !== null); - TEquals(666, copy.value); - copy = dbB.open(new_doc._id); - T(copy !== null); - TEquals(666, copy.value); - } - - var server_config = [ - { - section: "couch_httpd_auth", - key: "iterations", - value: "1" - }, - { - section: "replicator", - key: "db", - value: repDb.name - }, - { - section: "couch_httpd_auth", - key: "authentication_db", - value: usersDb.name - } - ]; - - repDb.deleteDb(); - run_on_modified_server(server_config, compact_rep_db); - - // cleanup - repDb.deleteDb(); - dbA.deleteDb(); - dbB.deleteDb(); - usersDb.deleteDb(); - (new CouchDB("test_suite_rep_db_a_copy")).deleteDb(); - (new CouchDB("test_suite_rep_db_b_copy")).deleteDb(); - -} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/couchdb/blob/e2d9c9b1/share/www/script/test/replicator_db_continuous.js ---------------------------------------------------------------------- diff --git a/share/www/script/test/replicator_db_continuous.js b/share/www/script/test/replicator_db_continuous.js deleted file mode 100644 index a2b17d0..0000000 --- a/share/www/script/test/replicator_db_continuous.js +++ /dev/null @@ -1,137 +0,0 @@ -// 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.replicator_db_continuous = function(debug) { - - if (debug) debugger; - - var populate_db = replicator_db.populate_db; - var docs1 = replicator_db.docs1; - var dbA = replicator_db.dbA; - var dbB = replicator_db.dbB; - var repDb = replicator_db.repDb; - var wait = replicator_db.wait; - var waitForRep = replicator_db.waitForRep; - var waitForSeq = replicator_db.waitForSeq; - - function continuous_replication() { - populate_db(dbA, docs1); - populate_db(dbB, []); - - var repDoc = { - _id: "foo_cont_rep_doc", - source: "http://" + CouchDB.host + "/" + dbA.name, - target: dbB.name, - continuous: true, - user_ctx: { - roles: ["_admin"] - } - }; - - T(repDb.save(repDoc).ok); - - waitForSeq(dbA, dbB); - for (var i = 0; i < docs1.length; i++) { - var doc = docs1[i]; - var copy = dbB.open(doc._id); - T(copy !== null); - T(copy.value === doc.value); - } - - var tasks = JSON.parse(CouchDB.request("GET", "/_active_tasks").responseText); - TEquals(1, tasks.length, "1 active task"); - TEquals(repDoc._id, tasks[0].doc_id, "replication doc id in active tasks"); - - // add another doc to source, it will be replicated to target - var docX = { - _id: "foo1000", - value: 1001 - }; - - T(dbA.save(docX).ok); - - waitForSeq(dbA, dbB); - var copy = dbB.open("foo1000"); - T(copy !== null); - T(copy.value === 1001); - - var repDoc1 = repDb.open(repDoc._id); - T(repDoc1 !== null); - T(repDoc1.source === repDoc.source); - T(repDoc1.target === repDoc.target); - T(repDoc1._replication_state === "triggered"); - T(typeof repDoc1._replication_state_time === "string"); - T(typeof repDoc1._replication_id === "string"); - - // 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" - }; - - T(dbA.save(ddoc).ok); - - waitForSeq(dbA, dbB); - var ddoc_copy = dbB.open("_design/foobar"); - T(ddoc_copy !== null); - T(ddoc.language === "javascript"); - - // update the design doc on source, test that the new revision is replicated - ddoc.language = "erlang"; - T(dbA.save(ddoc).ok); - T(ddoc._rev.indexOf("2-") === 0); - - waitForSeq(dbA, dbB); - ddoc_copy = dbB.open("_design/foobar"); - T(ddoc_copy !== null); - T(ddoc_copy._rev === ddoc._rev); - T(ddoc.language === "erlang"); - - // stop replication by deleting the replication document - T(repDb.deleteDoc(repDoc1).ok); - - // add another doc to source, it will NOT be replicated to target - var docY = { - _id: "foo666", - value: 999 - }; - - T(dbA.save(docY).ok); - - wait(200); // is there a way to avoid wait here? - var copy = dbB.open("foo666"); - T(copy === null); - } - - - var server_config = [ - { - section: "couch_httpd_auth", - key: "iterations", - value: "1" - }, - { - section: "replicator", - key: "db", - value: repDb.name - } - ]; - - repDb.deleteDb(); - run_on_modified_server(server_config, continuous_replication); - - // cleanup - repDb.deleteDb(); - dbA.deleteDb(); - dbB.deleteDb(); -} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/couchdb/blob/e2d9c9b1/share/www/script/test/replicator_db_credential_delegation.js ---------------------------------------------------------------------- diff --git a/share/www/script/test/replicator_db_credential_delegation.js b/share/www/script/test/replicator_db_credential_delegation.js deleted file mode 100644 index 7dd9d18..0000000 --- a/share/www/script/test/replicator_db_credential_delegation.js +++ /dev/null @@ -1,149 +0,0 @@ -// 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.replicator_db_credential_delegation = function(debug) { - - if (debug) debugger; - - var populate_db = replicator_db.populate_db; - var docs1 = replicator_db.docs1; - var dbA = replicator_db.dbA; - var dbB = replicator_db.dbB; - var repDb = replicator_db.repDb; - var usersDb = replicator_db.usersDb; - var wait = replicator_db.wait; - var waitForRep = replicator_db.waitForRep; - var waitForSeq = replicator_db.waitForSeq; - var wait_rep_doc = replicator_db.wait_rep_doc; - - function test_replication_credentials_delegation() { - populate_db(usersDb, []); - - var joeUserDoc = CouchDB.prepareUserDoc({ - name: "joe", - roles: ["god", "erlanger"] - }, "erly"); - T(usersDb.save(joeUserDoc).ok); - - var ddoc = { - _id: "_design/beer", - language: "javascript" - }; - populate_db(dbA, docs1.concat([ddoc])); - populate_db(dbB, []); - - T(dbB.setSecObj({ - admins: { - names: [], - roles: ["god"] - } - }).ok); - - var server_admins_config = [ - { - section: "couch_httpd_auth", - key: "iterations", - value: "1" - }, - { - section: "admins", - key: "fdmanana", - value: "qwerty" - } - ]; - - run_on_modified_server(server_admins_config, function() { - - T(CouchDB.login("fdmanana", "qwerty").ok); - T(CouchDB.session().userCtx.name === "fdmanana"); - T(CouchDB.session().userCtx.roles.indexOf("_admin") !== -1); - - var repDoc = { - _id: "foo_rep_del_doc_1", - source: dbA.name, - target: dbB.name, - user_ctx: { - name: "joe", - roles: ["erlanger"] - } - }; - - T(repDb.save(repDoc).ok); - - waitForRep(repDb, repDoc, "completed"); - for (var i = 0; i < docs1.length; i++) { - var doc = docs1[i]; - var copy = dbB.open(doc._id); - T(copy !== null); - T(copy.value === doc.value); - } - - // design doc was not replicated, because joe is not an admin of db B - var doc = dbB.open(ddoc._id); - T(doc === null); - - // now test the same replication but putting the role "god" in the - // delegation user context property - var repDoc2 = { - _id: "foo_rep_del_doc_2", - source: dbA.name, - target: dbB.name, - user_ctx: { - name: "joe", - roles: ["erlanger", "god"] - } - }; - T(repDb.save(repDoc2).ok); - - waitForRep(repDb, repDoc2, "completed"); - for (var i = 0; i < docs1.length; i++) { - var doc = docs1[i]; - var copy = dbB.open(doc._id); - T(copy !== null); - T(copy.value === doc.value); - } - - // because anyone with a 'god' role is an admin of db B, a replication - // that is delegated to a 'god' role can write design docs to db B - doc = dbB.open(ddoc._id); - T(doc !== null); - T(doc.language === ddoc.language); - }); - } - - var server_config = [ - { - section: "couch_httpd_auth", - key: "iterations", - value: "1" - }, - { - section: "replicator", - key: "db", - value: repDb.name - }, - { - section: "couch_httpd_auth", - key: "authentication_db", - value: usersDb.name - } - ]; - - repDb.deleteDb(); - run_on_modified_server(server_config, test_replication_credentials_delegation); - - // cleanup - repDb.deleteDb(); - dbA.deleteDb(); - dbB.deleteDb(); - usersDb.deleteDb(); -} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/couchdb/blob/e2d9c9b1/share/www/script/test/replicator_db_field_validation.js ---------------------------------------------------------------------- diff --git a/share/www/script/test/replicator_db_field_validation.js b/share/www/script/test/replicator_db_field_validation.js deleted file mode 100644 index 167bdcc..0000000 --- a/share/www/script/test/replicator_db_field_validation.js +++ /dev/null @@ -1,178 +0,0 @@ -// 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.replicator_db_field_validation = function(debug) { - - if (debug) debugger; - - var populate_db = replicator_db.populate_db; - var docs1 = replicator_db.docs1; - var dbA = replicator_db.dbA; - var dbB = replicator_db.dbB; - var repDb = replicator_db.repDb; - var usersDb = replicator_db.usersDb; - var wait = replicator_db.wait; - var waitForRep = replicator_db.waitForRep; - var waitForSeq = replicator_db.waitForSeq; - var wait_rep_doc = replicator_db.wait_rep_doc; - - function rep_doc_field_validation() { - var docs = makeDocs(1, 5); - - populate_db(dbA, docs); - populate_db(dbB, []); - - var repDoc = { - _id: "rep1", - target: dbB.name - }; - - try { - repDb.save(repDoc); - T(false, "should have failed because source field is missing"); - } catch (x) { - TEquals("forbidden", x.error); - } - - repDoc = { - _id: "rep1", - source: 123, - target: dbB.name - }; - - try { - repDb.save(repDoc); - T(false, "should have failed because source field is a number"); - } catch (x) { - TEquals("forbidden", x.error); - } - - repDoc = { - _id: "rep1", - source: dbA.name - }; - - try { - repDb.save(repDoc); - T(false, "should have failed because target field is missing"); - } catch (x) { - TEquals("forbidden", x.error); - } - - repDoc = { - _id: "rep1", - source: dbA.name, - target: null - }; - - try { - repDb.save(repDoc); - T(false, "should have failed because target field is null"); - } catch (x) { - TEquals("forbidden", x.error); - } - - repDoc = { - _id: "rep1", - source: dbA.name, - target: { url: 123 } - }; - - try { - repDb.save(repDoc); - T(false, "should have failed because target.url field is not a string"); - } catch (x) { - TEquals("forbidden", x.error); - } - - repDoc = { - _id: "rep1", - source: dbA.name, - target: { url: dbB.name, auth: null } - }; - - try { - repDb.save(repDoc); - T(false, "should have failed because target.auth field is null"); - } catch (x) { - TEquals("forbidden", x.error); - } - - repDoc = { - _id: "rep1", - source: dbA.name, - target: { url: dbB.name, auth: "foo:bar" } - }; - - try { - repDb.save(repDoc); - T(false, "should have failed because target.auth field is not an object"); - } catch (x) { - TEquals("forbidden", x.error); - } - - repDoc = { - _id: "rep1", - source: dbA.name, - target: dbB.name, - continuous: "true" - }; - - try { - repDb.save(repDoc); - T(false, "should have failed because continuous is not a boolean"); - } catch (x) { - TEquals("forbidden", x.error); - } - - repDoc = { - _id: "rep1", - source: dbA.name, - target: dbB.name, - filter: 123 - }; - - try { - repDb.save(repDoc); - T(false, "should have failed because filter is not a string"); - } catch (x) { - TEquals("forbidden", x.error); - } - } - - var server_config = [ - { - section: "couch_httpd_auth", - key: "iterations", - value: "1" - }, - { - section: "replicator", - key: "db", - value: repDb.name - }, - { - section: "couch_httpd_auth", - key: "authentication_db", - value: usersDb.name - } - ]; - - repDb.deleteDb(); - run_on_modified_server(server_config, rep_doc_field_validation); - - // cleanup - repDb.deleteDb(); - dbA.deleteDb(); - dbB.deleteDb(); - usersDb.deleteDb(); -} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/couchdb/blob/e2d9c9b1/share/www/script/test/replicator_db_filtered.js ---------------------------------------------------------------------- diff --git a/share/www/script/test/replicator_db_filtered.js b/share/www/script/test/replicator_db_filtered.js deleted file mode 100644 index 31c78a7..0000000 --- a/share/www/script/test/replicator_db_filtered.js +++ /dev/null @@ -1,105 +0,0 @@ -// 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.replicator_db_filtered = function(debug) { - - if (debug) debugger; - - var populate_db = replicator_db.populate_db; - var docs1 = replicator_db.docs1; - var dbA = replicator_db.dbA; - var dbB = replicator_db.dbB; - var repDb = replicator_db.repDb; - var waitForRep = replicator_db.waitForRep; - - function filtered_replication() { - var docs2 = docs1.concat([ - { - _id: "_design/mydesign", - language : "javascript", - filters : { - myfilter : (function(doc, req) { - return (doc.value % 2) !== Number(req.query.myparam); - }).toString() - } - } - ]); - - populate_db(dbA, docs2); - populate_db(dbB, []); - - var repDoc = { - _id: "foo_filt_rep_doc", - source: "http://" + CouchDB.host + "/" + dbA.name, - target: dbB.name, - filter: "mydesign/myfilter", - query_params: { - myparam: 1 - } - }; - T(repDb.save(repDoc).ok); - - waitForRep(repDb, repDoc, "completed"); - for (var i = 0; i < docs2.length; i++) { - var doc = docs2[i]; - var copy = dbB.open(doc._id); - - if (typeof doc.value === "number") { - if ((doc.value % 2) !== 1) { - T(copy !== null); - T(copy.value === doc.value); - } else { - T(copy === null); - } - } - } - - var repDoc1 = repDb.open(repDoc._id); - T(repDoc1 !== null); - T(repDoc1.source === repDoc.source); - T(repDoc1.target === repDoc.target); - T(repDoc1._replication_state === "completed", "filtered"); - T(typeof repDoc1._replication_state_time === "string"); - T(typeof repDoc1._replication_id === "string"); - T(typeof repDoc1._replication_stats === "object", "doc has stats"); - var stats = repDoc1._replication_stats; - TEquals(2, stats.revisions_checked, "right # of revisions_checked"); - TEquals(2, stats.missing_revisions_found, "right # of missing_revisions_found"); - TEquals(2, stats.docs_read, "right # of docs_read"); - TEquals(1, stats.docs_written, "right # of docs_written"); - TEquals(1, stats.doc_write_failures, "right # of doc_write_failures"); - TEquals(dbA.info().update_seq, stats.checkpointed_source_seq, - "right checkpointed_source_seq"); - } - - - var server_config = [ - { - section: "couch_httpd_auth", - key: "iterations", - value: "1" - }, - { - section: "replicator", - key: "db", - value: repDb.name - } - ]; - - repDb.deleteDb(); - run_on_modified_server(server_config, filtered_replication); - - // cleanup - repDb.deleteDb(); - dbA.deleteDb(); - dbB.deleteDb(); -} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/couchdb/blob/e2d9c9b1/share/www/script/test/replicator_db_identical.js ---------------------------------------------------------------------- diff --git a/share/www/script/test/replicator_db_identical.js b/share/www/script/test/replicator_db_identical.js deleted file mode 100644 index cdf4592..0000000 --- a/share/www/script/test/replicator_db_identical.js +++ /dev/null @@ -1,87 +0,0 @@ -// 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.replicator_db_identical = function(debug) { - - if (debug) debugger; - - var populate_db = replicator_db.populate_db; - var docs1 = replicator_db.docs1; - var dbA = replicator_db.dbA; - var dbB = replicator_db.dbB; - var repDb = replicator_db.repDb; - var wait = replicator_db.wait; - var waitForRep = replicator_db.waitForRep; - var waitForSeq = replicator_db.waitForSeq; - - // test the case where multiple replication docs (different IDs) - // describe in fact the same replication (source, target, etc) - function identical_rep_docs() { - populate_db(dbA, docs1); - populate_db(dbB, []); - - var repDoc1 = { - _id: "foo_dup_rep_doc_1", - source: "http://" + CouchDB.host + "/" + dbA.name, - target: dbB.name - }; - var repDoc2 = { - _id: "foo_dup_rep_doc_2", - source: "http://" + CouchDB.host + "/" + dbA.name, - target: dbB.name - }; - - T(repDb.save(repDoc1).ok); - T(repDb.save(repDoc2).ok); - - waitForRep(repDb, repDoc1, "completed"); - for (var i = 0; i < docs1.length; i++) { - var doc = docs1[i]; - var copy = dbB.open(doc._id); - T(copy !== null); - T(copy.value === doc.value); - } - - repDoc1 = repDb.open("foo_dup_rep_doc_1"); - T(repDoc1 !== null); - T(repDoc1._replication_state === "completed", "identical"); - T(typeof repDoc1._replication_state_time === "string"); - T(typeof repDoc1._replication_id === "string"); - - repDoc2 = repDb.open("foo_dup_rep_doc_2"); - T(repDoc2 !== null); - T(typeof repDoc2._replication_state === "undefined"); - T(typeof repDoc2._replication_state_time === "undefined"); - T(repDoc2._replication_id === repDoc1._replication_id); - } - - var server_config = [ - { - section: "couch_httpd_auth", - key: "iterations", - value: "1" - }, - { - section: "replicator", - key: "db", - value: repDb.name - } - ]; - - repDb.deleteDb(); - run_on_modified_server(server_config, identical_rep_docs); - - // cleanup - repDb.deleteDb(); - dbA.deleteDb(); - dbB.deleteDb(); -} \ No newline at end of file