You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by va...@apache.org on 2020/02/15 20:09:13 UTC

[couchdb] branch prototype/fdb-layer updated (c4bbae4 -> 1fd40ce)

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

vatamane pushed a change to branch prototype/fdb-layer
in repository https://gitbox.apache.org/repos/asf/couchdb.git.


    from c4bbae4  Add tests for database size tracking
     new 0292f0e  Convert versionstamps to binaries
     new e60ff85  Test coverage: list_dbs and list_dbs_info
     new dae118b  Test coverage: get_full_doc_info
     new 2b1a5d7  Test coverage: validate_dbname, validate_docid
     new 1fd40ce  Test coverage: apply_open_doc_opts

The 5 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 src/couch/src/couch_doc.erl                |   2 +-
 src/fabric/test/fabric2_db_crud_tests.erl  |  31 +++++-
 src/fabric/test/fabric2_db_misc_tests.erl  | 162 +++++++++++++++++++++++++++++
 src/fabric/test/fabric2_doc_crud_tests.erl |  99 +++++++++++++++++-
 4 files changed, 291 insertions(+), 3 deletions(-)


[couchdb] 05/05: Test coverage: apply_open_doc_opts

Posted by va...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

vatamane pushed a commit to branch prototype/fdb-layer
in repository https://gitbox.apache.org/repos/asf/couchdb.git

commit 1fd40cef8eb1d646ed38e240ccb3bde99b71bd8b
Author: Paul J. Davis <pa...@gmail.com>
AuthorDate: Fri Feb 14 14:48:48 2020 -0600

    Test coverage: apply_open_doc_opts
---
 src/fabric/test/fabric2_doc_crud_tests.erl | 99 +++++++++++++++++++++++++++++-
 1 file changed, 98 insertions(+), 1 deletion(-)

diff --git a/src/fabric/test/fabric2_doc_crud_tests.erl b/src/fabric/test/fabric2_doc_crud_tests.erl
index 46cd4fc..ce3757d 100644
--- a/src/fabric/test/fabric2_doc_crud_tests.erl
+++ b/src/fabric/test/fabric2_doc_crud_tests.erl
@@ -67,7 +67,8 @@ doc_crud_test_() ->
                 ?TDEF(create_a_large_local_doc),
                 ?TDEF(create_2_large_local_docs),
                 ?TDEF(local_doc_with_previous_encoding),
-                ?TDEF(before_doc_update_skips_local_docs)
+                ?TDEF(before_doc_update_skips_local_docs),
+                ?TDEF(open_doc_opts)
             ])
         }
     }.
