This is an automated email from the ASF dual-hosted git repository.

vatamane pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/couchdb.git

commit 264ad11f37340e6b1c7e5b1acc21bad5a81d0bec
Author: Nick Vatamaniuc <[email protected]>
AuthorDate: Thu Aug 18 21:03:22 2022 -0400

    Add some utility functions to couch_replicator_test_helper
    
    In preparation to start using chttpd (fabric) endpoints add some common 
utility
    functions to the replication test helper module.
    
    Since `couch_db:fold_docs/4` doesn't exit for fabric, use the changes feed 
to
    get all the revision leafs. That is used when comparing database endpoints.
    
    It turns our the majority replication tests can use the exact same setup,
    teardown and db_url functions so make sure those are also available in the
    helper module.
---
 .../test/eunit/couch_replicator_test_helper.erl    | 134 +++++++++++++++------
 1 file changed, 100 insertions(+), 34 deletions(-)

diff --git a/src/couch_replicator/test/eunit/couch_replicator_test_helper.erl 
b/src/couch_replicator/test/eunit/couch_replicator_test_helper.erl
index 4044e7c72..16423e85c 100644
--- a/src/couch_replicator/test/eunit/couch_replicator_test_helper.erl
+++ b/src/couch_replicator/test/eunit/couch_replicator_test_helper.erl
@@ -4,39 +4,75 @@
 -include_lib("couch/include/couch_db.hrl").
 -include_lib("couch_replicator/src/couch_replicator.hrl").
 
+-define(USERNAME, "rep_test_user").
+-define(PASSWORD, "rep_test_pass").
+
 -export([
-    compare_dbs/2,
-    compare_dbs/3,
-    db_url/1,
+    cluster_compare_dbs/2,
+    cluster_compare_dbs/3,
+    cluster_doc_revs/1,
+    cluster_open_rev/3,
+    cluster_url/0,
+    cluster_db_url/1,
     replicate/1,
     get_pid/1,
-    replicate/2
+    replicate/2,
+    test_setup/0,
+    test_teardown/1,
+    setup_db/0,
+    teardown_db/1
 ]).
 
