Getting started with riak_test and riak_core
If you don't know what riak_core
is, or don't have a riak_core
based application you'll probably not take too much practical use of this posts you might want to start with Ryan Zezeski's “working” blog try try try and the rebar plugin.
That said if you have a riak_core
app this posts should get you started on how to test it with riak_test
. We'll not go through the topic of how to write the tests itself, this might come in a later post also the riak_kv
tests are a good point to start.
Please note that the approach described here is what I choose to do, it might not be best practice of the best way for you to do things. I also will link to my fork of riak_test
instead of the official one since it includes some modifications required for testing apps other then riak_kv
I hope those modifications will be merged back at some point but for now I want to get it ironed out a bit more before making a pull request.
What is riak_test?
So before we start; a few words to riak_test
. riak_test
is a pretty nice framework for testing distributed applications, it is, just as much as all the other riak_
stuff created by Basho, pretty darn awesome.
At it's current state it is very focused on testing riak_kv
(or riak
as in the database) but from a first glance a lot of functionality is very universal and after all riak_kv
is also built on top of riak_core
, so modifying it to run with other riak_core
based apps is pretty easy.
The setup
Since I will be testing multiple riak_core
apps and not just one I decided to go the following path: Have the entire setup in a git repository, then have one branch for general fixes/changes to riak_core
then have one branch for each application I want to test that is based on the general branch so common changes can easily be merged so it will look like this:
---riak_test--------- (bashos master tree)
`---riak_core----- (modifications to make riak_test work with core apps)
` ` `---sniffle- (tests for sniffle)
` `---snarl----- (tests for snarl)
`---howl------- (tests for howl)
We'll go over this and setting up tests for the howl application it's rather small and simple and it's easier to follow along with something real instead of a made up situation.
Getting started
Step one of getting started is to get a clone from the riak_test
repository, that's pretty simple (alter the path if you decided to fork):
cd ~/Projects
git clone https://github.com/Licenser/riak_test.git
cd riak_test
Now we branch off to have a place to get our howl
application but first we need to checkout the riak_core branch to make sure we get the changes included in it:
git branch howl && git checkout howl can be git checkout -b howl
Okay that's it for the basic setup not that bad so far is it?
Configuration
Next thing we need to do is create a configuration, at this point we'll assume you don't have one yet so we'll start from scratch, if you add more then one application later on you can just add them to an existing configuration.
riak_test
looks for the configuration file ~/.riak_test.config
and reads all the data from there so we'll first need to copy the sample config there:
cp riak_test.config.sample ~/.riak_test.config
Next step is to open it in your favorite editor, you'll recognize it's a good old Erlang config file with tuples to group sections. We'll be ignoring the default
section for now, if you're interested in it the documentation is quite good!
So lets go down to where it reads:
%% ===============================================================
%% Project-specific configurations
%% ===============================================================
Here is where the fun starts, you'll see a tuple starting with {rtdev,
- note this rtdev
has nothing whatsoever to do with the rtdev
that is in the default
section as {rt_harness, rtdev}
. The rtdev
in the project part is just the name of the project, since your project is named howl
not rtdev
we'll go and change that first.
{rtdev, [
Now we can go to set up some variables first up the project name and executables, the name itself is just for information (or if you use giddyup
) the executables are how your application is started, since our application is named howl
it's started with the command howl
and the admin command for it is howl-admin
.
%% The name of the project/product, used when fetching the test
%% suite and reporting.
{rt_project, "howl"},
{rc_executable, "howl"},
{rc_admin, "howl-admin"},
With that done come the services, those are the buggers you register in your _app.erl file, lets have a look at the howl_app.erl:
%...
ok = riak_core_node_watcher:service_up(howl, self()),
%...
So we only have one service here we need to watch out for, named, you might guess … right howl
that makes the list rather short:
{rc_services, [howl]},
Now the cookie, it's a bit hidden in the code that you need to set it but you do, you will need this later so remember it! Since I am bad at remembering things I named it … howl
… again.
{rt_cookie, howl},
Now comes the setup of paths, for this we've to decide where we want to put our data later on, I've put all my riak_test
things in ~/rt/...
so we'll follow with this. Also note that my development process works on three branches:
test
- the most unstable branch.dev
- here things go that should work.master
- only full releases go in here.
This setup might not work for you at all, but since these are only path names it should be easy enough to adapt.
Note that by default riak_test
will run tests on the current
environment
%% Paths to the locations of various versions of the project. This
%% is only valid for the `rtdev' harness.
{rtdev_path, [
%% This is the root of the built `rtdev' repository,
%% used for manipulating the repo with git. All
%% versions should be inside this directory.
{root, "~/rt/howl"},
%% The path to the `current' version, which is used
%% exclusively except during upgrade tests.
{current, "~/rt/howl/howl-test"},
%% The path to the most immediately previous version
%% of the project, which is used when doing upgrade
%% tests.
{previous, "~/rt/howl/howl-dev"},
%% The path to the version before `previous', which
%% is used when doing upgrade tests.
{legacy, "~/rt/howl/howl-stable"}
]}
]}
And that's it now the config is set up and should look like this:
{rtdev, [
%% The name of the project/product, used when fetching the test
%% suite and reporting.
{rt_project, "howl"},
{rc_executable, "rhowl"},
{rc_admin, "howl-admin"},
{rc_services, [howl]},
{rt_cookie, howl},
%% Paths to the locations of various versions of the project. This
%% is only valid for the `rtdev' harness.
{rtdev_path, [
%% This is the root of the built `rtdev' repository,
%% used for manipulating the repo with git. All
%% versions should be inside this directory.
{root, "~/rt/howl"},
%% The path to the `current' version, which is used
%% exclusively except during upgrade tests.
{current, "~/rt/howl/howl-test"},
%% The path to the most immediately previous version
%% of the project, which is used when doing upgrade
%% tests.
{previous, "~/rt/howl/howl-dev"},
%% The path to the version before `previous', which
%% is used when doing upgrade tests.
{legacy, "~/rt/howl/howl-stable"}
]}
]}
Setting up the application
We've got riak_test
ready to test now next we need to prepare howl to be tested, we'll only look at the current
(aka test
) setup since the steps for others are pretty much the same.
The first step is that we need the folder, so lets create it
mkdir -p ~/rt/raw/howl
cd ~/rt/raw/howl
Since howl lives with the octocat on github it's easy to fetch our application and checkout the test branch (remember current
is on the test branch for me):
git clone https://github.com/project-fifo/howl.git howl-test
cd howl-test
git checkout test
And done, now since it's a riak_core
app we should have a task called stagedevrel
in our makefile which will basically generate three copies of howl
for us in the folders dev/dev{1,2,3}
and in the process take care of compiling and getting the dependencies. I prefer stagedevrel
over the normal devrel
since later on it will it easier to recompile code files (make
is enough) because it links them to the right place instead of copying them.
make stagedevrel
Now we've got to do a bit of cheating, riak_test
expects the root dir to be a git repository, that is why we can't just put the data in there directly, so we've to manually build the tree for riak core and set it up as a git repository.
mkdir -p ~/rt/howl
cd ~/rt/howl
git init
cat <<EOF > ~/rt/howl/.gitignore
*/dev/*/bin
*/dev/*/erts-*
*/dev/*/lib
*/dev/*/releases
*/dev/*/share
*/dev/*/snmp
EOF
git add .gitignore
Now we need to link our devrel files. Since howl uses [cuttlefish] I have to copy the howl.config.example
file to howl.config
into etc
directory, this may be different for your setup.
export RT_BASE=~/rt/howl/howl-test
export RC_BASE=~/rt/raw/howl/howl-test
for i in 1 2 3 4
do
mkdir -p ${RT_BASE}/dev/dev${i}/
cd ${RT_BASE}/dev/dev${i}/
mkdir data etc
touch data/.gitignore
ln -s ${RC_BASE}/dev/dev${i}/{bin,erts-*,lib,releases,share,snmp} .
cp ${RC_BASE}/dev/dev${i}/etc/howl.conf.example etc/howl.conf
done
We still need to edit the vm.args
in dev/dev{1,2,3,4}/etc/
since we need to set the correct cookie - I hope you still remember yours, I told you you'd need it (if not you can just look in the ~/.riak_test.config
)!
That's it.
How add the content to the git repository you initiated and commit it.
cd $RT_BASE && git add . && git commit -am 'First build.'
Running a first test
In the riak_core
branch of riak_test
I've moved all the riak_kv
specific tests from tests
to tests_riakkv
so you still can look at them but I left one of them in tests
, namely the basic command test - it will check if your applications command (howl
in our case) is well behaved.
We'll want to run it to see if howl
is a good boy and does well to do so we'll need to get back into the riak_test
folder and run the riak_test
command:
cd ~/Projects/riak_test
./riak_test -t tests/* -c howl -v -b none
I'd like to explain this a bit, the arguments have the following meaning:
-t tests/*
- we'll be running all tests in the foldertests/
.-c howl
- our application we want to test is named howl, this is the first element of the tuple we put in our config file when you remember.-v
- This just turns on verbose output.-b none
- This is still a relict from theriak_kv
roots, it means which backend to test with, since we don't have backends at all we'll just pass none which means riak_test will happily ignore it.
That's it! Now go and test all the things!
This is the first part of a series that goes on here.