summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Newson <rnewson@apache.org>2014-08-28 13:36:13 +0100
committerRobert Newson <rnewson@apache.org>2014-08-28 13:36:13 +0100
commitaa9f32d8f38b5e366e546843d1fe73bf317bb93c (patch)
tree77607ad747efc63bf5bd89cbb56d2585312a0c51
parent73a03074d9397151e8151d658b20f871c13d39f7 (diff)
parent881ead7e30f7113ab5c78d684a3b577d4fa42d0f (diff)
downloadcouchdb-aa9f32d8f38b5e366e546843d1fe73bf317bb93c.tar.gz
Merge branch 'windsor-merge'
-rw-r--r--Makefile5
-rwxr-xr-xdev/run1
-rw-r--r--rebar.config.script60
-rw-r--r--rel/files/sys.config19
-rw-r--r--rel/overlay/etc/default.ini5
-rw-r--r--rel/reltool.config8
-rw-r--r--share/www/script/test/config.js2
-rw-r--r--share/www/script/test/replication.js120
-rw-r--r--share/www/script/test/replicator_db_identical_continuous.js7
-rwxr-xr-xtest/etap/030-doc-from-json.t38
-rwxr-xr-xtest/etap/031-doc-to-json.t66
-rwxr-xr-xtest/etap/060-kt-merging.t53
-rwxr-xr-xtest/javascript/run14
13 files changed, 221 insertions, 177 deletions
diff --git a/Makefile b/Makefile
index 800b6ddc9..ea1aba89b 100644
--- a/Makefile
+++ b/Makefile
@@ -24,7 +24,7 @@ compile: config.erl
clean:
@echo "==> couchjs (clean)"
- @rebar clean
+ @rebar -r clean
check: eunit
@@ -36,6 +36,9 @@ dist: compile
distclean: clean
@rm -rf rel/couchdb
+devclean:
+ @rm -rf dev/lib/*/data
+
include install.mk
install: dist
@mkdir -p $(prefix)
diff --git a/dev/run b/dev/run
index 58a3c5f0d..a4f76cb80 100755
--- a/dev/run
+++ b/dev/run
@@ -151,6 +151,7 @@ def boot_node(node):
cmd = [
"erl",
"-args_file", os.path.join(DEV_PATH, "lib", node, "etc", "vm.args"),
+ "-config", os.path.join(COUCHDB, "rel", "files", "sys"),
"-couch_ini",
os.path.join(DEV_PATH, "lib", node, "etc", "default.ini"),
os.path.join(DEV_PATH, "lib", node, "etc", "local.ini"),
diff --git a/rebar.config.script b/rebar.config.script
index 252586526..3dab22f24 100644
--- a/rebar.config.script
+++ b/rebar.config.script
@@ -17,32 +17,44 @@ os:putenv("COUCHDB_CONFIG", ConfigureEnv).
DepDescs = [
- {couch_log, "couchdb-couch-log", {branch, "master"}, []},
- {config, "couchdb-config", {branch, "master"}, []},
- {chttpd, "couchdb-chttpd", {branch, "master"}, []},
- {couch, "couchdb-couch", {branch, "master"}, []},
- {couch_index, "couchdb-couch-index", {branch, "master"}, []},
- {couch_mrview, "couchdb-couch-mrview", {branch, "master"}, []},
- {couch_replicator, "couchdb-couch-replicator", {branch, "master"}, []},
- {couch_dbupdates, "couchdb-couch-dbupdates", {branch, "master"}, []},
- {couch_plugins, "couchdb-couch-plugins", {branch, "master"}, []},
- {ddoc_cache, "couchdb-ddoc-cache", {branch, "master"}, []},
- {ets_lru, "couchdb-ets-lru", {branch, "master"}, []},
- {fabric, "couchdb-fabric", {branch, "master"}, []},
- {ibrowse, "couchdb-ibrowse", {tag, "master"}, []},
- {jiffy, "couchdb-jiffy", {branch, "master"}, []},
- {mem3, "couchdb-mem3", {branch, "master"}, []},
- {mochiweb, "couchdb-mochiweb", {branch, "master"}, []},
- {oauth, "couchdb-oauth", {branch, "master"}, []},
- {rexi, "couchdb-rexi", {branch, "master"}, []},
- {snappy, "couchdb-snappy", {branch, "1994-merge-rcouch"}, []},
- {fauxton, "couchdb-fauxton", {branch, "master"}, [raw]},
- {docs, "couchdb-documentation", {branch, "master"}, [raw]}
+ {b64url, "b64url", {branch, "master"}},
+ {cassim, "cassim", {branch, "master"}},
+ {couch_log, "couch-log", {branch, "master"}},
+ {config, "config", {branch, "master"}},
+ {chttpd, "chttpd", {branch, "master"}},
+ {couch, "couch", {branch, "master"}},
+ {couch_index, "couch-index", {branch, "master"}},
+ {couch_mrview, "couch-mrview", {branch, "master"}},
+ {couch_replicator, "couch-replicator", {branch, "master"}},
+ {couch_dbupdates, "couch-dbupdates", {branch, "master"}},
+ {couch_plugins, "couch-plugins", {branch, "master"}},
+ {couch_event, "couch-event", {branch, "master"}},
+ {couch_stats, "couch-stats", {branch, "master"}},
+ {docs, "documentation", {branch, "master"}, [raw]},
+ {ddoc_cache, "ddoc-cache", {branch, "master"}},
+ {ets_lru, "ets-lru", {branch, "master"}},
+ {fabric, "fabric", {branch, "master"}},
+ {fauxton, "fauxton", {branch, "master"}, [raw]},
+ {global_changes, "global-changes", {branch, "master"}},
+ {ibrowse, "ibrowse", {branch, "master"}},
+ {jiffy, "jiffy", {branch, "master"}},
+ {khash, "khash", {branch, "master"}},
+ {mem3, "mem3", {branch, "master"}},
+ {mochiweb, "mochiweb", {branch, "master"}},
+ {oauth, "oauth", {branch, "master"}},
+ {rexi, "rexi", {branch, "master"}},
+ {snappy, "snappy", {branch, "1994-merge-rcouch"}}
],
-MakeDep = fun({AppName, RepoName, Version, Options}) ->
- Url = "https://git-wip-us.apache.org/repos/asf/" ++ RepoName ++ ".git",
- {AppName, ".*", {git, Url, Version}, Options}
+BaseUrl = "https://git-wip-us.apache.org/repos/asf/",
+
+MakeDep = fun
+ ({AppName, RepoName, Version}) ->
+ Url = BaseUrl ++ "couchdb-" ++ RepoName ++ ".git",
+ {AppName, ".*", {git, Url, Version}};
+ ({AppName, RepoName, Version, Options}) ->
+ Url = BaseUrl ++ "couchdb-" ++ RepoName ++ ".git",
+ {AppName, ".*", {git, Url, Version}, Options}
end,
AddConfig = [
diff --git a/rel/files/sys.config b/rel/files/sys.config
index 97562f561..6bfc77562 100644
--- a/rel/files/sys.config
+++ b/rel/files/sys.config
@@ -10,4 +10,21 @@
% License for the specific language governing permissions and limitations under
% the License.
-[].
+[
+ {lager, [
+ {error_logger_hwm, 1000},
+ {error_logger_redirect, true},
+ {handlers, [
+ {lager_console_backend, [debug, {
+ lager_default_formatter,
+ [
+ date, " ", time,
+ " [", severity, "] ",
+ node, " ", pid, " ",
+ message,
+ "\n"
+ ]
+ }]}
+ ]}
+ ]}
+].
diff --git a/rel/overlay/etc/default.ini b/rel/overlay/etc/default.ini
index dfcd3bcec..491c76a94 100644
--- a/rel/overlay/etc/default.ini
+++ b/rel/overlay/etc/default.ini
@@ -154,11 +154,8 @@ external_manager={couch_external_manager, start_link, []}
query_servers={couch_proc_manager, start_link, []}
vhosts={couch_httpd_vhost, start_link, []}
httpd={couch_httpd, start_link, []}
-stats_aggregator={couch_stats_aggregator, start, []}
-stats_collector={couch_stats_collector, start, []}
uuids={couch_uuids, start, []}
auth_cache={couch_auth_cache, start_link, []}
-replicator_manager={couch_replicator_manager, start_link, []}
os_daemons={couch_os_daemons, start_link, []}
compaction_daemon={couch_compaction_daemon, start_link, []}
@@ -176,7 +173,7 @@ _config = {couch_httpd_misc_handlers, handle_config_req}
_replicate = {couch_replicator_httpd, handle_req}
_uuids = {couch_httpd_misc_handlers, handle_uuids_req}
_restart = {couch_httpd_misc_handlers, handle_restart_req}
-_stats = {couch_httpd_stats_handlers, handle_stats_req}
+_stats = {couch_stats_httpd, handle_stats_req}
_session = {couch_httpd_auth, handle_session_req}
_oauth = {couch_httpd_oauth, handle_oauth_req}
_db_updates = {couch_dbupdates_httpd, handle_req}
diff --git a/rel/reltool.config b/rel/reltool.config
index d1b0321d8..d5c76bc80 100644
--- a/rel/reltool.config
+++ b/rel/reltool.config
@@ -27,6 +27,7 @@
syntax_tools,
xmerl,
%% couchdb
+ cassim,
chttpd,
config,
couch,
@@ -36,12 +37,15 @@
couch_mrview,
couch_plugins,
couch_replicator,
+ couch_event,
ddoc_cache,
ets_lru,
fabric,
+ global_changes,
goldrush,
ibrowse,
jiffy,
+ khash,
lager,
mem3,
mochiweb,
@@ -72,6 +76,7 @@
{app, xmerl, [{incl_cond, include}]},
%% couchdb
+ {app, cassim, [{incl_cond, include}]},
{app, chttpd, [{incl_cond, include}]},
{app, config, [{incl_cond, include}]},
{app, couch, [{incl_cond, include}]},
@@ -81,12 +86,15 @@
{app, couch_mrview, [{incl_cond, include}]},
{app, couch_plugins, [{incl_cond, include}]},
{app, couch_replicator, [{incl_cond, include}]},
+ {app, couch_event, [{incl_cond, include}]},
{app, ddoc_cache, [{incl_cond, include}]},
{app, ets_lru, [{incl_cond, include}]},
{app, fabric, [{incl_cond, include}]},
+ {app, global_changes, [{incl_cond, include}]},
{app, goldrush, [{incl_cond, include}]},
{app, ibrowse, [{incl_cond, include}]},
{app, jiffy, [{incl_cond, include}]},
+ {app, khash, [{incl_cond, include}]},
{app, lager, [{incl_cond, include}]},
{app, mem3, [{incl_cond, include}]},
{app, mochiweb, [{incl_cond, include}]},
diff --git a/share/www/script/test/config.js b/share/www/script/test/config.js
index 193aa89bc..37b339b99 100644
--- a/share/www/script/test/config.js
+++ b/share/www/script/test/config.js
@@ -53,7 +53,7 @@ couchTests.config = function(debug) {
T(config.couchdb.database_dir);
T(config.daemons.httpd);
T(config.httpd_global_handlers._config);
- T(config.log.level);
+ // T(config.log.level);
T(config.query_servers.javascript);
// test that settings can be altered, and that an undefined whitelist allows any change
diff --git a/share/www/script/test/replication.js b/share/www/script/test/replication.js
index 7e4ecc1b3..21a430452 100644
--- a/share/www/script/test/replication.js
+++ b/share/www/script/test/replication.js
@@ -97,7 +97,6 @@ couchTests.replication = function(debug) {
function populateDb(db, docs, dontRecreateDb) {
if (dontRecreateDb !== true) {
db.deleteDb();
- wait(100);
db.createDb();
}
for (var i = 0; i < docs.length; i++) {
@@ -150,26 +149,37 @@ couchTests.replication = function(debug) {
}
- function waitForSeq(sourceDb, targetDb) {
- var targetSeq,
- sourceSeq = sourceDb.info().update_seq,
- t0 = new Date(),
- t1,
- ms = 3000;
-
+ function getTask(rep_id, delay) {
+ var t0 = new Date();
+ var t1;
do {
- targetSeq = targetDb.info().update_seq;
+ 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) <= ms) && targetSeq < sourceSeq);
+ } while((t1 - t0) <= delay);
+
+ return null;
}
- function wait(ms) {
- var t0 = new Date(), t1;
+ function waitForSeq(sourceDb, targetDb, rep_id) {
+ var sourceSeq = sourceDb.info().update_seq,
+ t0 = new Date(),
+ t1,
+ ms = 3000;
+
do {
- CouchDB.request("GET", "/");
+ var task = getTask(rep_id, 0);
+ if(task && task["through_seq"] == sourceSeq) {
+ return;
+ }
t1 = new Date();
- } while ((t1 - t0) <= ms);
+ } while (((t1 - t0) <= ms));
}
@@ -700,11 +710,24 @@ couchTests.replication = function(debug) {
TEquals(true, repResult.history instanceof Array);
TEquals(1, repResult.history.length);
- // NOT 31 (31 is db seq for last doc - the ddoc, which was not replicated)
- TEquals(30, repResult.source_last_seq);
+ // 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(30, repResult.history[0].end_last_seq);
- TEquals(30, repResult.history[0].recorded_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);
@@ -750,7 +773,7 @@ couchTests.replication = function(debug) {
TEquals(36, repResult.source_last_seq);
TEquals(true, repResult.history instanceof Array);
TEquals(2, repResult.history.length);
- TEquals(30, repResult.history[0].start_last_seq);
+ 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);
@@ -1153,7 +1176,7 @@ couchTests.replication = function(debug) {
var rep_id = repResult._local_id;
- waitForSeq(sourceDb, targetDb);
+ waitForSeq(sourceDb, targetDb, rep_id);
for (j = 0; j < docs.length; j++) {
doc = docs[j];
@@ -1191,7 +1214,7 @@ couchTests.replication = function(debug) {
var ddoc = docs[docs.length - 1]; // design doc
addAtt(sourceDb, ddoc, "readme.txt", att1_data, "text/plain");
- waitForSeq(sourceDb, targetDb);
+ waitForSeq(sourceDb, targetDb, rep_id);
var modifDocs = docs.slice(10, 15).concat([ddoc]);
for (j = 0; j < modifDocs.length; j++) {
@@ -1236,7 +1259,7 @@ couchTests.replication = function(debug) {
// add another attachment to the ddoc on source
addAtt(sourceDb, ddoc, "data.dat", att2_data, "application/binary");
- waitForSeq(sourceDb, targetDb);
+ waitForSeq(sourceDb, targetDb, rep_id);
copy = targetDb.open(ddoc._id);
var atts = copy._attachments;
@@ -1273,7 +1296,7 @@ couchTests.replication = function(debug) {
var newDocs = makeDocs(25, 35);
populateDb(sourceDb, newDocs, true);
- waitForSeq(sourceDb, targetDb);
+ waitForSeq(sourceDb, targetDb, rep_id);
for (j = 0; j < newDocs.length; j++) {
doc = newDocs[j];
@@ -1290,10 +1313,9 @@ couchTests.replication = function(debug) {
// delete docs from source
TEquals(true, sourceDb.deleteDoc(newDocs[0]).ok);
- wait(1000);
TEquals(true, sourceDb.deleteDoc(newDocs[6]).ok);
- waitForSeq(sourceDb, targetDb);
+ waitForSeq(sourceDb, targetDb, rep_id);
copy = targetDb.open(newDocs[0]._id);
TEquals(null, copy);
@@ -1328,7 +1350,7 @@ couchTests.replication = function(debug) {
};
TEquals(true, sourceDb.save(doc).ok);
- wait(2000);
+ waitForSeq(sourceDb, targetDb, rep_id);
copy = targetDb.open(doc._id);
TEquals(null, copy);
}
@@ -1363,21 +1385,11 @@ couchTests.replication = function(debug) {
while (sourceDb.info().compact_running) {};
TEquals(true, sourceDb.save(makeDocs(30, 31)[0]).ok);
- xhr = CouchDB.request("GET", "/_active_tasks");
-
- var xhr = CouchDB.request("GET", "/_active_tasks");
- var tasks = JSON.parse(xhr.responseText);
- var found_task = false;
- for(var i = 0; i < tasks.length; i++) {
- if(tasks[i].replication_id == repResult._local_id) {
- found_task = true;
- break;
- }
- }
- TEquals(true, found_task);
+ var task = getTask(repResult._local_id, 1000);
+ T(task != null);
- waitForSeq(sourceDb, targetDb);
+ waitForSeq(sourceDb, targetDb, repResult._local_id);
T(sourceDb.open("30") !== null);
// cancel replication
@@ -1701,21 +1713,12 @@ couchTests.replication = function(debug) {
);
TEquals(true, repResult.ok);
TEquals('string', typeof repResult._local_id);
+ var repId = repResult._local_id;
- // Race conditions are awesome
- wait(500);
-
- xhr = CouchDB.request("GET", "/_active_tasks");
- tasks = JSON.parse(xhr.responseText);
+ var task = getTask(repId, 3000);
+ T(task != null);
- var repId;
- for (j = 0; j < tasks.length; j++) {
- if (tasks[j].replication_id === repResult._local_id) {
- repId = tasks[j].replication_id;
- }
- }
-
- TEquals(repResult._local_id, repId, "Replication found in _active_tasks");
+ TEquals(task["replication_id"], repId, "Replication found in _active_tasks");
xhr = CouchDB.request(
"POST", "/_replicate", {
body: JSON.stringify({"replication_id": repId, "cancel": true}),
@@ -1723,19 +1726,12 @@ couchTests.replication = function(debug) {
});
TEquals(200, xhr.status, "Replication cancel request success");
- xhr = CouchDB.request("GET", "/_active_tasks");
- tasks = JSON.parse(xhr.responseText);
- repId = null;
- for (j = 0; j < tasks.length; j++) {
- if (tasks[j].replication_id === repResult._local_id) {
- repId = tasks[j].replication_id;
- }
- }
- TEquals(null, repId, "Replication was canceled");
+ task = getTask(repId);
+ TEquals(null, task, "Replication was canceled");
xhr = CouchDB.request(
"POST", "/_replicate", {
- body: JSON.stringify({"replication_id": repResult._local_id, "cancel": true}),
+ body: JSON.stringify({"replication_id": repId, "cancel": true}),
headers: {"Content-Type": "application/json"}
});
TEquals(404, xhr.status, "2nd replication cancel failed");
diff --git a/share/www/script/test/replicator_db_identical_continuous.js b/share/www/script/test/replicator_db_identical_continuous.js
index 5e7f15121..240c531f5 100644
--- a/share/www/script/test/replicator_db_identical_continuous.js
+++ b/share/www/script/test/replicator_db_identical_continuous.js
@@ -54,6 +54,13 @@ couchTests.replicator_db_identical_continuous = function(debug) {
T(copy.value === doc.value);
}
+ // Rather than a timeout we're just waiting to hear the
+ // fourth change to the database. Changes 1 and 2 were
+ // us storing repDoc1 and repDoc2. Changes 3 and 4 are
+ // the replicator manager updating each document. This
+ // just waits until the fourth change before continuing.
+ repDb.changes({"feed":"longpoll", "since":3});
+
repDoc1 = repDb.open("foo_dup_cont_rep_doc_1");
T(repDoc1 !== null);
T(repDoc1._replication_state === "triggered");
diff --git a/test/etap/030-doc-from-json.t b/test/etap/030-doc-from-json.t
index 79d5692c7..1a11d8dcb 100755
--- a/test/etap/030-doc-from-json.t
+++ b/test/etap/030-doc-from-json.t
@@ -14,11 +14,7 @@
% License for the specific language governing permissions and limitations under
% the License.
-%% XXX: Figure out how to -include("couch_db.hrl")
--record(doc, {id= <<"">>, revs={0, []}, body={[]},
- atts=[], deleted=false, meta=[]}).
--record(att, {name, type, att_len, disk_len, md5= <<>>, revpos=0, data,
- encoding=identity}).
+-include_lib("couch/include/couch_db.hrl").
main(_) ->
test_util:init_code_path(),
@@ -84,22 +80,22 @@ test_from_json_success() ->
]}}
]}}]},
#doc{atts=[
- #att{
- name = <<"my_attachment.fu">>,
- data = stub,
- type = <<"application/awesome">>,
- att_len = 45,
- disk_len = 45,
- revpos = nil
- },
- #att{
- name = <<"noahs_private_key.gpg">>,
- data = <<"I have a pet fish!">>,
- type = <<"application/pgp-signature">>,
- att_len = 18,
- disk_len = 18,
- revpos = 0
- }
+ couch_att:new([
+ {name, <<"my_attachment.fu">>},
+ {data, stub},
+ {type, <<"application/awesome">>},
+ {att_len, 45},
+ {disk_len, 45},
+ {revpos, undefined}
+ ]),
+ couch_att:new([
+ {name, <<"noahs_private_key.gpg">>},
+ {data, <<"I have a pet fish!">>},
+ {type, <<"application/pgp-signature">>},
+ {att_len, 18},
+ {disk_len, 18},
+ {revpos, 0}
+ ])
]},
"Attachments are parsed correctly."
},
diff --git a/test/etap/031-doc-to-json.t b/test/etap/031-doc-to-json.t
index e0aaf70d5..d4227e7dd 100755
--- a/test/etap/031-doc-to-json.t
+++ b/test/etap/031-doc-to-json.t
@@ -14,11 +14,7 @@
% License for the specific language governing permissions and limitations under
% the License.
-%% XXX: Figure out how to -include("couch_db.hrl")
--record(doc, {id= <<"">>, revs={0, []}, body={[]},
- atts=[], deleted=false, meta=[]}).
--record(att, {name, type, att_len, disk_len, md5= <<>>, revpos=0, data,
- encoding=identity}).
+-include_lib("couch/include/couch_db.hrl").
main(_) ->
test_util:init_code_path(),
@@ -114,22 +110,22 @@ test_to_json_success() ->
},
{
#doc{atts=[
- #att{
- name = <<"big.xml">>,
- type = <<"xml/sucks">>,
- data = fun() -> ok end,
- revpos = 1,
- att_len = 400,
- disk_len = 400
- },
- #att{
- name = <<"fast.json">>,
- type = <<"json/ftw">>,
- data = <<"{\"so\": \"there!\"}">>,
- revpos = 1,
- att_len = 16,
- disk_len = 16
- }
+ couch_att:new([
+ {name, <<"big.xml">>},
+ {type, <<"xml/sucks">>},
+ {data, fun() -> ok end},
+ {revpos, 1},
+ {att_len, 400},
+ {disk_len, 400}
+ ]),
+ couch_att:new([
+ {name, <<"fast.json">>},
+ {type, <<"json/ftw">>},
+ {data, <<"{\"so\": \"there!\"}">>},
+ {revpos, 1},
+ {att_len, 16},
+ {disk_len, 16}
+ ])
]},
{[
{<<"_id">>, <<>>},
@@ -153,20 +149,20 @@ test_to_json_success() ->
{
[attachments],
#doc{atts=[
- #att{
- name = <<"stuff.txt">>,
- type = <<"text/plain">>,
- data = fun() -> <<"diet pepsi">> end,
- revpos = 1,
- att_len = 10,
- disk_len = 10
- },
- #att{
- name = <<"food.now">>,
- type = <<"application/food">>,
- revpos = 1,
- data = <<"sammich">>
- }
+ couch_att:new([
+ {name, <<"stuff.txt">>},
+ {type, <<"text/plain">>},
+ {data, fun() -> <<"diet pepsi">> end},
+ {revpos, 1},
+ {att_len, 10},
+ {disk_len, 10}
+ ]),
+ couch_att:new([
+ {name, <<"food.now">>},
+ {type, <<"application/food">>},
+ {revpos, 1},
+ {data, <<"sammich">>}
+ ])
]},
{[
{<<"_id">>, <<>>},
diff --git a/test/etap/060-kt-merging.t b/test/etap/060-kt-merging.t
index efbdbf695..e0b1a9c36 100755
--- a/test/etap/060-kt-merging.t
+++ b/test/etap/060-kt-merging.t
@@ -29,12 +29,12 @@ test() ->
One = {1, {"1","foo",[]}},
etap:is(
- {[One], no_conflicts},
+ {[One], new_leaf},
couch_key_tree:merge([], One, 10),
"The empty tree is the identity for merge."
),
etap:is(
- {[One], no_conflicts},
+ {[One], internal_node},
couch_key_tree:merge([One], One, 10),
"Merging is reflexive."
),
@@ -43,7 +43,7 @@ test() ->
{1, {"2","foo",[]}}],
etap:is(
- {TwoSibs, no_conflicts},
+ {TwoSibs, internal_node},
couch_key_tree:merge(TwoSibs, One, 10),
"Merging a prefix of a tree with the tree yields the tree."
),
@@ -54,7 +54,7 @@ test() ->
{1, {"3","foo",[]}}],
etap:is(
- {ThreeSibs, conflicts},
+ {ThreeSibs, new_branch},
couch_key_tree:merge(TwoSibs, Three, 10),
"Merging a third unrelated branch leads to a conflict."
),
@@ -63,30 +63,17 @@ test() ->
TwoChild = {1, {"1","foo", [{"1a", "bar", [{"1aa", "bar", []}]}]}},
etap:is(
- {[TwoChild], no_conflicts},
+ {[TwoChild], internal_node},
couch_key_tree:merge([TwoChild], TwoChild, 10),
"Merging two children is still reflexive."
),
TwoChildSibs = {1, {"1","foo", [{"1a", "bar", []},
{"1b", "bar", []}]}},
- etap:is(
- {[TwoChildSibs], no_conflicts},
- couch_key_tree:merge([TwoChildSibs], TwoChildSibs, 10),
- "Merging a tree to itself is itself."),
-
- TwoChildPlusSibs =
- {1, {"1","foo", [{"1a", "bar", [{"1aa", "bar", []}]},
- {"1b", "bar", []}]}},
-
- etap:is(
- {[TwoChildPlusSibs], no_conflicts},
- couch_key_tree:merge([TwoChild], TwoChildSibs, 10),
- "Merging tree of uneven length at node 2."),
Stemmed1b = {2, {"1a", "bar", []}},
etap:is(
- {[TwoChildSibs], no_conflicts},
+ {[TwoChildSibs], internal_node},
couch_key_tree:merge([TwoChildSibs], Stemmed1b, 10),
"Merging a tree with a stem."
),
@@ -95,7 +82,7 @@ test() ->
{"1b", "bar", [{"1bb", "boo", []}]}]}},
Stemmed1bb = {3, {"1bb", "boo", []}},
etap:is(
- {[TwoChildSibs2], no_conflicts},
+ {[TwoChildSibs2], internal_node},
couch_key_tree:merge([TwoChildSibs2], Stemmed1bb, 10),
"Merging a stem at a deeper level."
),
@@ -104,27 +91,27 @@ test() ->
{2,{"1b", "bar", [{"1bb", "boo", []}]}}],
etap:is(
- {StemmedTwoChildSibs2, no_conflicts},
+ {StemmedTwoChildSibs2, internal_node},
couch_key_tree:merge(StemmedTwoChildSibs2, Stemmed1bb, 10),
"Merging a stem at a deeper level against paths at deeper levels."
),
Stemmed1aa = {3, {"1aa", "bar", []}},
etap:is(
- {[TwoChild], no_conflicts},
+ {[TwoChild], internal_node},
couch_key_tree:merge([TwoChild], Stemmed1aa, 10),
"Merging a single tree with a deeper stem."
),
Stemmed1a = {2, {"1a", "bar", [{"1aa", "bar", []}]}},
etap:is(
- {[TwoChild], no_conflicts},
+ {[TwoChild], internal_node},
couch_key_tree:merge([TwoChild], Stemmed1a, 10),
"Merging a larger stem."
),
etap:is(
- {[Stemmed1a], no_conflicts},
+ {[Stemmed1a], internal_node},
couch_key_tree:merge([Stemmed1a], Stemmed1aa, 10),
"More merging."
),
@@ -132,13 +119,13 @@ test() ->
OneChild = {1, {"1","foo",[{"1a", "bar", []}]}},
Expect1 = [OneChild, Stemmed1aa],
etap:is(
- {Expect1, conflicts},
+ {Expect1, new_branch},
couch_key_tree:merge([OneChild], Stemmed1aa, 10),
"Merging should create conflicts."
),
etap:is(
- {[TwoChild], no_conflicts},
+ {[TwoChild], new_leaf},
couch_key_tree:merge(Expect1, TwoChild, 10),
"Merge should have no conflicts."
),
@@ -168,9 +155,21 @@ test() ->
]}},
etap:is(
- {[FooBar], no_conflicts},
+ {[FooBar], new_leaf},
couch_key_tree:merge([Foo],Bar,10),
"Merging trees with conflicts ought to behave."
),
+ etap:is(
+ {[TwoChild], internal_node},
+ couch_key_tree:merge([TwoChild],One,10),
+ "Merging tree with already-existing path."
+ ),
+
+ etap:is(
+ {[TwoChildSibs], internal_node},
+ couch_key_tree:merge([TwoChildSibs],One,10),
+ "Merging tree with already-existing path with siblings."
+ ),
+
ok.
diff --git a/test/javascript/run b/test/javascript/run
index 65562d747..883fd37c1 100755
--- a/test/javascript/run
+++ b/test/javascript/run
@@ -37,6 +37,7 @@ SCRIPTS = """
share/www/script/sha1.js
share/www/script/oauth.js
share/www/script/couch.js
+ share/www/script/replicator_db_inc.js
share/www/script/couch_test_runner.js
test/javascript/couch_http.js
test/javascript/test_setup.js
@@ -94,7 +95,10 @@ def run_couchjs(test, fmt):
def options():
- return []
+ return [
+ op.make_option("-s", "--start", metavar="FILENAME", default=None,
+ help="Start from the given filename if multiple files are passed")
+ ]
def main():
@@ -118,6 +122,14 @@ def main():
else:
sys.stderr.write("Unknown test: " + name + os.linesep)
exit(1)
+
+ if opts.start is not None:
+ tmp = []
+ for name in tests:
+ if name >= opts.start:
+ tmp.append(name)
+ tests = tmp
+
fmt = mkformatter(tests)
for test in tests:
run_couchjs(test, fmt)