| % 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(cpse_test_read_write_docs). |
| -compile(export_all). |
| -compile(nowarn_export_all). |
| |
| -include_lib("eunit/include/eunit.hrl"). |
| -include_lib("couch/include/couch_db.hrl"). |
| |
| setup_each() -> |
| {ok, Db} = cpse_util:create_db(), |
| Db. |
| |
| teardown_each(Db) -> |
| ok = couch_server:delete(couch_db:name(Db), []). |
| |
| cpse_read_docs_from_empty_db(Db) -> |
| ?assertEqual([not_found], couch_db_engine:open_docs(Db, [<<"foo">>])), |
| ?assertEqual( |
| [not_found, not_found], |
| couch_db_engine:open_docs(Db, [<<"a">>, <<"b">>]) |
| ). |
| |
| cpse_read_empty_local_docs(Db) -> |
| {LocalA, LocalB} = {<<"_local/a">>, <<"_local/b">>}, |
| ?assertEqual([not_found], couch_db_engine:open_local_docs(Db, [LocalA])), |
| ?assertEqual( |
| [not_found, not_found], |
| couch_db_engine:open_local_docs(Db, [LocalA, LocalB]) |
| ). |
| |
| cpse_write_one_doc(Db1) -> |
| ?assertEqual(0, couch_db_engine:get_doc_count(Db1)), |
| ?assertEqual(0, couch_db_engine:get_del_doc_count(Db1)), |
| ?assertEqual(0, couch_db_engine:get_update_seq(Db1)), |
| Commits = couch_stats:sample([couchdb, commits]), |
| |
| Actions = [ |
| {create, {<<"foo">>, {[{<<"vsn">>, 1}]}}} |
| ], |
| {ok, Db2} = cpse_util:apply_actions(Db1, Actions), |
| ?assertEqual(1, couch_db_engine:get_doc_count(Db2)), |
| |
| cpse_util:shutdown_db(Db2), |
| |
| {ok, Db3} = couch_db:reopen(Db2), |
| |
| ?assertEqual(1, couch_db_engine:get_doc_count(Db3)), |
| ?assertEqual(0, couch_db_engine:get_del_doc_count(Db3)), |
| ?assertEqual(1, couch_db_engine:get_update_seq(Db3)), |
| ?assert(couch_stats:sample([couchdb, commits]) > Commits), |
| ?assert(couch_stats:sample([couchdb, coalesced_updates, interactive]) >= 0), |
| ?assert(couch_stats:sample([couchdb, coalesced_updates, replicated]) >= 0), |
| [FDI] = couch_db_engine:open_docs(Db3, [<<"foo">>]), |
| #rev_info{ |
| rev = {RevPos, PrevRevId}, |
| deleted = Deleted, |
| body_sp = DocPtr |
| } = cpse_util:prev_rev(FDI), |
| |
| Doc0 = #doc{ |
| id = <<"foo">>, |
| revs = {RevPos, [PrevRevId]}, |
| deleted = Deleted, |
| body = DocPtr |
| }, |
| |
| Doc1 = couch_db_engine:read_doc_body(Db3, Doc0), |
| Body1 = |
| if |
| not is_binary(Doc1#doc.body) -> Doc1#doc.body; |
| true -> couch_compress:decompress(Doc1#doc.body) |
| end, |
| ?assertEqual({[{<<"vsn">>, 1}]}, Body1). |
| |
| cpse_write_two_docs(Db1) -> |
| ?assertEqual(0, couch_db_engine:get_doc_count(Db1)), |
| ?assertEqual(0, couch_db_engine:get_del_doc_count(Db1)), |
| ?assertEqual(0, couch_db_engine:get_update_seq(Db1)), |
| |
| Actions = [ |
| {create, {<<"foo">>, {[{<<"vsn">>, 1}]}}}, |
| {create, {<<"bar">>, {[{<<"stuff">>, true}]}}} |
| ], |
| {ok, Db2} = cpse_util:apply_actions(Db1, Actions), |
| cpse_util:shutdown_db(Db2), |
| |
| {ok, Db3} = couch_db:reopen(Db2), |
| |
| ?assertEqual(2, couch_db_engine:get_doc_count(Db3)), |
| ?assertEqual(0, couch_db_engine:get_del_doc_count(Db3)), |
| ?assertEqual(2, couch_db_engine:get_update_seq(Db3)), |
| |
| Resps = couch_db_engine:open_docs(Db3, [<<"foo">>, <<"bar">>]), |
| ?assertEqual(false, lists:member(not_found, Resps)). |
| |
| cpse_write_three_doc_batch(Db1) -> |
| ?assertEqual(0, couch_db_engine:get_doc_count(Db1)), |
| ?assertEqual(0, couch_db_engine:get_del_doc_count(Db1)), |
| ?assertEqual(0, couch_db_engine:get_update_seq(Db1)), |
| |
| Actions = [ |
| {batch, [ |
| {create, {<<"foo">>, {[{<<"vsn">>, 1}]}}}, |
| {create, {<<"bar">>, {[{<<"stuff">>, true}]}}}, |
| {create, {<<"baz">>, {[]}}} |
| ]} |
| ], |
| {ok, Db2} = cpse_util:apply_actions(Db1, Actions), |
| cpse_util:shutdown_db(Db2), |
| |
| {ok, Db3} = couch_db:reopen(Db2), |
| |
| ?assertEqual(3, couch_db_engine:get_doc_count(Db3)), |
| ?assertEqual(0, couch_db_engine:get_del_doc_count(Db3)), |
| ?assertEqual(3, couch_db_engine:get_update_seq(Db3)), |
| |
| Resps = couch_db_engine:open_docs(Db3, [<<"foo">>, <<"bar">>, <<"baz">>]), |
| ?assertEqual(false, lists:member(not_found, Resps)). |
| |
| cpse_update_doc(Db1) -> |
| ?assertEqual(0, couch_db_engine:get_doc_count(Db1)), |
| ?assertEqual(0, couch_db_engine:get_del_doc_count(Db1)), |
| ?assertEqual(0, couch_db_engine:get_update_seq(Db1)), |
| |
| Actions = [ |
| {create, {<<"foo">>, {[{<<"vsn">>, 1}]}}}, |
| {update, {<<"foo">>, {[{<<"vsn">>, 2}]}}} |
| ], |
| {ok, Db2} = cpse_util:apply_actions(Db1, Actions), |
| |
| cpse_util:shutdown_db(Db2), |
| |
| {ok, Db3} = couch_db:reopen(Db2), |
| |
| ?assertEqual(1, couch_db_engine:get_doc_count(Db3)), |
| ?assertEqual(0, couch_db_engine:get_del_doc_count(Db3)), |
| ?assertEqual(2, couch_db_engine:get_update_seq(Db3)), |
| |
| [FDI] = couch_db_engine:open_docs(Db3, [<<"foo">>]), |
| |
| #rev_info{ |
| rev = {RevPos, PrevRevId}, |
| deleted = Deleted, |
| body_sp = DocPtr |
| } = cpse_util:prev_rev(FDI), |
| |
| Doc0 = #doc{ |
| id = <<"foo">>, |
| revs = {RevPos, [PrevRevId]}, |
| deleted = Deleted, |
| body = DocPtr |
| }, |
| |
| Doc1 = couch_db_engine:read_doc_body(Db3, Doc0), |
| Body1 = |
| if |
| not is_binary(Doc1#doc.body) -> Doc1#doc.body; |
| true -> couch_compress:decompress(Doc1#doc.body) |
| end, |
| |
| ?assertEqual({[{<<"vsn">>, 2}]}, Body1). |
| |
| cpse_delete_doc(Db1) -> |
| ?assertEqual(0, couch_db_engine:get_doc_count(Db1)), |
| ?assertEqual(0, couch_db_engine:get_del_doc_count(Db1)), |
| ?assertEqual(0, couch_db_engine:get_update_seq(Db1)), |
| |
| Actions = [ |
| {create, {<<"foo">>, {[{<<"vsn">>, 1}]}}}, |
| {delete, {<<"foo">>, {[]}}} |
| ], |
| {ok, Db2} = cpse_util:apply_actions(Db1, Actions), |
| cpse_util:shutdown_db(Db2), |
| |
| {ok, Db3} = couch_db:reopen(Db2), |
| ?assertEqual(0, couch_db_engine:get_doc_count(Db3)), |
| ?assertEqual(1, couch_db_engine:get_del_doc_count(Db3)), |
| ?assertEqual(2, couch_db_engine:get_update_seq(Db3)), |
| |
| [FDI] = couch_db_engine:open_docs(Db3, [<<"foo">>]), |
| |
| #rev_info{ |
| rev = {RevPos, PrevRevId}, |
| deleted = Deleted, |
| body_sp = DocPtr |
| } = cpse_util:prev_rev(FDI), |
| |
| Doc0 = #doc{ |
| id = <<"foo">>, |
| revs = {RevPos, [PrevRevId]}, |
| deleted = Deleted, |
| body = DocPtr |
| }, |
| |
| Doc1 = couch_db_engine:read_doc_body(Db3, Doc0), |
| Body1 = |
| if |
| not is_binary(Doc1#doc.body) -> Doc1#doc.body; |
| true -> couch_compress:decompress(Doc1#doc.body) |
| end, |
| |
| ?assertEqual({[]}, Body1). |
| |
| cpse_write_local_doc(Db1) -> |
| ?assertEqual(0, couch_db_engine:get_doc_count(Db1)), |
| ?assertEqual(0, couch_db_engine:get_del_doc_count(Db1)), |
| ?assertEqual(0, couch_db_engine:get_update_seq(Db1)), |
| |
| Actions = [ |
| {create, {<<"_local/foo">>, {[{<<"yay">>, false}]}}} |
| ], |
| {ok, Db2} = cpse_util:apply_actions(Db1, Actions), |
| cpse_util:shutdown_db(Db2), |
| |
| {ok, Db3} = couch_db:reopen(Db2), |
| |
| ?assertEqual(0, couch_db_engine:get_doc_count(Db3)), |
| ?assertEqual(0, couch_db_engine:get_del_doc_count(Db3)), |
| ?assertEqual(0, couch_db_engine:get_update_seq(Db3)), |
| |
| [not_found] = couch_db_engine:open_docs(Db3, [<<"_local/foo">>]), |
| [#doc{} = Doc] = couch_db_engine:open_local_docs(Db3, [<<"_local/foo">>]), |
| ?assertEqual({[{<<"yay">>, false}]}, Doc#doc.body). |
| |
| cpse_write_mixed_batch(Db1) -> |
| ?assertEqual(0, couch_db_engine:get_doc_count(Db1)), |
| ?assertEqual(0, couch_db_engine:get_del_doc_count(Db1)), |
| ?assertEqual(0, couch_db_engine:get_update_seq(Db1)), |
| |
| Actions = [ |
| {batch, [ |
| {create, {<<"bar">>, {[]}}}, |
| {create, {<<"_local/foo">>, {[{<<"yay">>, false}]}}} |
| ]} |
| ], |
| {ok, Db2} = cpse_util:apply_actions(Db1, Actions), |
| cpse_util:shutdown_db(Db2), |
| |
| {ok, Db3} = couch_db:reopen(Db2), |
| |
| ?assertEqual(1, couch_db_engine:get_doc_count(Db3)), |
| ?assertEqual(0, couch_db_engine:get_del_doc_count(Db3)), |
| ?assertEqual(1, couch_db_engine:get_update_seq(Db3)), |
| |
| [#full_doc_info{}] = couch_db_engine:open_docs(Db3, [<<"bar">>]), |
| [not_found] = couch_db_engine:open_docs(Db3, [<<"_local/foo">>]), |
| |
| [not_found] = couch_db_engine:open_local_docs(Db3, [<<"bar">>]), |
| [#doc{}] = couch_db_engine:open_local_docs(Db3, [<<"_local/foo">>]). |
| |
| cpse_update_local_doc(Db1) -> |
| ?assertEqual(0, couch_db_engine:get_doc_count(Db1)), |
| ?assertEqual(0, couch_db_engine:get_del_doc_count(Db1)), |
| ?assertEqual(0, couch_db_engine:get_update_seq(Db1)), |
| |
| Actions = [ |
| {create, {<<"_local/foo">>, {[]}}}, |
| {update, {<<"_local/foo">>, {[{<<"stuff">>, null}]}}} |
| ], |
| {ok, Db2} = cpse_util:apply_actions(Db1, Actions), |
| cpse_util:shutdown_db(Db2), |
| |
| {ok, Db3} = couch_db:reopen(Db2), |
| |
| ?assertEqual(0, couch_db_engine:get_doc_count(Db3)), |
| ?assertEqual(0, couch_db_engine:get_del_doc_count(Db3)), |
| ?assertEqual(0, couch_db_engine:get_update_seq(Db3)), |
| |
| [not_found] = couch_db_engine:open_docs(Db3, [<<"_local/foo">>]), |
| [#doc{} = Doc] = couch_db_engine:open_local_docs(Db3, [<<"_local/foo">>]), |
| ?assertEqual({[{<<"stuff">>, null}]}, Doc#doc.body). |
| |
| cpse_delete_local_doc(Db1) -> |
| ?assertEqual(0, couch_db_engine:get_doc_count(Db1)), |
| ?assertEqual(0, couch_db_engine:get_del_doc_count(Db1)), |
| ?assertEqual(0, couch_db_engine:get_update_seq(Db1)), |
| |
| Actions = [ |
| {create, {<<"_local/foo">>, []}}, |
| {delete, {<<"_local/foo">>, []}} |
| ], |
| {ok, Db2} = cpse_util:apply_actions(Db1, Actions), |
| cpse_util:shutdown_db(Db2), |
| |
| {ok, Db3} = couch_db:reopen(Db2), |
| |
| ?assertEqual(0, couch_db_engine:get_doc_count(Db3)), |
| ?assertEqual(0, couch_db_engine:get_del_doc_count(Db3)), |
| ?assertEqual(0, couch_db_engine:get_update_seq(Db3)), |
| |
| [not_found] = couch_db_engine:open_docs(Db3, [<<"_local/foo">>]), |
| ?assertEqual( |
| [not_found], |
| couch_db_engine:open_local_docs(Db3, [<<"_local/foo">>]) |
| ). |