@@ -911,3 +912,99 @@ before_doc_update_skips_local_docs({Db0, _}) ->
 
     ?assertEqual({[]}, LDoc2#doc.body),
     ?assertEqual({[<<"bdu_was_here">>, true]}, Doc2#doc.body).
+
+
+open_doc_opts({Db, _}) ->
+    % Build out state so that we can exercise each doc
+    % open option. This requires a live revision with
+    % an attachment, a conflict, and a deleted conflict.
+    DocId = couch_uuids:random(),
+    Att1 = couch_att:new([
+        {name, <<"foo.txt">>},
+        {type, <<"application/octet-stream">>},
+        {att_len, 6},
+        {data, <<"foobar">>},
+        {encoding, identity},
+        {md5, <<>>}
+    ]),
+    Doc1A = #doc{
+        id = DocId,
+        atts = [Att1]
+    },
+    {ok, {Pos1, Rev1A}} = fabric2_db:update_doc(Db, Doc1A),
+    Att2 = couch_att:store([
+            {data, stub},
+            {revpos, 1}
+        ], Att1),
+    Doc1B = Doc1A#doc{
+        revs = {Pos1, [Rev1A]},
+        atts = [Att2]
+    },
+    {ok, {Pos2, Rev1B}} = fabric2_db:update_doc(Db, Doc1B),
+
+    Rev2 = crypto:strong_rand_bytes(16),
+    Rev3 = crypto:strong_rand_bytes(16),
+    Rev4 = crypto:strong_rand_bytes(16),
+
+    % Create a live conflict
+    Doc2 = #doc{
+        id = DocId,
+        revs = {1, [Rev2]}
+    },
+    {ok, _} = fabric2_db:update_doc(Db, Doc2, [replicated_changes]),
+
+    % Create a deleted conflict
+    Doc3 = #doc{
+        id = DocId,
+        revs = {1, [Rev3]}
+    },
+    {ok, _} = fabric2_db:update_doc(Db, Doc3, [replicated_changes]),
+    Doc4 = #doc{
+        id = DocId,
+        revs = {2, [Rev4, Rev3]},
+        deleted = true
+    },
+    {ok, _} = fabric2_db:update_doc(Db, Doc4, [replicated_changes]),
+
+    OpenOpts1 = [
+        revs_info,
+        conflicts,
+        deleted_conflicts,
+        local_seq,
+        {atts_since, [{Pos1, Rev1A}]}
+    ],
+    {ok, OpenedDoc1} = fabric2_db:open_doc(Db, DocId, OpenOpts1),
+
+    #doc{
+        id = DocId,
+        revs = {2, [Rev1B, Rev1A]},
+        atts = [Att3],
+        meta = Meta
+    } = OpenedDoc1,
+    ?assertEqual(stub, couch_att:fetch(data, Att3)),
+    ?assertEqual(
+            {revs_info, Pos2, [{Rev1B, available}, {Rev1A, missing}]},
+            lists:keyfind(revs_info, 1, Meta)
+        ),
+    ?assertEqual(
+            {conflicts, [{1, Rev2}]},
+            lists:keyfind(conflicts, 1, Meta)
+        ),
+    ?assertEqual(
+            {deleted_conflicts, [{2, Rev4}]},
+            lists:keyfind(deleted_conflicts, 1, Meta)
+        ),
+    ?assertMatch({_, <<_/binary>>}, lists:keyfind(local_seq, 1, Meta)),
+
+    % Empty atts_since list
+    {ok, OpenedDoc2} = fabric2_db:open_doc(Db, DocId, [{atts_since, []}]),
+    #doc{atts = [Att4]} = OpenedDoc2,
+    ?assertNotEqual(stub, couch_att:fetch(data, Att4)),
+
+    % Missing ancestor
+    Rev5 = crypto:strong_rand_bytes(16),
+    OpenOpts2 = [{atts_since, [{5, Rev5}]}],
+    {ok, OpenedDoc3} = fabric2_db:open_doc(Db, DocId, OpenOpts2),
+    #doc{atts = [Att5]} = OpenedDoc3,
+    ?assertNotEqual(stub, couch_att:fetch(data, Att5)).
+


[couchdb] 01/05: Convert versionstamps to binaries

Posted by va...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

vatamane pushed a commit to branch prototype/fdb-layer
in repository https://gitbox.apache.org/repos/asf/couchdb.git

commit 0292f0e0b5ee4e3e898f45a85cca45559bba9ea1
Author: Paul J. Davis <pa...@gmail.com>
AuthorDate: Fri Feb 14 11:16:19 2020 -0600

    Convert versionstamps to binaries
    
    Versionstamp sequences should always be binaries when retrieved from a
    rev info map.
---
 src/couch/src/couch_doc.erl | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/couch/src/couch_doc.erl b/src/couch/src/couch_doc.erl
index d33325e..e19d664 100644
--- a/src/couch/src/couch_doc.erl
+++ b/src/couch/src/couch_doc.erl
@@ -383,7 +383,7 @@ rev_info({#{} = RevInfo, {Pos, [RevId | _]}}) ->
     #rev_info{
         deleted = Deleted,
         body_sp = undefined,
-        seq = Sequence,
+        seq = fabric2_fdb:vs_to_seq(Sequence),
         rev = {Pos, RevId}
     }.
 


[couchdb] 02/05: Test coverage: list_dbs and list_dbs_info

Posted by va...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

vatamane pushed a commit to branch prototype/fdb-layer
in repository https://gitbox.apache.org/repos/asf/couchdb.git

commit e60ff8562b6cc7ff7eab15494e94c42265d876cf
Author: Paul J. Davis <pa...@gmail.com>
AuthorDate: Fri Feb 14 11:17:15 2020 -0600

    Test coverage: list_dbs and list_dbs_info
---
 src/fabric/test/fabric2_db_crud_tests.erl | 31 ++++++++++++++++++++++++++++++-
 1 file changed, 30 insertions(+), 1 deletion(-)

diff --git a/src/fabric/test/fabric2_db_crud_tests.erl b/src/fabric/test/fabric2_db_crud_tests.erl
index 8052551..943b55f 100644
--- a/src/fabric/test/fabric2_db_crud_tests.erl
+++ b/src/fabric/test/fabric2_db_crud_tests.erl
@@ -30,7 +30,10 @@ crud_test_() ->
                 ?TDEF(open_db),
                 ?TDEF(delete_db),
                 ?TDEF(list_dbs),
-                ?TDEF(list_dbs_info)
+                ?TDEF(list_dbs_user_fun),
+                ?TDEF(list_dbs_user_fun_partial),
+                ?TDEF(list_dbs_info),
+                ?TDEF(list_dbs_info_partial)
             ])
         }
     }.
