diff options
Diffstat (limited to 'src/couch_views/test/couch_views_custom_red_test.erl')
-rw-r--r-- | src/couch_views/test/couch_views_custom_red_test.erl | 193 |
1 files changed, 193 insertions, 0 deletions
diff --git a/src/couch_views/test/couch_views_custom_red_test.erl b/src/couch_views/test/couch_views_custom_red_test.erl new file mode 100644 index 000000000..e8f8cbc2f --- /dev/null +++ b/src/couch_views/test/couch_views_custom_red_test.erl @@ -0,0 +1,193 @@ +% 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(couch_views_custom_red_test). + +-include_lib("couch/include/couch_eunit.hrl"). +-include_lib("couch/include/couch_db.hrl"). +-include_lib("fabric/test/fabric2_test.hrl"). +-include("couch_views.hrl"). + + +-define(NUM_DOCS, 100). + + +custom_reduce_disabled_test_() -> + { + "Custom Reduce Disabled", + { + setup, + fun setup_disabled/0, + fun teardown/1, + with([ + ?TDEF(builtin_reductions_work), + ?TDEF(custom_reduces_disabled) + ]) + } + }. + + +custom_reduce_enabled_test_() -> + { + "Custom Reduce Disabled", + { + setup, + fun setup_enabled/0, + fun teardown/1, + with([ + ?TDEF(builtin_reductions_work), + ?TDEF(custom_reduces_enabled) + ]) + } + }. + + +sigs_change_test_() -> + { + "Sigs Change Test", + { + setup, + fun setup_sigs_change/0, + fun teardown_sigs_change/1, + with([ + ?TDEF(sigs_change) + ]) + } + }. + +setup_disabled() -> + setup_common(false). + + +setup_enabled() -> + setup_common(true). + + +setup_common(Enabled) -> + Ctx = test_util:start_couch([ + fabric, + couch_jobs, + couch_js, + couch_views + ]), + config:set_boolean("couch_views", "custom_reduce_enabled", Enabled, false), + {ok, Db} = fabric2_db:create(?tempdb(), [{user_ctx, ?ADMIN_USER}]), + fabric2_db:update_docs(Db, [create_ddoc()]), + make_docs(Db, ?NUM_DOCS), + run_query(Db, <<"builtin">>, #{limit => 0}), + {Db, Ctx}. + + +teardown({Db, Ctx}) -> + fabric2_db:delete(fabric2_db:name(Db), [{user_ctx, ?ADMIN_USER}]), + test_util:stop_couch(Ctx). + + +setup_sigs_change() -> + meck:new(config, [passthrough]), + meck:expect(config, get, fun(_, _, Default) -> Default end). + + +teardown_sigs_change(_) -> + meck:unload(). + + +builtin_reductions_work({Db, _}) -> + Result = run_query(Db, <<"builtin">>, #{}), + Expect = {ok, [row(null, ?NUM_DOCS)]}, + ?assertEqual(Expect, Result). + + +custom_reduces_disabled({Db, _}) -> + ?assertThrow({disabled, _}, run_query(Db, <<"custom">>, #{})). + + +custom_reduces_enabled({Db, _}) -> + Result = run_query(Db, <<"custom">>, #{}), + Expect = {ok, [row(null, <<"silly_reduce">>)]}, + ?assertEqual(Expect, Result). + + +sigs_change(_) -> + meck:expect(config, get_boolean, fun("couch_views", _, _) -> false end), + {ok, Mrst1} = couch_views_util:ddoc_to_mrst(<<"foo">>, create_ddoc()), + meck:expect(config, get_boolean, fun("couch_views", _, _) -> true end), + {ok, Mrst2} = couch_views_util:ddoc_to_mrst(<<"foo">>, create_ddoc()), + ?assertNotEqual(Mrst1#mrst.sig, Mrst2#mrst.sig). + + +run_query(Db, Idx, Args) -> + DDoc = create_ddoc(), + run_query(Db, DDoc, Idx, Args). + + +run_query(Db, DDoc, Idx, Args) -> + couch_views:query(Db, DDoc, Idx, fun default_cb/2, [], Args). + + +default_cb(complete, Acc) -> + {ok, lists:reverse(Acc)}; +default_cb({final, Info}, []) -> + {ok, [Info]}; +default_cb({final, _}, Acc) -> + {ok, Acc}; +default_cb({meta, _}, Acc) -> + {ok, Acc}; +default_cb(ok, ddoc_updated) -> + {ok, ddoc_updated}; +default_cb(Row, Acc) -> + {ok, [Row | Acc]}. + + +row(Key, Value) -> + {row, [{key, Key}, {value, Value}]}. + + +create_ddoc() -> + couch_doc:from_json_obj({[ + {<<"_id">>, <<"_design/bar">>}, + {<<"views">>, {[ + {<<"custom">>, {[ + {<<"map">>, <<"function(doc) {emit(doc.val, doc.val);}">>}, + {<<"reduce">>, << + "function(keys, values, rereduce) {\n" + " return \"silly_reduce\";\n" + "}\n" + >>} + ]}}, + {<<"builtin">>, {[ + {<<"map">>, <<"function(doc) {emit(doc.val, doc.val);}">>}, + {<<"reduce">>, <<"_count">>} + ]}} + ]}} + ]}). + + +make_docs(Db, TotalDocs) when TotalDocs > 0 -> + make_docs(Db, TotalDocs, 0). + + +make_docs(Db, TotalDocs, DocsMade) when TotalDocs > DocsMade -> + DocCount = min(TotalDocs - DocsMade, 500), + Docs = [doc(I + DocsMade) || I <- lists:seq(1, DocCount)], + fabric2_db:update_docs(Db, Docs), + make_docs(Db, TotalDocs, DocsMade + DocCount); + +make_docs(_Db, TotalDocs, DocsMade) when TotalDocs =< DocsMade -> + ok. + + +doc(Id) -> + couch_doc:from_json_obj({[ + {<<"_id">>, list_to_binary(integer_to_list(Id))}, + {<<"val">>, Id} + ]}). |