-compare_dbs(Source, Target) ->
-    compare_dbs(Source, Target, []).
-
-compare_dbs(Source, Target, ExceptIds) ->
-    {ok, SourceDb} = couch_db:open_int(Source, []),
-    {ok, TargetDb} = couch_db:open_int(Target, []),
-
-    Fun = fun(FullDocInfo, Acc) ->
-        {ok, DocSource} = couch_db:open_doc(SourceDb, FullDocInfo),
-        Id = DocSource#doc.id,
-        case lists:member(Id, ExceptIds) of
-            true ->
-                ?assertEqual(not_found, couch_db:get_doc_info(TargetDb, Id));
-            false ->
-                {ok, TDoc} = couch_db:open_doc(TargetDb, Id),
-                compare_docs(DocSource, TDoc)
+cluster_compare_dbs(Source, Target) ->
+    cluster_compare_dbs(Source, Target, []).
+
+cluster_compare_dbs(Source, Target, ExceptIds) ->
+    ?assertMatch({ok, [_ | _]}, fabric:get_db_info(Source)),
+    ?assertMatch({ok, [_ | _]}, fabric:get_db_info(Target)),
+    lists:foreach(
+        fun({Id, Rev}) ->
+            SrcDoc = cluster_open_rev(Source, Id, Rev),
+            TgtDoc = cluster_open_rev(Target, Id, Rev),
+            case lists:member(Id, ExceptIds) of
+                true ->
+                    ?assertEqual(not_found, TgtDoc);
+                false ->
+                    compare_docs(SrcDoc, TgtDoc)
+            end
         end,
-        {ok, Acc}
-    end,
+        cluster_doc_revs(Source)
+    ).
+
+cluster_open_rev(DbName, Id, Rev) ->
+    {ok, [Result]} = fabric:open_revs(DbName, Id, [Rev], []),
+    case Result of
+        {ok, #doc{} = Doc} ->
+            Doc;
+        {{not_found, missing}, _} ->
+            not_found
+    end.
+
+cluster_doc_revs(DbName) ->
+    Opts = [{style, all_docs}],
+    {ok, Acc} = fabric_util:isolate(fun() ->
+        fabric:changes(DbName, fun changes_callback/2, [], Opts)
+    end),
+    Acc.
 
-    {ok, _} = couch_db:fold_docs(SourceDb, Fun, [], []),
-    ok = couch_db:close(SourceDb),
-    ok = couch_db:close(TargetDb).
+changes_callback(start, Acc) ->
+    {ok, Acc};
+changes_callback({change, {Change}}, Acc) ->
+    Id = proplists:get_value(id, Change),
+    Revs = proplists:get_value(changes, Change),
+    IdRevs = [{Id, couch_doc:parse_rev(R)} || {[{<<"rev">>, R}]} <- Revs],
+    {ok, IdRevs ++ Acc};
+changes_callback(timeout, Acc) ->
+    {ok, Acc};
+changes_callback({stop, _EndSeq, _Pending}, Acc) ->
+    {ok, Acc}.
 
+compare_docs(#doc{} = Doc1, not_found) ->
+    error({not_found, Doc1#doc.id});
 compare_docs(Doc1, Doc2) ->
     ?assertEqual(Doc1#doc.body, Doc2#doc.body),
     #doc{atts = Atts1} = Doc1,
@@ -111,15 +147,17 @@ att_decoded_md5(Att) ->
     ),
     couch_hash:md5_hash_final(Md50).
 
-db_url(DbName) ->
-    iolist_to_binary([
-        "http://";,
-        config:get("httpd", "bind_address", "127.0.0.1"),
-        ":",
-        integer_to_list(mochiweb_socket_server:get(couch_httpd, port)),
-        "/",
-        DbName
-    ]).
+cluster_url() ->
+    Fmt = "http://~s:~s@~s:~b";,
+    Addr = config:get("chttpd", "bind_address", "127.0.0.1"),
+    Port = mochiweb_socket_server:get(chttpd, port),
+    Args = [?USERNAME, ?PASSWORD, Addr, Port],
+    ?l2b(io_lib:format(Fmt, Args)).
+
+cluster_db_url(<<"/", _/binary>> = Path) ->
+    <<(cluster_url())/binary, Path/binary>>;
+cluster_db_url(Path) ->
+    <<(cluster_url())/binary, "/", Path/binary>>.
 
 get_pid(RepId) ->
     Pid = global:whereis_name({couch_replicator_scheduler_job, RepId}),
@@ -145,3 +183,31 @@ replicate({[_ | _]} = RepObject) ->
             ok
     end,
     ok = couch_replicator_scheduler:remove_job(Rep#rep.id).
+
+setup_db() ->
+    DbName = ?tempdb(),
+    ok = fabric:create_db(DbName, [{q, 1}, {n, 1}, ?ADMIN_CTX]),
+    DbName.
+
+teardown_db(DbName) ->
+    try
+        ok = fabric:delete_db(DbName, [?ADMIN_CTX])
+    catch
+        error:database_does_not_exist ->
+            ok
+    end.
+
+test_setup() ->
+    Ctx = test_util:start_couch([fabric, mem3, chttpd, couch_replicator]),
+    Hashed = couch_passwords:hash_admin_password(?PASSWORD),
+    ok = config:set("admins", ?USERNAME, ?b2l(Hashed), _Persist = false),
+    Source = setup_db(),
+    Target = setup_db(),
+    {Ctx, {Source, Target}}.
+
+test_teardown({Ctx, {Source, Target}}) ->
+    meck:unload(),
+    teardown_db(Source),
+    teardown_db(Target),
+    config:delete("admins", ?USERNAME, _Persist = false),
+    ok = test_util:stop_couch(Ctx).

Reply via email to