diff options
author | Robert Newson <rnewson@apache.org> | 2014-08-28 13:36:13 +0100 |
---|---|---|
committer | Robert Newson <rnewson@apache.org> | 2014-08-28 13:36:13 +0100 |
commit | aa9f32d8f38b5e366e546843d1fe73bf317bb93c (patch) | |
tree | 77607ad747efc63bf5bd89cbb56d2585312a0c51 | |
parent | 73a03074d9397151e8151d658b20f871c13d39f7 (diff) | |
parent | 881ead7e30f7113ab5c78d684a3b577d4fa42d0f (diff) | |
download | couchdb-aa9f32d8f38b5e366e546843d1fe73bf317bb93c.tar.gz |
Merge branch 'windsor-merge'
-rw-r--r-- | Makefile | 5 | ||||
-rwxr-xr-x | dev/run | 1 | ||||
-rw-r--r-- | rebar.config.script | 60 | ||||
-rw-r--r-- | rel/files/sys.config | 19 | ||||
-rw-r--r-- | rel/overlay/etc/default.ini | 5 | ||||
-rw-r--r-- | rel/reltool.config | 8 | ||||
-rw-r--r-- | share/www/script/test/config.js | 2 | ||||
-rw-r--r-- | share/www/script/test/replication.js | 120 | ||||
-rw-r--r-- | share/www/script/test/replicator_db_identical_continuous.js | 7 | ||||
-rwxr-xr-x | test/etap/030-doc-from-json.t | 38 | ||||
-rwxr-xr-x | test/etap/031-doc-to-json.t | 66 | ||||
-rwxr-xr-x | test/etap/060-kt-merging.t | 53 | ||||
-rwxr-xr-x | test/javascript/run | 14 |
13 files changed, 221 insertions, 177 deletions
@@ -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) @@ -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) |