diff options
author | Adam Kocoloski <adam@cloudant.com> | 2010-06-30 16:31:06 -0400 |
---|---|---|
committer | Adam Kocoloski <adam@cloudant.com> | 2010-08-12 01:22:54 -0400 |
commit | b3172298ca9445c83f045e2c9a9ae1335a2c0841 (patch) | |
tree | d3186e61c02a16c601ca2227ea7311d482613045 | |
parent | 301e2345a51355fedb60f1668996ce43964f0801 (diff) |
remove unused/obsolete test code
-rw-r--r-- | test/cluster_ops_test.erl | 83 | ||||
-rw-r--r-- | test/mem2_code_change.erl | 12 | ||||
-rw-r--r-- | test/mem3_cache_bench.erl | 29 | ||||
-rw-r--r-- | test/mem_utils_test.erl | 97 | ||||
-rw-r--r-- | test/membership2_test.erl | 126 | ||||
-rw-r--r-- | test/mock.erl | 322 | ||||
-rw-r--r-- | test/mock_genserver.erl | 209 | ||||
-rw-r--r-- | test/replication_test.erl | 89 | ||||
-rw-r--r-- | test/stub.erl | 168 |
9 files changed, 0 insertions, 1135 deletions
diff --git a/test/cluster_ops_test.erl b/test/cluster_ops_test.erl deleted file mode 100644 index 7bc8fdeb..00000000 --- a/test/cluster_ops_test.erl +++ /dev/null @@ -1,83 +0,0 @@ --module(cluster_ops_test). - --include("../../couch/src/couch_db.hrl"). --include_lib("eunit/include/eunit.hrl"). - - -% read_quorum_test() -> -% % we need to be running a cluster here... -% % not sure how to start things up for unit tests - -% % but we're testing reads when a node is missing a doc, so disable internal -% % replication - a bit harsh if anything else is here, but hey, it's a test -% rpc:multicall(showroom, stop, []), -% rpc:multicall(supervisor, terminate_child, -% [couch_primary_services, couch_replication_supervisor]), -% rpc:multicall(supervisor, delete_child, -% [couch_primary_services, couch_replication_supervisor]), - -% % create db -% DbName = <<"cluster_ops_test">>, -% showroom_db:delete_db(DbName, []), -% {Status, #db{name=DbName}} = showroom_db:create_db(DbName, []), -% ?assertEqual(ok, Status), - -% % open db -% {ok, Db} = showroom_db:open_db(DbName, []), - -% % make a test doc -% Key = <<"a">>, -% Json = {[{<<"_id">>,Key}]}, -% Doc = couch_doc:from_json_obj(Json), -% Clock = vector_clock:create(node()), -% NewDoc = Doc#doc{clock=Clock}, - -% % insert a doc in two shards out of three -% % TODO: we need N=3, need to fix that at db create time Options above -% % (fb 1001) -% {M,F,A} = {dynomite_couch_api, put,[Db, NewDoc, []]}, -% CorrectNodeParts = membership2:nodeparts_for_key(Key), -% [{MissingNode, MissingPart} | BadNodeParts] = CorrectNodeParts, -% MapFun = fun({Node,Part}) -> -% rpc:call(Node, M, F, [[Part | A]]) -% end, -% {Good, Bad} = pcall(MapFun, BadNodeParts, 2), -% ?assertEqual(2, length(Good)), -% ?assertEqual([], Bad), - -% % make sure it's notfound on the MissingNode -% MissingNodeGet = rpc:call(MissingNode, dynomite_couch_api, get, -% [[MissingPart, Db, Key, nil, []]]), -% ?assertEqual({not_found, {[], [missing]}}, MissingNodeGet), - -% JsonDoc = {[{<<"_id">>,<<"a">>}, -% {<<"_rev">>, -% <<"1-967a00dff5e02add41819138abb3284d">>}]}, - -% % r=3 should fail -% {r_quorum_not_met, {[{message, _M}, {good, G}, {bad, B}]}} = -% showroom_doc:open_doc(Db, Key, nil, [{r, "3"}]), -% ?assertEqual([JsonDoc,JsonDoc], G), -% ?assertEqual([{not_found, missing}], B), - -% % r=2 should never fail (run it many times to make sure) -% do_opens({Db, Key, nil, [{r, "2"}]}, 20), - -% ok. - - -% pcall(MapFun, Servers, Const) -> -% Replies = lib_misc:pmap(MapFun, Servers, Const), -% lists:partition(fun valid/1, Replies). - - -% valid({ok, _}) -> true; -% valid(ok) -> true; -% valid(_) -> false. - - -% do_opens(_,0) -> ok; -% do_opens({Db, DocId, Refs, Options} = Payload, Times) -> -% {Status, _Doc} = showroom_doc:open_doc(Db, DocId, Refs, Options), -% ?assertEqual(ok, Status), -% do_opens(Payload, Times-1). diff --git a/test/mem2_code_change.erl b/test/mem2_code_change.erl deleted file mode 100644 index 3b0c73fb..00000000 --- a/test/mem2_code_change.erl +++ /dev/null @@ -1,12 +0,0 @@ --module(mem2_code_change). - --export([run/0]). - -run() -> - Pid = whereis(membership), - OldVsn = "0.7.1-cloudant", - Extra = "", - - sys:suspend(Pid), - sys:change_code(Pid, membership2, OldVsn, Extra), - sys:resume(Pid). diff --git a/test/mem3_cache_bench.erl b/test/mem3_cache_bench.erl deleted file mode 100644 index a78f029d..00000000 --- a/test/mem3_cache_bench.erl +++ /dev/null @@ -1,29 +0,0 @@ --module (mem3_cache_bench). - --export ([doit/1]). - --include("../include/config.hrl"). - - -init() -> - Config = #config{n=3,r=2,w=2,q=3,directory="/srv/db", - storage_mod="dynomite_couch_storage"}, - {ok, _Pid} = mem3:start_link([{test,true}, {config, Config}]), - mem3:join(first, [{1, a, []}, {2, b, []}]). - - -doit(Reps) -> - init(), - Begin = erlang:now(), - process(Reps), - % seconds to run the test - Time = timer:now_diff(erlang:now(), Begin)/1000000, - mem3:stop(), - Time. - - -process(0) -> - ok; -process(M) -> - mem3:fullmap(), - process(M-1). diff --git a/test/mem_utils_test.erl b/test/mem_utils_test.erl deleted file mode 100644 index b884d94e..00000000 --- a/test/mem_utils_test.erl +++ /dev/null @@ -1,97 +0,0 @@ --module(mem_utils_test). - --include_lib("eunit/include/eunit.hrl"). - - -join_type_test() -> - Options = [{replace,node3}], - ?assertEqual({replace,node3}, mem_utils:join_type(dummy,dummy,Options)). - - -pmap_from_full_test() -> - ?assertEqual([{n1,0},{n2,1},{n3,2},{n4,3}], - mem_utils:pmap_from_full(t_fullmap(0))). - - -fix_mappings_nodedown_test() -> - {PMap0, Fullmap0} = mem_utils:fix_mappings(nodedown, n3, t_fullmap(0)), - % with n3 down, n1 takes over - ?assertEqual([{n1,0},{n2,1},{n1,2},{n4,3}], PMap0), - ?assertEqual(t_fullmap(1), lists:sort(Fullmap0)). - - -fix_mappings_rejoin_test() -> - {PMap0, Fullmap0} = mem_utils:fix_mappings(nodedown, n3, t_fullmap(0)), - % with n3 down, n1 takes over - ?assertEqual([{n1,0},{n2,1},{n1,2},{n4,3}], PMap0), - ?assertEqual(t_fullmap(1), lists:sort(Fullmap0)), - % now have n3 rejoin - {PMap1, Fullmap1} = mem_utils:fix_mappings(rejoin, n3, Fullmap0), - ?assertEqual([{n1,0},{n2,1},{n3,2},{n4,3}], PMap1), - ?assertEqual(lists:sort(t_fullmap(0)), lists:sort(Fullmap1)). - - -fix_mappings_replace_test() -> - {PMap0, Fullmap0} = mem_utils:fix_mappings(nodedown, n3, t_fullmap(0)), - % with n3 down, n1 takes over - ?assertEqual([{n1,0},{n2,1},{n1,2},{n4,3}], PMap0), - ?assertEqual(t_fullmap(1), lists:sort(Fullmap0)), - % now replace n3 with n5 - {PMap2, Fullmap2} = mem_utils:fix_mappings(replace, {n3,n5}, Fullmap0), - ?assertEqual([{n1,0},{n2,1},{n5,2},{n4,3}], PMap2), - ?assertEqual(lists:sort(t_fullmap(2)), lists:sort(Fullmap2)). - - -fix_mappings_already_down_test() -> - {_PMap0, Fullmap0} = mem_utils:fix_mappings(nodedown, n3, t_fullmap(1)), - ?assertEqual(t_fullmap(1), lists:sort(Fullmap0)). - - -was_i_nodedown_test() -> - ?assertEqual(true, mem_utils:was_i_nodedown(n3, t_fullmap(1))), - ?assertEqual(false, mem_utils:was_i_nodedown(n3, t_fullmap(0))). - - -%% test helper funs - -t_fullmap(0) -> % four node, four part fullmap (unsorted) - [{n1,0,primary}, - {n2,0,partner}, - {n3,0,partner}, - {n2,1,primary}, - {n3,1,partner}, - {n4,1,partner}, - {n3,2,primary}, - {n4,2,partner}, - {n1,2,partner}, - {n4,3,primary}, - {n1,3,partner}, - {n2,3,partner}]; -t_fullmap(1) -> % like (0) above, but n3 is down (sorted) - [{n1,0,primary}, - {n1,2,partner}, - {n1,3,partner}, - {n2,0,partner}, - {n2,1,primary}, - {n2,3,partner}, - {n3,0,{nodedown,partner}}, - {n3,1,{nodedown,partner}}, - {n3,2,{nodedown,primary}}, - {n4,1,partner}, - {n4,2,partner}, - {n4,3,primary}]; -t_fullmap(2) -> % like (0) above, but n3 is replaced w/ n5 (unsorted) - [{n1,0,primary}, - {n2,0,partner}, - {n5,0,partner}, - {n2,1,primary}, - {n5,1,partner}, - {n4,1,partner}, - {n5,2,primary}, - {n4,2,partner}, - {n1,2,partner}, - {n4,3,primary}, - {n1,3,partner}, - {n2,3,partner}]; -t_fullmap(_Huh) -> - huh. diff --git a/test/membership2_test.erl b/test/membership2_test.erl deleted file mode 100644 index ed804cc2..00000000 --- a/test/membership2_test.erl +++ /dev/null @@ -1,126 +0,0 @@ -%%% -*- erlang-indent-level:2 -*- --module(membership2_test). --author('cliff@powerset.com'). --author('brad@cloudant.com'). - --include("../include/config.hrl"). --include("../include/common.hrl"). --include("../include/test.hrl"). - --include_lib("eunit/include/eunit.hrl"). - -% singular_startup_sequence_test() -> -% %% configuration:start_link(#config{n=1,r=1,w=1,q=6,directory=?TMP_DIR}), -% {ok, _} = mock:mock(configuration), -% mock:expects(configuration, get_config, fun(_Args) -> true end, -% #config{n=1,r=1,w=1,q=6,directory=?TMP_DIR}, 3), -% {ok, _} = mock:mock(replication), -% mock:expects(replication, partners, fun({_, [a], _}) -> true end, []), -% mock:expects(replication, partners_plus, fun({a, [a]}) -> true end, []), -% {ok, M} = membership2:start_link(a, [a]), -% State = gen_server:call(M, state), -% ?assertEqual(a, State#membership.node), -% ?assertEqual([a], State#membership.nodes), -% mock:verify_and_stop(replication), -% membership2:stop(M), -% %% configuration:stop(), -% mock:verify_and_stop(configuration), -% ?assertMatch({ok, [[a]]}, file:consult(?TMP_FILE("a.world"))), -% file:delete(?TMP_FILE("a.world")). - -% -define(NODEA, {a, ["d", "1", "4"]}). -% -define(NODEB, {b, ["e", "3", "1"]}). -% -define(NODEC, {c, ["f", "1", "2"]}). -% -define(NODES, [?NODEA, ?NODEB, ?NODEC]). - -% multi_startup_sequence_test() -> -% {ok, _} = mock:mock(configuration), -% mock:expects(configuration, get_config, fun(_Args) -> true end, -% (#config{n=3,r=1,w=1,q=6,directory=?TMP_DIR}), 3), -% {ok, _} = mock:mock(replication), -% VersionOne = vector_clock:create(make_ref()), -% Pid1 = make_ref(), -% VersionTwo = vector_clock:create(make_ref()), -% Pid2 = make_ref(), -% mock:expects(replication, partners, fun({_, ?NODES, _}) -> true end, [?NODEB, ?NODEC]), -% {ok, _} = stub:stub(membership2, call_join, fun(?NODEB, ?NODEA) -> -% {VersionOne, ?NODES, [{1,Pid1}]}; -% (?NODEC, ?NODEA) -> -% {VersionTwo, ?NODES, [{2,Pid2}]} -% end, 2), -% ?debugMsg("proxied"), -% ?debugFmt("check process code: ~p", [erlang:check_process_code(self(), membership2)]), -% {ok, M} = membership2:start_link(?NODEA, ?NODES), -% State = gen_server:call(M, state), -% ?assertEqual(?NODEA, State#membership.node), -% ?assertEqual(?NODES, State#membership.nodes), -% % Servers = State#membership.servers, -% % ?assertMatch([{1,Pid1},{2,Pid2}], membership2:servers_to_list(Servers)), -% ?assertEqual(greater, vector_clock:compare(State#membership.version, VersionOne)), -% ?assertEqual(greater, vector_clock:compare(State#membership.version, VersionTwo)), -% mock:verify_and_stop(replication), -% membership2:stop(M), -% mock:verify_and_stop(configuration), -% ?assertMatch({ok, [?NODES]}, file:consult(?TMP_FILE("a.world"))), -% file:delete(?TMP_FILE("a.world")). - -% startup_and_first_servers_for_key_test() -> -% configuration:start_link(#config{n=1,r=1,w=1,q=6,directory=?TMP_DIR}), -% {ok, _} = mock:mock(replication), -% mock:expects(replication, partners, fun({_, [a], _}) -> true end, []), -% {ok, M} = membership2:start_link(a, [a]), -% _State = gen_server:call(M, state), -% ?assertEqual([], membership2:servers_for_key("blah")), -% mock:verify_and_stop(replication), -% membership2:stop(M), -% configuration:stop(), -% ?assertMatch({ok, [[a]]}, file:consult(?TMP_FILE("a.world"))), -% file:delete(?TMP_FILE("a.world")). - -% startup_and_register_test() -> -% configuration:start_link(#config{n=1,r=1,w=1,q=0,directory=?TMP_DIR}), -% {ok, _} = mock:mock(replication), -% mock:expects(replication, partners, fun({_, [?NODEA], _}) -> true end, [], 3), -% {ok, M} = membership2:start_link(?NODEA, [?NODEA]), -% SServer1 = make_server(), -% SServer2 = make_server(), -% membership2:register(1, SServer1), -% membership2:register(1, SServer2), -% ?assertEqual([SServer1, SServer2], membership2:servers_for_key("blah")), -% mock:verify_and_stop(replication), -% membership2:stop(M), -% configuration:stop(), -% SServer1 ! stop, -% SServer2 ! stop, -% file:delete(?TMP_FILE("a.world")). - -% handle_local_server_outage_test() -> -% configuration:start_link(#config{n=1,r=1,w=1,q=0,directory=?TMP_DIR}), -% {ok, _} = mock:mock(replication), -% mock:expects(replication, partners, fun({_, [?NODEA], _}) -> true end, [], 4), -% {ok, M} = membership2:start_link(?NODEA, [?NODEA]), -% SServer1 = make_server(), -% SServer2 = make_server(), -% membership2:register(1, SServer1), -% membership2:register(1, SServer2), -% SServer1 ! stop, -% timer:sleep(1), -% ?assertEqual([SServer2], membership2:servers_for_key("blah")), -% mock:verify_and_stop(replication), -% membership2:stop(M), -% configuration:stop(), -% SServer2 ! stop, -% file:delete(?TMP_FILE("a.world")). - -% full_gossip_test() -> -% configuration:start_link(#config{n=1,r=1,w=1,q=2,directory=priv_dir()}), -% {ok, _} = mock:mock(replication), -% mock:expects(replication, partners, fun({_, ?NODES, _}) -> true end, [?NODEB, ?NODEC],4), - - -% make_server() -> -% spawn(fun() -> -% receive -% stop -> ok -% end -% end). diff --git a/test/mock.erl b/test/mock.erl deleted file mode 100644 index 2ecbf4f7..00000000 --- a/test/mock.erl +++ /dev/null @@ -1,322 +0,0 @@ -%%% -*- erlang-indent-level:2 -*- -%%%------------------------------------------------------------------- -%%% File: mock.erl -%%% @author Cliff Moon <> [] -%%% @copyright 2009 Cliff Moon -%%% @doc -%%% -%%% @end -%%% -%%% @since 2009-01-04 by Cliff Moon -%%%------------------------------------------------------------------- --module(mock). --author('cliff@powerset.com'). - -%% API --export([mock/1, proxy_call/2, proxy_call/3, expects/4, expects/5, - verify_and_stop/1, verify/1, stub_proxy_call/3, stop/1]). - --include_lib("eunit/include/eunit.hrl"). --include("../include/common.hrl"). - -%% gen_server callbacks --export([init/1, handle_call/3, handle_cast/2, handle_info/2, - terminate/2, code_change/3]). - --record(mockstate, {old_code, module, expectations=[]}). - -%%==================================================================== -%% API -%%==================================================================== -%%-------------------------------------------------------------------- -%% @spec mock(Module::atom()) -> {ok,Mock::record()} | ignore | {error,Error} -%% @doc Starts the server -%% @end -%%-------------------------------------------------------------------- -mock(Module) -> - case gen_server:start_link({local, mod_to_name(Module)}, mock, Module, []) of - {ok, Pid} -> {ok, Pid}; - {error, Reason} -> {error, Reason} - end. - -%% @spec proxy_call(Module::atom(), Function::atom()) -> term() -%% @doc Proxies a call to the mock server for Module without arguments -%% @end -proxy_call(Module, Function) -> - gen_server:call(mod_to_name(Module), {proxy_call, Function, {}}). - -%% @spec proxy_call(Module::atom(), Function::atom(), Args::tuple()) -> term() -%% @doc Proxies a call to the mock server for Module with arguments -%% @end -proxy_call(Module, Function, Args) -> - gen_server:call(mod_to_name(Module), {proxy_call, Function, Args}). - -stub_proxy_call(Module, Function, Args) -> - RegName = list_to_atom(lists:concat([Module, "_", Function, "_stub"])), - Ref = make_ref(), - RegName ! {Ref, self(), Args}, - ?debugFmt("sending {~p,~p,~p}", [Ref, self(), Args]), - receive - {Ref, Answer} -> Answer - end. - -%% @spec expects(Module::atom(), -%% Function::atom(), -%% Args::function(), -%% Ret::function() | term() ) -> term() - -%% Times:: {at_least, integer()} | never | {no_more_than, integer()} | integer()) -> term() - -%% @doc Sets the expectation that Function of Module will be called during a -%% test with Args. Args should be a fun predicate that will return true or -%% false whether or not the argument list matches. The argument list of the -%% function is passed in as a tuple. Ret is either a value to return or a fun -%% of arity 2 to be evaluated in response to a proxied call. The first argument -%% is the actual args from the call, the second is the call count starting -%% with 1. -expects(Module, Function, Args, Ret) -> - gen_server:call(mod_to_name(Module), {expects, Function, Args, Ret, 1}). - -expects(Module, Function, Args, Ret, Times) -> - gen_server:call(mod_to_name(Module), {expects, Function, Args, Ret, Times}). - -%% stub(Module, Function, Args, Ret) -> -%% gen_server:call(mod_to_name(Module), {stub, Function, Args, Ret}). - -verify_and_stop(Module) -> - verify(Module), - stop(Module). - -verify(Module) -> - ?assertEqual(ok, gen_server:call(mod_to_name(Module), verify)). - -stop(Module) -> - gen_server:cast(mod_to_name(Module), stop), - timer:sleep(10). - - -%%==================================================================== -%% gen_server callbacks -%%==================================================================== - -%%-------------------------------------------------------------------- -%% @spec init(Args) -> {ok, State} | -%% {ok, State, Timeout} | -%% ignore | -%% {stop, Reason} -%% @doc Initiates the server -%% @end -%%-------------------------------------------------------------------- -init(Module) -> - case code:get_object_code(Module) of - {Module, Bin, Filename} -> - case replace_code(Module) of - ok -> {ok, #mockstate{module=Module,old_code={Module, Bin, Filename}}}; - {error, Reason} -> {stop, Reason} - end; - error -> {stop, ?fmt("Could not get object code for module ~p", [Module])} - end. - -%%-------------------------------------------------------------------- -%% @spec -%% handle_call(Request, From, State) -> {reply, Reply, State} | -%% {reply, Reply, State, Timeout} | -%% {noreply, State} | -%% {noreply, State, Timeout} | -%% {stop, Reason, Reply, State} | -%% {stop, Reason, State} -%% @doc Handling call messages -%% @end -%%-------------------------------------------------------------------- -handle_call({proxy_call, Function, Args}, _From, - State = #mockstate{module=Mod,expectations=Expects}) -> - case match_expectation(Function, Args, Expects) of - {matched, ReturnTerm, NewExpects} -> - {reply, ReturnTerm, State#mockstate{expectations=NewExpects}}; - unmatched -> - {stop, ?fmt("got unexpected call to ~p:~p", [Mod,Function])} - end; - -handle_call({expects, Function, Args, Ret, Times}, _From, - State = #mockstate{expectations=Expects}) -> - {reply, ok, State#mockstate{ - expectations=add_expectation(Function, Args, Ret, Times, Expects)}}; - -handle_call(verify, _From, State = #mockstate{expectations=Expects,module=Mod}) -> - ?infoFmt("verifying ~p~n", [Mod]), - if - length(Expects) > 0 -> - {reply, {mismatch, format_missing_expectations(Expects, Mod)}, State}; - true -> {reply, ok, State} - end. - -%%-------------------------------------------------------------------- -%% @spec handle_cast(Msg, State) -> {noreply, State} | -%% {noreply, State, Timeout} | -%% {stop, Reason, State} -%% @doc Handling cast messages -%% @end -%%-------------------------------------------------------------------- -handle_cast(stop, State) -> - timer:sleep(10), - {stop, normal, State}. - -%%-------------------------------------------------------------------- -%% @spec handle_info(Info, State) -> {noreply, State} | -%% {noreply, State, Timeout} | -%% {stop, Reason, State} -%% @doc Handling all non call/cast messages -%% @end -%%-------------------------------------------------------------------- -handle_info(_Info, State) -> - {noreply, State}. - -%%-------------------------------------------------------------------- -%% @spec terminate(Reason, State) -> void() -%% @doc This function is called by a gen_server when it is about to -%% terminate. It should be the opposite of Module:init/1 and do any necessary -%% cleaning up. When it returns, the gen_server terminates with Reason. -%% The return value is ignored. -%% @end -%%-------------------------------------------------------------------- -terminate(_Reason, #mockstate{old_code={Module, Binary, Filename}}) -> - code:purge(Module), - code:delete(Module), - code:load_binary(Module, Filename, Binary), - timer:sleep(10). - -%%-------------------------------------------------------------------- -%% @spec code_change(OldVsn, State, Extra) -> {ok, NewState} -%% @doc Convert process state when code is changed -%% @end -%%-------------------------------------------------------------------- -code_change(_OldVsn, State, _Extra) -> - {ok, State}. - -%%-------------------------------------------------------------------- -%%% Internal functions -%%-------------------------------------------------------------------- -format_missing_expectations(Expects, Mod) -> - format_missing_expectations(Expects, Mod, []). - -format_missing_expectations([], _, Msgs) -> - lists:reverse(Msgs); - -format_missing_expectations([{Function, _Args, _Ret, Times, Called}|Expects], Mod, Msgs) -> - Msgs1 = [?fmt("expected ~p:~p to be called ~p times but was called ~p", [Mod,Function,Times,Called])|Msgs], - format_missing_expectations(Expects, Mod, Msgs1). - -add_expectation(Function, Args, Ret, Times, Expects) -> - Expects ++ [{Function, Args, Ret, Times, 0}]. - -match_expectation(Function, Args, Expectations) -> - match_expectation(Function, Args, Expectations, []). - -match_expectation(_Function, _Args, [], _Rest) -> - unmatched; - -match_expectation(Function, Args, [{Function, Matcher, Ret, MaxTimes, Invoked}|Expects], Rest) -> - case Matcher(Args) of - true -> - ReturnTerm = prepare_return(Args, Ret, Invoked+1), - if - Invoked + 1 >= MaxTimes -> {matched, ReturnTerm, lists:reverse(Rest) ++ Expects}; - true -> {matched, ReturnTerm, lists:reverse(Rest) ++ [{Function, Matcher, Ret, MaxTimes, Invoked+1}] ++ Expects} - end; - false -> match_expectation(Function, Args, Expects, [{Function,Matcher,Ret,MaxTimes,Invoked}|Rest]) - end; - -match_expectation(Function, Args, [Expect|Expects], Rest) -> - match_expectation(Function, Args, Expects, [Expect|Rest]). - -prepare_return(Args, Ret, Invoked) when is_function(Ret) -> - Ret(Args, Invoked); - -prepare_return(_Args, Ret, _Invoked) -> - Ret. - -replace_code(Module) -> - Info = Module:module_info(), - Exports = get_exports(Info), - unload_code(Module), - NewFunctions = generate_functions(Module, Exports), - Forms = [ - {attribute,1,module,Module}, - {attribute,2,export,Exports} - ] ++ NewFunctions, - case compile:forms(Forms, [binary]) of - {ok, Module, Binary} -> case code:load_binary(Module, atom_to_list(Module) ++ ".erl", Binary) of - {module, Module} -> ok; - {error, Reason} -> {error, Reason} - end; - error -> {error, "An undefined error happened when compiling."}; - {error, Errors, Warnings} -> {error, Errors ++ Warnings} - end. - -unload_code(Module) -> - code:purge(Module), - code:delete(Module). - -get_exports(Info) -> - get_exports(Info, []). - -get_exports(Info, Acc) -> - case lists:keytake(exports, 1, Info) of - {value, {exports, Exports}, ModInfo} -> - get_exports(ModInfo, Acc ++ lists:filter(fun({module_info, _}) -> false; (_) -> true end, Exports)); - _ -> Acc - end. - -%% stub_function_loop(Fun) -> -%% receive -%% {Ref, Pid, Args} -> -%% ?debugFmt("received {~p,~p,~p}", [Ref, Pid, Args]), -%% Ret = (catch Fun(Args) ), -%% ?debugFmt("sending {~p,~p}", [Ref,Ret]), -%% Pid ! {Ref, Ret}, -%% stub_function_loop(Fun) -%% end. - -% Function -> {function, Lineno, Name, Arity, [Clauses]} -% Clause -> {clause, Lineno, [Variables], [Guards], [Expressions]} -% Variable -> {var, Line, Name} -% -generate_functions(Module, Exports) -> - generate_functions(Module, Exports, []). - -generate_functions(_Module, [], FunctionForms) -> - lists:reverse(FunctionForms); - -generate_functions(Module, [{Name,Arity}|Exports], FunctionForms) -> - generate_functions(Module, Exports, [generate_function(Module, Name, Arity)|FunctionForms]). - -generate_function(Module, Name, Arity) -> - {function, 1, Name, Arity, [{clause, 1, generate_variables(Arity), [], generate_expression(mock, proxy_call, Module, Name, Arity)}]}. - -generate_variables(0) -> []; -generate_variables(Arity) -> - lists:map(fun(N) -> - {var, 1, list_to_atom(lists:concat(['Arg', N]))} - end, lists:seq(1, Arity)). - -generate_expression(M, F, Module, Name, 0) -> - [{call,1,{remote,1,{atom,1,M},{atom,1,F}}, [{atom,1,Module}, {atom,1,Name}]}]; -generate_expression(M, F, Module, Name, Arity) -> - [{call,1,{remote,1,{atom,1,M},{atom,1,F}}, [{atom,1,Module}, {atom,1,Name}, {tuple,1,lists:map(fun(N) -> - {var, 1, list_to_atom(lists:concat(['Arg', N]))} - end, lists:seq(1, Arity))}]}]. - -mod_to_name(Module) -> - list_to_atom(lists:concat([mock_, Module])). - -%% replace_function(FF, Forms) -> -%% replace_function(FF, Forms, []). - -%% replace_function(FF, [], Ret) -> -%% [FF|lists:reverse(Ret)]; - -%% replace_function({function,_,Name,Arity,Clauses}, [{function,Line,Name,Arity,_}|Forms], Ret) -> -%% lists:reverse(Ret) ++ [{function,Line,Name,Arity,Clauses}|Forms]; - -%% replace_function(FF, [FD|Forms], Ret) -> -%% replace_function(FF, Forms, [FD|Ret]). diff --git a/test/mock_genserver.erl b/test/mock_genserver.erl deleted file mode 100644 index cde41ff5..00000000 --- a/test/mock_genserver.erl +++ /dev/null @@ -1,209 +0,0 @@ -%%%------------------------------------------------------------------- -%%% File: mock_genserver.erl -%%% @author Cliff Moon <> [] -%%% @copyright 2009 Cliff Moon -%%% @doc -%%% -%%% @end -%%% -%%% @since 2009-01-02 by Cliff Moon -%%%------------------------------------------------------------------- --module(mock_genserver). --author('cliff@powerset.com'). - --behaviour(gen_server). - --include_lib("eunit/include/eunit.hrl"). - -%% API --export([start_link/1, stub_call/3, expects_call/3, expects_call/4, stop/1]). - -%% gen_server callbacks --export([init/1, handle_call/3, handle_cast/2, handle_info/2, - terminate/2, code_change/3]). - --record(state, {call_stubs=[], call_expects=[], cast_expectations, info_expectations}). - -%%==================================================================== -%% API -%%==================================================================== -%%-------------------------------------------------------------------- -%% @spec start_link(Reference::atom()) -> {ok,Pid} | ignore | {error,Error} -%% @doc Starts the server -%% @end -%%-------------------------------------------------------------------- -start_link(Reference) -> - gen_server:start_link(Reference, ?MODULE, [], []). - -stub_call(Server, Sym, Fun) when is_function(Fun) -> - gen_server:call(Server, {mock_stub_call, Sym, Fun}). - -expects_call(Server, Args, Fun) when is_function(Fun) -> - gen_server:call(Server, {mock_expects_call, Args, Fun}). - -expects_call(Server, Args, Fun, Times) when is_function(Fun) -> - gen_server:call(Server, {mock_expects_call, Args, Fun, Times}). - -stop(Server) -> - gen_server:call(Server, mock_stop). - -%%==================================================================== -%% gen_server callbacks -%%==================================================================== - -%%-------------------------------------------------------------------- -%% @spec init(Args) -> {ok, State} | -%% {ok, State, Timeout} | -%% ignore | -%% {stop, Reason} -%% @doc Initiates the server -%% @end -%%-------------------------------------------------------------------- -init([]) -> - {ok, #state{}}. - -%%-------------------------------------------------------------------- -%% @spec -%% handle_call(Request, From, State) -> {reply, Reply, State} | -%% {reply, Reply, State, Timeout} | -%% {noreply, State} | -%% {noreply, State, Timeout} | -%% {stop, Reason, Reply, State} | -%% {stop, Reason, State} -%% @doc Handling call messages -%% @end -%%-------------------------------------------------------------------- -handle_call({mock_stub_call, Sym, Fun}, _From, State = #state{call_stubs=Stubs}) -> - {reply, ok, State#state{call_stubs=[{Sym, Fun}|Stubs]}}; - -handle_call({mock_expects_call, Args, Fun}, _From, State = #state{call_expects=Expects}) -> - {reply, ok, State#state{call_expects=add_expectation(Args, Fun, at_least_once, Expects)}}; - -handle_call({mock_expects_call, Args, Fun, Times}, _From, State = #state{call_expects=Expects}) -> - {reply, ok, State#state{call_expects=add_expectation(Args, Fun, Times, Expects)}}; - -handle_call(mock_stop, _From, State) -> - {stop, normal, ok, State}; - -handle_call(Request, _From, State = #state{call_stubs=Stubs,call_expects=Expects}) -> - % expectations have a higher priority - case find_expectation(Request, Expects) of - {found, {_, Fun, Time}, NewExpects} -> {reply, Fun(Request, Time), State#state{call_expects=NewExpects}}; - not_found -> % look for a stub - case find_stub(Request, Stubs) of - {found, {_, Fun}} -> {reply, Fun(Request), State}; - not_found -> - {stop, {unexpected_call, Request}, State} - end - end. - -%%-------------------------------------------------------------------- -%% @spec handle_cast(Msg, State) -> {noreply, State} | -%% {noreply, State, Timeout} | -%% {stop, Reason, State} -%% @doc Handling cast messages -%% @end -%%-------------------------------------------------------------------- -handle_cast(_Msg, State) -> - {noreply, State}. - -%%-------------------------------------------------------------------- -%% @spec handle_info(Info, State) -> {noreply, State} | -%% {noreply, State, Timeout} | -%% {stop, Reason, State} -%% @doc Handling all non call/cast messages -%% @end -%%-------------------------------------------------------------------- -handle_info(_Info, State) -> - {noreply, State}. - -%%-------------------------------------------------------------------- -%% @spec terminate(Reason, State) -> void() -%% @doc This function is called by a gen_server when it is about to -%% terminate. It should be the opposite of Module:init/1 and do any necessary -%% cleaning up. When it returns, the gen_server terminates with Reason. -%% The return value is ignored. -%% @end -%%-------------------------------------------------------------------- -terminate(_Reason, _State) -> - ok. - -%%-------------------------------------------------------------------- -%% @spec code_change(OldVsn, State, Extra) -> {ok, NewState} -%% @doc Convert process state when code is changed -%% @end -%%-------------------------------------------------------------------- -code_change(_OldVsn, State, _Extra) -> - {ok, State}. - -%%-------------------------------------------------------------------- -%%% Internal functions -%%-------------------------------------------------------------------- - - -add_expectation(Args, Fun, Times, Expects) -> - Expects ++ [{Args, Fun, Times}]. - -find_expectation(Request, Expects) -> - find_expectation(Request, Expects, []). - -find_expectation(_Request, [], _Rest) -> - not_found; - -find_expectation(Request, [{Args, Fun, Times}|Expects], Rest) -> - MatchFun = generate_match_fun(Args), - case MatchFun(Request) of - true -> - if - Times == at_least_once -> {found, {Args, Fun, Times}, lists:reverse(Rest) ++ [{Args, Fun, Times}] ++ Expects}; - Times == 1 -> {found, {Args, Fun, Times}, lists:reverse(Rest) ++ Expects}; - true -> {found, {Args, Fun, Times}, lists:reverse(Rest) ++ [{Args, Fun, Times-1}] ++ Expects} - end; - false -> find_expectation(Request, Expects, [{Args, Fun, Times}|Rest]) - end. - -find_stub(Request, Stub) when is_tuple(Request) -> - Sym = element(1, Request), - find_stub(Sym, Stub); - -find_stub(_Sym, []) -> - not_found; - -find_stub(Sym, _Stubs) when not is_atom(Sym) -> - not_found; - -find_stub(Sym, [{Sym, Fun}|_Stubs]) -> - {found, {Sym, Fun}}; - -find_stub(Sym, [_Stub|Stubs]) -> - find_stub(Sym, Stubs). - -generate_match_fun(Args) when is_tuple(Args) -> - generate_match_fun(tuple_to_list(Args)); - -generate_match_fun(Args) when not is_list(Args) -> - generate_match_fun([Args]); - -generate_match_fun(Args) when is_list(Args) -> - Src = generate_match_fun("fun({", Args), - {ok, Tokens, _} = erl_scan:string(Src), - {ok, [Form]} = erl_parse:parse_exprs(Tokens), - {value, Fun, _} = erl_eval:expr(Form, erl_eval:new_bindings()), - Fun. - -generate_match_fun(Src, []) -> - Src ++ "}) -> true; (_) -> false end."; - -% unbound atom means you don't care about an arg -generate_match_fun(Src, [unbound|Args]) -> - if - length(Args) > 0 -> generate_match_fun(Src ++ "_,", Args); - true -> generate_match_fun(Src ++ "_", Args) - end; - -generate_match_fun(Src, [Bound|Args]) -> - Term = lists:flatten(io_lib:format("~w", [Bound])), - if - length(Args) > 0 -> generate_match_fun(Src ++ Term ++ ",", Args); - true -> generate_match_fun(Src ++ Term, Args) - end. diff --git a/test/replication_test.erl b/test/replication_test.erl deleted file mode 100644 index 095e1b44..00000000 --- a/test/replication_test.erl +++ /dev/null @@ -1,89 +0,0 @@ -%%% -*- erlang-indent-level:2 -*- --module(replication_test). --author('brad@cloudant.com'). - --include("../include/config.hrl"). --include("../include/test.hrl"). - --include_lib("eunit/include/eunit.hrl"). - --define(NODEA, {a, ["d", "1", "4"]}). --define(NODEB, {b, ["e", "3", "1"]}). --define(NODEC, {c, ["f", "1", "2"]}). --define(NODED, {d, ["e", "1", "2"]}). --define(NODEE, {e, ["e", "2", "2"]}). --define(NODES, [?NODEA, ?NODEB, ?NODEC, ?NODED, ?NODEE]). - -%% TODO: give this some effigy love, mock configuration up all of these -%% different ways. - -metadata_level_1_test() -> - configuration:start_link(#config{n=3,r=1,w=1,q=6, - directory=?TMP_DIR, - meta=[{datacenter,roundrobin}, - {rack, roundrobin}, - {slot, roundrobin} - ]}), - Partners = replication:partners(?NODEA, - [?NODEA, ?NODEB, ?NODEC], - configuration:get_config()), - ?assertEqual([?NODEB, ?NODEC], Partners), - configuration:stop(). - - -metadata_level_2_test() -> - configuration:start_link(#config{n=3,r=1,w=1,q=6, - directory=?TMP_DIR, - meta=[{datacenter,roundrobin}, - {rack, roundrobin}, - {slot, roundrobin} - ]}), - Partners = replication:partners(?NODEA, - ?NODES, - configuration:get_config()), - ?assertEqual([?NODED,?NODEE], Partners), - configuration:stop(). - - -no_metadata_test() -> - configuration:start_link(#config{n=2,r=1,w=1,q=6, - directory=?TMP_DIR, - meta=[]}), - Partners = replication:partners(a, - [a,b,c,d], - configuration:get_config()), - ?assertEqual([b], Partners), - configuration:stop(). - - -wrap_test() -> - configuration:start_link(#config{n=3,r=1,w=1,q=6, - directory=?TMP_DIR, - meta=[]}), - Wrap1Partners = replication:partners(c, - [a,b,c,d], - configuration:get_config()), - ?assertEqual([a,d], Wrap1Partners), - Wrap2Partners = replication:partners(d, - [a,b,c,d], - configuration:get_config()), - ?assertEqual([a,b], Wrap2Partners), - configuration:stop(). - - -self_test() -> - configuration:start_link(#config{n=3,r=1,w=1,q=6, - directory=?TMP_DIR, - meta=[]}), - Partners = replication:partners(a, [a], - configuration:get_config()), - ?assertEqual([], Partners), - configuration:stop(). - - -remove_self_test() -> - configuration:start_link( - #config{n=4,r=1,w=1,q=6, directory=?TMP_DIR, meta=[]}), - Partners = replication:partners(a, [a,b], configuration:get_config()), - ?assertEqual([b], Partners), - configuration:stop(). diff --git a/test/stub.erl b/test/stub.erl deleted file mode 100644 index 2a6173b5..00000000 --- a/test/stub.erl +++ /dev/null @@ -1,168 +0,0 @@ -%%%------------------------------------------------------------------- -%%% File: stub.erl -%%% @author Cliff Moon <> [] -%%% @copyright 2009 Cliff Moon -%%% @doc -%%% -%%% @end -%%% -%%% @since 2009-05-10 by Cliff Moon -%%%------------------------------------------------------------------- --module(stub). --author('cliff@powerset.com'). - --behaviour(gen_server). - -%% API --export([stub/3, stub/4, proxy_call/3]). - -%% gen_server callbacks --export([init/1, handle_call/3, handle_cast/2, handle_info/2, - terminate/2, code_change/3]). - --include_lib("eunit/include/eunit.hrl"). --include("../include/common.hrl"). - --record(state, {old_code, module, stub, times}). - -%%==================================================================== -%% API -%%==================================================================== - -stub(Module, Function, Fun) -> - stub(Module, Function, Fun, 1). - -stub(Module, Function, Fun, Times) when is_function(Fun) -> - gen_server:start({local, name(Module, Function)}, ?MODULE, [Module, Function, Fun, Times], []). - -proxy_call(_, Name, Args) -> - {Times, Reply} = gen_server:call(Name, {proxy_call, Args}), - if - Times =< 0 -> gen_server:cast(Name, stop); - true -> ok - end, - Reply. - -%%==================================================================== -%% gen_server callbacks -%%==================================================================== - -%%-------------------------------------------------------------------- -%% @spec init(Args) -> {ok, State} | -%% {ok, State, Timeout} | -%% ignore | -%% {stop, Reason} -%% @doc Initiates the server -%% @end -%%-------------------------------------------------------------------- -init([Module, Function, Fun, Times]) -> - case code:get_object_code(Module) of - {Module, Bin, Filename} -> - ?debugMsg("stubbing"), - stub_function(Module, Function, arity(Fun)), - {ok, #state{module=Module,old_code={Module,Bin,Filename},times=Times,stub=Fun}}; - error -> {stop, ?fmt("Could not get object code for module ~p", [Module])} - end. - -%%-------------------------------------------------------------------- -%% @spec -%% handle_call(Request, From, State) -> {reply, Reply, State} | -%% {reply, Reply, State, Timeout} | -%% {noreply, State} | -%% {noreply, State, Timeout} | -%% {stop, Reason, Reply, State} | -%% {stop, Reason, State} -%% @doc Handling call messages -%% @end -%%-------------------------------------------------------------------- -handle_call({proxy_call, Args}, _From, State = #state{stub=Fun, times=Times}) -> - Reply = apply(Fun, tuple_to_list(Args)), - {reply, {Times-1, Reply}, State#state{times=Times-1}}. - -%%-------------------------------------------------------------------- -%% @spec handle_cast(Msg, State) -> {noreply, State} | -%% {noreply, State, Timeout} | -%% {stop, Reason, State} -%% @doc Handling cast messages -%% @end -%%-------------------------------------------------------------------- -handle_cast(stop, State) -> - sleep:timer(10), - {stop, normal, State}. - -%%-------------------------------------------------------------------- -%% @spec handle_info(Info, State) -> {noreply, State} | -%% {noreply, State, Timeout} | -%% {stop, Reason, State} -%% @doc Handling all non call/cast messages -%% @end -%%-------------------------------------------------------------------- -handle_info(_Info, State) -> - {noreply, State}. - -%%-------------------------------------------------------------------- -%% @spec terminate(Reason, State) -> void() -%% @doc This function is called by a gen_server when it is about to -%% terminate. It should be the opposite of Module:init/1 and do any necessary -%% cleaning up. When it returns, the gen_server terminates with Reason. -%% The return value is ignored. -%% @end -%%-------------------------------------------------------------------- -terminate(_Reason, #state{old_code={_Module,_Bin,_Filename}}) -> - ok. - -%%-------------------------------------------------------------------- -%% @spec code_change(OldVsn, State, Extra) -> {ok, NewState} -%% @doc Convert process state when code is changed -%% @end -%%-------------------------------------------------------------------- -code_change(_OldVsn, State, _Extra) -> - {ok, State}. - -%%-------------------------------------------------------------------- -%%% Internal functions -%%-------------------------------------------------------------------- -name(Module, Function) -> - list_to_atom(lists:concat([Module, Function, "stub"])). - -stub_function(Module, Function, Arity) -> - {_, Bin, _} = code:get_object_code(Module), - {ok, {Module,[{abstract_code,{raw_abstract_v1,Forms}}]}} = beam_lib:chunks(Bin, [abstract_code]), - ?debugMsg("replacing function"), - StubbedForms = replace_function(Module, Function, Arity, Forms), - case compile:forms(StubbedForms, [binary]) of - {ok, Module, Binary} -> code:load_binary(Module, atom_to_list(Module) ++ ".erl", Binary); - Other -> Other - end. - -arity(Fun) when is_function(Fun) -> - Props = erlang:fun_info(Fun), - proplists:get_value(arity, Props). - -replace_function(Module, Function, Arity, Forms) -> - replace_function(Module, Function, Arity, Forms, []). - -replace_function(_Module, _Function, _Arity, [], Acc) -> - lists:reverse(Acc); -replace_function(Module, Function, Arity, [{function, Line, Function, Arity, _Clauses}|Forms], Acc) -> - lists:reverse(Acc) ++ [{function, Line, Function, Arity, [ - {clause, - Line, - generate_variables(Arity), - [], - generate_expression(stub,proxy_call,Module,name(Module,Function),Arity)}]}] ++ Forms; -replace_function(Module, Function, Arity, [Form|Forms], Acc) -> - replace_function(Module, Function, Arity, Forms, [Form|Acc]). - -generate_variables(0) -> []; -generate_variables(Arity) -> - lists:map(fun(N) -> - {var, 1, list_to_atom(lists:concat(['Arg', N]))} - end, lists:seq(1, Arity)). - -generate_expression(M, F, Module, Name, 0) -> - [{call,1,{remote,1,{atom,1,M},{atom,1,F}}, [{atom,1,Module}, {atom,1,Name}]}]; -generate_expression(M, F, Module, Name, Arity) -> - [{call,1,{remote,1,{atom,1,M},{atom,1,F}}, [{atom,1,Module}, {atom,1,Name}, {tuple,1,lists:map(fun(N) -> - {var, 1, list_to_atom(lists:concat(['Arg', N]))} - end, lists:seq(1, Arity))}]}]. |