February 2016 Archives

cpanparty first members

Below is the list of cpanparty first members

  • Kelp 0.9071
  • Dancer2 0.166001
  • Mojolicious::Plugin::Vparam 1.4
  • Dancer2::Plugin::Ajax 0.200001
  • Dancer2::Plugin::Res 0.03
  • Plack::Middleware::StackTrace::LinkedSource 0.12
  • Raisin 0.63


-- Alexey

Introducing CPANParty

Not long time ago I asked a community about possible service to run integration tests for existed cpan modules , not having too much feedback I decided to run such a service to make my suggestion visible and available to try for other users.

So, meet CPANParty - an alternative integration tests for cpan modules. Right now service is hosted on swatpm site, but in the future I will probably move it to dedicated domain.

Only a few randomly chosen cpan modules was picked up and tested. Eventually I will add more.

So, questions, ideas, issues?

Please comment here or to https://github.com/melezhik/cpanparty

Thanks in advance

Alexey Melezhik

PS CPANParty reports page below

cpanparty reports

3Party - cpan modules third party testing

Last time I have been deeply involved into test automation development. So some projects was born like swat, outthentic and finally sparrowhub.

After some mediation on the future of my projects I am still committed to the idea of sharing such a tests with the rest of perl/cpan community.

An issues arise on my way though:

  • people used to stick to convenient unit tests kept under their cpan distributions and are half-heartedly for third party tests alternative which of course is respected by me.

  • (IMHO) integration tests are hard to write and maintain, this is probably why people prefer to write unit tests, and as swat is kind of integration test tool, it could be "neglected" for the reason above. I believe still that integration tests are essential part of development.

Taking into account all of this I am introducing an idea of third party tests service - 3Party ( working name, just can't invent something better right now ) with the following features:

  • tests are written on swat or outthentic frameworks

  • cpan modules to test are randomly chosen and tests are provided

  • if one want to force your cpan module to get tested via 3Party - welcome! we could discuss it

  • a cpan modules author receive test reports via email or through 3Party web interface

  • tests triggered at every cpan module release so they could be considered as regression base

  • no warranty for full coverage of cpan module API, but test base could be increased eventually as far as tests contributors have a free time on it ( or new tests contributors join the team )

  • now tests contributors team is me only but new developers are welcome

  • tests relies on cpan module public API provided by it's documentation, in case false test issue a cpan module author is encouraged to help test author to correct tests behavior, but it is only guaranteed that test author will follow cpan module documentation and try to implement things based on his understanding of such a documentation

This only an informal draft of the idea.

I need a community feedback before to dive into this project.


Alexey Melezhik

Am I reinventing a wheel?

The thing that hath been, it is that which shall be; and that which is done is that which shall be done: and there is no new thing under the sun. Is there any thing whereof it may be said, See, this is new? it hath been already of old time, which was before us. (Ecclesiastes 1:9,10)

Outthentic is a tool for rapid plugin developments. When I say "plugin" I mean a little utility to solve a specific task.

Having a risk to reinvent the wheel, from time to time I still start to create some useful stuff, at least useful from my point of view ...

Disk usage monitoring

This little plugin does what is stated at the header:

  • checks disk space in partition by partition basis
  • alerts in case of shortage
  • a threshold parameter could be set and equal 80 default, which means before 80 percentage of disk usage we are ok.


This plugin is written on outthentic and better way to install is sparrow - outthentic plugin manager. So here we go:

# a basic prerequisites  
apt-get install curl
cpanm Sparrow

# now we install plugin
sparrow index update
sparrow plg install df-check
sparrow project create system
sparrow check add system disk
sparrow check set system disk df-check
sparrow check ini system disk # skip this step if you want default settings

Once plugin is installed one my run it:

sparrow check run  system disk | perl -n -e 'print "    ", $_'
# running cd /home/vagrant/sparrow/plugins/public/df-check && carton exec 'strun --root ./  --ini /home/vagrant/sparrow/projects/system/checkpoints/disk/suite.ini ' ...

/tmp/.outthentic/9034/home/vagrant/sparrow/plugins/public/df-check/disk-shortage/story.t ..
ok 1 - perl /home/vagrant/sparrow/plugins/public/df-check/disk-shortage/story.pl succeeded
ok 2 - stdout saved to /tmp/.outthentic/9034/gJBohrjXGg
# threshhold: 93
# verify ... /dev/sda1
# verify ... udev
# verify ... tmpfs
# verify ... tmpfs
# verify ... tmpfs
# verify ... tmpfs
# verify ... none
# verify ... none
ok 3 - output match /(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)/
ok 4 - enough disk space (74%) on /dev/sda1
ok 5 - enough disk space (0%) on udev
ok 6 - enough disk space (1%) on tmpfs
ok 7 - enough disk space (1%) on tmpfs
ok 8 - enough disk space (0%) on tmpfs
ok 9 - enough disk space (0%) on tmpfs
ok 10 - enough disk space (90%) on none
ok 11 - enough disk space (90%) on none
All tests successful.
Files=1, Tests=11,  0 wallclock secs ( 0.02 usr  0.00 sys +  0.04 cusr  0.00 csys =  0.06 CPU)
Result: PASS

And finally make it cronable

crontab -e 
*/30 * * * *  sparrow check run  system disk --cron

Is it a better wheel?

Well, ... I think so )))), at least my thoughts are:

  • it is written on perl
  • it has clear and simple installation and configuration layout
  • it has minimal dependencies - a few perl modules and df utility itself
  • it is hack-able - consider some improvements? check out a source code and make a MR!

