From ed0752019f5d2a1ab418896b1e759cfade82124a Mon Sep 17 00:00:00 2001 From: Dave Smith Date: Wed, 10 Dec 2008 18:18:05 -0700 Subject: [PATCH] Adding thrash test --- test/thrash_SUITE.erl | 99 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 99 insertions(+) create mode 100644 test/thrash_SUITE.erl diff --git a/test/thrash_SUITE.erl b/test/thrash_SUITE.erl new file mode 100644 index 0000000..b669cdb --- /dev/null +++ b/test/thrash_SUITE.erl @@ -0,0 +1,99 @@ +%% ------------------------------------------------------------------- +%% +%% bdberl: Port Driver Thrash tests +%% Copyright (c) 2008 The Hive. All rights reserved. +%% +%% ------------------------------------------------------------------- +-module(thrash_SUITE). + +-compile(export_all). + +all() -> + [test_thrash]. + +-define(PROCS, 1). + +test_thrash(_Config) -> + %% Spin up 15 processes (async thread pool is 10) + start_procs(?PROCS), + wait_for_finish(?PROCS). + +start_procs(0) -> + ok; +start_procs(Count) -> + spawn_link(?MODULE, thrash_run, [self()]), + start_procs(Count-1). + +wait_for_finish(0) -> + ok; +wait_for_finish(Count) -> + receive + {finished, Pid} -> + io:format("~p is done; ~p remaining.\n", [Pid, Count-1]), + wait_for_finish(Count-1) + end. + +thrash_run(Owner) -> + %% Seed the RNG + {A1, A2, A3} = now(), + random:seed(A1, A2, A3), + + %% Open up a port and database + {ok, P} = bdberl_port:new(), + {ok, 0} = bdberl_port:open_database(P, "thrash", btree), + + %% Start thrashing + thrash_incr_loop(P, Owner, 5000). + + + +thrash_incr_loop(Port, Owner, 0) -> + Owner ! {finished, self()}; +thrash_incr_loop(Port, Owner, Count) -> + %% Choose random key + Key = random:uniform(12), + + %% Start a txn that will read the current value of the key and increment by 1 + F = fun() -> + case get_or_die(Port, 0, Key) of + not_found -> + Value = 0; + + {ok, Value} -> + Value + end, + put_or_die(Port, 0, Key, Value) + end, + ok = do_txn(Port, F, 20), + thrash_incr_loop(Port, Owner, Count-1). + + +get_or_die(Port, DbRef, Key) -> + case bdberl_port:get(Port, DbRef, Key) of + not_found -> + not_found; + {ok, Value} -> + Value + end. + +put_or_die(Port, DbRef, Key, Value) -> + ok = bdberl_port:put(Port, DbRef, Key, Value). + +do_txn(Port, F, 0) -> + ct:print("Max retries exceeded for txn; giving up!"), + failed; +do_txn(Port, F, Count) -> + case bdberl_port:txn_begin(Port) of + ok -> + case catch(F()) of + {'EXIT', Reason} -> + io:format("Txn failed; retrying. Last error: ~p\n", [Reason]), + do_txn(Port, F, Count-1); + Other -> + io:format("Txn success (~p): ~p\n", [Count, Other]), + ok = bdberl_port:txn_commit(Port) + end; + {error, Reason} -> + io:format("Txn failed(2); retrying. Last error: ~p\n", [Reason]), + do_txn(Port, F, Count-1) + end.