You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by da...@apache.org on 2019/04/28 20:42:50 UTC

[couchdb] branch prototype/rfc-001-revision-metadata-model updated: Filling out more eunit tests

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

davisp pushed a commit to branch prototype/rfc-001-revision-metadata-model
in repository https://gitbox.apache.org/repos/asf/couchdb.git


The following commit(s) were added to refs/heads/prototype/rfc-001-revision-metadata-model by this push:
     new 268aa44  Filling out more eunit tests
268aa44 is described below

commit 268aa44a10e9db39b18b61943a40927e6a551e47
Author: Paul J. Davis <pa...@gmail.com>
AuthorDate: Sun Apr 28 15:42:27 2019 -0500

    Filling out more eunit tests
---
 src/fabric/src/fabric2_db.erl                 |  16 ++-
 src/fabric/src/fabric2_fdb.erl                |   2 +-
 src/fabric/test/fabric2_db_crud_tests.erl     |  19 ++-
 src/fabric/test/fabric2_db_misc_tests.erl     |  61 ++++++++++
 src/fabric/test/fabric2_db_security_tests.erl | 162 ++++++++++++++++++++++++++
 5 files changed, 253 insertions(+), 7 deletions(-)

diff --git a/src/fabric/src/fabric2_db.erl b/src/fabric/src/fabric2_db.erl
index d6d4981..eaa2faf 100644
--- a/src/fabric/src/fabric2_db.erl
+++ b/src/fabric/src/fabric2_db.erl
@@ -355,20 +355,26 @@ is_system_db_name(DbName) when is_binary(DbName) ->
 
 set_revs_limit(#{} = Db, RevsLimit) ->
     RevsLimBin = ?uint2bin(RevsLimit),
-    fabric2_fdb:transactional(Db, fun(TxDb) ->
+    Resp = fabric2_fdb:transactional(Db, fun(TxDb) ->
         fabric2_fdb:set_config(TxDb, <<"revs_limit">>, RevsLimBin)
-    end).
+    end),
+    if Resp /= ok -> Resp; true ->
+        fabric2_server:store(Db#{revs_limit := RevsLimit})
+    end.
 
 
 set_security(#{} = Db, Security) ->
     SecBin = ?JSON_ENCODE(Security),
-    fabric2_fdb:transactional(Db, fun(TxDb) ->
+    Resp = fabric2_fdb:transactional(Db, fun(TxDb) ->
         fabric2_fdb:set_config(TxDb, <<"security_doc">>, SecBin)
-    end).
+    end),
+    if Resp /= ok -> Resp; true ->
+        fabric2_server:store(Db#{security_doc := Security})
+    end.
 
 
 set_user_ctx(#{} = Db, UserCtx) ->
-    Db#{user_ctx => UserCtx}.
+    Db#{user_ctx := UserCtx}.
 
 
 ensure_full_commit(#{}) ->
diff --git a/src/fabric/src/fabric2_fdb.erl b/src/fabric/src/fabric2_fdb.erl
index 096137a..13f9038 100644
--- a/src/fabric/src/fabric2_fdb.erl
+++ b/src/fabric/src/fabric2_fdb.erl
@@ -182,7 +182,7 @@ reopen(#{} = OldDb) ->
     require_transaction(OldDb),
     #{
         tx := Tx,
-        dbname := DbName,
+        name := DbName,
         db_options := Options
     } = OldDb,
     open(init_db(Tx, DbName, Options), Options).
diff --git a/src/fabric/test/fabric2_db_crud_tests.erl b/src/fabric/test/fabric2_db_crud_tests.erl
index 228ef0b..24deeb2 100644
--- a/src/fabric/test/fabric2_db_crud_tests.erl
+++ b/src/fabric/test/fabric2_db_crud_tests.erl
@@ -30,7 +30,8 @@ crud_test_() ->
             [
                 ?TDEF(create_db),
                 ?TDEF(open_db),
-                ?TDEF(delete_db)
+                ?TDEF(delete_db),
+                ?TDEF(list_dbs)
             ]
         }
     }.
@@ -69,3 +70,19 @@ delete_db() ->
     ?assertEqual(false, ets:member(fabric2_server, DbName)),
 
     ?assertError(database_does_not_exist, fabric2_db:open(DbName, [])).
+
+
+list_dbs() ->
+    DbName = ?tempdb(),
+    AllDbs1 = fabric2_db:list_dbs(),
+
+    ?assert(is_list(AllDbs1)),
+    ?assert(not lists:member(DbName, AllDbs1)),
+
+    ?assertMatch({ok, _}, fabric2_db:create(DbName, [])),
+    AllDbs2 = fabric2_db:list_dbs(),
+    ?assert(lists:member(DbName, AllDbs2)),
+
+    ?assertEqual(ok, fabric2_db:delete(DbName, [])),
+    AllDbs3 = fabric2_db:list_dbs(),
+    ?assert(not lists:member(DbName, AllDbs3)).
diff --git a/src/fabric/test/fabric2_db_misc_tests.erl b/src/fabric/test/fabric2_db_misc_tests.erl
new file mode 100644
index 0000000..21aafd1
--- /dev/null
+++ b/src/fabric/test/fabric2_db_misc_tests.erl
@@ -0,0 +1,61 @@
+% 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.
+
+-module(fabric2_db_misc_tests).
+
+
+-include_lib("couch/include/couch_eunit.hrl").
+-include_lib("eunit/include/eunit.hrl").
+
+
+-define(TDEF(A), {atom_to_list(A), fun A/1}).
+
+
+misc_test_() ->
+    {
+        "Test database miscellaney",
+        {
+            setup,
+            fun setup/0,
+            fun cleanup/1,
+            {with, [
+                fun empty_db_info/1,
+                fun accessors/1,
+            ]}
+        }
+    }.
+
+
+setup() ->
+    Ctx = test_util:start_couch([fabric]),
+    DbName = ?tempdb(),
+    {ok, Db} = fabric2_db:create(DbName, []),
+    {DbName, Db, Ctx}.
+
+
+cleanup({_DbName, Db, Ctx}) ->
+    ok = fabric2_db:delete(fabric2_db:name(Db), []),
+    test_util:stop_couch(Ctx).
+
+
+empty_db_info({DbName, Db, _}) ->
+    {ok, Info} = fabric2_db:get_db_info(Db),
+    ?assertEqual(DbName, fabric2_util:get_value(db_name, Info)),
+    ?assertEqual(0, fabric2_util:get_value(doc_count, Info)),
+    ?assertEqual(0, fabric2_util:get_value(doc_del_count, Info)),
+    ?assert(is_binary(fabric2_util:get_value(update_seq, Info))).
+
+
+dbname({DbName, Db, _}) ->
+    ?assertEqual(DbName, fabric2_db:name(Db)).
+    ?assertEqual(0, fabric2_db:get_instance_start_time(Db)).
+    ?assertEqual(nil, fabric2_db:get_pid(Db)).
diff --git a/src/fabric/test/fabric2_db_security_tests.erl b/src/fabric/test/fabric2_db_security_tests.erl
new file mode 100644
index 0000000..dba5ccb
--- /dev/null
+++ b/src/fabric/test/fabric2_db_security_tests.erl
@@ -0,0 +1,162 @@
+% 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.
+
+-module(fabric2_db_security_tests).
+
+
+-include_lib("couch/include/couch_db.hrl").
+-include_lib("couch/include/couch_eunit.hrl").
+-include_lib("eunit/include/eunit.hrl").
+
+
+security_test_() ->
+    {
+        "Test database security operations",
+        {
+            setup,
+            fun setup/0,
+            fun cleanup/1,
+            {with, [
+                fun is_admin_name/1,
+                fun is_not_admin_name/1,
+                fun is_admin_role/1,
+                fun is_not_admin_role/1,
+                fun check_is_admin/1,
+                fun check_is_not_admin/1,
+                fun check_is_member_name/1,
+                fun check_is_not_member_name/1,
+                fun check_is_member_role/1,
+                fun check_is_not_member_role/1,
+                fun check_admin_is_member/1,
+                fun check_is_member_of_public_db/1,
+                fun check_set_user_ctx/1
+            ]}
+        }
+    }.
+
+
+setup() ->
+    Ctx = test_util:start_couch([fabric]),
+    DbName = ?tempdb(),
+    {ok, Db1} = fabric2_db:create(DbName, []),
+    SecProps = {[
+        {<<"admins">>, {[
+            {<<"names">>, [<<"admin_name1">>, <<"admin_name2">>]},
+            {<<"roles">>, [<<"admin_role1">>, <<"admin_role2">>]}
+        ]}},
+        {<<"members">>, {[
+            {<<"names">>, [<<"member_name1">>, <<"member_name2">>]},
+            {<<"roles">>, [<<"member_role1">>, <<"member_role2">>]}
+        ]}}
+    ]},
+    ok = fabric2_db:set_security(Db1, SecProps),
+    {ok, Db2} = fabric2_db:open(DbName, []),
+    {Db2, Ctx}.
+
+
+cleanup({Db, Ctx}) ->
+    ok = fabric2_db:delete(fabric2_db:name(Db), []),
+    test_util:stop_couch(Ctx).
+
+
+is_admin_name({Db, _}) ->
+    UserCtx = #user_ctx{name = <<"admin_name1">>},
+    ?assertEqual(true, fabric2_db:is_admin(Db#{user_ctx := UserCtx})).
+
+
+is_not_admin_name({Db, _}) ->
+    UserCtx = #user_ctx{name = <<"member1">>},
+    ?assertEqual(false, fabric2_db:is_admin(Db#{user_ctx := UserCtx})).
+
+
+is_admin_role({Db, _}) ->
+    UserCtx = #user_ctx{roles = [<<"admin_role1">>]},
+    ?assertEqual(true, fabric2_db:is_admin(Db#{user_ctx := UserCtx})).
+
+
+is_not_admin_role({Db, _}) ->
+    UserCtx = #user_ctx{roles = [<<"member_role1">>]},
+    ?assertEqual(false, fabric2_db:is_admin(Db#{user_ctx := UserCtx})).
+
+
+check_is_admin({Db, _}) ->
+    UserCtx = #user_ctx{name = <<"admin_name1">>},
+    ?assertEqual(ok, fabric2_db:check_is_admin(Db#{user_ctx := UserCtx})).
+
+
+check_is_not_admin({Db, _}) ->
+    UserCtx = #user_ctx{name = <<"member_name1">>},
+    ?assertThrow(
+        {unauthorized, <<"You are not a db or server admin.">>},
+        fabric2_db:check_is_admin(Db#{user_ctx := #user_ctx{}})
+    ),
+    ?assertThrow(
+        {forbidden, <<"You are not a db or server admin.">>},
+        fabric2_db:check_is_admin(Db#{user_ctx := UserCtx})
+    ).
+
+
+check_is_member_name({Db, _}) ->
+    UserCtx = #user_ctx{name = <<"member_name1">>},
+    ?assertEqual(ok, fabric2_db:check_is_member(Db#{user_ctx := UserCtx})).
+
+
+check_is_not_member_name({Db, _}) ->
+    UserCtx = #user_ctx{name = <<"foo">>},
+    ?assertThrow(
+        {unauthorized, <<"You are not authorized", _/binary>>},
+        fabric2_db:check_is_member(Db#{user_ctx := #user_ctx{}})
+    ),
+    ?assertThrow(
+        {forbidden, <<"You are not allowed to access", _/binary>>},
+        fabric2_db:check_is_member(Db#{user_ctx := UserCtx})
+    ).
+
+
+check_is_member_role({Db, _}) ->
+    UserCtx = #user_ctx{name = <<"foo">>, roles = [<<"member_role1">>]},
+    ?assertEqual(ok, fabric2_db:check_is_member(Db#{user_ctx := UserCtx})).
+
+
+check_is_not_member_role({Db, _}) ->
+    UserCtx = #user_ctx{name = <<"foo">>, roles = [<<"bar">>]},
+    ?assertThrow(
+        {forbidden, <<"You are not allowed to access", _/binary>>},
+        fabric2_db:check_is_member(Db#{user_ctx := UserCtx})
+    ).
+
+
+check_admin_is_member({Db, _}) ->
+    UserCtx = #user_ctx{name = <<"admin_name1">>},
+    ?assertEqual(ok, fabric2_db:check_is_member(Db#{user_ctx := UserCtx})).
+
+
+check_is_member_of_public_db({Db, _}) ->
+    PublicDb = Db#{security_doc := {[]}},
+    UserCtx = #user_ctx{name = <<"foo">>, roles = [<<"bar">>]},
+    ?assertEqual(
+        ok,
+        fabric2_db:check_is_member(PublicDb#{user_ctx := #user_ctx{}})
+    ),
+    ?assertEqual(
+        ok,
+        fabric2_db:check_is_member(PublicDb#{user_ctx := UserCtx})
+    ).
+
+
+check_set_user_ctx({Db0, _}) ->
+    DbName = fabric2_db:name(Db0),
+    UserCtx = #user_ctx{name = <<"foo">>, roles = [<<"bar">>]},
+    {ok, Db1} = fabric2_db:open(DbName, [{user_ctx, UserCtx}]),
+    ?assertEqual(UserCtx, fabric2_db:get_user_ctx(Db1)).
+
+