From 2bd2e101d1b11432d9b1d75577c94b9b5a4cdc92 Mon Sep 17 00:00:00 2001 From: Kelly McLaughlin Date: Wed, 13 Aug 2014 14:13:22 -0600 Subject: [PATCH 1/2] Major overhaul of the internal workings of riak_test * Upgrade versions have moved to being a list not just a single version. `upgrade_version` is removed in favor of `upgrade_path`. `upgrade_path` is a comma-separated list representing an upgrade sequence *e.g.* `1.3.4,1.4.10,2.0.0` * Unification of node deployment code: common code and work from the individual harness modules has been brought into the framework where possible. * Further decouple and distinguish between framework setup and prep, test setup, and test execution. * Streamline the configuration for versions and root path. Move away from convention of *current*, *previous*, and *legacy*. Too restrictive and not enough benefit and *current* especially is ambiguous. Config must specify `root_path` and all versions under root path are represented as release directories. A subdirectory of `2.0.0` means that *2.0.0* can now be used as a version the same as *current*, *previous*, or *legacy* could previously, but the upside is that it requires no extra configuration. * Upgrade transitions can be specified as a list with no bound so if we want to test upgrading to each major release from `1.0.0` to `2.0.0` then that is possible. * Node deployment and teardown for a particular test execution is more isolated. The framework attempts to stop **all** nodes during its setup phase, but doing so after each test execution is unnecessary. Node deployment is now a matter of requesting the number of required nodes and the versions involved in the test. The framework determines if the number of nodes to cover the requirements of the test are available and returns success or failure on that criteria. As the last statement implies, concurrent test execution is now attempted where possible. If there are 8 nodes available for the *2.0.0* version and 4 tests queued to be run that require only 2 nodes each and do not require upgrade testing then there is no reason to block on serial execution. * Responsibility for management of test execution is more clearly delineated. Previously it was hard to account for responsibility of tasks between `riak_test_escript`, `riak_test_runner`, and `rt`. `riak_test_escript` has been heavily refactored and the work it does has been minimized to command line argument parsing and spawning the workhorse processes to execute the tests. It also made sense to make use of OTP behaviors for the implementation of some of the execution helpers. The `riak_test_executor`, an `gen_fsm`, is introduced to manage the scheduling of tests and handle reporting results. It is a named process and only one runs at a time. Individual test execution is managed by a `riak_test_runner` process. These are spawned by the `riak_test_executor` and there is one for each test that executes. `riak_test_runner` is also implemented as a `gen_fsm`. Finally there is the `node_manager` process. It is a `gen_server` that handles all node manipulation and manages access to the nodes for testing. The `riak_test_executor` requests to reserve `N` number of nodes from the node manager and if the reservation can be fulfilled the `node_manager` responds with the list of nodes for the requesting test to use. If the requested number of nodes is not available the execution of the test is deferred. The `node_manager` is aware if the current series of test executions involves upgrades and deploys nodes initially using the correct version based on that information. Thus when a test receives a list of nodes there is no need to take any action and test execution can begin immediately. * Maximize resource efficiency and length of execution duration by seeking to avoid unnecessary node starts or cycles. *e.g.* The `node_manager` is initialized with a list of nodes and the versions involved in test execution, but no nodes are deployed until the first call to `node_manager:reserve_nodes` that requires those nodes. If only one test slated for execution and it only requires 3 nodes there is no reason to start or stop more than 3 nodes. * Facilitate replication testing setup and eliminate crufty setup code duplicated in replication test with new properties `cluster_count` (defaults to 1) and `cluster_weights`, a list of weights that determine distribution of available nodes among requested clusters (defaults to `undefined`). Setting up multiple clusters for testing replication should not require any kludgy steps, it should have full support in the framework. * Update backend setup so that backend configuration can be done for selected nodes only instead of all nodes * Change setup scripts to use only version numbers as directory names. * Change setup scripts to avoid the unnecessary `dev` directory when installing devrel releases. *e.g.* Instead of `~/rt/riak/2.0.0/dev/` being the path to the `dev*` releases, the path is just `~/rt/riak/2.0.0/`. This just removes an unnecessary subdirectory and removes the need for some complications in node deployment. * Refactor properties to distinguish between node name and id: The helper functions used by the framework have different input requirements. Some that use rpc require the actual node name which may be different depending on the harness used. Others use the node identifier to form strings representing shell commands to execute. The node property has been replaced by a node_id property and a node_map structure that maps a node identifier to a full node name. * Add new rtdev-install script that is intended to replace most of the other setup scripts. * Allow distinction between console and file logging levels: Move from a single lager_level configuration option to lager_console_level and lager_file_level in order to be able to control these independently. The default level for the console output is notice to minimize the output display during a run. The default level for the file output is info in order to capture all of the logging that previously has been output to the console. * Use `riak_cli` table generation for display of test result details when using the `-v` option. * Update rebar to 2.5.1 * Update Makefile to use tools.mk --- Makefile | 43 +-- bin/rtdev-current.sh | 29 +- bin/rtdev-install.sh | 56 ++++ bin/rtdev-setup-releases.sh | 6 +- rebar | Bin 155065 -> 160405 bytes rebar.config | 3 +- src/node_manager.erl | 230 +++++++++++++ src/riak_test_escript.erl | 435 +++++++++++++------------ src/riak_test_executor.erl | 273 ++++++++++++++++ src/riak_test_runner.erl | 551 ++++++++++++++++++++++---------- src/rt.erl | 2 +- src/rt_backend.erl | 49 ++- src/rt_cluster.erl | 217 ++++++------- src/rt_harness.erl | 88 ++--- src/rt_harness_util.erl | 199 +++++++----- src/rt_node.erl | 103 +++--- src/rt_pb.erl | 11 +- src/rt_properties.erl | 46 ++- src/rtdev.erl | 501 +++++++++++++++++------------ src/rtssh.erl | 23 +- src/test_harness.erl | 16 +- tests/always_fail_test.erl | 7 +- tests/always_pass_test.erl | 15 + tests/secondary_index_tests.erl | 12 +- tests/verify_listkeys.erl | 131 ++++---- tools.mk | 115 +++++++ 26 files changed, 2150 insertions(+), 1011 deletions(-) create mode 100755 bin/rtdev-install.sh create mode 100644 src/node_manager.erl create mode 100644 src/riak_test_executor.erl create mode 100644 tests/always_pass_test.erl create mode 100644 tools.mk diff --git a/Makefile b/Makefile index dffba0254..efc06301d 100644 --- a/Makefile +++ b/Makefile @@ -1,10 +1,5 @@ .PHONY: deps -APPS = kernel stdlib sasl erts ssl tools os_mon runtime_tools crypto inets \ - xmerl webtool eunit syntax_tools compiler hipe mnesia public_key \ - observer wx gs -PLT = $(HOME)/.riak-test_dialyzer_plt - all: deps compile ./rebar skip_deps=true escriptize SMOKE_TEST=1 ./rebar skip_deps=true escriptize @@ -12,12 +7,6 @@ all: deps compile deps: ./rebar get-deps -docs: - ./rebar skip_deps=true doc - -docsclean: - @rm -rf doc/*.png doc/*.html doc/*.css edoc-info - compile: deps ./rebar compile @@ -31,30 +20,8 @@ quickbuild: ./rebar skip_deps=true compile ./rebar escriptize -################## -# Dialyzer targets -################## - -# public targets -dialyzer: compile $(PLT) - dialyzer -Wno_return -Wunderspecs -Wunmatched_returns --plt $(PLT) ebin deps/*/ebin | \ - egrep -v -f ./dialyzer.ignore-warnings - -clean_plt: - @echo - @echo "Are you sure? It takes about 1/2 hour to re-build." - @echo Deleting $(PLT) in 5 seconds. - @echo - sleep 5 - rm $(PLT) - -# internal targets -# build plt file. assumes 'compile' was already run, e.g. from 'dialyzer' target -$(PLT): - @echo - @echo "Building dialyzer's plt file. This can take 1/2 hour." - @echo " Because it wasn't here:" $(PLT) - @echo " Consider using R15B03 or later for 100x faster build time!" - @echo - @sleep 1 - dialyzer --build_plt --output_plt $(PLT) --apps $(APPS) +DIALYZER_APPS = kernel stdlib sasl erts ssl tools os_mon runtime_tools crypto inets \ + xmerl webtool eunit syntax_tools compiler hipe mnesia public_key \ + observer wx gs + +include tools.mk diff --git a/bin/rtdev-current.sh b/bin/rtdev-current.sh index aba1721a8..56841aa66 100755 --- a/bin/rtdev-current.sh +++ b/bin/rtdev-current.sh @@ -1,32 +1,33 @@ #!/usr/bin/env bash -# bail out if things go south +# just bail out if things go south set -e : ${RT_DEST_DIR:="$HOME/rt/riak"} -echo "Making $(pwd) the current release:" +echo "Making $(pwd) a tagged release:" cwd=$(pwd) echo -n " - Determining version: " if [ -f $cwd/dependency_manifest.git ]; then VERSION=`cat $cwd/dependency_manifest.git | awk '/^-/ { print $NF }'` else - VERSION="$(git describe --tags)-$(git branch | awk '/\*/ {print $2}')" + VERSION=`git describe --tags | awk '{sub(/riak-/,"",$0);print}'` fi echo $VERSION cd $RT_DEST_DIR echo " - Resetting existing $RT_DEST_DIR" -git reset HEAD --hard > /dev/null -git clean -fd > /dev/null -echo " - Removing and recreating $RT_DEST_DIR/current" -rm -rf $RT_DEST_DIR/current -mkdir $RT_DEST_DIR/current +git reset HEAD --hard > /dev/null 2>&1 +git clean -fd > /dev/null 2>&1 +echo " - Removing and recreating $RT_DEST_DIR/$VERSION" +rm -rf $RT_DEST_DIR/$VERSION +mkdir $RT_DEST_DIR/$VERSION cd $cwd -echo " - Copying devrel to $RT_DEST_DIR/current" -cp -p -P -R dev $RT_DEST_DIR/current -echo " - Writing $RT_DEST_DIR/current/VERSION" -echo -n $VERSION > $RT_DEST_DIR/current/VERSION +echo " - Copying devrel to $RT_DEST_DIR/$VERSION" +cd dev +for i in `ls`; do cp -p -P -R $i $RT_DEST_DIR/$VERSION/; done +echo " - Writing $RT_DEST_DIR/$VERSION/VERSION" +echo -n $VERSION > $RT_DEST_DIR/$VERSION/VERSION cd $RT_DEST_DIR echo " - Reinitializing git state" -git add . -git commit -a -m "riak_test init" --amend > /dev/null +git add -f . +git commit -a -m "riak_test init" --amend > /dev/null 2>&1 diff --git a/bin/rtdev-install.sh b/bin/rtdev-install.sh new file mode 100755 index 000000000..5b34a65f7 --- /dev/null +++ b/bin/rtdev-install.sh @@ -0,0 +1,56 @@ +#!/usr/bin/env bash + +# just bail out if things go south +set -e + +: ${RT_DEST_DIR:="$HOME/rt/riak"} + +cwd=$(pwd) +echo -n " - Determining version: " +if [ -z "${VERSION+xxx}" ] || ([ -z "$VERSION" ] && [ "${VERSION+xxx}" = "xxx" ]); then + if [ -f $cwd/dependency_manifest.git ]; then + VERSION=`cat $cwd/dependency_manifest.git | awk '/^-/ { print $NF }'` + else + echo "Making $(pwd) a tagged release:" + VERSION=`git describe --tags | awk '{sub(/riak-/,"",$0);print}'` + fi +fi +echo $VERSION +if [ ! -d $RT_DEST_DIR ]; then + mkdir $RT_DEST_DIR +fi +cd $RT_DEST_DIR +if [ -d ".git" ]; then + echo " - Resetting existing $RT_DEST_DIR" + git reset HEAD --hard > /dev/null 2>&1 + git clean -fd > /dev/null 2>&1 +fi +echo " - Removing and recreating $RT_DEST_DIR/$VERSION" +rm -rf $RT_DEST_DIR/$VERSION +mkdir $RT_DEST_DIR/$VERSION +cd $cwd +echo " - Copying devrel to $RT_DEST_DIR/$VERSION" +if [ ! -d "dev" ]; then + echo "You need to run \"make devrel\" or \"make stagedevrel\" first" + exit 1 +fi +cd dev +for i in `ls`; do cp -p -P -R $i $RT_DEST_DIR/$VERSION/; done +echo " - Writing $RT_DEST_DIR/$VERSION/VERSION" +echo -n $VERSION > $RT_DEST_DIR/$VERSION/VERSION +cd $RT_DEST_DIR +if [ -d ".git" ]; then + echo " - Reinitializing git state" + git add -f . + git commit -a -m "riak_test init" --amend > /dev/null 2>&1 +else + git init + + ## Some versions of git and/or OS require these fields + git config user.name "Riak Test" + git config user.email "dev@basho.com" + + git add . + git commit -a -m "riak_test init" > /dev/null + echo " - Successfully completed initial git commit of $RT_DEST_DIR" +fi diff --git a/bin/rtdev-setup-releases.sh b/bin/rtdev-setup-releases.sh index a692e5a21..fef0629c4 100755 --- a/bin/rtdev-setup-releases.sh +++ b/bin/rtdev-setup-releases.sh @@ -16,10 +16,10 @@ echo " - Creating $RT_DEST_DIR" rm -rf $RT_DEST_DIR mkdir -p $RT_DEST_DIR -count=$(ls */dev 2> /dev/null | wc -l) +count=$(ls * 2> /dev/null | wc -l) if [ "$count" -ne "0" ] then - for rel in */dev; do + for rel in *; do vsn=$(dirname "$rel") echo " - Initializing $RT_DEST_DIR/$vsn" mkdir -p "$RT_DEST_DIR/$vsn" @@ -34,7 +34,7 @@ else fi cd $RT_DEST_DIR -git init +git init ## Some versions of git and/or OS require these fields git config user.name "Riak Test" diff --git a/rebar b/rebar index f38f1451aea54c6809ab0eebbc75fa7398433432..a8cbf1b7c5c7e292a8fd0873e985df481be50fde 100755 GIT binary patch delta 141754 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�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 diff --git a/rebar.config b/rebar.config index 5a62510c3..c11791b4d 100644 --- a/rebar.config +++ b/rebar.config @@ -16,7 +16,8 @@ {riakc, ".*", {git, "git://github.com/basho/riak-erlang-client", {branch, "master"}}}, {riakhttpc, ".*", {git, "git://github.com/basho/riak-erlang-http-client", {branch, "master"}}}, {kvc, "1.3.0", {git, "https://github.com/etrepum/kvc", {tag, "v1.3.0"}}}, - {druuid, ".*", {git, "git://github.com/kellymclaughlin/druuid.git", {tag, "0.2"}}} + {druuid, ".*", {git, "git://github.com/kellymclaughlin/druuid.git", {tag, "0.2"}}}, + {riak_cli, ".*", {git, "git@github.com:basho/riak_cli", {branch, "master"}}} ]}. {escript_incl_apps, [goldrush, lager, getopt, riakhttpc, riakc, ibrowse, mochiweb, kvc]}. diff --git a/src/node_manager.erl b/src/node_manager.erl new file mode 100644 index 000000000..fa150d610 --- /dev/null +++ b/src/node_manager.erl @@ -0,0 +1,230 @@ +-module(node_manager). + +-behavior(gen_server). + +%% API +-export([start_link/3, + reserve_nodes/3, + deploy_nodes/5, + upgrade_nodes/5, + return_nodes/1, + status/0, + stop/0]). + +%% gen_server callbacks +-export([init/1, + handle_call/3, + handle_cast/2, + handle_info/2, + terminate/2, + code_change/3]). + +-record(state, {nodes :: [string()], + node_map :: [{string(), node()}], + nodes_available :: [string()], + nodes_deployed=[] :: [string()], + deployed_versions=[] :: [{string(), string()}], + version_map :: [{string(), [string()]}]}). + +%%%=================================================================== +%%% API +%%%=================================================================== + +start_link(Nodes, NodeMap, VersionMap) -> + Args = [Nodes, NodeMap, VersionMap], + gen_server:start_link({local, ?MODULE}, ?MODULE, Args, []). + +-spec reserve_nodes(pos_integer(), [string()], function()) -> ok. +reserve_nodes(NodeCount, Versions, NotifyFun) -> + gen_server:cast(?MODULE, {reserve_nodes, NodeCount, Versions, NotifyFun}). + +-spec deploy_nodes([string()], string(), term(), list(atom()), function()) -> ok. +deploy_nodes(Nodes, Version, Config, Services, NotifyFun) -> + gen_server:cast(?MODULE, {deploy_nodes, Nodes, Version, Config, Services, NotifyFun}). + +-spec upgrade_nodes([string()], string(), string(), term(), function()) -> ok. +upgrade_nodes(Nodes, CurrentVersion, NewVersion, Config, NotifyFun) -> + gen_server:cast(?MODULE, {deploy_nodes, Nodes, CurrentVersion, NewVersion, Config, NotifyFun}). + +-spec return_nodes([string()]) -> ok. +return_nodes(Nodes) -> + gen_server:cast(?MODULE, {return_nodes, Nodes}). + +-spec status() -> [{atom(), list()}]. +status() -> + gen_server:call(?MODULE, status, infinity). + +-spec stop() -> ok. +stop() -> + gen_server:call(?MODULE, stop, infinity). + +%%%=================================================================== +%%% gen_server callbacks +%%%=================================================================== + +init([Nodes, NodeMap, VersionMap]) -> + SortedNodes = lists:sort(Nodes), + {ok, #state{nodes=SortedNodes, + node_map=NodeMap, + nodes_available=SortedNodes, + version_map=VersionMap}}. + +handle_call(status, _From, State) -> + Status = [{nodes, State#state.nodes}, + {nodes_available, State#state.nodes_available}, + {version_map, State#state.version_map}], + {reply, Status, State}; +handle_call(stop, _From, State) -> + {stop, normal, ok, State}. + +handle_cast({reserve_nodes, Count, Versions, NotifyFun}, State) -> + {Result, UpdState} = + reserve(Count, Versions, State), + NotifyFun({nodes, Result, State#state.node_map}), + {noreply, UpdState}; +handle_cast({deploy_nodes, Nodes, Version, Config, Services, NotifyFun}, State) -> + Result = deploy(Nodes, State#state.node_map, Version, Config, Services), + DeployedVersions = State#state.deployed_versions, + UpdDeployedVersions = update_deployed_versions(deploy, Nodes, Version, DeployedVersions), + NotifyFun({nodes_deployed, Result}), + {noreply, State#state{deployed_versions=UpdDeployedVersions}}; +handle_cast({upgrade_nodes, Nodes, CurrentVersion, NewVersion, Config, NotifyFun}, State) -> + Result = upgrade(Nodes, CurrentVersion, NewVersion, Config), + DeployedVersions = State#state.deployed_versions, + UpdDeployedVersions = update_deployed_versions(upgrade, Nodes, NewVersion, DeployedVersions), + NotifyFun({nodes_upgraded, Result}), + {noreply, State#state{deployed_versions=UpdDeployedVersions}}; +handle_cast({return_nodes, Nodes}, State) -> + %% Stop nodes and clean data dirs so they are ready for next use. + NodesAvailable = State#state.nodes_available, + DeployedVersions = State#state.deployed_versions, + NodeMap = State#state.node_map, + stop_and_clean(Nodes, NodeMap, DeployedVersions, false), + NodesNowAvailable = lists:merge(lists:sort(Nodes), NodesAvailable), + + UpdDeployedVersions = update_deployed_versions(return, Nodes, undefined, DeployedVersions), + {noreply, State#state{nodes_available=NodesNowAvailable, + deployed_versions=UpdDeployedVersions}}; +handle_cast(_Msg, State) -> + {noreply, State}. + +handle_info(_Info, State) -> + {noreply, State}. + +terminate(_Reason, State) -> + %% Stop and reset all deployed nodes + stop_and_clean(State#state.nodes_deployed, + State#state.node_map, + State#state.deployed_versions, + true), + ok. + +code_change(_OldVsn, State, _Extra) -> + {ok, State}. + +%%%=================================================================== +%%% Internal functions +%%%=================================================================== + +stop_and_clean(NodeIds, NodeMap, DeployedVersions, Wait) -> + [begin + case version_deployed(NodeId, DeployedVersions) of + undefined -> + ok; + Version -> + rt_node:stop_and_wait(NodeId, + rt_node:node_name(NodeId, NodeMap), + Version), + wait_for_cleaner(rt_node:clean_data_dir(NodeId, Version), Wait) + end + end || NodeId <- NodeIds]. + +wait_for_cleaner(Pid, true) -> + WaitFun = + fun() -> + not is_process_alive(Pid) + end, + rt:wait_until(WaitFun); +wait_for_cleaner(_, false) -> + ok. + +reserve(Count, _Versions, State=#state{nodes_available=NodesAvailable}) + when Count > length(NodesAvailable) -> + {not_enough_nodes, State}; +reserve(Count, Versions, State=#state{nodes_available=NodesAvailable, + nodes_deployed=NodesDeployed, + version_map=VersionMap}) + when Count =:= length(NodesAvailable) -> + case versions_available(Count, Versions, VersionMap) of + true -> + UpdNodesDeployed = lists:sort(NodesDeployed ++ NodesAvailable), + {NodesAvailable, State#state{nodes_available=[], + nodes_deployed=UpdNodesDeployed}}; + false -> + {insufficient_versions_available, State} + end; +reserve(Count, Versions, State=#state{nodes_available=NodesAvailable, + nodes_deployed=NodesDeployed, + version_map=VersionMap}) -> + case versions_available(Count, Versions, VersionMap) of + true -> + {Reserved, UpdNodesAvailable} = lists:split(Count, NodesAvailable), + UpdNodesDeployed = lists:sort(NodesDeployed ++ Reserved), + UpdState = State#state{nodes_available=UpdNodesAvailable, + nodes_deployed=UpdNodesDeployed}, + {Reserved, UpdState}; + false -> + {insufficient_versions_available, State} + end. + +versions_available(Count, Versions, VersionMap) -> + lists:all(version_available_fun(Count, VersionMap), Versions). + +version_available_fun(Count, VersionMap) -> + fun(Version) -> + case lists:keyfind(Version, 1, VersionMap) of + {Version, VersionNodes} when length(VersionNodes) >= Count -> + true; + {Version, _} -> + false; + false -> + false + end + end. + +deploy(Nodes, NodeMap, Version, Config, Services) -> + rt_harness_util:deploy_nodes(Nodes, NodeMap, Version, Config, Services). + +upgrade(Nodes, CurrentVersion, NewVersion, Config) -> + [rt_node:upgrade(Node, CurrentVersion, NewVersion, Config) || + Node <- Nodes]. + +update_deployed_versions(deploy, Nodes, Version, DeployedVersions) -> + {_, UpdDeployedVersions} = lists:foldl(fun add_deployed_version/2, + {Version, DeployedVersions}, + Nodes), + UpdDeployedVersions; +update_deployed_versions(upgrade, Nodes, Version, DeployedVersions) -> + {_, UpdDeployedVersions} = lists:foldl(fun replace_deployed_version/2, + {Version, DeployedVersions}, + Nodes), + UpdDeployedVersions; +update_deployed_versions(return, Nodes, _, DeployedVersions) -> + lists:foldl(fun remove_deployed_version/2, DeployedVersions, Nodes). + +add_deployed_version(Node, {Version, DeployedVersions}) -> + {Version, [{Node, Version} | DeployedVersions]}. + +replace_deployed_version(Node, {Version, DeployedVersions}) -> + {Version, lists:keyreplace(Node, 1, DeployedVersions, {Node, Version})}. + +remove_deployed_version(Node, DeployedVersions) -> + lists:keydelete(Node, 1, DeployedVersions). + +version_deployed(Node, DeployedVersions) -> + case lists:keyfind(Node, 1, DeployedVersions) of + {Node, Version} -> + Version; + false -> + undefined + end. diff --git a/src/riak_test_escript.erl b/src/riak_test_escript.erl index f48ab8acf..09a355201 100644 --- a/src/riak_test_escript.erl +++ b/src/riak_test_escript.erl @@ -21,51 +21,100 @@ %% @private -module(riak_test_escript). -include("rt.hrl"). +%% TODO: Temporary build workaround, remove!! +-compile(export_all). -export([main/1]). -export([add_deps/1]). +-define(HEADER, [<<"Test">>, <<"Result">>, <<"Reason">>, <<"Test Duration">>]). + main(Args) -> - case prepare(Args) of - ok -> - ok; - {ParsedArgs, HarnessArgs, Tests} -> - OutDir = proplists:get_value(outdir, ParsedArgs), - Results = execute(Tests, OutDir, report(ParsedArgs), HarnessArgs), - finalize(Results, ParsedArgs) - end. + {ParsedArgs, HarnessArgs, Tests, _} = prepare(Args), + Results = execute(Tests, ParsedArgs, HarnessArgs), + finalize(Results, ParsedArgs). prepare(Args) -> - case parse_args(Args) of - {ParsedArgs, _, Tests} = ParseResults -> - io:format("Tests to run: ~p~n", [Tests]), - ok = erlang_setup(ParsedArgs), - ok = test_setup(ParsedArgs), - ParseResults; - ok -> - io:format("No tests to run.~n"), - ok - end. + {ParsedArgs, _, Tests, NonTests} = ParseResults = parse_args(Args), + io:format("Tests to run: ~p~n", [Tests]), + case NonTests of + [] -> + ok; + _ -> + io:format("These modules are not runnable tests: ~p~n", + [[NTMod || {NTMod, _} <- NonTests]]) + end, + ok = erlang_setup(ParsedArgs), + ok = test_setup(ParsedArgs), + ParseResults. -execute(Tests, Outdir, Report, HarnessArgs) -> - TestCount = length(Tests), - TestResults = [run_test(Test, - Outdir, - TestMetaData, - Report, - HarnessArgs, - TestCount) || - {Test, TestMetaData} <- Tests], - lists:filter(fun results_filter/1, TestResults). +execute(Tests, ParsedArgs, _HarnessArgs) -> + OutDir = proplists:get_value(outdir, ParsedArgs), + Report = report(ParsedArgs), + UpgradeList = upgrade_list( + proplists:get_value(upgrade_path, ParsedArgs)), + Backend = proplists:get_value(backend, ParsedArgs, bitcask), + + {ok, Executor} = riak_test_executor:start_link(Tests, + Backend, + OutDir, + Report, + UpgradeList, + self()), + wait_for_results(Executor, [], length(Tests), 0). + + +report_results(Results, Verbose) -> + %% TODO: Good place to also do giddyup reporting and provide a + %% place for extending to any other reporting sources that might + %% be useful. + print_summary(Results, undefined, Verbose), + ok. + + %% TestResults = run_tests(Tests, Outdir, Report, HarnessArgs), + %% lists:filter(fun results_filter/1, TestResults). + +%% run_test(Test, Outdir, TestMetaData, Report, HarnessArgs, NumTests) -> +%% rt_cover:maybe_start(Test), +%% SingleTestResult = riak_test_runner:run(Test, Outdir, TestMetaData, HarnessArgs), + + %% case NumTests of + %% 1 -> keep_them_up; + %% _ -> rt_cluster:teardown() + %% end, + +%% TODO: Do this in the test runner +%% CoverDir = rt_config:get(cover_output, "coverage"), +%% CoverFile = rt_cover:maybe_export_coverage(Test, CoverDir, erlang:phash2(TestMetaData)), +%% publish_report(SingleTestResult, CoverFile, Report), + +%% [{coverdata, CoverFile} | SingleTestResult]. + +%% TODO: Use `TestCount' and `Completed' to display progress output +wait_for_results(Executor, TestResults, TestCount, Completed) -> + receive + {Executor, {test_result, Result}} -> + wait_for_results(Executor, [Result | TestResults], TestCount, Completed+1); + {Executor, done} -> + rt_cover:stop(), + TestResults; + _ -> + wait_for_results(Executor, TestResults, TestCount, Completed) + end. finalize(TestResults, Args) -> - [rt_cover:maybe_import_coverage(proplists:get_value(coverdata, R)) || - R <- TestResults], - CoverDir = rt_config:get(cover_output, "coverage"), - Coverage = rt_cover:maybe_write_coverage(all, CoverDir), + %% TODO: Fixup coverage reporting + %% [rt_cover:maybe_import_coverage(proplists:get_value(coverdata, R)) || + %% R <- TestResults], + %% CoverDir = rt_config:get(cover_output, "coverage"), + %% Coverage = rt_cover:maybe_write_coverage(all, CoverDir), + node_manager:stop(), Verbose = proplists:is_defined(verbose, Args), - Teardown = not proplists:get_value(keep, Args, false), - maybe_teardown(Teardown, TestResults, Coverage, Verbose), + report_results(TestResults, Verbose), + + + %% Teardown = not proplists:get_value(keep, Args, false), + %% maybe_teardown(Teardown, TestResults, Coverage, Verbose), ok. %% Option Name, Short Code, Long Code, Argument Spec, Help Message @@ -81,7 +130,7 @@ cli_options() -> {verbose, $v, "verbose", undefined, "verbose output"}, {outdir, $o, "outdir", string, "output directory"}, {backend, $b, "backend", atom, "backend to test [memory | bitcask | eleveldb]"}, - {upgrade_version, $u, "upgrade", atom, "which version to upgrade from [ previous | legacy ]"}, + {upgrade_path, $u, "upgrade-path", atom, "comma-separated list representing an upgrade path (e.g. 1.2.1,1.3.4,1.4.10,2.0.0)"}, {keep, undefined, "keep", boolean, "do not teardown cluster"}, {report, $r, "report", string, "you're reporting an official test run, provide platform info (e.g. ubuntu-1204-64)\nUse 'config' if you want to pull from ~/.riak_test.config"}, {file, $F, "file", string, "use the specified file instead of ~/.riak_test.config"} @@ -98,11 +147,17 @@ add_deps(Path) -> test_setup(ParsedArgs) -> %% File output - OutDir = proplists:get_value(outdir, ParsedArgs), + OutDir = proplists:get_value(outdir, ParsedArgs, "log"), ensure_dir(OutDir), lager_setup(OutDir), + %% Prepare the test harness + {NodeIds, NodeMap, VersionMap} = rt_harness:setup(), + + %% Start the node manager + _ = node_manager:start_link(NodeIds, NodeMap, VersionMap), + %% Ensure existence of scratch_dir case ensure_dir(rt_config:get(rt_scratch_dir) ++ "/test.file") of ok -> @@ -113,6 +168,12 @@ test_setup(ParsedArgs) -> end, ok. +-spec upgrade_list(undefined | string()) -> undefined | [string()]. +upgrade_list(undefined) -> + undefined; +upgrade_list(Path) -> + string:tokens(Path, ","). + report(ParsedArgs) -> case proplists:get_value(report, ParsedArgs, undefined) of undefined -> @@ -129,8 +190,8 @@ parse_args(Args) -> help_or_parse_args({ok, {[], _}}) -> print_help(); help_or_parse_args({ok, {ParsedArgs, HarnessArgs}}) -> - help_or_parse_tests(ParsedArgs, - HarnessArgs, + help_or_parse_tests(ParsedArgs, + HarnessArgs, lists:member(help, ParsedArgs), args_invalid(ParsedArgs)); help_or_parse_args(_) -> @@ -145,24 +206,22 @@ help_or_parse_tests(ParsedArgs, HarnessArgs, false, false) -> %% test metadata load_initial_config(ParsedArgs), - Groups = proplists:get_all_values(groups, ParsedArgs), - TestData = load_tests(Groups, ParsedArgs), - - Tests = which_tests_to_run(report(ParsedArgs), TestData), + TestData = compose_test_data(ParsedArgs), + {Tests, NonTests} = which_tests_to_run(report(ParsedArgs), TestData), Offset = rt_config:get(offset, undefined), Workers = rt_config:get(workers, undefined), - shuffle_tests(ParsedArgs, HarnessArgs, Tests, Offset, Workers). + shuffle_tests(ParsedArgs, HarnessArgs, Tests, NonTests, Offset, Workers). args_invalid(ParsedArgs) -> - case { proplists:is_defined(groups, ParsedArgs), + case { proplists:is_defined(groups, ParsedArgs), proplists:is_defined(tests, ParsedArgs) } of {true, true} -> io:format("--groups and --tests are currently mutually exclusive.~n~n"), - true; - {_, _} -> + true; + {_, _} -> false end. - + load_initial_config(ParsedArgs) -> %% Loads application defaults application:load(riak_test), @@ -171,14 +230,14 @@ load_initial_config(ParsedArgs) -> rt_config:load(proplists:get_value(config, ParsedArgs), proplists:get_value(file, ParsedArgs)). -shuffle_tests(_, _, [], _, _) -> - lager:warning("No tests are scheduled to run"), - init:stop(1); -shuffle_tests(ParsedArgs, HarnessArgs, Tests, undefined, _) -> - {ParsedArgs, HarnessArgs, Tests}; -shuffle_tests(ParsedArgs, HarnessArgs, Tests, _, undefined) -> - {ParsedArgs, HarnessArgs, Tests}; -shuffle_tests(ParsedArgs, HarnessArgs, Tests, Offset, Workers) -> +shuffle_tests(_, _, [], _, _, _) -> + io:format("No tests are scheduled to run~n"), + halt(1); +shuffle_tests(ParsedArgs, HarnessArgs, Tests, NonTests, undefined, _) -> + {ParsedArgs, HarnessArgs, Tests, NonTests}; +shuffle_tests(ParsedArgs, HarnessArgs, Tests, NonTests, _, undefined) -> + {ParsedArgs, HarnessArgs, Tests, NonTests}; +shuffle_tests(ParsedArgs, HarnessArgs, Tests, NonTests, Offset, Workers) -> TestCount = length(Tests), %% Avoid dividing by zero, computers hate that Denominator = case Workers rem (TestCount+1) of @@ -189,7 +248,7 @@ shuffle_tests(ParsedArgs, HarnessArgs, Tests, Offset, Workers) -> {TestA, TestB} = lists:split(ActualOffset, Tests), lager:info("Offsetting ~b tests by ~b (~b workers, ~b offset)", [TestCount, ActualOffset, Workers, Offset]), - {ParsedArgs, HarnessArgs, TestB ++ TestA}. + {ParsedArgs, HarnessArgs, TestB ++ TestA, NonTests}. erlang_setup(_ParsedArgs) -> register(riak_test, self()), @@ -229,39 +288,38 @@ ensure_dir(undefined) -> ensure_dir(Dir) -> filelib:ensure_dir(Dir). -lager_setup(undefined) -> - set_lager_env(rt_config:get(lager_level, info)), - lager:start(); -lager_setup(_) -> - set_lager_env(notice), +lager_setup(OutputDir) -> + set_lager_env(OutputDir, + rt_config:get(lager_console_level, notice), + rt_config:get(lager_file_level, info)), lager:start(). -set_lager_env(LagerLevel) -> +set_lager_env(OutputDir, ConsoleLevel, FileLevel) -> application:load(lager), - HandlerConfig = [{lager_console_backend, LagerLevel}, - {lager_file_backend, [{file, "log/test.log"}, - {level, LagerLevel}]}], + HandlerConfig = [{lager_console_backend, ConsoleLevel}, + {lager_file_backend, [{file, filename:join(OutputDir, "test.log")}, + {level, FileLevel}]}], application:set_env(lager, handlers, HandlerConfig). -maybe_teardown(false, TestResults, Coverage, Verbose) -> - print_summary(TestResults, Coverage, Verbose), - lager:info("Keeping cluster running as requested"); -maybe_teardown(true, TestResults, Coverage, Verbose) -> - case {length(TestResults), proplists:get_value(status, hd(TestResults))} of - {1, fail} -> - print_summary(TestResults, Coverage, Verbose), - so_kill_riak_maybe(); - _ -> - lager:info("Multiple tests run or no failure"), - rt_cluster:teardown(), - print_summary(TestResults, Coverage, Verbose) - end, - ok. +%% maybe_teardown(false, TestResults, Coverage, Verbose) -> +%% print_summary(TestResults, Coverage, Verbose), +%% lager:info("Keeping cluster running as requested"); +%% maybe_teardown(true, TestResults, Coverage, Verbose) -> +%% case {length(TestResults), proplists:get_value(status, hd(TestResults))} of +%% {1, fail} -> +%% print_summary(TestResults, Coverage, Verbose), +%% so_kill_riak_maybe(); +%% _ -> +%% lager:info("Multiple tests run or no failure"), +%% rt_cluster:teardown(), +%% print_summary(TestResults, Coverage, Verbose) +%% end, +%% ok. load_tests([], ParsedArgs) -> RawTestList = proplists:get_all_values(tests, ParsedArgs), - TestList = lists:foldl(fun(X, Acc) -> - string:tokens(X, ", ") ++ Acc + TestList = lists:foldl(fun(X, Acc) -> + string:tokens(X, ", ") ++ Acc end, [], RawTestList), %% Parse Command Line Tests {CodePaths, SpecificTests} = @@ -275,90 +333,25 @@ load_tests([], ParsedArgs) -> Dirs = proplists:get_all_values(dir, ParsedArgs), SkipTests = string:tokens(proplists:get_value(skip, ParsedArgs, []), [$,]), DirTests = lists:append([load_tests_in_dir(Dir, SkipTests) || Dir <- Dirs]), - compose_test_data(DirTests, SpecificTests, ParsedArgs); -load_tests(RawGroupList, ParsedArgs) -> - Groups = lists:foldl(fun(X, Acc) -> - string:tokens(X, ", ") ++ Acc - end, [], RawGroupList), - Dirs = proplists:get_value(dir, ParsedArgs, ["./ebin"]), - AllDirTests = lists:append([load_tests_in_dir(Dir, []) || Dir <- Dirs]), - DirTests = get_group_tests(AllDirTests, Groups), - compose_test_data(DirTests, [], ParsedArgs). - -get_group_tests(Tests, Groups) -> - lists:filter(fun(Test) -> - Mod = list_to_atom(Test), - Attrs = Mod:module_info(attributes), - match_group_attributes(Attrs, Groups) - end, Tests). - -match_group_attributes(Attributes, Groups) -> - case proplists:get_value(test_type, Attributes) of - undefined -> - false; - TestTypes -> - lists:member(true, - [ TestType == list_to_atom(Group) - || Group <- Groups, TestType <- TestTypes ]) - end. + %% Project = list_to_binary(rt_config:get(rt_project, "undefined")), -compose_test_data(DirTests, SpecificTests, ParsedArgs) -> - Project = list_to_binary(rt_config:get(rt_project, "undefined")), - Backends = case proplists:get_all_values(backend, ParsedArgs) of - [] -> [undefined]; - Other -> Other - end, - Upgrades = case proplists:get_all_values(upgrade_version, ParsedArgs) of - [] -> [undefined]; - UpgradeList -> UpgradeList - end, - TestFoldFun = test_data_fun(rt:get_version(), Project, Backends, Upgrades), - lists:foldl(TestFoldFun, [], lists:usort(DirTests ++ SpecificTests)). - - -test_data_fun(Version, Project, Backends, Upgrades) -> - fun(Test, Tests) -> - [{list_to_atom(Test), - compose_test_datum(Version, Project, Backend, Upgrade)} - || Backend <- Backends, Upgrade <- Upgrades ] ++ Tests - end. - -compose_test_datum(Version, Project, undefined, undefined) -> - [{id, -1}, - {platform, <<"local">>}, - {version, Version}, - {project, Project}]; -compose_test_datum(Version, Project, undefined, Upgrade) -> - compose_test_datum(Version, Project, undefined, undefined) ++ - [{upgrade_version, Upgrade}]; -compose_test_datum(Version, Project, Backend, undefined) -> - compose_test_datum(Version, Project, undefined, undefined) ++ - [{backend, Backend}]; -compose_test_datum(Version, Project, Backend, Upgrade) -> - compose_test_datum(Version, Project, undefined, undefined) ++ - [{backend, Backend}, {upgrade_version, Upgrade}]. + %% Upgrades = proplists:get_value(upgrade_path, ParsedArgs), + %% TestFoldFun = test_data_fun(rt:get_version(), Project, Upgrades), + %% lists:foldl(TestFoldFun, [], lists:usort(DirTests ++ SpecificTests)). + lists:usort(DirTests ++ SpecificTests). extract_test_names(Test, {CodePaths, TestNames}) -> {[filename:dirname(Test) | CodePaths], - [filename:rootname(filename:basename(Test)) | TestNames]}. + [list_to_atom(filename:rootname(filename:basename(Test))) | TestNames]}. which_tests_to_run(undefined, CommandLineTests) -> - {Tests, NonTests} = - lists:partition(fun is_runnable_test/1, CommandLineTests), - lager:info("These modules are not runnable tests: ~p", - [[NTMod || {NTMod, _} <- NonTests]]), - Tests; + lists:partition(fun is_runnable_test/1, CommandLineTests); which_tests_to_run(Platform, []) -> giddyup:get_suite(Platform); which_tests_to_run(Platform, CommandLineTests) -> Suite = filter_zip_suite(Platform, CommandLineTests), - {Tests, NonTests} = - lists:partition(fun is_runnable_test/1, - lists:foldr(fun filter_merge_tests/2, [], Suite)), - - lager:info("These modules are not runnable tests: ~p", - [[NTMod || {NTMod, _} <- NonTests]]), - Tests. + lists:partition(fun is_runnable_test/1, + lists:foldr(fun filter_merge_tests/2, [], Suite)). filter_zip_suite(Platform, CommandLineTests) -> [ {SModule, SMeta, CMeta} || {SModule, SMeta} <- giddyup:get_suite(Platform), @@ -388,24 +381,29 @@ filter_merge_meta(SMeta, CMeta, [Field|Rest]) -> end. %% Check for api compatibility -is_runnable_test({TestModule, _}) -> +is_runnable_test(TestModule) -> {Mod, Fun} = riak_test_runner:function_name(confirm, TestModule), code:ensure_loaded(Mod), erlang:function_exported(Mod, Fun, 0) orelse erlang:function_exported(Mod, Fun, 2). -run_test(Test, Outdir, TestMetaData, Report, HarnessArgs, NumTests) -> - rt_cover:maybe_start(Test), - SingleTestResult = riak_test_runner:run(Test, Outdir, TestMetaData, HarnessArgs), - CoverDir = rt_config:get(cover_output, "coverage"), - case NumTests of - 1 -> keep_them_up; - _ -> rt_cluster:teardown() - end, - CoverFile = rt_cover:maybe_export_coverage(Test, CoverDir, erlang:phash2(TestMetaData)), - publish_report(SingleTestResult, CoverFile, Report), - rt_cover:stop(), - [{coverdata, CoverFile} | SingleTestResult]. +%% run_tests(Tests, Outdir, Report, HarnessArgs) -> + %% Need properties for tests prior to getting here Need server to + %% manage the aquisition of nodes and to handle comparison of test + %% `node_count' property with resources available. Also handle + %% notification of test completion. Hmm, maybe test execution + %% should be handled by a `gen_fsm' at this point to distinguish + %% the case when there are tests left to be tried with available + %% resources versus all have been tried or resources are + %% exhausted. + +%% [run_test(Test, +%% Outdir, +%% TestMetaData, +%% Report, +%% HarnessArgs, +%% TestCount) || +%% {Test, TestMetaData} <- Tests], publish_report(_SingleTestResult, _CoverFile, undefined) -> ok; @@ -451,44 +449,80 @@ parse_webhook(Props) -> undefined end. -print_summary(TestResults, CoverResult, Verbose) -> - io:format("~nTest Results:~n"), - - Results = [ - [ atom_to_list(proplists:get_value(test, SingleTestResult)) ++ "-" ++ - backend_list(proplists:get_value(backend, SingleTestResult)), - proplists:get_value(status, SingleTestResult), - proplists:get_value(reason, SingleTestResult)] - || SingleTestResult <- TestResults], - Width = test_name_width(Results), - - Print = fun(Test, Status, Reason) -> - case {Status, Verbose} of - {fail, true} -> io:format("~s: ~s ~p~n", [string:left(Test, Width), Status, Reason]); - _ -> io:format("~s: ~s~n", [string:left(Test, Width), Status]) - end +test_summary_fun({Test, pass, _}, {{Pass, _Fail, _Skipped}, Width}) -> + TestNameLength = length(atom_to_list(Test)), + UpdWidth = + case TestNameLength > Width of + true -> + TestNameLength; + false -> + Width + end, + {{Pass+1, _Fail, _Skipped}, UpdWidth}; +test_summary_fun({Test, {fail, _}, _}, {{_Pass, Fail, _Skipped}, Width}) -> + TestNameLength = length(atom_to_list(Test)), + UpdWidth = + case TestNameLength > Width of + true -> + TestNameLength; + false -> + Width + end, + {{_Pass, Fail+1, _Skipped}, UpdWidth}; +test_summary_fun({Test, {skipped, _}, _}, {{_Pass, _Fail, Skipped}, Width}) -> + TestNameLength = length(atom_to_list(Test)), + UpdWidth = + case TestNameLength > Width of + true -> + TestNameLength; + false -> + Width + end, + {{_Pass, _Fail, Skipped+1}, UpdWidth}. + +format_test_row({Test, Result, Duration}, _Width) -> + TestString = atom_to_list(Test), + case Result of + {Status, Reason} -> + [TestString, Status, Reason, Duration]; + pass -> + [TestString, "pass", "N/A", Duration] + end. + +print_summary(TestResults, _CoverResult, Verbose) -> + io:format("~nTest Results:~n~n"), + + {StatusCounts, Width} = lists:foldl(fun test_summary_fun/2, {{0,0,0}, 0}, TestResults), + + case Verbose of + true -> + Rows = + [format_test_row(Result, Width) || Result <- TestResults], + Table = riak_cli_table:autosize_create_table(?HEADER, Rows), + io:format("~ts~n", [Table]); + false -> + ok end, - [ Print(Test, Status, Reason) || [Test, Status, Reason] <- Results], - PassCount = length(lists:filter(fun(X) -> proplists:get_value(status, X) =:= pass end, TestResults)), - FailCount = length(lists:filter(fun(X) -> proplists:get_value(status, X) =:= fail end, TestResults)), + {PassCount, FailCount, SkippedCount} = StatusCounts, io:format("---------------------------------------------~n"), io:format("~w Tests Failed~n", [FailCount]), + io:format("~w Tests Skipped~n", [SkippedCount]), io:format("~w Tests Passed~n", [PassCount]), Percentage = case PassCount == 0 andalso FailCount == 0 of true -> 0; - false -> (PassCount / (PassCount + FailCount)) * 100 + false -> (PassCount / (PassCount + FailCount + SkippedCount)) * 100 end, io:format("That's ~w% for those keeping score~n", [Percentage]), - case CoverResult of - cover_disabled -> - ok; - {Coverage, AppCov} -> - io:format("Coverage : ~.1f%~n", [Coverage]), - [io:format(" ~s : ~.1f%~n", [App, Cov]) - || {App, Cov, _} <- AppCov] - end, + %% case CoverResult of + %% cover_disabled -> + %% ok; + %% {Coverage, AppCov} -> + %% io:format("Coverage : ~.1f%~n", [Coverage]), + %% [io:format(" ~s : ~.1f%~n", [App, Cov]) + %% || {App, Cov, _} <- AppCov] + %% end, ok. test_name_width(Results) -> @@ -504,14 +538,6 @@ backend_list(Backends) when is_list(Backends) -> end, lists:foldl(FoldFun, [], Backends). -results_filter(Result) -> - case proplists:get_value(status, Result) of - not_a_runnable_test -> - false; - _ -> - true - end. - load_tests_in_dir(Dir, SkipTests) -> case filelib:is_dir(Dir) of true -> @@ -549,4 +575,3 @@ so_kill_riak_maybe() -> io:format("Leaving Riak Up... "), rt:whats_up() end. - diff --git a/src/riak_test_executor.erl b/src/riak_test_executor.erl new file mode 100644 index 000000000..a185c2ce3 --- /dev/null +++ b/src/riak_test_executor.erl @@ -0,0 +1,273 @@ +-module(riak_test_executor). + +-behavior(gen_fsm). + +%% API +-export([start_link/6, + send_event/1, + stop/0]). + +%% gen_fsm callbacks +-export([init/1, + gather_properties/2, + gather_properties/3, + request_nodes/2, + request_nodes/3, + launch_test/2, + launch_test/3, + wait_for_completion/2, + wait_for_completion/3, + handle_event/3, + handle_sync_event/4, + handle_info/3, + terminate/3, + code_change/4]). + +-record(state, {pending_tests :: [atom()], + running_tests=[] :: [atom()], + waiting_tests=[] :: [atom()], + notify_pid :: pid(), + backend :: atom(), + upgrade_list :: [string()], + test_properties :: [proplists:proplist()], + runner_pids=[] :: [pid()], + log_dir :: string(), + report_info :: string()}). + +%%%=================================================================== +%%% API +%%%=================================================================== + +%% @doc Start the test executor +-spec start_link(atom(), atom(), string(), string(), [string()], pid()) -> {ok, pid()} | ignore | {error, term()}. +start_link(Tests, Backend, LogDir, ReportInfo, UpgradeList, NotifyPid) -> + Args = [Tests, Backend, LogDir, ReportInfo, UpgradeList, NotifyPid], + gen_fsm:start_link({local, ?MODULE}, ?MODULE, Args, []). + +send_event(Msg) -> + gen_fsm:send_event(?MODULE, Msg). + +%% @doc Stop the executor +-spec stop() -> ok | {error, term()}. +stop() -> + gen_fsm:sync_send_all_state_event(?MODULE, stop, infinity). + +%%%=================================================================== +%%% gen_fsm callbacks +%%%=================================================================== + +init([Tests, Backend, LogDir, ReportInfo, UpgradeList, NotifyPid]) -> + State = #state{pending_tests=Tests, + backend=Backend, + log_dir=LogDir, + report_info=ReportInfo, + upgrade_list=UpgradeList, + notify_pid=NotifyPid}, + {ok, gather_properties, State, 0}. + +%% @doc there are no all-state events for this fsm +handle_event(_Event, StateName, State) -> + {next_state, StateName, State}. + +%% @doc Handle synchronous events that should be handled +%% the same regardless of the current state. +-spec handle_sync_event(term(), term(), atom(), #state{}) -> + {reply, term(), atom(), #state{}}. +handle_sync_event(_Event, _From, _StateName, _State) -> + {reply, ok, ok, _State}. + +handle_info(_Info, StateName, State) -> + {next_state, StateName, State}. + +terminate(normal, _StateName, State) -> + report_done(State), + ok; +terminate(_Reason, _StateName, _State) -> + ok. + +%% @doc this fsm has no special upgrade process +code_change(_OldVsn, StateName, State, _Extra) -> + {ok, StateName, State}. + +%%% Asynchronous call handling functions for each FSM state + +%% TODO: Modify property gathering to account for `upgrade_path' +%% specified via the command line and replace accordingly in +%% properties record. +gather_properties(timeout, State) -> + OverrideProps = override_props(State), + Properties = test_properties(State#state.pending_tests, OverrideProps), + {next_state, request_nodes, State#state{test_properties=Properties}, 0}; +gather_properties(_Event, _State) -> + {next_state, gather_properties, _State}. + +request_nodes(timeout, State) -> + #state{pending_tests=[NextTest | _], + test_properties=PropertiesList} = State, + lager:notice("Starting next test: ~p", [NextTest]), + %% Find the properties for the next pending test + {NextTest, TestProps} = lists:keyfind(NextTest, 1, PropertiesList), + %% Send async request to node manager + VersionsToTest = versions_to_test(TestProps), + node_manager:reserve_nodes(rt_properties:get(node_count, TestProps), + VersionsToTest, + reservation_notify_fun()), + {next_state, launch_test, State}; +request_nodes({test_complete, Test, Pid, Results, Duration}, State) -> + #state{pending_tests=Pending, + waiting_tests=Waiting, + running_tests=Running, + runner_pids=Pids} = State, + %% Report results + report_results(Test, Results, Duration, State), + UpdState = State#state{running_tests=lists:delete(Test, Running), + runner_pids=lists:delete(Pid, Pids), + pending_tests=Pending++Waiting, + waiting_tests=[]}, + {next_state, request_nodes, UpdState}; +request_nodes(_Event, _State) -> + {next_state, request_nodes, _State}. + +launch_test(insufficient_versions_available, State) -> + #state{pending_tests=[HeadPending | RestPending]} = State, + report_results(HeadPending, {skipped, insufficient_versions}, 0, State), + UpdState = State#state{pending_tests=RestPending}, + launch_test_transition(UpdState); +launch_test(not_enough_nodes, State) -> + %% Move head of pending to waiting and try next test if there is + %% one left in pending. + #state{pending_tests=[HeadPending | RestPending], + waiting_tests=Waiting} = State, + UpdState = State#state{pending_tests=RestPending, + waiting_tests=[HeadPending | Waiting]}, + launch_test_transition(UpdState); +launch_test({nodes, Nodes, NodeMap}, State) -> + %% Spawn a test runner for the head of pending. If pending is now + %% empty transition to `wait_for_completion'; otherwise, + %% transition to `request_nodes'. + #state{pending_tests=[NextTest | RestPending], + backend=Backend, + test_properties=PropertiesList, + runner_pids=Pids, + running_tests=Running} = State, + {NextTest, TestProps} = lists:keyfind(NextTest, 1, PropertiesList), + UpdTestProps = rt_properties:set([{node_map, NodeMap}, {node_ids, Nodes}], + TestProps), + Pid = spawn_link(riak_test_runner, start, [NextTest, Backend, UpdTestProps]), + UpdState = State#state{pending_tests=RestPending, + runner_pids=[Pid | Pids], + running_tests=[NextTest | Running]}, + launch_test_transition(UpdState); +launch_test({test_complete, Test, Pid, Results, Duration}, State) -> + #state{pending_tests=Pending, + waiting_tests=Waiting, + running_tests=Running, + runner_pids=Pids} = State, + %% Report results + report_results(Test, Results, Duration, State), + UpdState = State#state{running_tests=lists:delete(Test, Running), + runner_pids=lists:delete(Pid, Pids), + pending_tests=Pending++Waiting, + waiting_tests=[]}, + {next_state, launch_test, UpdState}; +launch_test(_Event, _State) -> + ok. + +wait_for_completion({test_complete, Test, Pid, Results, Duration}, State) -> + #state{pending_tests=Pending, + waiting_tests=Waiting, + running_tests=Running, + runner_pids=Pids} = State, + %% Report results + report_results(Test, Results, Duration, State), + UpdState = State#state{running_tests=lists:delete(Test, Running), + runner_pids=lists:delete(Pid, Pids), + pending_tests=Pending++Waiting, + waiting_tests=[]}, + wait_for_completion_transition(UpdState); +wait_for_completion(_Event, _State) -> + ok. + +%% Synchronous call handling functions for each FSM state + +gather_properties(_Event, _From, _State) -> + ok. + +request_nodes(_Event, _From, _State) -> + ok. + +launch_test(_Event, _From, _State) -> + ok. + +wait_for_completion(_Event, _From, _State) -> + ok. + +%%%=================================================================== +%%% Internal functions +%%%=================================================================== + +report_results(Test, Results, Duration, #state{notify_pid=NotifyPid}) -> + NotifyPid ! {self(), {test_result, {Test, Results, Duration}}}, + ok. + +report_done(#state{notify_pid=NotifyPid}) -> + NotifyPid ! {self(), done}, + ok. + +wait_for_completion_transition(State=#state{pending_tests=[], + running_tests=[]}) -> + {stop, normal, State}; +wait_for_completion_transition(State=#state{pending_tests=[]}) -> + {next_state, wait_for_completion, State}; +wait_for_completion_transition(State) -> + {next_state, request_nodes, State, 0}. + +launch_test_transition(State=#state{pending_tests=[]}) -> + {next_state, wait_for_completion, State}; +launch_test_transition(State) -> + {next_state, request_nodes, State, 0}. + +reservation_notify_fun() -> + fun(X) -> + ?MODULE:send_event(X) + end. + +test_properties(Tests, OverriddenProps) -> + lists:foldl(test_property_fun(OverriddenProps), [], Tests). + +test_property_fun(OverrideProps) -> + fun(TestModule, Acc) -> + {PropsMod, PropsFun} = riak_test_runner:function_name(properties, + TestModule, + 0, + rt_cluster), + Properties = rt_properties:set(OverrideProps, PropsMod:PropsFun()), + [{TestModule, Properties} | Acc] + end. + +versions_to_test(Properties) -> + versions_to_test(Properties, rt_properties:get(rolling_upgrade, Properties)). + +%% An `upgrade_path' specified on the command line overrides the test +%% property setting. If the `rolling_upgrade' property is is `false' +%% then the `start_version' property of the test is the only version +%% tested. +versions_to_test(Properties, true) -> + case rt_properties:get(upgrade_path, Properties) of + undefined -> + [rt_properties:get(start_version, Properties)]; + UpgradePath -> + UpgradePath + end; +versions_to_test(Properties, false) -> + [rt_properties:get(start_version, Properties)]. + +%% Function to abstract away the details of what properties +%% can be overridden on the command line. +override_props(State) -> + case State#state.upgrade_list of + undefined -> + []; + UpgradeList -> + [{upgrade_path, UpgradeList}] + end. diff --git a/src/riak_test_runner.erl b/src/riak_test_runner.erl index cbc00c37b..22616d809 100644 --- a/src/riak_test_runner.erl +++ b/src/riak_test_runner.erl @@ -18,164 +18,319 @@ %% %% ------------------------------------------------------------------- -%% @doc riak_test_runner runs a riak_test module's run/0 function. +%% @doc riak_test_runner runs a riak_test module's `confirm/0' function. -module(riak_test_runner). -%% Need to export to use with `spawn_link'. --export([return_to_exit/3]). --export([run/4, metadata/0, metadata/1, function_name/2]). +-behavior(gen_fsm). + +%% API +-export([start/3, + send_event/2, + stop/0]). + +-export([function_name/2, + function_name/4]). + +%% gen_fsm callbacks +-export([init/1, + setup/2, + setup/3, + execute/2, + execute/3, + wait_for_completion/2, + wait_for_completion/3, + wait_for_upgrade/2, + wait_for_upgrade/3, + handle_event/3, + handle_sync_event/4, + handle_info/3, + terminate/3, + code_change/4]). + -include("rt.hrl"). -include_lib("eunit/include/eunit.hrl"). --spec(metadata() -> [{atom(), term()}]). -%% @doc fetches test metadata from spawned test process -metadata() -> - riak_test ! metadata, - receive - {metadata, TestMeta} -> TestMeta - end. +-record(state, {test_module :: atom(), + properties :: proplists:proplist(), + metadata :: term(), + backend :: atom(), + test_timeout :: integer(), + execution_pid :: pid(), + group_leader :: pid(), + start_time :: erlang:timestamp(), + end_time :: erlang:timestamp(), + setup_modfun :: {atom(), atom()}, + confirm_modfun :: {atom(), atom()}, + backend_check :: atom(), + prereq_check :: atom(), + current_version :: string(), + remaining_versions :: [string()], + test_results :: [term()]}). -metadata(Pid) -> - riak_test ! {metadata, Pid}, - receive - {metadata, TestMeta} -> TestMeta - end. +%%%=================================================================== +%%% API +%%%=================================================================== --spec(run(integer(), atom(), [{atom(), term()}], list()) -> [tuple()]). -%% @doc Runs a module's run/0 function after setting up a log -%% capturing backend for lager. It then cleans up that backend -%% and returns the logs as part of the return proplist. -run(TestModule, Outdir, TestMetaData, HarnessArgs) -> - start_lager_backend(TestModule, Outdir), - rt:setup_harness(TestModule, HarnessArgs), - BackendExtras = case proplists:get_value(multi_config, TestMetaData) of - undefined -> []; - Value -> [{multi_config, Value}] - end, - Backend = rt_backend:set_backend( - proplists:get_value(backend, TestMetaData), BackendExtras), - {PropsMod, PropsFun} = function_name(properties, TestModule, 0, rt_cluster), - {SetupMod, SetupFun} = function_name(setup, TestModule, 2, rt_cluster), - {ConfirmMod, ConfirmFun} = function_name(confirm, TestModule), - {Status, Reason} = case check_prereqs(ConfirmMod) of - true -> - lager:notice("Running Test ~s", [TestModule]), - execute(TestModule, - {PropsMod, PropsFun}, - {SetupMod, SetupFun}, - {ConfirmMod, ConfirmFun}, - TestMetaData); - not_present -> - {fail, test_does_not_exist}; - _ -> - {fail, all_prereqs_not_present} - end, +%% @doc Start the test executor +start(TestModule, Backend, Properties) -> + Args = [TestModule, Backend, Properties], + gen_fsm:start_link(?MODULE, Args, []). - lager:notice("~s Test Run Complete", [TestModule]), - {ok, Logs} = stop_lager_backend(), - Log = unicode:characters_to_binary(Logs), +send_event(Pid, Msg) -> + gen_fsm:send_event(Pid, Msg). - RetList = [{test, TestModule}, {status, Status}, {log, Log}, {backend, Backend} | proplists:delete(backend, TestMetaData)], - case Status of - fail -> RetList ++ [{reason, iolist_to_binary(io_lib:format("~p", [Reason]))}]; - _ -> RetList - end. +%% @doc Stop the executor +-spec stop() -> ok | {error, term()}. +stop() -> + gen_fsm:sync_send_all_state_event(?MODULE, stop, infinity). -start_lager_backend(TestModule, Outdir) -> - case Outdir of - undefined -> ok; - _ -> - gen_event:add_handler(lager_event, lager_file_backend, - {Outdir ++ "/" ++ atom_to_list(TestModule) ++ ".dat_test_output", - rt_config:get(lager_level, info), 10485760, "$D0", 1}), - lager:set_loglevel(lager_file_backend, rt_config:get(lager_level, info)) - end, - gen_event:add_handler(lager_event, riak_test_lager_backend, [rt_config:get(lager_level, info), false]), - lager:set_loglevel(riak_test_lager_backend, rt_config:get(lager_level, info)). - -stop_lager_backend() -> - gen_event:delete_handler(lager_event, lager_file_backend, []), - gen_event:delete_handler(lager_event, riak_test_lager_backend, []). - -%% does some group_leader swapping, in the style of EUnit. -execute(TestModule, PropsModFun, SetupModFun, ConfirmModFun, TestMetaData) -> - process_flag(trap_exit, true), - OldGroupLeader = group_leader(), +%%%=================================================================== +%%% gen_fsm callbacks +%%%=================================================================== + +%% @doc Read the storage schedule and go to idle. +%% compose_test_datum(Version, Project, undefined, undefined) -> +init([TestModule, Backend, Properties]) -> + lager:debug("Started riak_test_runnner with pid ~p", [self()]), + Project = list_to_binary(rt_config:get(rt_project, "undefined")), + MetaData = [{id, -1}, + {platform, <<"local">>}, + {version, rt:get_version()}, + {project, Project}], + TestTimeout = rt_config:get(test_timeout, rt_config:get(rt_max_wait_time)), + SetupModFun = function_name(setup, TestModule, 2, rt_cluster), + {ConfirmMod, _} = ConfirmModFun = function_name(confirm, TestModule), + BackendCheck = check_backend(Backend, + rt_properties:get(valid_backends, Properties)), + PreReqCheck = check_prereqs(ConfirmMod), + State = #state{test_module=TestModule, + properties=Properties, + metadata=MetaData, + backend=Backend, + test_timeout=TestTimeout, + setup_modfun=SetupModFun, + confirm_modfun=ConfirmModFun, + backend_check=BackendCheck, + prereq_check=PreReqCheck, + group_leader=group_leader()}, + {ok, setup, State, 0}. + +%% @doc there are no all-state events for this fsm +handle_event(_Event, StateName, State) -> + {next_state, StateName, State}. + +%% @doc Handle synchronous events that should be handled +%% the same regardless of the current state. +-spec handle_sync_event(term(), term(), atom(), #state{}) -> + {reply, term(), atom(), #state{}}. +handle_sync_event(_Event, _From, _StateName, _State) -> + {reply, ok, ok, _State}. + +handle_info(_Info, StateName, State) -> + {next_state, StateName, State}. + +terminate(_Reason, _StateName, _State) -> + ok. + +%% @doc this fsm has no special upgrade process +code_change(_OldVsn, StateName, State, _Extra) -> + {ok, StateName, State}. + +%% Asynchronous call handling functions for each FSM state + +setup(timeout, State=#state{backend_check=false}) -> + notify_executor({skipped, invalid_backend}, State), + cleanup(State), + {stop, normal, State}; +setup(timeout, State=#state{prereq_check=false}) -> + notify_executor({fail, prereq_check_failed}, State), + cleanup(State), + {stop, normal, State}; +setup(timeout, State=#state{backend=Backend, + properties=Properties}) -> NewGroupLeader = riak_test_group_leader:new_group_leader(self()), group_leader(NewGroupLeader, self()), {0, UName} = rt:cmd("uname -a"), - lager:info("Test Runner `uname -a` : ~s", [UName]), + lager:info("Test Runner: ~s", [UName]), - %% Pid = spawn_link(?MODULE, return_to_exit, [Mod, Fun, []]), - Pid = spawn_link(test_fun(PropsModFun, SetupModFun, ConfirmModFun, TestMetaData)), - Ref = case rt_config:get(test_timeout, undefined) of - Timeout when is_integer(Timeout) -> - erlang:send_after(Timeout, self(), test_took_too_long); - _ -> - undefined - end, + NodeIds = rt_properties:get(node_ids, Properties), + Services = rt_properties:get(required_services, Properties), + {StartVersion, OtherVersions} = test_versions(Properties), + Config = rt_backend:set(Backend, rt_properties:get(config, Properties)), + node_manager:deploy_nodes(NodeIds, + StartVersion, + Config, + Services, + notify_fun(self())), + lager:info("Waiting for deploy nodes response at ~p", [self()]), - {Status, Reason} = rec_loop(Pid, TestModule, TestMetaData), - case Ref of - undefined -> - ok; - _ -> - erlang:cancel_timer(Ref) - end, - riak_test_group_leader:tidy_up(OldGroupLeader), - case Status of - fail -> - ErrorHeader = "================ " ++ atom_to_list(TestModule) ++ " failure stack trace =====================", - ErrorFooter = [ $= || _X <- lists:seq(1,length(ErrorHeader))], - Error = io_lib:format("~n~s~n~p~n~s~n", [ErrorHeader, Reason, ErrorFooter]), - lager:error(Error); - _ -> meh - end, - {Status, Reason}. - --spec test_fun({atom(), atom()}, {atom(), atom()}, {atom(), atom()}, proplists:proplist()) -> function(). -test_fun({PropsMod, PropsFun}, {SetupMod, SetupFun}, ConfirmModFun, MetaData) -> - fun() -> - Properties = PropsMod:PropsFun(), - case SetupMod:SetupFun(Properties, MetaData) of - {ok, SetupData} -> - RollingUpgradeTest = rt_properties:get(rolling_upgrade, SetupData), - ConfirmFun = compose_confirm_fun(ConfirmModFun, - SetupData, - MetaData, - RollingUpgradeTest), - - ConfirmFun(); - _ -> - fail - end - end. + %% Set the initial value for `current_version' in the properties record + {ok, UpdProperties} = + rt_properties:set(current_version, StartVersion, Properties), -compose_confirm_fun({ConfirmMod, ConfirmFun}, SetupData, MetaData, true) -> - Nodes = rt_properties:get(nodes, SetupData), - WaitForTransfers = rt_properties:get(wait_for_transfers, SetupData), - UpgradeVersion = rt_properties:get(upgrade_version, SetupData), - fun() -> - InitialResult = ConfirmMod:ConfirmFun(SetupData, MetaData), - OtherResults = [begin - ensure_all_nodes_running(Nodes), - _ = rt_node:upgrade(Node, UpgradeVersion), - _ = rt_cluster:maybe_wait_for_transfers(Nodes, WaitForTransfers), - ConfirmMod:ConfirmFun(SetupData, MetaData) - end || Node <- Nodes], - lists:all(fun(R) -> R =:= pass end, [InitialResult | OtherResults]) - end; -compose_confirm_fun({ConfirmMod, ConfirmFun}, SetupData, MetaData, false) -> + UpdState = State#state{current_version=StartVersion, + remaining_versions=OtherVersions, + properties=UpdProperties}, + {next_state, execute, UpdState}; +setup(_Event, _State) -> + ok. + +execute({nodes_deployed, _}, State) -> + #state{test_module=TestModule, + properties=Properties, + setup_modfun={SetupMod, SetupFun}, + confirm_modfun=ConfirmModFun, + metadata=MetaData, + test_timeout=TestTimeout} = State, + lager:notice("Running ~s", [TestModule]), + + StartTime = os:timestamp(), + %% Perform test setup which includes clustering of the nodes if + %% required by the test properties. The cluster information is placed + %% into the properties record and returned by the `setup' function. + UpdState = + case SetupMod:SetupFun(Properties, MetaData) of + {ok, UpdProperties} -> + Pid = spawn_link(test_fun(UpdProperties, + ConfirmModFun, + MetaData, + self())), + State#state{execution_pid=Pid, + properties=UpdProperties, + start_time=StartTime}; + _ -> + ?MODULE:send_event(self(), test_result({fail, test_setup_failed})), + State#state{start_time=StartTime} + end, + {next_state, wait_for_completion, UpdState, TestTimeout}; +execute(_Event, _State) -> + {next_state, execute, _State}. + +wait_for_completion(timeout, State) -> + %% Test timed out + UpdState = State#state{end_time=os:timestamp()}, + notify_executor(timeout, UpdState), + cleanup(UpdState), + {stop, normal, UpdState}; +wait_for_completion({test_result, Result}, State=#state{remaining_versions=[]}) -> + %% TODO: Format results for aggregate test runs if needed. For + %% upgrade tests with failure return which versions had failure + %% along with reasons. + UpdState = State#state{end_time=os:timestamp()}, + notify_executor(Result, UpdState), + cleanup(UpdState), + {stop, normal, UpdState}; +wait_for_completion({test_result, Result}, State) -> + #state{backend=Backend, + test_results=TestResults, + current_version=CurrentVersion, + remaining_versions=[NextVersion | RestVersions], + properties=Properties} = State, + Config = rt_backend:set(Backend, rt_properties:get(config, Properties)), + NodeIds = rt_properties:get(node_ids, Properties), + node_manager:upgrade_nodes(NodeIds, + CurrentVersion, + NextVersion, + Config, + notify_fun(self())), + UpdState = State#state{test_results=[Result | TestResults], + current_version=NextVersion, + remaining_versions=RestVersions}, + {next_state, wait_for_upgrade, UpdState}; +wait_for_completion(_Msg, _State) -> + {next_state, wait_for_completion, _State}. + +wait_for_upgrade(nodes_upgraded, State) -> + #state{properties=Properties, + confirm_modfun=ConfirmModFun, + current_version=CurrentVersion, + metadata=MetaData, + test_timeout=TestTimeout} = State, + + %% Update the `current_version' in the properties record + {ok, UpdProperties} = + rt_properties:set(current_version, CurrentVersion, Properties), + + %% TODO: Maybe wait for transfers. Probably should be + %% a call to an exported function in `rt_cluster' + Pid = spawn_link(test_fun(UpdProperties, + ConfirmModFun, + MetaData, + self())), + UpdState = State#state{execution_pid=Pid, + properties=UpdProperties}, + {next_state, wait_for_completion, UpdState, TestTimeout}; +wait_for_upgrade(_Event, _State) -> + {next_state, wait_for_upgrade, _State}. + +%% Synchronous call handling functions for each FSM state + +setup(_Event, _From, _State) -> + ok. + +execute(_Event, _From, _State) -> + ok. + +wait_for_completion(_Event, _From, _State) -> + ok. + +wait_for_upgrade(_Event, _From, _State) -> + ok. + +%%%=================================================================== +%%% Internal functions +%%%=================================================================== + +-spec test_fun(rt_properties:properties(), {atom(), atom()}, proplists:proplist(), pid()) -> + function(). +test_fun(Properties, {ConfirmMod, ConfirmFun}, MetaData, NotifyPid) -> fun() -> - ConfirmMod:ConfirmFun(SetupData, MetaData) + %% Exceptions and their handling sucks, but eunit throws + %% errors `erlang:error' so here we are + try ConfirmMod:ConfirmFun(Properties, MetaData) of + TestResult -> + ?MODULE:send_event(NotifyPid, test_result(TestResult)) + catch + Error:Reason -> + lager:notice("Error: ~p Reason: ~p", [Error, Reason]), + TestResult = format_eunit_error(Reason), + ?MODULE:send_event(NotifyPid, test_result(TestResult)) + end end. -ensure_all_nodes_running(Nodes) -> - [begin - ok = rt_node:start_and_wait(Node), - ok = rt:wait_until_registered(Node, riak_core_ring_manager) - end || Node <- Nodes]. +format_eunit_error({assertion_failed, InfoList}) -> + LineNum = proplists:get_value(line, InfoList), + Expression = proplists:get_value(expression, InfoList), + Value = proplists:get_value(value, InfoList), + ErrorStr = io_lib:format("Assertion ~s is ~p at line ~B", + [Expression, Value, LineNum]), + {fail, ErrorStr}; +format_eunit_error({assertCmd_failed, InfoList}) -> + LineNum = proplists:get_value(line, InfoList), + Command = proplists:get_value(command, InfoList), + Status = proplists:get_value(status, InfoList), + ErrorStr = io_lib:format("Command \"~s\" returned a status of ~B at line ~B", + [Command, Status, LineNum]), + {fail, ErrorStr}; +format_eunit_error({assertMatch_failed, InfoList}) -> + LineNum = proplists:get_value(line, InfoList), + Pattern = proplists:get_value(pattern, InfoList), + Value = proplists:get_value(value, InfoList), + ErrorStr = io_lib:format("Pattern ~s did not match value ~p at line ~B", + [Pattern, Value, LineNum]), + {fail, ErrorStr}; +format_eunit_error({assertEqual_failed, InfoList}) -> + LineNum = proplists:get_value(line, InfoList), + Expression = proplists:get_value(expression, InfoList), + Expected = proplists:get_value(expected, InfoList), + Value = proplists:get_value(value, InfoList), + ErrorStr = io_lib:format("~s = ~p is not equal to expected value ~p at line ~B", + [Expression, Value, Expected, LineNum]), + {fail, ErrorStr}; +format_eunit_error(Other) -> + ErrorStr = io_lib:format("Unknown error encountered: ~p", [Other]), + {fail, ErrorStr}. function_name(confirm, TestModule) -> TMString = atom_to_list(TestModule), @@ -195,46 +350,96 @@ function_name(FunName, TestModule, Arity, Default) when is_atom(TestModule) -> {Default, FunName} end. -rec_loop(Pid, TestModule, TestMetaData) -> - receive - test_took_too_long -> - exit(Pid, kill), - {fail, test_timed_out}; - metadata -> - Pid ! {metadata, TestMetaData}, - rec_loop(Pid, TestModule, TestMetaData); - {metadata, P} -> - P ! {metadata, TestMetaData}, - rec_loop(Pid, TestModule, TestMetaData); - {'EXIT', Pid, normal} -> {pass, undefined}; - {'EXIT', Pid, Error} -> - lager:warning("~s failed: ~p", [TestModule, Error]), - {fail, Error} - end. +%% remove_lager_backend() -> +%% gen_event:delete_handler(lager_event, lager_file_backend, []), +%% gen_event:delete_handler(lager_event, riak_test_lager_backend, []). + %% A return of `fail' must be converted to a non normal exit since %% status is determined by `rec_loop'. %% %% @see rec_loop/3 --spec return_to_exit(module(), atom(), list()) -> ok. -return_to_exit(Mod, Fun, Args) -> - case apply(Mod, Fun, Args) of - pass -> - %% same as exit(normal) - ok; - fail -> - exit(fail) - end. +%% -spec return_to_exit(module(), atom(), list()) -> ok. +%% return_to_exit(Mod, Fun, Args) -> +%% case apply(Mod, Fun, Args) of +%% pass -> +%% %% same as exit(normal) +%% ok; +%% fail -> +%% exit(fail) +%% end. + +-spec check_backend(atom(), all | [atom()]) -> boolean(). +check_backend(_Backend, all) -> + true; +check_backend(Backend, ValidBackends) -> + lists:member(Backend, ValidBackends). +%% Check the prequisites for executing the test check_prereqs(Module) -> - try Module:module_info(attributes) of - Attrs -> - Prereqs = proplists:get_all_values(prereq, Attrs), - P2 = [ {Prereq, rt_local:which(Prereq)} || Prereq <- Prereqs], - lager:info("~s prereqs: ~p", [Module, P2]), - [ lager:warning("~s prereq '~s' not installed.", [Module, P]) || {P, false} <- P2], - lists:all(fun({_, Present}) -> Present end, P2) - catch - _DontCare:_Really -> - not_present + Attrs = Module:module_info(attributes), + Prereqs = proplists:get_all_values(prereq, Attrs), + P2 = [{Prereq, rt_local:which(Prereq)} || Prereq <- Prereqs], + lager:info("~s prereqs: ~p", [Module, P2]), + [lager:warning("~s prereq '~s' not installed.", + [Module, P]) || {P, false} <- P2], + lists:all(fun({_, Present}) -> Present end, P2). + +notify_fun(Pid) -> + fun(X) -> + ?MODULE:send_event(Pid, X) end. + +cleanup(#state{group_leader=OldGroupLeader, + properties=Properties}) -> + node_manager:return_nodes(rt_properties:get(node_ids, Properties)), + riak_test_group_leader:tidy_up(OldGroupLeader). + +notify_executor(timeout, #state{test_module=Test, + start_time=Start, + end_time=End}) -> + Duration = timer:now_diff(End, Start), + Notification = {test_complete, Test, self(), {fail, timeout}, Duration}, + riak_test_executor:send_event(Notification); +notify_executor(fail, #state{test_module=Test, + start_time=Start, + end_time=End}) -> + Duration = timer:now_diff(End, Start), + Notification = {test_complete, Test, self(), {fail, unknown}, Duration}, + riak_test_executor:send_event(Notification); +notify_executor(pass, #state{test_module=Test, + start_time=Start, + end_time=End}) -> + Duration = timer:now_diff(End, Start), + Notification = {test_complete, Test, self(), pass, Duration}, + riak_test_executor:send_event(Notification); +notify_executor(FailResult, #state{test_module=Test, + start_time=Start, + end_time=End}) -> + Duration = now_diff(End, Start), + Notification = {test_complete, Test, self(), FailResult, Duration}, + riak_test_executor:send_event(Notification). + +test_versions(Properties) -> + StartVersion = rt_properties:get(start_version, Properties), + UpgradePath = rt_properties:get(upgrade_path, Properties), + case UpgradePath of + undefined -> + {StartVersion, []}; + [] -> + {StartVersion, []}; + _ -> + [UpgradeHead | Rest] = UpgradePath, + {UpgradeHead, Rest} + end. + +now_diff(undefined, _) -> + 0; +now_diff(_, undefined) -> + 0; +now_diff(End, Start) -> + timer:now_diff(End, Start). + +%% Simple function to hide the details of the message wrapping +test_result(Result) -> + {test_result, Result}. diff --git a/src/rt.erl b/src/rt.erl index 8883ddd6c..7c599e47d 100644 --- a/src/rt.erl +++ b/src/rt.erl @@ -52,7 +52,7 @@ rpc_get_env/2, setup_harness/2, setup_log_capture/1, - stream_cmd/1, + stream_cmd/1, stream_cmd/2, spawn_cmd/1, spawn_cmd/2, diff --git a/src/rt_backend.erl b/src/rt_backend.erl index 3fe13e64d..496afd446 100644 --- a/src/rt_backend.erl +++ b/src/rt_backend.erl @@ -22,13 +22,58 @@ -include_lib("eunit/include/eunit.hrl"). -compile(export_all). - --define(HARNESS, (rt_config:get(rt_harness))). +-export([set/2]). %%%=================================================================== %%% Test harness setup, configuration, and internal utilities %%%=================================================================== +replace_backend(Backend, false) -> + [{storage_backend, Backend}]; +replace_backend(Backend, {riak_kv, KVSection}) -> + lists:keystore(storage_backend, 1, KVSection, {storage_backend, Backend}). + +%% TODO: Probably should abstract this into the rt_config module and +%% make a sensible API to hide the ugliness of dealing with the lists +%% module funs. +%% +%% TODO: Add support for Riak CS backend and arbitrary multi backend +%% configurations +set(eleveldb, Config) -> + UpdKVSection = replace_backend(riak_kv_eleveldb_backend, + lists:keyfind(riak_kv, 1, Config)), + lists:keystore(riak_kv, 1, Config, {riak_kv, UpdKVSection}); +set(memory, Config) -> + UpdKVSection = replace_backend(riak_kv_eleveldb_backend, + lists:keyfind(riak_kv, 1, Config)), + lists:keystore(riak_kv, 1, Config, {riak_kv, UpdKVSection}); +set(multi, Config) -> + UpdKVSection = + replace_backend(riak_kv_multi_backend, + lists:keyfind(riak_kv, 1, Config)) ++ + multi_backend_config(default), + lists:keystore(riak_kv, 1, Config, {riak_kv, UpdKVSection}); +set({multi, indexmix}, Config) -> + UpdKVSection = + replace_backend(riak_kv_multi_backend, + lists:keyfind(riak_kv, 1, Config)) ++ + multi_backend_config(indexmix), + lists:keystore(riak_kv, 1, Config, {riak_kv, UpdKVSection}); +set(_, Config) -> + UpdKVSection = replace_backend(riak_kv_bitcask_backend, + lists:keyfind(riak_kv, 1, Config)), + lists:keystore(riak_kv, 1, Config, {riak_kv, UpdKVSection}). + +multi_backend_config(default) -> + [{multi_backend_default, <<"eleveldb1">>}, + {multi_backend, [{<<"eleveldb1">>, riak_kv_eleveldb_backend, []}, + {<<"memory1">>, riak_kv_memory_backend, []}, + {<<"bitcask1">>, riak_kv_bitcask_backend, []}]}]; +multi_backend_config(indexmix) -> + [{multi_backend_default, <<"eleveldb1">>}, + {multi_backend, [{<<"eleveldb1">>, riak_kv_eleveldb_backend, []}, + {<<"memory1">>, riak_kv_memory_backend, []}]}]. + %% @doc Sets the backend of ALL nodes that could be available to riak_test. %% this is not limited to the nodes under test, but any node that %% riak_test is able to find. It then queries each available node diff --git a/src/rt_cluster.erl b/src/rt_cluster.erl index 79cf0e52a..1b7f237df 100644 --- a/src/rt_cluster.erl +++ b/src/rt_cluster.erl @@ -24,27 +24,18 @@ -export([properties/0, setup/2, augment_config/3, - deploy_nodes/1, - deploy_nodes/2, - deploy_clusters/1, - build_cluster/1, - build_cluster/2, - build_cluster/3, - build_clusters/1, clean_cluster/1, - join_cluster/1, + join_cluster/2, clean_data_dir/1, clean_data_dir/2, try_nodes_ready/3, versions/0, teardown/0]). --export([maybe_wait_for_transfers/2]). +-export([maybe_wait_for_transfers/3]). -include("rt.hrl"). --define(HARNESS, (rt_config:get(rt_harness))). - %% @doc Default properties used if a riak_test module does not specify %% a custom properties function. -spec properties() -> rt_properties:properties(). @@ -53,110 +44,110 @@ properties() -> -spec setup(rt_properties:properties(), proplists:proplist()) -> {ok, rt_properties:properties()} | {error, term()}. -setup(Properties, MetaData) -> - rt_config:set_conf(all, [{"buckets.default.allow_mult", "false"}]), - - RollingUpgrade = - proplists:get_value(rolling_upgrade, - MetaData, - rt_properties:get(rolling_upgrade, Properties)), - Version = rt_properties:get(start_version, Properties), - Config = rt_properties:get(config, Properties), - Versions = [{Version, Config} || - _ <- lists:seq(1, rt_properties:get(node_count, Properties))], - Nodes = deploy_or_build_cluster(Versions, - rt_properties:get(make_cluster, Properties)), - maybe_wait_for_transfers(Nodes, - rt_properties:get(wait_for_transfers, Properties)), - UpdPropertyList = [{nodes, Nodes}, {rolling_upgrade, RollingUpgrade}], - rt_properties:set(UpdPropertyList, Properties). - -deploy_or_build_cluster(Versions, true) -> - build_cluster(Versions); -deploy_or_build_cluster(Versions, false) -> - deploy_nodes(Versions). - -%% @doc Deploy a set of freshly installed Riak nodes, returning a list of the -%% nodes deployed. -%% @todo Re-add -spec after adding multi-version support -deploy_nodes(Versions) when is_list(Versions) -> - deploy_nodes(Versions, [riak_kv]); -deploy_nodes(NumNodes) when is_integer(NumNodes) -> - deploy_nodes([ current || _ <- lists:seq(1, NumNodes)]). - -%% @doc Deploy a set of freshly installed Riak nodes with the given -%% `InitialConfig', returning a list of the nodes deployed. --spec deploy_nodes(NumNodes :: integer(), any()) -> [node()]. -deploy_nodes(NumNodes, InitialConfig) when is_integer(NumNodes) -> - NodeConfig = [{current, InitialConfig} || _ <- lists:seq(1,NumNodes)], - deploy_nodes(NodeConfig); -deploy_nodes(Versions, Services) -> - NodeConfig = [ rt_config:version_to_config(Version) || Version <- Versions ], - Nodes = rt_harness:deploy_nodes(NodeConfig), - lager:info("Waiting for services ~p to start on ~p.", [Services, Nodes]), - [ ok = rt:wait_for_service(Node, Service) || Node <- Nodes, - Service <- Services ], - Nodes. - -deploy_clusters(Settings) -> - ClusterConfigs = [case Setting of - Configs when is_list(Configs) -> - Configs; - NumNodes when is_integer(NumNodes) -> - [{current, default} || _ <- lists:seq(1, NumNodes)]; - {NumNodes, InitialConfig} when is_integer(NumNodes) -> - [{current, InitialConfig} || _ <- lists:seq(1,NumNodes)]; - {NumNodes, Vsn, InitialConfig} when is_integer(NumNodes) -> - [{Vsn, InitialConfig} || _ <- lists:seq(1,NumNodes)] - end || Setting <- Settings], - rt_harness:deploy_clusters(ClusterConfigs). - -build_clusters(Settings) -> - Clusters = deploy_clusters(Settings), - [begin - join_cluster(Nodes), - lager:info("Cluster built: ~p", [Nodes]) - end || Nodes <- Clusters], - Clusters. - -maybe_wait_for_transfers(Nodes, true) -> +setup(Properties, _MetaData) -> + %% rt_config:set_conf(all, [{"buckets.default.allow_mult", "false"}]), + case form_clusters(Properties) of + {ok, Clusters} -> + maybe_wait_for_transfers(rt_properties:get(node_ids, Properties), + rt_properties:get(node_map, Properties), + rt_properties:get(wait_for_transfers, Properties)), + rt_properties:set(clusters, Clusters, Properties); + Error -> + Error + end. + +-type clusters() :: [{pos_integer(), [string()]}]. +-spec form_clusters(rt_properties:properties()) -> clusters(). +form_clusters(Properties) -> + NodeIds = rt_properties:get(node_ids, Properties), + NodeMap = rt_properties:get(node_map, Properties), + ClusterCount = rt_properties:get(cluster_count, Properties), + ClusterWeights = rt_properties:get(cluster_weights, Properties), + MakeCluster = rt_properties:get(make_cluster, Properties), + case divide_nodes(NodeIds, ClusterCount, ClusterWeights) of + {ok, Clusters} -> + maybe_join_clusters(Clusters, NodeMap, MakeCluster), + {ok, Clusters}; + Error -> + Error + end. + +divide_nodes(Nodes, Count, Weights) + when length(Nodes) < Count; + Weights =/= undefined, length(Weights) =/= Count -> + {error, invalid_cluster_properties}; +divide_nodes(Nodes, 1, _) -> + {ok, [{1, Nodes}]}; +divide_nodes(Nodes, Count, Weights) -> + case validate_weights(Weights) of + true -> + TotalNodes = length(Nodes), + NodeCounts = node_counts_from_weights(TotalNodes, Count, Weights), + {_, Clusters, _} = lists:foldl(fun take_nodes/2, {1, [], Nodes}, NodeCounts), + {ok, lists:reverse(Clusters)}; + false -> + {error, invalid_cluster_weights} + end. + +take_nodes(NodeCount, {Index, ClusterAcc, Nodes}) -> + {NewClusterNodes, RestNodes} = lists:split(NodeCount, Nodes), + {Index + 1, [{Index, NewClusterNodes} | ClusterAcc], RestNodes}. + +validate_weights(undefined) -> + true; +validate_weights(Weights) -> + not lists:sum(Weights) > 1.0 . + +node_counts_from_weights(NodeCount, ClusterCount, undefined) -> + %% Split the nodes evenly. A remainder of nodes is handled by + %% distributing one node per cluster until the remainder is + %% exhausted. + NodesPerCluster = NodeCount div ClusterCount, + Remainder = NodeCount rem ClusterCount, + [NodesPerCluster + remainder_to_apply(Remainder, ClusterIndex) || + ClusterIndex <- lists:seq(1, ClusterCount)]; +node_counts_from_weights(NodeCount, ClusterCount, Weights) -> + InitialNodeCounts = [node_count_from_weight(NodeCount, Weight) || Weight <- Weights], + Remainder = NodeCount - lists:sum(InitialNodeCounts), + [ClusterNodeCount + remainder_to_apply(Remainder, ClusterIndex) || + {ClusterIndex, ClusterNodeCount} + <- lists:zip(lists:seq(1, ClusterCount), InitialNodeCounts)]. + +node_count_from_weight(TotalNodes, Weight) -> + RawNodeCount = TotalNodes * Weight, + IntegerPortion = trunc(RawNodeCount), + Remainder = RawNodeCount - IntegerPortion, + case Remainder >= 0.5 of + true -> + IntegerPortion + 1; + false -> + IntegerPortion + end. + +remainder_to_apply(Remainder, Index) when Remainder > Index -> + 0; +remainder_to_apply(_Remainder, _Index) -> + 1. + +maybe_join_clusters(Clusters, NodeMap, true) -> + [join_cluster(ClusterNodes, NodeMap) || {_, ClusterNodes} <- Clusters]; +maybe_join_clusters(_Clusters, _NodeMap, false) -> + ok. + +maybe_wait_for_transfers(NodeIds, NodeMap, true) -> lager:info("Waiting for transfers"), - rt:wait_until_transfers_complete(Nodes); -maybe_wait_for_transfers(_Nodes, false) -> + rt:wait_until_transfers_complete([rt_node:node_name(NodeId, NodeMap) + || NodeId <- NodeIds]); +maybe_wait_for_transfers(_NodeIds, _NodeMap, false) -> ok. -%% @doc Safely construct a new cluster and return a list of the deployed nodes -%% @todo Add -spec and update doc to reflect mult-version changes -build_cluster(Versions) when is_list(Versions) -> - build_cluster(length(Versions), Versions, default); -build_cluster(NumNodes) -> - build_cluster(NumNodes, default). - -%% @doc Safely construct a `NumNode' size cluster using -%% `InitialConfig'. Return a list of the deployed nodes. -build_cluster(NumNodes, InitialConfig) -> - build_cluster(NumNodes, [], InitialConfig). - -build_cluster(NumNodes, Versions, InitialConfig) -> - %% Deploy a set of new nodes - Nodes = - case Versions of - [] -> - deploy_nodes(NumNodes, InitialConfig); - _ -> - deploy_nodes(Versions) - end, - - join_cluster(Nodes), - lager:info("Cluster built: ~p", [Nodes]), - Nodes. - -join_cluster(Nodes) -> +join_cluster(NodeIds, NodeMap) -> + NodeNames = [rt_node:node_name(NodeId, NodeMap) || NodeId <- NodeIds], %% Ensure each node owns 100% of it's own ring - [?assertEqual([Node], rt_ring:owners_according_to(Node)) || Node <- Nodes], + [?assertEqual([Node], rt_ring:owners_according_to(Node)) || Node <- NodeNames], %% Join nodes - [Node1|OtherNodes] = Nodes, + [Node1|OtherNodes] = NodeNames, case OtherNodes of [] -> %% no other nodes, nothing to join/plan/commit @@ -166,14 +157,14 @@ join_cluster(Nodes) -> %% large amount of redundant handoff done in a sequential join [rt_node:staged_join(Node, Node1) || Node <- OtherNodes], rt_node:plan_and_commit(Node1), - try_nodes_ready(Nodes, 3, 500) + try_nodes_ready(NodeNames, 3, 500) end, - ?assertEqual(ok, rt_node:wait_until_nodes_ready(Nodes)), + ?assertEqual(ok, rt_node:wait_until_nodes_ready(NodeNames)), %% Ensure each node owns a portion of the ring - rt_node:wait_until_nodes_agree_about_ownership(Nodes), - ?assertEqual(ok, rt:wait_until_no_pending_changes(Nodes)), + rt_node:wait_until_nodes_agree_about_ownership(NodeNames), + ?assertEqual(ok, rt:wait_until_no_pending_changes(NodeNames)), ok. try_nodes_ready([Node1 | _Nodes], 0, _SleepMs) -> diff --git a/src/rt_harness.erl b/src/rt_harness.erl index 1270f3bfc..88822445d 100644 --- a/src/rt_harness.erl +++ b/src/rt_harness.erl @@ -25,46 +25,46 @@ -define(HARNESS_MODULE, (rt_config:get(rt_harness))). --export([ - start/1, - stop/1, - deploy_clusters/1, - clean_data_dir/2, - deploy_nodes/1, - spawn_cmd/1, - spawn_cmd/2, - cmd/1, - cmd/2, - setup_harness/2, - get_deps/0, - get_version/0, - get_backends/0, - set_backend/1, - whats_up/0, - get_ip/1, - node_id/1, - node_version/1, - admin/2, - riak/2, - attach/2, - attach_direct/2, - console/2, - update_app_config/2, - teardown/0, - set_conf/2, - set_advanced_conf/2]). - -start(Node) -> - ?HARNESS_MODULE:start(Node). - -stop(Node) -> - ?HARNESS_MODULE:stop(Node). - +-export([start/2, + stop/2, + deploy_clusters/1, + clean_data_dir/3, + deploy_nodes/1, + spawn_cmd/1, + spawn_cmd/2, + cmd/1, + cmd/2, + setup/0, + get_deps/0, + get_version/0, + get_backends/0, + set_backend/1, + whats_up/0, + get_ip/1, + node_id/1, + node_version/1, + admin/2, + riak/2, + run_riak/3, + attach/2, + attach_direct/2, + console/2, + update_app_config/3, + teardown/0, + set_conf/2, + set_advanced_conf/2]). + +start(Node, Version) -> + ?HARNESS_MODULE:start(Node, Version). + +stop(Node, Version) -> + ?HARNESS_MODULE:stop(Node, Version). + deploy_clusters(ClusterConfigs) -> ?HARNESS_MODULE:deploy_clusters(ClusterConfigs). - -clean_data_dir(Nodes, SubDir) -> - ?HARNESS_MODULE:clean_data_dir(Nodes, SubDir). + +clean_data_dir(Node, Version, SubDir) -> + ?HARNESS_MODULE:clean_data_dir(Node, Version, SubDir). spawn_cmd(Cmd) -> ?HARNESS_MODULE:spawn_cmd(Cmd). @@ -81,11 +81,12 @@ cmd(Cmd, Opts) -> deploy_nodes(NodeConfig) -> ?HARNESS_MODULE:deploy_nodes(NodeConfig). -setup_harness(Test, Args) -> - ?HARNESS_MODULE:setup_harness(Test, Args). +setup() -> + ?HARNESS_MODULE:setup_harness(). get_deps() -> ?HARNESS_MODULE:get_deps(). + get_version() -> ?HARNESS_MODULE:get_version(). @@ -113,6 +114,9 @@ admin(Node, Args) -> riak(Node, Args) -> ?HARNESS_MODULE:riak(Node, Args). +run_riak(Node, Version, Command) -> + ?HARNESS_MODULE:run_riak(Node, Version, Command). + attach(Node, Expected) -> ?HARNESS_MODULE:attach(Node, Expected). @@ -122,8 +126,8 @@ attach_direct(Node, Expected) -> console(Node, Expected) -> ?HARNESS_MODULE:console(Node, Expected). -update_app_config(Node, Config) -> - ?HARNESS_MODULE:update_app_config(Node, Config). +update_app_config(Node, Version, Config) -> + ?HARNESS_MODULE:update_app_config(Node, Version, Config). teardown() -> ?HARNESS_MODULE:teardown(). diff --git a/src/rt_harness_util.erl b/src/rt_harness_util.erl index 82c6a4abb..71ee8f016 100644 --- a/src/rt_harness_util.erl +++ b/src/rt_harness_util.erl @@ -22,9 +22,9 @@ -module(rt_harness_util). -include_lib("eunit/include/eunit.hrl"). --define(DEVS(N), lists:concat(["dev", N, "@127.0.0.1"])). +-define(DEVS(N), lists:concat([N, "@127.0.0.1"])). -define(DEV(N), list_to_atom(?DEVS(N))). --define(PATH, (rt_config:get(rtdev_path))). +-define(PATH, (rt_config:get(root_path))). -export([admin/2, attach/2, @@ -32,13 +32,14 @@ cmd/1, cmd/2, console/2, - deploy_clusters/1, + deploy_nodes/5, get_ip/1, node_id/1, node_version/1, riak/2, set_conf/2, set_advanced_conf/2, + setup_harness/3, get_advanced_riak_conf/1, update_app_config_file/2, spawn_cmd/1, @@ -63,73 +64,75 @@ attach_direct(Node, Expected) -> console(Node, Expected) -> interactive(Node, "console", Expected). -deploy_clusters(ClusterConfigs) -> - NumNodes = rt_config:get(num_nodes, 6), - RequestedNodes = lists:flatten(ClusterConfigs), - - case length(RequestedNodes) > NumNodes of - true -> - erlang:error("Requested more nodes than available"); - false -> - Nodes = deploy_nodes(RequestedNodes), - {DeployedClusters, _} = lists:foldl( - fun(Cluster, {Clusters, RemNodes}) -> - {A, B} = lists:split(length(Cluster), RemNodes), - {Clusters ++ [A], B} - end, {[], Nodes}, ClusterConfigs), - DeployedClusters - end. - -deploy_nodes(NodeConfig) -> - Path = relpath(root), - lager:info("Riak path: ~p", [Path]), - NumNodes = length(NodeConfig), - NodesN = lists:seq(1, NumNodes), - Nodes = [?DEV(N) || N <- NodesN], - NodeMap = orddict:from_list(lists:zip(Nodes, NodesN)), - {Versions, Configs} = lists:unzip(NodeConfig), - VersionMap = lists:zip(NodesN, Versions), - - %% Check that you have the right versions available - [ check_node(Version) || Version <- VersionMap ], - rt_config:set(rt_nodes, NodeMap), - rt_config:set(rt_versions, VersionMap), - - create_dirs(Nodes), +%% deploy_clusters(ClusterConfigs) -> +%% NumNodes = rt_config:get(num_nodes, 6), +%% RequestedNodes = lists:flatten(ClusterConfigs), + +%% case length(RequestedNodes) > NumNodes of +%% true -> +%% erlang:error("Requested more nodes than available"); +%% false -> +%% Nodes = deploy_nodes(RequestedNodes), +%% {DeployedClusters, _} = lists:foldl( +%% fun(Cluster, {Clusters, RemNodes}) -> +%% {A, B} = lists:split(length(Cluster), RemNodes), +%% {Clusters ++ [A], B} +%% end, {[], Nodes}, ClusterConfigs), +%% DeployedClusters +%% end. + +%% deploy_nodes(NodeConfig) -> +deploy_nodes(NodeIds, NodeMap, Version, Config, Services) -> + %% create snmp dirs, for EE + create_dirs(Version, NodeIds), %% Set initial config - add_default_node_config(Nodes), - rt:pmap(fun({_, default}) -> - ok; - ({Node, {cuttlefish, Config}}) -> - set_conf(Node, Config); - ({Node, Config}) -> - rt_config:update_app_config(Node, Config) - end, - lists:zip(Nodes, Configs)), - - %% create snmp dirs, for EE - create_dirs(Nodes), + ConfigUpdateFun = + fun(Node) -> + rt_harness:update_app_config(Node, Version, Config) + end, + rt:pmap(ConfigUpdateFun, NodeIds), %% Start nodes - %%[run_riak(N, relpath(node_version(N)), "start") || N <- Nodes], - rt:pmap(fun(N) -> run_riak(N, relpath(node_version(N)), "start") end, NodesN), + RunRiakFun = + fun(Node) -> + rt_harness:run_riak(Node, Version, "start") + end, + rt:pmap(RunRiakFun, NodeIds), %% Ensure nodes started - [ok = rt:wait_until_pingable(N) || N <- Nodes], + lager:debug("Wait until pingable: ~p", [NodeIds]), + [ok = rt:wait_until_pingable(rt_node:node_name(NodeId, NodeMap)) + || NodeId <- NodeIds], + %% TODO Rubbish! Fix this. %% %% Enable debug logging - %% [rpc:call(N, lager, set_loglevel, [lager_console_backend, debug]) || N <- Nodes], + %% [rpc:call(N, lager, set_loglevel, [lager_console_backend, debug]) + %% || N <- Nodes], - %% We have to make sure that riak_core_ring_manager is running before we can go on. - [ok = rt:wait_until_registered(N, riak_core_ring_manager) || N <- Nodes], + %% We have to make sure that riak_core_ring_manager is running + %% before we can go on. + [ok = rt:wait_until_registered(rt_node:node_name(NodeId, NodeMap), + riak_core_ring_manager) + || NodeId <- NodeIds], %% Ensure nodes are singleton clusters - [ok = rt_ring:check_singleton_node(?DEV(N)) || {N, Version} <- VersionMap, - Version /= "0.14.2"], + case Version =/= "0.14.2" of + true -> + [ok = rt_ring:check_singleton_node(rt_node:node_name(NodeId, NodeMap)) + || NodeId <- NodeIds]; + false -> + ok + end, + + %% Wait for services to start + lager:debug("Waiting for services ~p to start on ~p.", [Services, NodeIds]), + [ ok = rt:wait_for_service(rt_node:node_name(NodeId, NodeMap), Service) + || NodeId <- NodeIds, + Service <- Services ], - lager:info("Deployed nodes: ~p", [Nodes]), - Nodes. + lager:debug("Deployed nodes: ~p", [NodeIds]), + NodeIds. interactive(Node, Command, Exp) -> N = node_id(Node), @@ -374,35 +377,37 @@ all_the_files(DevPath, File) -> devpaths() -> lists:usort([ DevPath || {_Name, DevPath} <- proplists:delete(root, rt_config:get(rtdev_path))]). -create_dirs(Nodes) -> - Snmp = [node_path(Node) ++ "/data/snmp/agent/db" || Node <- Nodes], +create_dirs(Version, NodeIds) -> + VersionPath = filename:join(?PATH, Version), + Snmp = [filename:join([VersionPath, NodeId, "data/snmp/agent/db"]) || + NodeId <- NodeIds], [?assertCmd("mkdir -p " ++ Dir) || Dir <- Snmp]. -check_node({_N, Version}) -> - case proplists:is_defined(Version, rt_config:get(rtdev_path)) of - true -> ok; - _ -> - lager:error("You don't have Riak ~s installed or configured", [Version]), - erlang:error("You don't have Riak " ++ atom_to_list(Version) ++ " installed or configured") - end. - -add_default_node_config(Nodes) -> - case rt_config:get(rt_default_config, undefined) of - undefined -> ok; - Defaults when is_list(Defaults) -> - rt:pmap(fun(Node) -> - rt_config:update_app_config(Node, Defaults) - end, Nodes), - ok; - BadValue -> - lager:error("Invalid value for rt_default_config : ~p", [BadValue]), - throw({invalid_config, {rt_default_config, BadValue}}) - end. - -node_path(Node) -> - N = node_id(Node), - Path = relpath(node_version(N)), - lists:flatten(io_lib:format("~s/dev/dev~b", [Path, N])). +%% check_node({_N, Version}) -> +%% case proplists:is_defined(Version, rt_config:get(rtdev_path)) of +%% true -> ok; +%% _ -> +%% lager:error("You don't have Riak ~s installed or configured", [Version]), +%% erlang:error("You don't have Riak " ++ atom_to_list(Version) ++ " installed or configured") +%% end. + +%% add_default_node_config(Nodes) -> +%% case rt_config:get(rt_default_config, undefined) of +%% undefined -> ok; +%% Defaults when is_list(Defaults) -> +%% rt:pmap(fun(Node) -> +%% rt_config:update_app_config(Node, Defaults) +%% end, Nodes), +%% ok; +%% BadValue -> +%% lager:error("Invalid value for rt_default_config : ~p", [BadValue]), +%% throw({invalid_config, {rt_default_config, BadValue}}) +%% end. + +%% node_path(Node) -> +%% N = node_id(Node), +%% Path = relpath(node_version(N)), +%% lists:flatten(io_lib:format("~s/dev/dev~b", [Path, N])). set_advanced_conf(all, NameValuePairs) -> lager:info("rtdev:set_advanced_conf(all, ~p)", [NameValuePairs]), @@ -442,3 +447,27 @@ update_app_config_file(ConfigFile, Config) -> NewConfigOut = io_lib:format("~p.", [NewConfig]), ?assertEqual(ok, file:write_file(ConfigFile, NewConfigOut)), ok. + +%% TODO: This made sense in an earlier iteration, but probably is no +%% longer needed. Original idea was to provide a place for setup that +%% was general to all harnesses to happen. +setup_harness(VersionMap, NodeIds, NodeMap) -> + %% rt_config:set(rt_nodes, Nodes), + %% rt_config:set(rt_nodes_available, Nodes), + %% rt_config:set(rt_version_map, VersionMap), + %% rt_config:set(rt_versions, VersionMap), + %% [create_dirs(Version, VersionNodes) || {Version, VersionNodes} <- VersionMap], + {NodeIds, NodeMap, VersionMap}. + +%% %% @doc Stop nodes and wipe out their data directories +%% stop_and_clean_nodes(Nodes, Version) when is_list(Nodes) -> +%% [rt_node:stop_and_wait(Node) || Node <- Nodes], +%% clean_data_dir(Nodes). + +%% clean_data_dir(Nodes) -> +%% clean_data_dir(Nodes, ""). + +%% clean_data_dir(Nodes, SubDir) when not is_list(Nodes) -> +%% clean_data_dir([Nodes], SubDir); +%% clean_data_dir(Nodes, SubDir) when is_list(Nodes) -> +%% rt_harness:clean_data_dir(Nodes, SubDir). diff --git a/src/rt_node.erl b/src/rt_node.erl index e52316035..22a1268f9 100644 --- a/src/rt_node.erl +++ b/src/rt_node.erl @@ -21,15 +21,14 @@ -include("rt.hrl"). -include_lib("eunit/include/eunit.hrl"). --export([start/1, - start_and_wait/1, - async_start/1, - stop/1, - stop_and_wait/1, - upgrade/2, - upgrade/3, +-export([start/2, + start_and_wait/3, + async_start/2, + stop/2, + stop_and_wait/3, + upgrade/4, is_ready/1, - slow_upgrade/3, + %% slow_upgrade/3, join/2, staged_join/2, plan_and_commit/1, @@ -43,57 +42,75 @@ wait_until_nodes_ready/1, wait_until_owners_according_to/2, wait_until_nodes_agree_about_ownership/1, - is_pingable/1]). + is_pingable/1, + clean_data_dir/2, + node_name/2]). + +-spec node_name(string(), [{string(), node()}]) -> node() | undefined. +%% @doc Hide the details of underlying data structure of the node map +%% in case it needs to change at some point. +node_name(NodeId, NodeMap) -> + case lists:keyfind(NodeId, 1, NodeMap) of + {NodeId, NodeName} -> + NodeName; + false -> + undefined + end. + +clean_data_dir(Node, Version) -> + clean_data_dir(Node, Version, ""). --define(HARNESS, (rt_config:get(rt_harness))). +clean_data_dir(Node, Version, SubDir) -> + rt_harness:clean_data_dir(Node, Version, SubDir). %% @doc Start the specified Riak node -start(Node) -> - rt_harness:start(Node). +start(Node, Version) -> + rt_harness:start(Node, Version). %% @doc Start the specified Riak `Node' and wait for it to be pingable -start_and_wait(Node) -> - start(Node), - ?assertEqual(ok, rt:wait_until_pingable(Node)). +start_and_wait(NodeId, NodeName, Version) -> + start(NodeId, Version), + ?assertEqual(ok, rt:wait_until_pingable(NodeName)). -async_start(Node) -> - spawn(fun() -> start(Node) end). +async_start(Node, Version) -> + spawn(fun() -> start(Node, Version) end). %% @doc Stop the specified Riak `Node'. -stop(Node) -> +stop(Node, Version) -> lager:info("Stopping riak on ~p", [Node]), - timer:sleep(10000), %% I know, I know! - rt_harness:stop(Node). + %% timer:sleep(10000), %% I know, I know! + rt_harness:stop(Node, Version). %%rpc:call(Node, init, stop, []). %% @doc Stop the specified Riak `Node' and wait until it is not pingable -stop_and_wait(Node) -> - stop(Node), - ?assertEqual(ok, rt:wait_until_unpingable(Node)). +-spec stop_and_wait(string(), node(), string()) -> ok. +stop_and_wait(NodeId, NodeName, Version) -> + stop(NodeId, Version), + ?assertEqual(ok, rt:wait_until_unpingable(NodeName)). -%% @doc Upgrade a Riak `Node' to the specified `NewVersion'. -upgrade(Node, NewVersion) -> - rt_harness:upgrade(Node, NewVersion). +%% %% @doc Upgrade a Riak `Node' to the specified `NewVersion'. +%% upgrade(Node, NewVersion) -> +%% rt_harness:upgrade(Node, NewVersion). %% @doc Upgrade a Riak `Node' to the specified `NewVersion' and update %% the config based on entries in `Config'. -upgrade(Node, NewVersion, Config) -> - rt_harness:upgrade(Node, NewVersion, Config). +upgrade(Node, CurrentVersion, NewVersion, Config) -> + rt_harness:upgrade(Node, CurrentVersion, NewVersion, Config). %% @doc Upgrade a Riak node to a specific version using the alternate %% leave/upgrade/rejoin approach -slow_upgrade(Node, NewVersion, Nodes) -> - lager:info("Perform leave/upgrade/join upgrade on ~p", [Node]), - lager:info("Leaving ~p", [Node]), - leave(Node), - ?assertEqual(ok, rt:wait_until_unpingable(Node)), - upgrade(Node, NewVersion), - lager:info("Rejoin ~p", [Node]), - join(Node, hd(Nodes -- [Node])), - lager:info("Wait until all nodes are ready and there are no pending changes"), - ?assertEqual(ok, rt:wait_until_nodes_ready(Nodes)), - ?assertEqual(ok, rt:wait_until_no_pending_changes(Nodes)), - ok. +%% slow_upgrade(Node, NewVersion, Nodes) -> +%% lager:info("Perform leave/upgrade/join upgrade on ~p", [Node]), +%% lager:info("Leaving ~p", [Node]), +%% leave(Node), +%% ?assertEqual(ok, rt:wait_until_unpingable(Node)), +%% upgrade(Node, NewVersion), +%% lager:info("Rejoin ~p", [Node]), +%% join(Node, hd(Nodes -- [Node])), +%% lager:info("Wait until all nodes are ready and there are no pending changes"), +%% ?assertEqual(ok, rt:wait_until_nodes_ready(Nodes)), +%% ?assertEqual(ok, rt:wait_until_no_pending_changes(Nodes)), +%% ok. %% @doc Have `Node' send a join request to `PNode' join(Node, PNode) -> @@ -114,7 +131,11 @@ plan_and_commit(Node) -> lager:info("planning and commiting cluster join"), case rpc:call(Node, riak_core_claimant, plan, []) of {error, ring_not_ready} -> - lager:info("plan: ring not ready"), + lager:info("plan: ring not ready on ~p", [Node]), + timer:sleep(100), + plan_and_commit(Node); + {badrpc, _} -> + lager:info("plan: ring not ready on ~p", [Node]), timer:sleep(100), plan_and_commit(Node); {ok, _, _} -> diff --git a/src/rt_pb.erl b/src/rt_pb.erl index 157261758..3b720e6a6 100644 --- a/src/rt_pb.erl +++ b/src/rt_pb.erl @@ -22,6 +22,7 @@ -include_lib("eunit/include/eunit.hrl"). -export([pbc/1, + stop/1, pbc_read/3, pbc_read/4, pbc_read_check/4, @@ -45,12 +46,16 @@ %% @doc get me a protobuf client process and hold the mayo! -spec pbc(node()) -> pid(). pbc(Node) -> - rt:wait_for_service(Node, riak_kv), - ConnInfo = proplists:get_value(Node, rt:connection_info([Node])), - {IP, PBPort} = proplists:get_value(pb, ConnInfo), + %% rt:wait_for_service(Node, riak_kv), + %% ConnInfo = proplists:get_value(Node, rt:connection_info([Node])), + %% {IP, PBPortz} = proplists:get_value(pb, ConnInfo), + {ok, [{IP, PBPort}]} = get_pb_conn_info(Node), {ok, Pid} = riakc_pb_socket:start_link(IP, PBPort, [{auto_reconnect, true}]), Pid. +stop(Pid) -> + riakc_pb_socket:stop(Pid). + %% @doc does a read via the erlang protobuf client -spec pbc_read(pid(), binary(), binary()) -> binary(). pbc_read(Pid, Bucket, Key) -> diff --git a/src/rt_properties.erl b/src/rt_properties.erl index fb29afe17..bb0ec2090 100644 --- a/src/rt_properties.erl +++ b/src/rt_properties.erl @@ -19,24 +19,38 @@ %% ------------------------------------------------------------------- %% @doc Implements a set of functions for accessing and manipulating -%% an `rt_properties' record.-module(rt_properties). +%% an `rt_properties' record. -module(rt_properties). -include("rt.hrl"). -include_lib("eunit/include/eunit.hrl"). +%% A quick note on the distinction between `node_ids' and +%% `node_map'. `node_ids' are short identifers (e.g. dev1) and the +%% `node_map' maps each node_id to a full erlang node names. Both are +%% necessary because the different existing helper functions make use +%% of each one to either compose shell commands or execute rpc calls. +%% The `node_map' is used to make the details of the actual node +%% names, which are harness-specific, opaque to the helper functions +%% and ensure that the helpers are valid for use with any harness. -record(rt_properties_v1, { - nodes :: [node()], - node_count=6 :: non_neg_integer(), + node_ids :: [string()], + node_map :: [{string(), node()}], + node_count=3 :: non_neg_integer(), metadata=[] :: proplists:proplist(), properties=[] :: proplists:proplist(), rolling_upgrade=false :: boolean(), - start_version=current :: atom(), - upgrade_version=current :: atom(), + start_version="head" :: string(), + current_version :: string(), + upgrade_path :: [string()], wait_for_transfers=false :: boolean(), valid_backends=all :: all | [atom()], make_cluster=true :: boolean(), + cluster_count=1 :: pos_integer(), + cluster_weights :: [float()], + clusters :: proplists:proplist(), + required_services=[riak_kv] :: [atom()], config=default_config() :: term() }). -type properties() :: #rt_properties_v1{}. @@ -81,7 +95,7 @@ get(Property, Properties) -> %% or if any of the properties to be set are not a valid property. In %% the case that invalid properties are specified the error returned %% contains a list of erroneous properties. --spec set([{atom(), term()}], properties()) -> {ok, properties()} | {error, atom()}. +-spec set([{atom(), term()}], properties()) -> properties() | {error, atom()}. set(PropertyList, Properties) when is_list(PropertyList) -> set_properties(PropertyList, Properties, validate_record(Properties)). @@ -178,8 +192,10 @@ is_valid_property(Property) -> lists:member(Property, Fields). -spec field_index(atom()) -> non_neg_integer(). -field_index(nodes) -> - ?RT_PROPERTIES.nodes; +field_index(node_ids) -> + ?RT_PROPERTIES.node_ids; +field_index(node_map) -> + ?RT_PROPERTIES.node_map; field_index(node_count) -> ?RT_PROPERTIES.node_count; field_index(metadata) -> @@ -190,13 +206,23 @@ field_index(rolling_upgrade) -> ?RT_PROPERTIES.rolling_upgrade; field_index(start_version) -> ?RT_PROPERTIES.start_version; -field_index(upgrade_version) -> - ?RT_PROPERTIES.upgrade_version; +field_index(current_version) -> + ?RT_PROPERTIES.current_version; +field_index(upgrade_path) -> + ?RT_PROPERTIES.upgrade_path; field_index(wait_for_transfers) -> ?RT_PROPERTIES.wait_for_transfers; field_index(valid_backends) -> ?RT_PROPERTIES.valid_backends; field_index(make_cluster) -> ?RT_PROPERTIES.make_cluster; +field_index(cluster_count) -> + ?RT_PROPERTIES.cluster_count; +field_index(cluster_weights) -> + ?RT_PROPERTIES.cluster_weights; +field_index(clusters) -> + ?RT_PROPERTIES.clusters; +field_index(required_services) -> + ?RT_PROPERTIES.required_services; field_index(config) -> ?RT_PROPERTIES.config. diff --git a/src/rtdev.erl b/src/rtdev.erl index 375de6e47..f43b33057 100644 --- a/src/rtdev.erl +++ b/src/rtdev.erl @@ -19,16 +19,18 @@ %% ------------------------------------------------------------------- -module(rtdev). --behaviour(test_harness). --export([start/1, - stop/1, +%% -behaviour(test_harness). +-export([start/2, + stop/2, deploy_clusters/1, clean_data_dir/2, + clean_data_dir/3, spawn_cmd/1, spawn_cmd/2, cmd/1, cmd/2, - setup_harness/2, + setup_harness/0, + %% setup_harness/2, get_version/0, get_backends/0, set_backend/1, @@ -41,27 +43,29 @@ attach/2, attach_direct/2, console/2, - update_app_config/2, + update_app_config/3, teardown/0, set_conf/2, - set_advanced_conf/2]). + set_advanced_conf/2, + rm_dir/1]). -compile(export_all). -include_lib("eunit/include/eunit.hrl"). --define(DEVS(N), lists:concat(["dev", N, "@127.0.0.1"])). +-define(DEVS(N), lists:concat([N, "@127.0.0.1"])). -define(DEV(N), list_to_atom(?DEVS(N))). --define(PATH, (rt_config:get(rtdev_path))). +-define(PATH, (rt_config:get(root_path))). +-define(SCRATCH_DIR, (rt_config:get(rt_scratch_dir))). get_deps() -> - lists:flatten(io_lib:format("~s/dev/dev1/lib", [relpath(current)])). + lists:flatten(io_lib:format("~s/dev1/lib", [filename:join(?PATH, "head")])). riakcmd(Path, N, Cmd) -> ExecName = rt_config:get(exec_name, "riak"), - io_lib:format("~s/dev/dev~b/bin/~s ~s", [Path, N, ExecName, Cmd]). + io_lib:format("~s/~s/bin/~s ~s", [Path, N, ExecName, Cmd]). riakreplcmd(Path, N, Cmd) -> - io_lib:format("~s/dev/dev~b/bin/riak-repl ~s", [Path, N, Cmd]). + io_lib:format("~s/~s/bin/riak-repl ~s", [Path, N, Cmd]). gitcmd(Path, Cmd) -> io_lib:format("git --git-dir=\"~s/.git\" --work-tree=\"~s/\" ~s", @@ -76,34 +80,35 @@ riak_admin_cmd(Path, N, Args) -> end, Args), ArgStr = string:join(Quoted, " "), ExecName = rt_config:get(exec_name, "riak"), - io_lib:format("~s/dev/dev~b/bin/~s-admin ~s", [Path, N, ExecName, ArgStr]). + io_lib:format("~s/~s/bin/~s-admin ~s", [Path, N, ExecName, ArgStr]). run_git(Path, Cmd) -> lager:info("Running: ~s", [gitcmd(Path, Cmd)]), {0, Out} = cmd(gitcmd(Path, Cmd)), Out. -run_riak(N, Path, Cmd) -> - lager:info("Running: ~s", [riakcmd(Path, N, Cmd)]), - R = os:cmd(riakcmd(Path, N, Cmd)), - case Cmd of - "start" -> - rt_cover:maybe_start_on_node(?DEV(N), node_version(N)), - %% Intercepts may load code on top of the cover compiled - %% modules. We'll just get no coverage info then. - case rt_intercept:are_intercepts_loaded(?DEV(N)) of - false -> - ok = rt_intercept:load_intercepts([?DEV(N)]); - true -> - ok - end, - R; - "stop" -> - rt_cover:maybe_stop_on_node(?DEV(N)), - R; - _ -> - R - end. +run_riak(Node, Version, "start") -> + VersionPath = filename:join(?PATH, Version), + RiakCmd = riakcmd(VersionPath, Node, "start"), + lager:info("Running: ~s", [RiakCmd]), + CmdRes = os:cmd(RiakCmd), + %% rt_cover:maybe_start_on_node(?DEV(Node), Version), + %% Intercepts may load code on top of the cover compiled + %% modules. We'll just get no coverage info then. + case rt_intercept:are_intercepts_loaded(?DEV(Node)) of + false -> + ok = rt_intercept:load_intercepts([?DEV(Node)]); + true -> + ok + end, + CmdRes; +run_riak(Node, Version, "stop") -> + VersionPath = filename:join(?PATH, Version), + %% rt_cover:maybe_stop_on_node(?DEV(Node)), + os:cmd(riakcmd(VersionPath, Node, "stop")); +run_riak(Node, Version, Cmd) -> + VersionPath = filename:join(?PATH, Version), + os:cmd(riakcmd(VersionPath, Node, Cmd)). run_riak_repl(N, Path, Cmd) -> lager:info("Running: ~s", [riakcmd(Path, N, Cmd)]), @@ -111,32 +116,76 @@ run_riak_repl(N, Path, Cmd) -> %% don't mess with intercepts and/or coverage, %% they should already be setup at this point -setup_harness(_Test, _Args) -> - %% make sure we stop any cover processes on any nodes - %% otherwise, if the next test boots a legacy node we'll end up with cover +-spec versions() -> [string()]. +versions() -> + RootPath = ?PATH, + case file:list_dir(RootPath) of + {ok, RootFiles} -> + [Version || Version <- RootFiles, + filelib:is_dir(filename:join(RootPath, Version)), + hd(Version) =/= $.]; + {error, _} -> + [] + end. + +-spec harness_node_ids(string()) -> [string()]. +harness_node_ids(Version) -> + VersionPath = filename:join(?PATH, Version), + case file:list_dir(VersionPath) of + {ok, VersionFiles} -> + SortedVersionFiles = lists:sort(VersionFiles), + [Node || Node <- SortedVersionFiles, + filelib:is_dir(filename:join(VersionPath, Node))]; + {error, _} -> + [] + end. + +-spec harness_nodes([string()]) -> [atom()]. +harness_nodes(NodeIds) -> + [list_to_atom(NodeId ++ "@127.0.0.1") || NodeId <- NodeIds]. + +so_fresh_so_clean(VersionMap) -> + %% make sure we stop any cover processes on any nodes otherwise, + %% if the next test boots a legacy node we'll end up with cover %% incompatabilities and crash the cover server - rt_cover:maybe_stop_on_nodes(), - Path = relpath(root), - %% Stop all discoverable nodes, not just nodes we'll be using for this test. - rt:pmap(fun(X) -> stop_all(X ++ "/dev") end, devpaths()), + %% rt_cover:maybe_stop_on_nodes(), + %% Path = relpath(root), + %% Stop all discoverable nodes, not just nodes we'll be using for + %% this test. + StopAllFun = + fun({Version, VersionNodes}) -> + VersionPath = filename:join([?PATH, Version]), + stop_nodes(VersionPath, VersionNodes) + end, + rt:pmap(StopAllFun, VersionMap), %% Reset nodes to base state lager:info("Resetting nodes to fresh state"), - _ = run_git(Path, "reset HEAD --hard"), - _ = run_git(Path, "clean -fd"), + _ = run_git(?PATH, "reset HEAD --hard"), + _ = run_git(?PATH, "clean -fd"), lager:info("Cleaning up lingering pipe directories"), - rt:pmap(fun(Dir) -> + rt:pmap(fun({Version, _}) -> %% when joining two absolute paths, filename:join intentionally %% throws away the first one. ++ gets us around that, while %% keeping some of the security of filename:join. %% the extra slashes will be pruned by filename:join, but this %% ensures that there will be at least one between "/tmp" and Dir - PipeDir = filename:join(["/tmp//" ++ Dir, "dev"]), + %% TODO: Double check this is correct + PipeDir = filename:join("/tmp" ++ ?PATH, Version), {0, _} = cmd("rm -rf " ++ PipeDir) - end, devpaths()), + end, VersionMap), ok. +setup_harness() -> + %% Get node names and populate node map + VersionMap = [{Version, harness_node_ids(Version)} || Version <- versions()], + NodeIds = harness_node_ids(rt_config:get(default_version, "head")), + NodeMap = lists:zip(NodeIds, harness_nodes(NodeIds)), + so_fresh_so_clean(VersionMap), + rm_dir(filename:join(?SCRATCH_DIR, "gc")), + rt_harness_util:setup_harness(VersionMap, NodeIds, NodeMap). + relpath(Vsn) -> Path = ?PATH, relpath(Vsn, Path). @@ -150,37 +199,39 @@ relpath(root, Path) -> relpath(_, _) -> throw("Version requested but only one path provided"). -upgrade(Node, NewVersion) -> - upgrade(Node, NewVersion, same). +%% upgrade(Node, CurrentVersion, NewVersion) -> +%% upgrade(Node, CurrentVersion, NewVersion, same). -upgrade(Node, NewVersion, Config) -> - N = node_id(Node), - Version = node_version(N), - lager:info("Upgrading ~p : ~p -> ~p", [Node, Version, NewVersion]), - stop(Node), +upgrade(Node, CurrentVersion, NewVersion, Config) -> + lager:info("Upgrading ~p : ~p -> ~p", [Node, CurrentVersion, NewVersion]), + stop(Node, CurrentVersion), rt:wait_until_unpingable(Node), - OldPath = relpath(Version), - NewPath = relpath(NewVersion), - + CurrentPath = filename:join([?PATH, CurrentVersion, Node]), + NewPath = filename:join([?PATH, NewVersion, Node]), Commands = [ - io_lib:format("cp -p -P -R \"~s/dev/dev~b/data\" \"~s/dev/dev~b\"", - [OldPath, N, NewPath, N]), - io_lib:format("rm -rf ~s/dev/dev~b/data/*", - [OldPath, N]), - io_lib:format("cp -p -P -R \"~s/dev/dev~b/etc\" \"~s/dev/dev~b\"", - [OldPath, N, NewPath, N]) + io_lib:format("cp -p -P -R \"~s\" \"~s\"", + [filename:join(CurrentPath, "data"), + NewPath]), + %% io_lib:format("rm -rf ~s/dev/dev~b/data/*", + %% [CurrePath, N]), + io_lib:format("cp -p -P -R \"~s\" \"~s\"", + [filename:join(CurrentPath, "etc"), + NewPath]) ], - [ begin - lager:info("Running: ~s", [Cmd]), - os:cmd(Cmd) - end || Cmd <- Commands], - VersionMap = orddict:store(N, NewVersion, rt_config:get(rt_versions)), - rt_config:set(rt_versions, VersionMap), + [begin + lager:debug("Running: ~s", [Cmd]), + os:cmd(Cmd) + end || Cmd <- Commands], + clean_data_dir(Node, CurrentVersion, ""), + + %% VersionMap = orddict:store(N, NewVersion, rt_config:get(rt_versions)), + %% rt_config:set(rt_versions, VersionMap), + case Config of - same -> ok; - _ -> update_app_config(Node, Config) + same -> ok; + _ -> update_app_config(Node, NewVersion, Config) end, - start(Node), + start(Node, NewVersion), rt:wait_until_pingable(Node), ok. @@ -242,29 +293,28 @@ all_the_app_configs(DevPath) -> AppConfigs end. -update_app_config(all, Config) -> - lager:info("rtdev:update_app_config(all, ~p)", [Config]), - [ update_app_config(DevPath, Config) || DevPath <- devpaths()]; -update_app_config(Node, Config) when is_atom(Node) -> - N = node_id(Node), - Path = relpath(node_version(N)), - FileFormatString = "~s/dev/dev~b/etc/~s.config", +%% update_app_config(all, Config) -> +%% lager:info("rtdev:update_app_config(all, ~p)", [Config]), +%% [ update_app_config(DevPath, Config) || DevPath <- devpaths()]; +update_app_config(Node, Version, Config) -> + VersionPath = filename:join(?PATH, Version), + FileFormatString = "~s/~s/etc/~s.config", + AppConfigFile = io_lib:format(FileFormatString, + [VersionPath, Node, "app"]), + AdvConfigFile = io_lib:format(FileFormatString, + [VersionPath, Node, "advanced"]), - AppConfigFile = io_lib:format(FileFormatString, [Path, N, "app"]), - AdvConfigFile = io_lib:format(FileFormatString, [Path, N, "advanced"]), %% If there's an app.config, do it old style - %% if not, use cuttlefish's adavnced.config + %% if not, use cuttlefish's advanced.config case filelib:is_file(AppConfigFile) of true -> update_app_config_file(AppConfigFile, Config); _ -> update_app_config_file(AdvConfigFile, Config) - end; -update_app_config(DevPath, Config) -> - [update_app_config_file(AppConfig, Config) || AppConfig <- all_the_app_configs(DevPath)]. + end. update_app_config_file(ConfigFile, Config) -> - lager:info("rtdev:update_app_config_file(~s, ~p)", [ConfigFile, Config]), + lager:debug("rtdev:update_app_config_file(~s, ~p)", [ConfigFile, Config]), BaseConfig = case file:consult(ConfigFile) of {ok, [ValidConfig]} -> @@ -354,8 +404,40 @@ clean_data_dir(Nodes, SubDir) when is_list(Nodes) -> DataDirs = [node_path(Node) ++ "/data/" ++ SubDir || Node <- Nodes], lists:foreach(fun rm_dir/1, DataDirs). +%% Blocking to delete files is not the best use of time. Generally it +%% is quicker to move directories than to recursively delete them so +%% move the directory to a GC subdirectory in the riak_test scratch +%% directory, recreate the subdirectory, and asynchronously remove the +%% files from the scratch directory. +clean_data_dir(Node, Version, "") -> + DataDir = filename:join([?PATH, Version, Node, "data"]), + TmpDir = filename:join([?SCRATCH_DIR, "gc", Version, Node]), + filelib:ensure_dir(filename:join(TmpDir, "child")), + mv_dir(DataDir, TmpDir), + Pid = spawn(?MODULE, rm_dir, [TmpDir]), + mk_dir(DataDir), + Pid; +clean_data_dir(Node, Version, SubDir) -> + DataDir = filename:join([?PATH, Version, Node, "data", SubDir]), + TmpDir = filename:join([?SCRATCH_DIR, "gc", Version, Node, "data"]), + filelib:ensure_dir(filename:join(TmpDir, "child")), + mv_dir(DataDir, TmpDir), + Pid = spawn(?MODULE, rm_dir, [TmpDir]), + mk_dir(DataDir), + Pid. + +mk_dir(Dir) -> + lager:debug("Making directory ~s", [Dir]), + ?assertCmd("mkdir " ++ Dir), + ?assertEqual(true, filelib:is_dir(Dir)). + +mv_dir(Src, Dest) -> + lager:debug("Moving directory ~s to ~s", [Src, Dest]), + ?assertCmd("mv " ++ Src ++ " " ++ Dest), + ?assertEqual(false, filelib:is_dir(Src)). + rm_dir(Dir) -> - lager:info("Removing directory ~s", [Dir]), + lager:debug("Removing directory ~s", [Dir]), ?assertCmd("rm -rf " ++ Dir), ?assertEqual(false, filelib:is_dir(Dir)). @@ -364,7 +446,7 @@ add_default_node_config(Nodes) -> undefined -> ok; Defaults when is_list(Defaults) -> rt:pmap(fun(Node) -> - update_app_config(Node, Defaults) + update_app_config(Node, version_here, Defaults) end, Nodes), ok; BadValue -> @@ -372,40 +454,25 @@ add_default_node_config(Nodes) -> throw({invalid_config, {rt_default_config, BadValue}}) end. -deploy_clusters(ClusterConfigs) -> - NumNodes = rt_config:get(num_nodes, 6), - RequestedNodes = lists:flatten(ClusterConfigs), - - case length(RequestedNodes) > NumNodes of - true -> - erlang:error("Requested more nodes than available"); - false -> - Nodes = deploy_nodes(RequestedNodes), - {DeployedClusters, _} = lists:foldl( - fun(Cluster, {Clusters, RemNodes}) -> - {A, B} = lists:split(length(Cluster), RemNodes), - {Clusters ++ [A], B} - end, {[], Nodes}, ClusterConfigs), - DeployedClusters - end. - -deploy_nodes(NodeConfig) -> - Path = relpath(root), - lager:info("Riak path: ~p", [Path]), - NumNodes = length(NodeConfig), - NodesN = lists:seq(1, NumNodes), - Nodes = [?DEV(N) || N <- NodesN], - NodeMap = orddict:from_list(lists:zip(Nodes, NodesN)), - {Versions, Configs} = lists:unzip(NodeConfig), - VersionMap = lists:zip(NodesN, Versions), - - %% Check that you have the right versions available - [ check_node(Version) || Version <- VersionMap ], - rt_config:set(rt_nodes, NodeMap), - rt_config:set(rt_versions, VersionMap), - - create_dirs(Nodes), - +deploy_clusters(_ClusterConfigs) -> + ok. +%% NumNodes = rt_config:get(num_nodes, 6), +%% RequestedNodes = lists:flatten(ClusterConfigs), + +%% case length(RequestedNodes) > NumNodes of +%% true -> +%% erlang:error("Requested more nodes than available"); +%% false -> +%% Nodes = deploy_nodes(RequestedNodes), +%% {DeployedClusters, _} = lists:foldl( +%% fun(Cluster, {Clusters, RemNodes}) -> +%% {A, B} = lists:split(length(Cluster), RemNodes), +%% {Clusters ++ [A], B} +%% end, {[], Nodes}, ClusterConfigs), +%% DeployedClusters +%% end. + +configure_nodes(Nodes, Configs) -> %% Set initial config add_default_node_config(Nodes), rt:pmap(fun({_, default}) -> @@ -413,49 +480,80 @@ deploy_nodes(NodeConfig) -> ({Node, {cuttlefish, Config}}) -> set_conf(Node, Config); ({Node, Config}) -> - update_app_config(Node, Config) + update_app_config(Node, version_here, Config) end, - lists:zip(Nodes, Configs)), - - %% create snmp dirs, for EE - create_dirs(Nodes), - - %% Start nodes - %%[run_riak(N, relpath(node_version(N)), "start") || N <- Nodes], - rt:pmap(fun(N) -> run_riak(N, relpath(node_version(N)), "start") end, NodesN), - - %% Ensure nodes started - [ok = rt:wait_until_pingable(N) || N <- Nodes], - - %% %% Enable debug logging - %% [rpc:call(N, lager, set_loglevel, [lager_console_backend, debug]) || N <- Nodes], - - %% We have to make sure that riak_core_ring_manager is running before we can go on. - [ok = rt:wait_until_registered(N, riak_core_ring_manager) || N <- Nodes], - - %% Ensure nodes are singleton clusters - [ok = rt_ring:check_singleton_node(?DEV(N)) || {N, Version} <- VersionMap, - Version /= "0.14.2"], - - lager:info("Deployed nodes: ~p", [Nodes]), - Nodes. - -gen_stop_fun(Timeout) -> - fun({C,Node}) -> - net_kernel:hidden_connect_node(Node), - case rpc:call(Node, os, getpid, []) of + lists:zip(Nodes, Configs)). + +%% deploy_nodes(NodeConfig) -> +%% Path = relpath(root), +%% lager:info("Riak path: ~p", [Path]), +%% NumNodes = length(NodeConfig), +%% %% TODO: The starting index should not be fixed to 1 +%% NodesN = lists:seq(1, NumNodes), +%% Nodes = [?DEV(N) || N <- NodesN], +%% NodeMap = orddict:from_list(lists:zip(Nodes, NodesN)), +%% {Versions, Configs} = lists:unzip(NodeConfig), +%% VersionMap = lists:zip(NodesN, Versions), + +%% %% Check that you have the right versions available +%% [ check_node(Version) || Version <- VersionMap ], +%% rt_config:set(rt_nodes, NodeMap), +%% rt_config:set(rt_versions, VersionMap), + +%% create_dirs(Nodes), + +%% %% Set initial config +%% add_default_node_config(Nodes), +%% rt:pmap(fun({_, default}) -> +%% ok; +%% ({Node, {cuttlefish, Config}}) -> +%% set_conf(Node, Config); +%% ({Node, Config}) -> +%% update_app_config(Node, Config) +%% end, +%% lists:zip(Nodes, Configs)), + +%% %% create snmp dirs, for EE +%% create_dirs(Nodes), + +%% %% Start nodes +%% %%[run_riak(N, relpath(node_version(N)), "start") || N <- Nodes], +%% rt:pmap(fun(N) -> run_riak(N, relpath(node_version(N)), "start") end, NodesN), + +%% %% Ensure nodes started +%% [ok = rt:wait_until_pingable(N) || N <- Nodes], + +%% %% %% Enable debug logging +%% %% [rpc:call(N, lager, set_loglevel, [lager_console_backend, debug]) || N <- Nodes], + +%% %% We have to make sure that riak_core_ring_manager is running before we can go on. +%% [ok = rt:wait_until_registered(N, riak_core_ring_manager) || N <- Nodes], + +%% %% Ensure nodes are singleton clusters +%% [ok = rt_ring:check_singleton_node(?DEV(N)) || {N, Version} <- VersionMap, +%% Version /= "0.14.2"], + +%% lager:info("Deployed nodes: ~p", [Nodes]), +%% Nodes. + +gen_stop_fun(Path, Timeout) -> + fun(Node) -> + NodeName = ?DEV(Node), + NodePath = filename:join(Path, Node), + net_kernel:hidden_connect_node(NodeName), + case rpc:call(NodeName, os, getpid, []) of PidStr when is_list(PidStr) -> - lager:info("Preparing to stop node ~p (process ID ~s) with init:stop/0...", - [Node, PidStr]), - rpc:call(Node, init, stop, []), + lager:debug("Preparing to stop node ~p (process ID ~s) with init:stop/0...", + [NodePath, PidStr]), + rpc:call(NodeName, init, stop, []), %% If init:stop/0 fails here, the wait_for_pid/2 call %% below will timeout and the process will get cleaned %% up by the kill_stragglers/2 function wait_for_pid(PidStr, Timeout); BadRpc -> - Cmd = C ++ "/bin/riak stop", - lager:info("RPC to node ~p returned ~p, will try stop anyway... ~s", - [Node, BadRpc, Cmd]), + Cmd = filename:join([Path, Node, "bin/riak stop"]), + lager:debug("RPC to node ~p returned ~p, will try stop anyway... ~s", + [NodeName, BadRpc, Cmd]), Output = os:cmd(Cmd), Status = case Output of "ok\n" -> @@ -470,12 +568,12 @@ gen_stop_fun(Timeout) -> _ -> "wasn't running" end, - lager:info("Stopped node ~p, stop status: ~s.", [Node, Status]) + lager:debug("Stopped node ~p, stop status: ~s.", [NodePath, Status]) end end. -kill_stragglers(DevPath, Timeout) -> - {ok, Re} = re:compile("^\\s*\\S+\\s+(\\d+).+\\d+\\s+"++DevPath++"\\S+/beam"), +kill_stragglers(Path, Timeout) -> + {ok, Re} = re:compile("^\\s*\\S+\\s+(\\d+).+\\d+\\s+"++Path++"\\S+/beam"), ReOpts = [{capture,all_but_first,list}], Pids = tl(string:tokens(os:cmd("ps -ef"), "\n")), Fold = fun(Proc, Acc) -> @@ -483,13 +581,13 @@ kill_stragglers(DevPath, Timeout) -> nomatch -> Acc; {match,[Pid]} -> - lager:info("Process ~s still running, killing...", + lager:debug("Process ~s still running, killing...", [Pid]), os:cmd("kill -15 "++Pid), case wait_for_pid(Pid, Timeout) of ok -> ok; fail -> - lager:info("Process ~s still hasn't stopped, " + lager:debug("Process ~s still hasn't stopped, " "resorting to kill -9...", [Pid]), os:cmd("kill -9 "++Pid) end, @@ -508,45 +606,41 @@ wait_for_pid(PidStr, Timeout) -> _ -> ok end. -stop_all(DevPath) -> - case filelib:is_dir(DevPath) of - true -> - Devs = filelib:wildcard(DevPath ++ "/dev*"), - Nodes = [?DEV(N) || N <- lists:seq(1, length(Devs))], - MyNode = 'riak_test@127.0.0.1', - case net_kernel:start([MyNode, longnames]) of - {ok, _} -> - true = erlang:set_cookie(MyNode, riak); - {error,{already_started,_}} -> - ok - end, - lager:info("Trying to obtain node shutdown_time via RPC..."), - Tmout = case rpc:call(hd(Nodes), init, get_argument, [shutdown_time]) of - {ok,[[Tm]]} -> list_to_integer(Tm)+10000; - _ -> 20000 - end, - lager:info("Using node shutdown_time of ~w", [Tmout]), - rt:pmap(gen_stop_fun(Tmout), lists:zip(Devs, Nodes)), - kill_stragglers(DevPath, Tmout); - _ -> - lager:info("~s is not a directory.", [DevPath]) +stop_nodes(Path, Nodes) -> + MyNode = 'riak_test@127.0.0.1', + case net_kernel:start([MyNode, longnames]) of + {ok, _} -> + true = erlang:set_cookie(MyNode, riak); + {error,{already_started,_}} -> + ok end, + lager:debug("Trying to obtain node shutdown_time via RPC..."), + Tmout = case rpc:call(?DEV(hd(Nodes)), init, get_argument, [shutdown_time]) of + {ok,[[Tm]]} -> list_to_integer(Tm)+10000; + _ -> 20000 + end, + lager:debug("Using node shutdown_time of ~w", [Tmout]), + rt:pmap(gen_stop_fun(Path, Tmout), Nodes), + kill_stragglers(Path, Tmout), ok. -stop(Node) -> - RiakPid = rpc:call(Node, os, getpid, []), - N = node_id(Node), - rt_cover:maybe_stop_on_node(Node), - run_riak(N, relpath(node_version(N)), "stop"), - F = fun(_N) -> - os:cmd("kill -0 " ++ RiakPid) =/= [] - end, - ?assertEqual(ok, rt:wait_until(Node, F)), - ok. +stop(Node, Version) -> + case rpc:call(?DEV(Node), os, getpid, []) of + {badrpc, nodedown} -> + ok; + RiakPid -> + %% rt_cover:maybe_stop_on_node(Node), + run_riak(Node, Version, "stop"), + F = fun(_N) -> + os:cmd("kill -0 " ++ RiakPid) =/= [] + end, + ?assertEqual(ok, rt:wait_until(?DEV(Node), F)), + ok + end. -start(Node) -> - N = node_id(Node), - run_riak(N, relpath(node_version(N)), "start"), +start(Node, Version) -> + %% N = node_id(Node), + run_riak(Node, Version, "start"), ok. attach(Node, Expected) -> @@ -562,7 +656,7 @@ interactive(Node, Command, Exp) -> N = node_id(Node), Path = relpath(node_version(N)), Cmd = riakcmd(Path, N, Command), - lager:info("Opening a port for riak ~s.", [Command]), + lager:debug("Opening a port for riak ~s.", [Command]), lager:debug("Calling open_port with cmd ~s", [binary_to_list(iolist_to_binary(Cmd))]), P = open_port({spawn, binary_to_list(iolist_to_binary(Cmd))}, [stream, use_stdio, exit_status, binary, stderr_to_stdout]), @@ -714,9 +808,9 @@ set_backend(Backend) -> set_backend(Backend, []). set_backend(Backend, OtherOpts) -> - lager:info("rtdev:set_backend(~p, ~p)", [Backend, OtherOpts]), + lager:debug("rtdev:set_backend(~p, ~p)", [Backend, OtherOpts]), Opts = [{storage_backend, Backend} | OtherOpts], - update_app_config(all, [{riak_kv, Opts}]), + update_app_config(all, version_here, [{riak_kv, Opts}]), get_backends(). get_version() -> @@ -726,9 +820,10 @@ get_version() -> end. teardown() -> - rt_cover:maybe_stop_on_nodes(), + %% rt_cover:maybe_stop_on_nodes(), %% Stop all discoverable nodes, not just nodes we'll be using for this test. - rt:pmap(fun(X) -> stop_all(X ++ "/dev") end, devpaths()). + %% rt:pmap(fun(X) -> stop_all(X ++ "/dev") end, devpaths()). + ok. whats_up() -> io:format("Here's what's running...~n"), @@ -739,8 +834,8 @@ whats_up() -> devpaths() -> lists:usort([ DevPath || {_Name, DevPath} <- proplists:delete(root, rt_config:get(rtdev_path))]). -versions() -> - proplists:get_keys(rt_config:get(rtdev_path)) -- [root]. +%% versions() -> +%% proplists:get_keys(rt_config:get(rtdev_path)) -- [root]. get_node_logs() -> Root = filename:absname(proplists:get_value(root, ?PATH)), diff --git a/src/rtssh.erl b/src/rtssh.erl index 69d97bbeb..2e5cd3d65 100644 --- a/src/rtssh.erl +++ b/src/rtssh.erl @@ -151,6 +151,22 @@ node_to_host(Node) -> throw(io_lib:format("rtssh:node_to_host couldn't figure out the host of ~p", [Node])) end. + +nodes(Count) -> + Hosts = rt_config:get(rtssh_hosts), + %% NumNodes = length(NodeConfig), + NodeConfig = busted_stuff, + NumNodes = Count, + NumHosts = length(Hosts), + case NumNodes > NumHosts of + true -> + erlang:error("Not enough hosts available to deploy nodes", + [NumNodes, NumHosts]); + false -> + Hosts2 = lists:sublist(Hosts, NumNodes), + deploy_nodes(NodeConfig, Hosts2) + end. + deploy_nodes(NodeConfig, Hosts) -> Path = relpath(root), lager:info("Riak path: ~p", [Path]), @@ -350,6 +366,7 @@ load_hosts() -> Hosts = lists:sort(HostsIn), rt_config:set(rtssh_hosts, Hosts), rt_config:set(rtssh_aliases, Aliases), + rt_config:set(rtssh_nodes, length(Hosts)), Hosts. read_hosts_file(File) -> @@ -707,10 +724,10 @@ whats_up() -> Up = [rpc:call(Node, os, cmd, ["pwd"]) || Node <- nodes()], [io:format(" ~s~n",[string:substr(Dir, 1, length(Dir)-1)]) || Dir <- Up]. -node_version(Node) -> +node_version(Node) -> rt_harness_util:node_version(Node). -attach(Node, Expected) -> +attach(Node, Expected) -> rt_harness_util:attach(Node, Expected). attach_direct(Node, Expected) -> @@ -812,7 +829,7 @@ teardown() -> to_list(X) when is_integer(X) -> integer_to_list(X); to_list(X) when is_float(X) -> float_to_list(X); to_list(X) when is_atom(X) -> atom_to_list(X); -to_list(X) when is_list(X) -> X. %Assumed to be a string +to_list(X) when is_list(X) -> X. %Assumed to be a string to_binary(X) when is_binary(X) -> X; diff --git a/src/test_harness.erl b/src/test_harness.erl index 11006372f..760c70202 100644 --- a/src/test_harness.erl +++ b/src/test_harness.erl @@ -17,18 +17,18 @@ %% under the License. %% %% ------------------------------------------------------------------- -%% @doc behaviour for all test harnesses. --module(test_harness). +%% @doc behaviour for all test harnesses. +-module(test_harness). --callback start(Node :: node()) -> 'ok'. --callback stop(Node :: node()) -> 'ok'. --callback deploy_clusters(ClusterConfigs :: list()) -> list(). +%% -callback start(Node :: node(), Version :: string()) -> 'ok'. +%% -callback stop(Node :: node()) -> 'ok'. +%% -callback deploy_clusters(ClusterConfigs :: list()) -> list(). -callback clean_data_dir(Nodes :: list(), SubDir :: string()) -> 'ok'. -callback spawn_cmd(Cmd :: string()) -> Port :: pos_integer(). -callback spawn_cmd(Cmd :: string(), Opts :: list()) -> Port :: pos_integer(). -callback cmd(Cmd :: string()) -> term()|timeout. -callback cmd(Cmd :: string(), Opts :: [atom()]) -> term()|timeout. --callback setup_harness(Test :: string(), Args :: list()) -> 'ok'. +%% -callback setup_harness(Test :: string(), Args :: list()) -> 'ok'. -callback get_version() -> term(). -callback get_backends() -> [atom()]. -callback set_backend(Backend :: atom()) -> [atom()]. @@ -41,9 +41,7 @@ -callback attach(Node :: node(), Expected:: list()) -> 'ok'. -callback attach_direct(Node :: node(), Expected:: list()) -> 'ok'. -callback console(Node :: node(), Expected:: list()) -> 'ok'. --callback update_app_config(atom()|node(), Config :: term()) -> 'ok'. +%% -callback update_app_config(atom()|node(), Config :: term()) -> 'ok'. -callback teardown() -> list(). -callback set_conf(atom()|node(), NameValuePairs :: [{string(), string()}]) -> 'ok'. -callback set_advanced_conf(atom()|node(), NameValuePairs :: [{string(), string()}]) -> 'ok'. - - diff --git a/tests/always_fail_test.erl b/tests/always_fail_test.erl index 39d6e341a..6734ec284 100644 --- a/tests/always_fail_test.erl +++ b/tests/always_fail_test.erl @@ -1,7 +1,8 @@ %% @doc A test that always returns `fail'. -module(always_fail_test). --export([confirm/0]). +-export([confirm/2]). --spec confirm() -> pass | fail. -confirm() -> +-spec confirm(rt_properties:properties(), proplists:proplist()) -> pass | fail. +confirm(_Properties, _MD) -> + lager:info("Running test confirm function"), fail. diff --git a/tests/always_pass_test.erl b/tests/always_pass_test.erl new file mode 100644 index 000000000..8b7a3aaa8 --- /dev/null +++ b/tests/always_pass_test.erl @@ -0,0 +1,15 @@ +%% @doc A test that always returns `fail'. +-module(always_pass_test). +-export([properties/0, + confirm/2]). + +-include_lib("eunit/include/eunit.hrl"). + +properties() -> + rt_properties:new([{make_cluster, false}]). + +-spec confirm(rt_properties:properties(), proplists:proplist()) -> pass | fail. +confirm(_Properties, _MD) -> + lager:info("Running test confirm function"), + ?assertEqual(1,1), + pass. diff --git a/tests/secondary_index_tests.erl b/tests/secondary_index_tests.erl index df58b8f41..0b9b99de5 100644 --- a/tests/secondary_index_tests.erl +++ b/tests/secondary_index_tests.erl @@ -33,18 +33,24 @@ -define(KEYS(A,B,C), [int_to_key(N) || N <- lists:seq(A,B), C]). -define(KEYS(A,B,G1,G2), [int_to_key(N) || N <- lists:seq(A,B), G1, G2]). +-define(DEVS(N), lists:concat([N, "@127.0.0.1"])). +-define(DEV(N), list_to_atom(?DEVS(N))). + properties() -> rt_properties:new([{node_count, 3}, {wait_for_transfers, true}, - {start_version, previous}, + {valid_backends, [eleveldb, memory]}, {config, config()}]). config() -> [{riak_kv, [{secondary_index_sort_default, false}]}, {riak_core, [{handoff_concurrency, 11}]}]. +-spec confirm(rt_properties:properties(), proplists:proplist()) -> pass | fail. confirm(Properties, _MD) -> - Nodes = rt_properties:get(nodes, Properties), + NodeMap= rt_properties:get(node_map, Properties), + Nodes = [rt_node:node_name(NodeId, NodeMap) + || NodeId <- rt_properties:get(node_ids, Properties)], Bucket = druuid:v4_str(), lager:info("Bucket: ~p", [Bucket]), PBC = rt_pb:pbc(hd(Nodes)), @@ -110,7 +116,7 @@ confirm(Properties, _MD) -> <<"field2_int">>, 1000000000000, TestIdxVal), - + rt_pb:stop(PBC), pass. assertExactQuery(Clients, Bucket, Expected, Index, Value) -> diff --git a/tests/verify_listkeys.erl b/tests/verify_listkeys.erl index 8ef477eb9..91c5efa1d 100644 --- a/tests/verify_listkeys.erl +++ b/tests/verify_listkeys.erl @@ -18,8 +18,9 @@ %% %% ------------------------------------------------------------------- -module(verify_listkeys). --behavior(riak_test). --export([confirm/0]). +%% -behavior(riak_test). +-export([properties/0, + confirm/2]). -include_lib("eunit/include/eunit.hrl"). -define(BUCKET, <<"listkeys_bucket">>). @@ -28,11 +29,17 @@ -define(UNDEFINED_BUCKET, <<"880bf69d-5dab-44ee-8762-d24c6f759ce1">>). -define(UNDEFINED_BUCKET_TYPE, <<"880bf69d-5dab-44ee-8762-d24c6f759ce1">>). -confirm() -> - [Node1, Node2, Node3, Node4] = Nodes = rt_cluster:deploy_nodes(4), - ?assertEqual(ok, rt_node:wait_until_nodes_ready(Nodes)), +properties() -> + rt_properties:new([{node_count, 4}, + {make_cluster, false}]). - lager:info("Nodes deployed, but not joined."), +-spec confirm(rt_properties:properties(), proplists:proplist()) -> pass | fail. +confirm(Properties, _MD) -> + [NodeId1, NodeId2, NodeId3 | _] = NodeIds = rt_properties:get(node_ids, Properties), + NodeMap = rt_properties:get(node_map, Properties), + Nodes = [rt_node:node_name(NodeId, NodeMap) || NodeId <- NodeIds], + + [Node1, Node2, Node3 | _] = Nodes, lager:info("Writing some known data to Node 1"), put_keys(Node1, ?BUCKET, ?NUM_KEYS), @@ -40,49 +47,29 @@ confirm() -> timer:sleep(2000), check_it_all([Node1]), - lists:foldl(fun(Node, [N1|_] = Cluster) -> - lager:info("An invitation to this party is cordially extended to ~p.", [Node]), - rt_node:join(Node, N1), - lager:info("Wait until there are no pending changes"), - Ns = lists:usort([Node|Cluster]), - rt:wait_until_no_pending_changes(Ns), - rt:wait_for_cluster_service(Ns, riak_kv), - ok = rt:wait_until_transfers_complete(Ns), - lager:info("Check keys and buckets after transfer"), - check_it_all(Ns), - Ns - end, [Node1], [Node2, Node3, Node4]), + lists:foldl(fun growing_cluster_check/2, [Node1], tl(Nodes)), lager:info("Checking basic HTTP"), check_it_all(Nodes, http), + Version = rt_properties:get(current_version, Properties), + lager:info("Stopping Node1"), - rt_node:stop(Node1), + rt_node:stop(NodeId1, Version), + rt:wait_until_unpingable(Node1), %% Stop current node, restart previous node, verify - lists:foldl(fun(Node, Prev) -> - lager:info("Stopping Node ~p", [Node]), - rt_node:stop(Node), - rt:wait_until_unpingable(Node), - - lager:info("Starting Node ~p", [Prev]), - rt_node:start(Prev), - UpNodes = Nodes -- [Node], - lager:info("Waiting for riak_kv service to be ready in ~p", [Prev]), - rt:wait_for_cluster_service(UpNodes, riak_kv), - - lager:info("Check keys and buckets"), - check_it_all(UpNodes), - Node - end, Node1, [Node2, Node3, Node4]), + lists:foldl(fun shrinking_cluster_check/2, + {{hd(NodeIds), Node1}, Nodes, Version}, + lists:zip(tl(NodeIds), tl(Nodes))), lager:info("Stopping Node2"), - rt_node:stop(Node2), + rt_node:stop(NodeId2, Version), rt:wait_until_unpingable(Node2), lager:info("Stopping Node3"), - rt_node:stop(Node3), + rt_node:stop(NodeId3, Version), rt:wait_until_unpingable(Node3), lager:info("Only Node1 is up, so test should fail!"), @@ -90,6 +77,33 @@ confirm() -> check_it_all([Node1], pbc, false), pass. +growing_cluster_check(JoiningNode, [ClusterNode|_] = Cluster) -> + lager:info("An invitation to this party is cordially extended to ~p.", [JoiningNode]), + rt_node:join(JoiningNode, ClusterNode), + lager:info("Wait until there are no pending changes"), + Ns = lists:usort([JoiningNode|Cluster]), + rt:wait_until_no_pending_changes(Ns), + rt:wait_for_cluster_service(Ns, riak_kv), + ok = rt:wait_until_transfers_complete(Ns), + lager:info("Check keys and buckets after transfer"), + check_it_all(Ns), + Ns. + +shrinking_cluster_check({NodeId, Node}, {{PrevId, PrevNode}, Nodes, Version}) -> + lager:info("Stopping Node ~p", [Node]), + rt_node:stop(NodeId, Version), + rt:wait_until_unpingable(Node), + + lager:info("Starting Node ~p", [PrevId]), + rt_node:start(PrevId, Version), + UpNodes = Nodes -- [Node], + lager:info("Waiting for riak_kv service to be ready in ~p", [PrevNode]), + rt:wait_for_cluster_service(UpNodes, riak_kv), + + lager:info("Check keys and buckets"), + check_it_all(UpNodes), + {{NodeId, Node}, Nodes, Version}. + put_keys(Node, Bucket, Num) -> Pid = rt_pb:pbc(Node), Keys = [list_to_binary(["", integer_to_list(Ki)]) || Ki <- lists:seq(0, Num - 1)], @@ -138,11 +152,11 @@ list_keys_for_undefined_bucket_type(Node, Interface, Bucket, Attempt, ShouldPass lager:info("Listing keys using undefined bucket type ~p on ~p using ~p. Attempt #~p", [?UNDEFINED_BUCKET_TYPE, Node, Interface, Attempt]), case ShouldPass of - true -> ok; - _ -> - {Status, Message} = Mod:list_keys(Pid, { ?UNDEFINED_BUCKET_TYPE, Bucket }), - ?assertEqual(error, Status), - ?assertEqual(<<"No bucket-type named '880bf69d-5dab-44ee-8762-d24c6f759ce1'">>, Message) + true -> ok; + _ -> + {Status, Message} = Mod:list_keys(Pid, { ?UNDEFINED_BUCKET_TYPE, Bucket }), + ?assertEqual(error, Status), + ?assertEqual(<<"No bucket-type named '880bf69d-5dab-44ee-8762-d24c6f759ce1'">>, Message) end, case Interface of @@ -195,30 +209,30 @@ list_buckets(Node, Interface, Attempt, Num, ShouldPass) -> list_buckets_for_undefined_bucket_type(Node, Interface, Attempt, ShouldPass) -> case Interface of - pbc -> - Pid = rt_pb:pbc(Node), - Mod = riakc_pb_socket; - http -> - Pid = rt_http:httpc(Node), - Mod = rhc + pbc -> + Pid = rt_pb:pbc(Node), + Mod = riakc_pb_socket; + http -> + Pid = rt_http:httpc(Node), + Mod = rhc end, lager:info("Listing buckets on ~p for undefined bucket type ~p using ~p. Attempt ~p.", - [Node, ?UNDEFINED_BUCKET_TYPE, Interface, Attempt]), + [Node, ?UNDEFINED_BUCKET_TYPE, Interface, Attempt]), case ShouldPass of - true -> ok; - _ -> - {Status, Message} = Mod:list_buckets(Pid, ?UNDEFINED_BUCKET_TYPE, []), - lager:info("Received status ~p and message ~p", [Status, Message]), - ?assertEqual(error, Status), - ?assertEqual(<<"No bucket-type named '880bf69d-5dab-44ee-8762-d24c6f759ce1'">>, Message) + true -> ok; + _ -> + {Status, Message} = Mod:list_buckets(Pid, ?UNDEFINED_BUCKET_TYPE, []), + lager:info("Received status ~p and message ~p", [Status, Message]), + ?assertEqual(error, Status), + ?assertEqual(<<"No bucket-type named '880bf69d-5dab-44ee-8762-d24c6f759ce1'">>, Message) end, case Interface of - pbc -> - riakc_pb_socket:stop(Pid); - _ -> ok + pbc -> + riakc_pb_socket:stop(Pid); + _ -> ok end. assert_equal(Expected, Actual) -> @@ -244,7 +258,6 @@ check_a_node(Node, Interface, ShouldPass) -> [list_keys_for_undefined_bucket_type(Node, Interface, ?BUCKET, Attempt, ShouldPass) || Attempt <- [1,2,3] ], [list_buckets(Node, Interface, Attempt, ?NUM_BUCKETS, ShouldPass) - || Attempt <- [1,2,3] ], + || Attempt <- [1,2,3] ], [list_buckets_for_undefined_bucket_type(Node, Interface, Attempt, ShouldPass) || Attempt <- [1,2,3] ]. - diff --git a/tools.mk b/tools.mk new file mode 100644 index 000000000..44ebe904c --- /dev/null +++ b/tools.mk @@ -0,0 +1,115 @@ +REBAR ?= ./rebar + +.PHONY: compile-no-deps test docs xref dialyzer-run dialyzer-quick dialyzer \ + cleanplt + +compile-no-deps: + ${REBAR} compile skip_deps=true + +test: compile + ${REBAR} eunit skip_deps=true + +docs: + ${REBAR} doc skip_deps=true + +xref: compile + ${REBAR} xref skip_deps=true + +PLT ?= $(HOME)/.combo_dialyzer_plt +LOCAL_PLT = .local_dialyzer_plt +DIALYZER_FLAGS ?= -Wunmatched_returns + +${PLT}: compile + @if [ -f $(PLT) ]; then \ + dialyzer --check_plt --plt $(PLT) --apps $(DIALYZER_APPS) && \ + dialyzer --add_to_plt --plt $(PLT) --output_plt $(PLT) --apps $(DIALYZER_APPS) ; test $$? -ne 1; \ + else \ + dialyzer --build_plt --output_plt $(PLT) --apps $(DIALYZER_APPS); test $$? -ne 1; \ + fi + +${LOCAL_PLT}: compile + @if [ -d deps ]; then \ + if [ -f $(LOCAL_PLT) ]; then \ + dialyzer --check_plt --plt $(LOCAL_PLT) deps/*/ebin && \ + dialyzer --add_to_plt --plt $(LOCAL_PLT) --output_plt $(LOCAL_PLT) deps/*/ebin ; test $$? -ne 1; \ + else \ + dialyzer --build_plt --output_plt $(LOCAL_PLT) deps/*/ebin ; test $$? -ne 1; \ + fi \ + fi + +dialyzer-run: + @echo "==> $(shell basename $(shell pwd)) (dialyzer)" +# The bulk of the code below deals with the dialyzer.ignore-warnings file +# which contains strings to ignore if output by dialyzer. +# Typically the strings include line numbers. Using them exactly is hard +# to maintain as the code changes. This approach instead ignores the line +# numbers, but takes into account the number of times a string is listed +# for a given file. So if one string is listed once, for example, and it +# appears twice in the warnings, the user is alerted. It is possible but +# unlikely that this approach could mask a warning if one ignored warning +# is removed and two warnings of the same kind appear in the file, for +# example. But it is a trade-off that seems worth it. +# Details of the cryptic commands: +# - Remove line numbers from dialyzer.ignore-warnings +# - Pre-pend duplicate count to each warning with sort | uniq -c +# - Remove annoying white space around duplicate count +# - Save in dialyer.ignore-warnings.tmp +# - Do the same to dialyzer_warnings +# - Remove matches from dialyzer.ignore-warnings.tmp from output +# - Remove duplicate count +# - Escape regex special chars to use lines as regex patterns +# - Add pattern to match any line number (file.erl:\d+:) +# - Anchor to match the entire line (^entire line$) +# - Save in dialyzer_unhandled_warnings +# - Output matches for those patterns found in the original warnings + @if [ -f $(LOCAL_PLT) ]; then \ + PLTS="$(PLT) $(LOCAL_PLT)"; \ + else \ + PLTS=$(PLT); \ + fi; \ + if [ -f dialyzer.ignore-warnings ]; then \ + if [ $$(grep -cvE '[^[:space:]]' dialyzer.ignore-warnings) -ne 0 ]; then \ + echo "ERROR: dialyzer.ignore-warnings contains a blank/empty line, this will match all messages!"; \ + exit 1; \ + fi; \ + dialyzer $(DIALYZER_FLAGS) --plts $${PLTS} -c ebin > dialyzer_warnings ; \ + cat dialyzer.ignore-warnings \ + | sed -E 's/^([^:]+:)[^:]+:/\1/' \ + | sort \ + | uniq -c \ + | sed -E '/.*\.erl: /!s/^[[:space:]]*[0-9]+[[:space:]]*//' \ + > dialyzer.ignore-warnings.tmp ; \ + egrep -v "^[[:space:]]*(done|Checking|Proceeding|Compiling)" dialyzer_warnings \ + | sed -E 's/^([^:]+:)[^:]+:/\1/' \ + | sort \ + | uniq -c \ + | sed -E '/.*\.erl: /!s/^[[:space:]]*[0-9]+[[:space:]]*//' \ + | grep -F -f dialyzer.ignore-warnings.tmp -v \ + | sed -E 's/^[[:space:]]*[0-9]+[[:space:]]*//' \ + | sed -E 's/([]\^:+?|()*.$${}\[])/\\\1/g' \ + | sed -E 's/(\\\.erl\\\:)/\1\\d+:/g' \ + | sed -E 's/^(.*)$$/^\1$$/g' \ + > dialyzer_unhandled_warnings ; \ + rm dialyzer.ignore-warnings.tmp; \ + if [ $$(cat dialyzer_unhandled_warnings | wc -l) -gt 0 ]; then \ + egrep -f dialyzer_unhandled_warnings dialyzer_warnings ; \ + found_warnings=1; \ + fi; \ + [ "$$found_warnings" != 1 ] ; \ + else \ + dialyzer $(DIALYZER_FLAGS) --plts $${PLTS} -c ebin; \ + fi + +dialyzer-quick: compile-no-deps dialyzer-run + +dialyzer: ${PLT} ${LOCAL_PLT} dialyzer-run + +cleanplt: + @echo + @echo "Are you sure? It takes several minutes to re-build." + @echo Deleting $(PLT) and $(LOCAL_PLT) in 5 seconds. + @echo + sleep 5 + rm $(PLT) + rm $(LOCAL_PLT) + From e11f1833e3c6f74498efde19e0344788577c0617 Mon Sep 17 00:00:00 2001 From: Kelly McLaughlin Date: Mon, 15 Dec 2014 12:38:01 -0700 Subject: [PATCH 2/2] Port Jon Anderson's work on test groups to avoid merge pain --- src/riak_test_escript.erl | 103 ++++++++++++++++++++++++++------------ 1 file changed, 72 insertions(+), 31 deletions(-) diff --git a/src/riak_test_escript.erl b/src/riak_test_escript.erl index 09a355201..ffb8f5f52 100644 --- a/src/riak_test_escript.erl +++ b/src/riak_test_escript.erl @@ -192,16 +192,13 @@ help_or_parse_args({ok, {[], _}}) -> help_or_parse_args({ok, {ParsedArgs, HarnessArgs}}) -> help_or_parse_tests(ParsedArgs, HarnessArgs, - lists:member(help, ParsedArgs), - args_invalid(ParsedArgs)); + lists:member(help, ParsedArgs)); help_or_parse_args(_) -> print_help(). -help_or_parse_tests(_, _, true, _) -> +help_or_parse_tests(_, _, true) -> print_help(); -help_or_parse_tests(_, _, false, true) -> - print_help(); -help_or_parse_tests(ParsedArgs, HarnessArgs, false, false) -> +help_or_parse_tests(ParsedArgs, HarnessArgs, false) -> %% Have to load the `riak_test' config prior to assembling the %% test metadata load_initial_config(ParsedArgs), @@ -212,16 +209,6 @@ help_or_parse_tests(ParsedArgs, HarnessArgs, false, false) -> Workers = rt_config:get(workers, undefined), shuffle_tests(ParsedArgs, HarnessArgs, Tests, NonTests, Offset, Workers). -args_invalid(ParsedArgs) -> - case { proplists:is_defined(groups, ParsedArgs), - proplists:is_defined(tests, ParsedArgs) } of - {true, true} -> - io:format("--groups and --tests are currently mutually exclusive.~n~n"), - true; - {_, _} -> - false - end. - load_initial_config(ParsedArgs) -> %% Loads application defaults application:load(riak_test), @@ -316,11 +303,16 @@ set_lager_env(OutputDir, ConsoleLevel, FileLevel) -> %% end, %% ok. -load_tests([], ParsedArgs) -> +-spec comma_tokenizer(string(), [string()]) -> [string()]. +comma_tokenizer(S, Acc) -> + string:tokens(S, ", ") ++ Acc. + +compose_test_data(ParsedArgs) -> RawTestList = proplists:get_all_values(tests, ParsedArgs), - TestList = lists:foldl(fun(X, Acc) -> - string:tokens(X, ", ") ++ Acc - end, [], RawTestList), + RawGroupList = proplists:get_all_values(groups, ParsedArgs), + TestList = lists:foldl(fun comma_tokenizer/2, [], RawTestList), + GroupList = lists:foldl(fun comma_tokenizer/2, [], RawGroupList), + %% Parse Command Line Tests {CodePaths, SpecificTests} = lists:foldl(fun extract_test_names/2, @@ -330,16 +322,29 @@ load_tests([], ParsedArgs) -> [code:add_patha(CodePath) || CodePath <- CodePaths, CodePath /= "."], - Dirs = proplists:get_all_values(dir, ParsedArgs), + Dirs = get_test_dirs(ParsedArgs, default_test_dir(GroupList)), SkipTests = string:tokens(proplists:get_value(skip, ParsedArgs, []), [$,]), - DirTests = lists:append([load_tests_in_dir(Dir, SkipTests) || Dir <- Dirs]), - %% Project = list_to_binary(rt_config:get(rt_project, "undefined")), - - %% Upgrades = proplists:get_value(upgrade_path, ParsedArgs), - %% TestFoldFun = test_data_fun(rt:get_version(), Project, Upgrades), - %% lists:foldl(TestFoldFun, [], lists:usort(DirTests ++ SpecificTests)). + DirTests = lists:append([load_tests_in_dir(Dir, GroupList, SkipTests) || Dir <- Dirs]), lists:usort(DirTests ++ SpecificTests). +-spec default_test_dir([string()]) -> [string()]. +%% @doc If any groups have been specified then we want to check in the +%% local test directory by default; otherwise, the default behavior is +%% that no directory is used to pull tests from. +default_test_dir([]) -> + []; +default_test_dir(_) -> + ["./ebin"]. + +-spec get_test_dirs(term(), [string()]) -> [string()]. +get_test_dirs(ParsedArgs, DefaultDirs) -> + case proplists:get_all_values(dir, ParsedArgs) of + [] -> + DefaultDirs; + Dirs -> + Dirs + end. + extract_test_names(Test, {CodePaths, TestNames}) -> {[filename:dirname(Test) | CodePaths], [list_to_atom(filename:rootname(filename:basename(Test))) | TestNames]}. @@ -387,6 +392,23 @@ is_runnable_test(TestModule) -> erlang:function_exported(Mod, Fun, 0) orelse erlang:function_exported(Mod, Fun, 2). +get_group_tests(Tests, Groups) -> + lists:filter(fun(Test) -> + Mod = list_to_atom(Test), + Attrs = Mod:module_info(attributes), + match_group_attributes(Attrs, Groups) + end, Tests). + +match_group_attributes(Attributes, Groups) -> + case proplists:get_value(test_type, Attributes) of + undefined -> + false; + TestTypes -> + lists:member(true, + [ TestType == list_to_atom(Group) + || Group <- Groups, TestType <- TestTypes ]) + end. + %% run_tests(Tests, Outdir, Report, HarnessArgs) -> %% Need properties for tests prior to getting here Need server to %% manage the aquisition of nodes and to handle comparison of test @@ -538,29 +560,48 @@ backend_list(Backends) when is_list(Backends) -> end, lists:foldl(FoldFun, [], Backends). -load_tests_in_dir(Dir, SkipTests) -> +load_tests_in_dir(Dir, Groups, SkipTests) -> case filelib:is_dir(Dir) of true -> code:add_path(Dir), lists:sort( - lists:foldl(load_tests_folder(SkipTests), + lists:foldl(load_tests_folder(Groups, SkipTests), [], filelib:wildcard("*.beam", Dir))); _ -> io:format("~s is not a dir!~n", [Dir]) end. -load_tests_folder(SkipTests) -> +load_tests_folder([], SkipTests) -> fun(X, Acc) -> + %% Drop the .beam suffix Test = string:substr(X, 1, length(X) - 5), case lists:member(Test, SkipTests) of true -> Acc; false -> - [Test | Acc] + [list_to_atom(Test) | Acc] + end + end; +load_tests_folder(Groups, SkipTests) -> + fun(X, Acc) -> + %% Drop the .beam suffix + Test = string:substr(X, 1, length(X) - 5), + case group_match(Test, Groups) + andalso not lists:member(Test, SkipTests) of + true -> + [list_to_atom(Test) | Acc]; + false -> + Acc end end. +-spec group_match(string(), [string()]) -> boolean(). +group_match(Test, Groups) -> + Mod = list_to_atom(Test), + Attrs = Mod:module_info(attributes), + match_group_attributes(Attrs, Groups). + so_kill_riak_maybe() -> io:format("~n~nSo, we find ourselves in a tricky situation here. ~n"), io:format("You've run a single test, and it has failed.~n"),