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