@@ -87,6 +90,26 @@ list_dbs(_) ->
     ?assert(not lists:member(DbName, AllDbs3)).
 
 
+list_dbs_user_fun(_) ->
+    ?assertMatch({ok, _}, fabric2_db:create(?tempdb(), [])),
+
+    UserFun = fun(Row, Acc) -> {ok, [Row | Acc]} end,
+    {ok, UserAcc} = fabric2_db:list_dbs(UserFun, [], []),
+
+    Base = lists:foldl(fun(DbName, Acc) ->
+        [{row, [{id, DbName}]} | Acc]
+    end, [{meta, []}], fabric2_db:list_dbs()),
+    Expect = lists:reverse(Base, [complete]),
+
+    ?assertEqual(Expect, lists:reverse(UserAcc)).
+
+
+list_dbs_user_fun_partial(_) ->
+    UserFun = fun(Row, Acc) -> {stop, [Row | Acc]} end,
+    {ok, UserAcc} = fabric2_db:list_dbs(UserFun, [], []),
+    ?assertEqual([{meta, []}], UserAcc).
+
+
 list_dbs_info(_) ->
     DbName = ?tempdb(),
     {ok, AllDbInfos1} = fabric2_db:list_dbs_info(),
@@ -103,6 +126,12 @@ list_dbs_info(_) ->
     ?assert(not is_db_info_member(DbName, AllDbInfos3)).
 
 
+list_dbs_info_partial(_) ->
+    UserFun = fun(Row, Acc) -> {stop, [Row | Acc]} end,
+    {ok, UserAcc} = fabric2_db:list_dbs_info(UserFun, [], []),
+    ?assertEqual([{meta, []}], UserAcc).
+
+
 is_db_info_member(_, []) ->
     false;
 


[couchdb] 04/05: Test coverage: validate_dbname, validate_docid

Posted by va...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

vatamane pushed a commit to branch prototype/fdb-layer
in repository https://gitbox.apache.org/repos/asf/couchdb.git

commit 2b1a5d76541df7d493ed00387409a6552bd21b8e
Author: Paul J. Davis <pa...@gmail.com>
AuthorDate: Fri Feb 14 12:42:28 2020 -0600

    Test coverage: validate_dbname, validate_docid
---
 src/fabric/test/fabric2_db_misc_tests.erl | 75 +++++++++++++++++++++++++++++++
 1 file changed, 75 insertions(+)

diff --git a/src/fabric/test/fabric2_db_misc_tests.erl b/src/fabric/test/fabric2_db_misc_tests.erl
index f1ee8a8..c48ee2c 100644
--- a/src/fabric/test/fabric2_db_misc_tests.erl
+++ b/src/fabric/test/fabric2_db_misc_tests.erl
@@ -33,6 +33,8 @@ misc_test_() ->
                 ?TDEF(set_revs_limit),
                 ?TDEF(set_security),
                 ?TDEF(is_system_db),
+                ?TDEF(validate_dbname),
+                ?TDEF(validate_doc_ids),
                 ?TDEF(get_doc_info),
                 ?TDEF(get_doc_info_not_found),
                 ?TDEF(get_full_doc_info),
@@ -54,6 +56,7 @@ setup() ->
 
 
 cleanup({_DbName, Db, Ctx}) ->