Playing games with outthentic dsl

Playing games with outthentic dsl

Outthentic - is language to parse unstructured text. It was grown as supporter for web application test tool named swat. Web application is where text often comes in unstructured and unordered way, even though there is json and xml, there are a lot of applications when it is not the case.

Then a generic test tool named outthentic was created as solution for any text parsing/testing tasks. This tool is based on outthentic dsl as well.

Creation a new consumers of outthentic language is way too easy, with API exposed and explained at outthentic documentation.

What I try to do in this short post is to highlight some randomly picked features to let readers to have a sense what is outthentic way to analyze and verify text output, which of course could be used wide in daily testing tasks.

If ( after reading this post ) you feel like to know more - an official outthentic documentation is here and ( less formal ) - here


Sometimes you are given with some repetitive lines bounded by some conditions .

A classic thing is tables.

Imagine a table with two columns of ABC letters and a position numbers:

Letter  Number
A       1
B       2
C       3
Z       26
End of table

Let's write up a dsl code to verify that:

  • we have table 26 rows with 2 cell in each one
  • a first cell of every row is ABC letter and second one is a number.

First let's verify a basic structure:

between: Letter\s+Number End\s+of\s+table
    regexp: ([A-Z]+)\s+(\d+)

Having this we asked outthentic dsl parser to check that we have Letters and numbers inside range bounded by table header and table footer. Quite easy so far.

Then let's count a table rows.

To do this we need to add some imperative constructions to this quite declarative code:

between: Letter\s+Number End\s+of\s+table
    regexp: ([A-Z]+)\s+(\d+)
    code: our $total_rows++ for @{match_lines()};
    validator: [  our $total_rows == 26, 'valid rows number ']

Comments here:

  • code: expressions

Define perl code being executed during parsing process

  • match_lines() function

Returns array of successfully matched lines

  • validator: expressions

Define perl code being executed, once code is executed a return value is passed as as arguments to Test::More::ok function:

# $r - is array reference returned after execution of :validator code 


Fine control with captures

Captures function let you gain more fine control over data being checked. It returns all the chunks get captured over latest regular expression check.

between: Letter\s+Number End\s+of\s+table
    regexp: ([A-Z]+)\s+(\d+)
    code:                                   \
    for my $c (@{captures()}){              \
        print $c->[0],'/',$c->[1], "\n";    \

The code above will print:


Sequences and generators

Continuous lines sequences are often a subject of testing when dealing with unstructured text.

Let's rewrite latest code example using text block expressions:

    A 1
    B 2
    C 3
    # and so on till Z 26

This simple code snippet is example of continuous sequence check, when you need to verify that one line followed by another and so on.

Quite easy, but we need to hardcode all 26 rows, which is not good. Let's rewrite this simple test again using generator expression:

    generator: [ my $i, map { $i++; "$_ $i" } A .. Z ]

Generators like code: or validator: expressions are just piece of perl code being executed.

A return value of generator code ( should be array reference ) defines new outthentic entities get parsed by outthentic parser.

There is no limit, as generator could create:

  • new check expressions

  • validator expressions

  • code expressions

  • ... and generator expressions - a sophisticated example is described here


And finally new killer feature of outthentic dsl called streams.

Stream() function like match_lines() function return lines successfully matched during verification process.

But streams add some improvements against match_lines, they are able to:

  • accumulate data ( match_lines always relates to latest check )

  • group data ( see example below )

Let's see a trivial text output need to verify:




Writing a dsl code:

between <letters> <\/letters>
regexp: [A-Z]

So good so far. Let's add some debugging lines:

between <letters> <\/letters>
regexp: [A-Z]
code: for my $l (@{match_lines}) { print "$l "\n" }

Get this: ( which is obvious )


What we could see? We lost group context, all the letters now are seen at one heap, without knowledge about original groups.

Now with stream() function:

between <letters> <\/letters>
regexp: [A-Z]
code:                           \
my $i;                          \
for my $s (@{stream()}) {    \
    $i++;                       \
    print "stream #$i\n";       \
    for my $l (@{$s}){          \
        print "$l\n"            \
    }                           \       



stream # 1
stream # 2
stream # 3

-- Regards

Alexey Melezhik

About melezhik

user-pic Dev & Devops --- Then I beheld all the work of God, that a man cannot find out the work that is done under the sun: because though a man labour to seek it out, yet he shall not find it; yea further; though a wise man think to know it, yet shall he not be able to find it. (Ecclesiastes 8:17)