| % 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_tx_options_tests). |
| |
| -include_lib("couch/include/couch_eunit.hrl"). |
| -include_lib("eunit/include/eunit.hrl"). |
| -include_lib("couch/include/couch_db.hrl"). |
| -include("fabric2_test.hrl"). |
| -include("fabric2.hrl"). |
| |
| fdb_tx_options_test_() -> |
| { |
| "Test setting default transaction options", |
| setup, |
| fun() -> |
| meck:new(erlfdb, [passthrough]), |
| % erlfdb, ctrace are all dependent apps for fabric. We make |
| % sure to start them so when fabric is started during the test it |
| % already has its dependencies |
| test_util:start_couch([erlfdb, ctrace, fabric]) |
| end, |
| fun(Ctx) -> |
| meck:unload(), |
| |
| config:delete("fdb_tx_options", "size_limit", false), |
| config:delete("fdb_tx_options", "max_retry_delay", false), |
| config:delete("fdb_tx_options", "machine_id", false), |
| config:delete("fdb_tx_options", "datacenter_id", false), |
| |
| test_util:stop_couch(Ctx) |
| end, |
| with([ |
| ?TDEF(options_take_effect, 15), |
| ?TDEF(can_configure_options_at_runtime, 15), |
| ?TDEF(can_apply_options_to_db_name_transactions), |
| ?TDEF(can_apply_options_to_db_handle_transactions) |
| ]) |
| }. |
| |
| options_take_effect(_) -> |
| ok = application:stop(fabric), |
| |
| % Try one of each type including some invalid values |
| config:set("fdb_tx_options", "size_limit", "150000", false), |
| config:set("fdb_tx_options", "max_retry_delay", "badness", false), |
| config:set("fdb_tx_options", "machine_id", "123abc", false), |
| TooLong = ["x" || _ <- lists:seq(1, 1000)], |
| config:set("fdb_tx_options", "datacenter_id", TooLong, false), |
| ok = application:start(fabric), |
| |
| DbName = ?tempdb(), |
| {ok, Db} = fabric2_db:create(DbName, [?ADMIN_CTX]), |
| ?assertError( |
| {erlfdb_error, ?ERLFDB_TRANSACTION_TOO_LARGE}, |
| add_large_doc(Db, 200000) |
| ), |
| ok = fabric2_db:delete(DbName, [?ADMIN_CTX]). |
| |
| can_configure_options_at_runtime(_) -> |
| meck:expect(erlfdb, set_option, fun(Fdb, Option, Val) -> |
| meck:passthrough([Fdb, Option, Val]) |
| end), |
| |
| meck:reset(erlfdb), |
| |
| config:set("fdb_tx_options", "size_limit", "150000", false), |
| meck:wait(erlfdb, set_option, ['_', size_limit, 150000], 4000), |
| |
| DbName = ?tempdb(), |
| |
| {ok, Db} = fabric2_db:create(DbName, [?ADMIN_CTX]), |
| ?assertError( |
| {erlfdb_error, ?ERLFDB_TRANSACTION_TOO_LARGE}, |
| add_large_doc(Db, 200000) |
| ), |
| |
| meck:reset(erlfdb), |
| |
| % Wait until after fabric2_server has updated the new fdb handle |
| OldDbHandle = get(?PDICT_DB_KEY), |
| config:delete("fdb_tx_options", "size_limit", false), |
| test_util:wait(fun() -> |
| case application:get_env(fabric, db) of |
| {ok, OldDbHandle} -> wait; |
| {ok, _} -> ok |
| end |
| end), |
| erase(?PDICT_DB_KEY), |
| |
| {ok, Db1} = fabric2_db:open(DbName, [?ADMIN_CTX]), |
| ?assertMatch({ok, _}, add_large_doc(Db1, 200000)), |
| |
| ok = fabric2_db:delete(DbName, [?ADMIN_CTX]). |
| |
| can_apply_options_to_db_name_transactions(_) -> |
| DbName = ?tempdb(), |
| |
| TxFun = fun(TxDb) -> |
| #{tx := Tx} = TxDb, |
| fabric2_fdb:create(TxDb, [?ADMIN_CTX]), |
| erlfdb:wait(erlfdb:get(Tx, <<16#FF, "/primaryDatacenter">>)) |
| end, |
| TxOpts = #{read_system_keys => <<>>}, |
| ?assertEqual(<<>>, fabric2_fdb:transactional(DbName, TxOpts, TxFun)), |
| |
| ok = fabric2_db:delete(DbName, [?ADMIN_CTX]). |
| |
| can_apply_options_to_db_handle_transactions(_) -> |
| DbName = ?tempdb(), |
| {ok, Db} = fabric2_db:create(DbName, [?ADMIN_CTX]), |
| |
| TxFun = fun(TxDb) -> |
| fabric2_db:update_doc(TxDb, large_doc(200000)) |
| end, |
| TxOpts = #{size_limit => 150000}, |
| ?assertError( |
| {erlfdb_error, ?ERLFDB_TRANSACTION_TOO_LARGE}, |
| fabric2_fdb:transactional(Db, TxOpts, TxFun) |
| ), |
| |
| ok = fabric2_db:delete(DbName, [?ADMIN_CTX]). |
| |
| add_large_doc(Db, Size) -> |
| fabric2_db:update_doc(Db, large_doc(Size)). |
| |
| large_doc(Size) -> |
| #doc{ |
| id = fabric2_util:uuid(), |
| body = {[{<<"x">>, crypto:strong_rand_bytes(Size)}]} |
| }. |