In this post I am going to give a quick introduction into Tomty.
Tomty is installed as Raku module, using zef - Raku package manager:
zef install --/test https://github.com/melezhik/Sparrow6.git zef install --/test https://github.com/melezhik/Tomty.git
We need bleeding edge version of Tomty and Sparrow (dependency for Tomty) to get an access to all the features mentioned in this post.
Working with Tomty requires some initialization. First of all we need to create a working directory for tests and initialize it. Optionally we can install Bash completion for
tomty - Tomty cli application:
export SP6_REPO=https://sparrowhub.io/repo mkdir work cd work tomty --init tomty --completion
Scenarios could be written on many languages, in this post I'll focus on Bash as it's a simple and quite popular scripting language for devops tasks and automation. Tomty allows effectively right low level tasks in Bash while gluing them together with Raku.
A Bash scenario should be just a file named
task.bash and located at some directory:
mkdir -p tasks/task1/ nano tasks/task1/task.bash
echo "hello world"
Once bash task is created, we can run it through a Raku wrapper:
tomty --edit my-task
#!raku task-run "tasks/task1"
In context of Raku a Bash task gets called as a Raku function
task-run, with a parameter setting a task directory.
The approach gives us a benefit of using high level language to call low level Bash scenarios.
Now, let's run our first task:
[repository] :: index updated from file:///root/repo/api/v1/index [tasks/task1] :: hello world
The task executed successfully, now let's convert this trivial hello world example it into something more practical.
The task of checking an http resource health check is quite common in daily devops @job. Let's see how we could do this in Tomty.
First, let's create a Bash task.
curl -s -f $(config url) -o /dev/null -D - | head -n 4
The task is just using
curl command to GET some http URL, pay attention that
-f flag causes curl to exit with none zero exit code in case of receiving none successful http response.
A Tomty scenario, would change a bit to pass tested URL as a paramater into a Bash task:
tomty --edit my-task
#!raku task-run "tasks/task1", %( url => "https://raku.org" );
Now let's see how it works:
[tasks/task1] :: HTTP/2 200 [tasks/task1] :: date: Fri, 02 Jul 2021 18:20:58 GMT [tasks/task1] :: content-type: text/html [tasks/task1] :: last-modified: Tue, 25 May 2021 16:30:03 GMT
As we could see Bash
config name is used as function to access named parameters passed to Bash from Raku as a Raku Hash. This semantic works because Tomty is build on top of Sparrow automation tool, that provides all type of such functionality.
Many times, relying on a script exit code to check if a test passes or not works just fine, however sometime one needs to specify expected script output to define a test state.
Let's see how Tomty allows that.
Task checks allow define an output a test expects to see in a running script:
So we check that https://raku.org web server servers HTTP v2 protocol:
[repository] :: index updated from file:///root/repo/api/v1/index [tasks/task1] :: HTTP/2 200 [tasks/task1] :: date: Fri, 02 Jul 2021 19:08:34 GMT [tasks/task1] :: content-type: text/html [tasks/task1] :: last-modified: Tue, 25 May 2021 16:30:03 GMT [task check] stdout match <HTTP/2 200> True
And if we want to check against v1 or v2, we can use Raku regular expressions:
regexp: "HTTP/" 1 || 2 " 200"
Refer to Sparrow task check documentation to get full explanation of the DSL and see more complex examples of validating scripts output.
Once you have more and more tests you can run all then by using
--all parameter of tomty cli:
However when there are too many tests, it's gets really difficult to manage them.
Tags allows to split your tests by multiple groups and run them specifically. It's could extremely useful with a huge tests base.
Let me show a quick simple example using the previous web site check scenario.
Say, we don't want to run our web site availability test if we don't have the internet access on our testing environment.
Let's first add a tag to a Raku scenario:
tomty --edit my-task
#!raku =begin tomty %( tags => [ 'offline'] ) =end tomty task-run "tasks/task1", %( url => "https://raku.org" );
As we can see tags added into dedicated "tomty" Pod6 sections as Raku array ( there could be many tags ).
Now let's see how we could use this tag, when running tomty cli:
[1/1] / [my-task] ....... SKIP ========================================= (=: /  tests in 0 sec / (0) tests passed
As we can see Tomty did not execute the test, as we required to skip any tests tagged as
We could have build even more sophisticated examples. For example to run only offline tests for application version 2, but to skip production tests:
tomty --only=offline+app-v2 --skip=production
To list all available tags run:
tomty --list --tags
Sometimes you want only list tests with theirs tags, not execute them, the previous example would be rewritten as:
tomty --tags --only=offline+app-v2 --skip=production
This was a brief introduction into Tomty - test framework written on Raku and supporting many scripting languages to write low level tasks. The main philosophy of Sparrow ( the engine Tomty is built upon ) - use those languages that fits your domain best ( in our case - Bash is simple and efficient way to send http requests) and glue scripts together using high language - Raku, where scripts get called as functions.
When I develop tests for my daily devops tasks on Tomty, I switch between Bash and Raku often and this approach allows me do my work effectively and with minimal efforts.
Thanks for reading. I'd like to hear feedback as usual.