+    meck:unload(),
     ok = fabric2_db:delete(fabric2_db:name(Db), []),
     test_util:stop_couch(Ctx).
 
@@ -114,6 +117,78 @@ is_system_db({DbName, Db, _}) ->
     ?assertEqual(false, fabric2_db:is_system_db_name(<<"foo/bar">>)).
 
 
+validate_dbname(_) ->
+    Tests = [
+        {ok, <<"foo">>},
+        {ok, "foo"},
+        {ok, <<"_replicator">>},
+        {error, illegal_database_name, <<"Foo">>},
+        {error, illegal_database_name, <<"foo|bar">>},
+        {error, illegal_database_name, <<"Foo">>},
+        {error, database_name_too_long, <<
+                "0123456789012345678901234567890123456789"
+                "0123456789012345678901234567890123456789"
+                "0123456789012345678901234567890123456789"
+                "0123456789012345678901234567890123456789"
+                "0123456789012345678901234567890123456789"
+                "0123456789012345678901234567890123456789"
+            >>}
+    ],
+    CheckFun = fun
+        ({ok, DbName}) ->
+            ?assertEqual(ok, fabric2_db:validate_dbname(DbName));
+        ({error, Reason, DbName}) ->
+            Expect = {error, {Reason, DbName}},
+            ?assertEqual(Expect, fabric2_db:validate_dbname(DbName))
+    end,
+    lists:foreach(CheckFun, Tests).
+
+
+validate_doc_ids(_) ->
+    % Basic test with default max infinity length
+    ?assertEqual(ok, fabric2_db:validate_docid(<<"foo">>)),
+
+    Tests = [
+        {ok, <<"_local/foo">>},
+        {ok, <<"_design/foo">>},
+        {ok, <<"0123456789012345">>},
+        {illegal_docid, <<"">>},
+        {illegal_docid, <<"_design/">>},
+        {illegal_docid, <<"_local/">>},
+        {illegal_docid, <<"01234567890123456">>},
+        {illegal_docid, <<16#FF>>},
+        {illegal_docid, <<"_bad">>},
+        {illegal_docid, null}
+    ],
+    CheckFun = fun
+        ({ok, DocId}) ->
+            ?assertEqual(ok, fabric2_db:validate_docid(DocId));
+        ({illegal_docid, DocId}) ->
+            ?assertThrow({illegal_docid, _}, fabric2_db:validate_docid(DocId))
+    end,
+
+    try
+        meck:new(config, [passthrough]),
+        meck:expect(
+                config,
+                get,
+                ["couchdb", "max_document_id_length", "infinity"],
+                "16"
+            ),
+        lists:foreach(CheckFun, Tests),
+
+        % Check that fabric2_db_plugin can't allow for
+        % underscore prefixed dbs
+        meck:new(fabric2_db_plugin, [passthrough]),
+        meck:expect(fabric2_db_plugin, validate_docid, ['_'], true),
+        ?assertEqual(ok, fabric2_db:validate_docid(<<"_wheee">>))
+    after
+        % Unloading within the test as the config mock
+        % interferes with the db version bump test.
+        meck:unload()
+    end.
+
+
 get_doc_info({_, Db, _}) ->
     DocId = couch_uuids:random(),
     InsertDoc = #doc{


[couchdb] 03/05: Test coverage: get_full_doc_info

Posted by va...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

vatamane pushed a commit to branch prototype/fdb-layer
in repository https://gitbox.apache.org/repos/asf/couchdb.git

commit dae118bd2585fbe0d080df88fe3c958f7b58b773
Author: Paul J. Davis <pa...@gmail.com>
AuthorDate: Fri Feb 14 11:17:52 2020 -0600

    Test coverage: get_full_doc_info
---
 src/fabric/test/fabric2_db_misc_tests.erl | 87 +++++++++++++++++++++++++++++++
 1 file changed, 87 insertions(+)

diff --git a/src/fabric/test/fabric2_db_misc_tests.erl b/src/fabric/test/fabric2_db_misc_tests.erl
index 12fc3e5..f1ee8a8 100644
--- a/src/fabric/test/fabric2_db_misc_tests.erl
+++ b/src/fabric/test/fabric2_db_misc_tests.erl
@@ -33,6 +33,11 @@ misc_test_() ->
                 ?TDEF(set_revs_limit),
                 ?TDEF(set_security),
                 ?TDEF(is_system_db),
+                ?TDEF(get_doc_info),
+                ?TDEF(get_doc_info_not_found),
+                ?TDEF(get_full_doc_info),
+                ?TDEF(get_full_doc_info_not_found),
+                ?TDEF(get_full_doc_infos),
                 ?TDEF(ensure_full_commit),
                 ?TDEF(metadata_bump),
                 ?TDEF(db_version_bump)
@@ -109,6 +114,88 @@ is_system_db({DbName, Db, _}) ->
     ?assertEqual(false, fabric2_db:is_system_db_name(<<"foo/bar">>)).
 
 
+get_doc_info({_, Db, _}) ->
+    DocId = couch_uuids:random(),
+    InsertDoc = #doc{
+        id = DocId,
+        body = {[{<<"foo">>, true}]}
+    },
+    {ok, {Pos, Rev}} = fabric2_db:update_doc(Db, InsertDoc, []),
+
+    DI = fabric2_db:get_doc_info(Db, DocId),
+    ?assert(is_record(DI, doc_info)),
+    #doc_info{
+        id = DIDocId,
+        high_seq = HighSeq,
+        revs = Revs
+    } = DI,
+
+    ?assertEqual(DocId, DIDocId),
+    ?assert(is_binary(HighSeq)),
+    ?assertMatch([#rev_info{}], Revs),
+
+    [#rev_info{
+        rev = DIRev,
+        seq = Seq,
+        deleted = Deleted,
+        body_sp = BodySp
+    }] = Revs,
+
+    ?assertEqual({Pos, Rev}, DIRev),
+    ?assert(is_binary(Seq)),
+    ?assert(not Deleted),
+    ?assertMatch(undefined, BodySp).
+
+
+get_doc_info_not_found({_, Db, _}) ->
+    DocId = couch_uuids:random(),
+    ?assertEqual(not_found, fabric2_db:get_doc_info(Db, DocId)).
+
+
+get_full_doc_info({_, Db, _}) ->
+    DocId = couch_uuids:random(),
+    InsertDoc = #doc{
+        id = DocId,
+        body = {[{<<"foo">>, true}]}
+    },
+    {ok, {Pos, Rev}} = fabric2_db:update_doc(Db, InsertDoc, []),
+    FDI = fabric2_db:get_full_doc_info(Db, DocId),
+
+    ?assert(is_record(FDI, full_doc_info)),
+    #full_doc_info{
+        id = FDIDocId,
+        update_seq = UpdateSeq,
+        deleted = Deleted,
+        rev_tree = RevTree,
+        sizes = SizeInfo
+    } = FDI,
+
+    ?assertEqual(DocId, FDIDocId),
+    ?assert(is_binary(UpdateSeq)),
+    ?assert(not Deleted),
+    ?assertMatch([{Pos, {Rev, _, []}}], RevTree),
+    ?assertEqual(#size_info{}, SizeInfo).
+
+
+get_full_doc_info_not_found({_, Db, _}) ->
+    DocId = couch_uuids:random(),
+    ?assertEqual(not_found, fabric2_db:get_full_doc_info(Db, DocId)).
+
+
+get_full_doc_infos({_, Db, _}) ->
+    DocIds = lists:map(fun(_) ->
+        DocId = couch_uuids:random(),
+        Doc = #doc{id = DocId},
+        {ok, _} = fabric2_db:update_doc(Db, Doc, []),
+        DocId
+    end, lists:seq(1, 5)),
+
+    FDIs = fabric2_db:get_full_doc_infos(Db, DocIds),
+    lists:zipwith(fun(DocId, FDI) ->
+        ?assertEqual(DocId, FDI#full_doc_info.id)
+    end, DocIds, FDIs).
+
+
 ensure_full_commit({_, Db, _}) ->
     ?assertEqual({ok, 0}, fabric2_db:ensure_full_commit(Db)),
     ?assertEqual({ok, 0}, fabric2_db:ensure_full_commit(Db, 5)).