Hi Cleto,

On Wed, Dec 08, 2010 at 01:03:43PM +0100, Cleto Martin Angelina wrote [edited]:
> I am going to ask to upstream about this but I think "OutContains" condition
> has never been implemented. Instead of this, you can use "FileContains"
> condition. In fact, FileContains condition has the task output as default
> filename value.

Yeah, I noticed FileContains but I need something more flexible. I've written
an OutputContains plugin (attached) that filters and transforms stdout using
passed functions, and then verifies that the result contains a list of strings
in the given order. Here's an example invocation:

t.post += OutputContains(['foo::%s' % s for s in strings],
                         filter_func = lambda x: x.endswith(' started'),
                         map_func = lambda x: x.split()[8])


It could be generalised by testing the type of the strings argument, and do a
simple "str in stdout" check if the argument is a string, or an unordered
comparison if the argument is a set. Also, the filter and map args could
default to None, in case no filtering and transformation is needed.

Anyway, my 2c.

Cheers,
Serafeim
import atheist
import logging
Log = logging.getLogger('atheist')

class OutputContains(atheist.Condition):

    def __init__(self, strings, filter_func, map_func):
        self.strings = strings
        self.filter_func = filter_func
        self.map_func = map_func
        atheist.Condition.__init__(self)

    def before(self, task):
        atheist.Condition.before(self, task)
        if not task.save_stdout:
            task.setup_outs(True)
        self.stdout = task.stdout

    def run(self):
        stdout = open(self.stdout).read().split('\n')
        stdout = [self.map_func(line) for line in stdout
                  if self.filter_func(line)]
        ok = stdout == self.strings
        if not ok:
            Log.error('expecting: %s' % ', '.join(self.strings))
            Log.error('actual:    %s' % stdout)
        return ok

Reply via email to