I hate writing tests. There’s only one thing I hate more: not having tests. So I like it when writing and running tests for anything is easy.
In part 1 of Rex in practice series, we got started with describing our infrastructure as code. All of those automation bits are kept in git repositories. They are nothing but code after all. Since they are code, we want them covered by tests.
Normally, we would start with writing tests which can check for the expected state of a remote machine, and then we write our code in iterations to pass all the cases.
Rex supports managing virtual machines and containers through different methods, like LibVirt, VirtualBox or Docker (and even some cloud providers). Built on top of this functionality, it also has a Vagrant-like feature called Rex::Box.
Rex::Test in turn, makes use of Rex::Box to quickly create a VM, provision it by running one or more tasks and then run a series of tests checking the state of the machine.
Following up on the example in the previous part of the series, our NTP tests would probably be similar to this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
Let’s see the elementary steps of this example:
It starts with importing some modules we would like to use:
Rex::Test::Base for the tests themselves
Rex::Commands::MD5 for the
used later in one of the examples.
The default virtualization method is VirtualBox, but in this example we would like to use a KVM box, so we need to specify that explicitly.
Next we instantiate a
Its methods will enable us
to tell Rex what we would like to test and how.
1 2 3
First we give a name to the VM which will run the tests
ntp_test in this case),
then point Rex to the base image to use when creating this new VM,
and finally specify the authentication credentials for the VM.
Rex downloads the specified image into
and then tries to import it as a new VM,
cloning the base image into
(so the original file is left untouched
and can be reused multiple times).
Depending on the virtualization method requested
and the type of the image,
Rex also tries to extract and/or convert it before using it.
if the specified base image is a
or if a file in OVA format should be used with KVM.
As the last step of initialization,
this line will provision the VM
by running a Rex task called
ntp on it.
That’s the task we specified in the previous post,
but normally would define it when this step fails.
It is possible to run multiple tasks,
by passing them as an array reference.
1 2 3 4 5 6 7 8 9 10 11 12 13 14
After the boilerplate and test initialization, let’s see the tests themselves. The above code snippet executes the following tests inside the VM in order:
- check if it has a specific package installed,
- check if it has a specific file present,
- check if that file has specific properties, like owner and group
- check if that file has a specific content,
matching the regular expression
- run the
md5Rex command inside the VM to calculate the MD5 checksum for the same configuration file, and then check if it matches a specific value
- check if the VM has a specific service (
ntpd) in a running state
- finish the test suite
As you can see,
we’re not limited to the built-in tests,
but we can run arbitrary commands inside the VM,
record their output or return code,
and then check them against their expected values
Before we can actually run the test via Rex, we need to add one more line to our Rexfile we showed in the previous post:
1 2 3 4