1

I want to write a simple test that succeeds if all specified patterns are there in the output.

Specifically I am testing if my program is correctly using a configuration file to configure itself. This worked fine when I only had one parameter, but now I am doing the same with multiple parameters and it seems like I need to go the less quick and dirty way now because grep succeeds if any of the pattern matches, instead of all of them.

The program:

    logger_ << yaaf::LogLevel::info << "intParam is " << get_parameters().intParam << std::endl;
    logger_ << yaaf::LogLevel::info << "boolParam is " << get_parameters().boolParam << std::endl;
    logger_ << yaaf::LogLevel::info << "charParam is " << get_parameters().charParam << std::endl;
    logger_ << yaaf::LogLevel::info << "floatParam is " << get_parameters().floatParam << std::endl;
    logger_ << yaaf::LogLevel::info << "doubleParam is " << get_parameters().doubleParam << std::endl;
    logger_ << yaaf::LogLevel::info << "longParam is " << get_parameters().longParam << std::endl;
    logger_ << yaaf::LogLevel::info << "uintParam is " << get_parameters().uintParam << std::endl;
    logger_ << yaaf::LogLevel::info << "ulongParam is " << get_parameters().ulongParam << std::endl;
    logger_ << yaaf::LogLevel::info << "stringParam is " << get_parameters().stringParam << std::endl;

Current test:

 timeout 3 ${ini_test} | grep 'intParam is 1'

 timeout 3 ${ini_test} -i ${workspace}/tests/eclipseProject/algos/testsIni/initest.ini | grep 'intParam is 2'

What does not work:

timeout 3 ${ini_test} | grep -e 'intParam is 1' -e 'boolParam is false' -e 'charParam is a' [and so on...]

does not work because grep will exit with code 0 if any of the pattern match. I want it to return 0 iff all patterns can be matched against the output.

For this case I will probably just write some python code to do what I want, yet the case will probably present itself again in the future, or for someone else. How do I solve this problem?

codeforester
  • 39,467
  • 16
  • 112
  • 140
kutschkem
  • 7,826
  • 3
  • 21
  • 56

1 Answers1

0

Grep will get you the union (OR) of -e expressions. You could solve this by chaining greps like |grep … |grep … |grep … but I see that your expressions are all plain text rather than regexes, so here's an awk solution that will be faster:

timeout 3 ${ini_test} | awk '
  function in(s) { return index($0, s) }
  in("intParam is 1") && in("boolParam is false") && in("charParam is a") {
    print
    retval = 1
  }
  END { if (retval != 1) exit 1 }
'

I've defined a function here to make it more legible (I assume you have a lot of tests given your "and so on" note). It should be pretty obvious how to do this without the function.

AWK's index(string, substring) gives you the index of substring in a given string or else zero (awk strings are not zero-indexed), so if any of the requested substrings does not match, index() returns zero and the conditional short circuits. AWK's index() is, in my experience, much faster than grep -F.

AWK always exits 0 (true) unless explicitly told to do otherwise in an END stanza. You can add an extra exit at the end of the other stanza if that's sufficient to stop evaluations.

Adam Katz
  • 14,455
  • 5
  • 68
  • 83