Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Pattern Matching

clitest provides two main types of pattern matching: auto-escaped patterns (!) and raw patterns (?). Each has its own use cases and syntax.

Auto-escaped Patterns (!)

Auto-escaped patterns treat non-grok parts as literal text, making them perfect for exact matches:

$ printf "[LOG] Hello, world!\n"
! [LOG] Hello, world!

Raw Patterns (?)

Raw patterns treat everything as a pattern, requiring special characters to be escaped with backslash:

$ printf "[LOG] Hello, world!\n"
? \[LOG\] Hello, world!

You can use ^ and $ anchors in raw patterns for exact line matching:

$ printf "  X  \n"
? ^  X  $

Grok Patterns

clitest supports grok patterns for flexible matching:

$ echo "Hello, anything"
? Hello, %{GREEDYDATA}

Common grok patterns:

  • %{DATA} - Matches any text
  • %{GREEDYDATA} - Matches any text greedily

You can also customize grok patterns by providing a name and value:

$ printf "[LOG] Hello, world!\n"
? \[%{log=(LOG)}\] %{GREEDYDATA}

Multi-line Matching

Auto-escaped Multi-line (!!!)

$ printf "a\nb\nc\n"
!!!
a
b
c
!!!

Raw Multi-line (???)

$ printf "a\nb\nc\n"
???
a
b
c
???

When using multi-line patterns, the indentation of the !!! or ??? lines is removed from all lines between them. This makes it easy to maintain proper indentation in your test files while matching unindented output:

$ printf "abc\n\ndef\n"
  !!!
  abc

  def
  !!!

Pattern Structures

Any Pattern (*)

The * pattern matches any number of lines lazily, completing when the next structure matches. It can be used at the start, middle, or end of patterns:

# Match any output
$ printf "a\nb\nc\n"
*

# Match start, any middle, end
$ printf "a\nb\nc\nd\ne\n"
! a
! b
*
! d
! e

# Match within repeat
$ printf "start\n1\n2\nend\nstart\n1\n2\nend\n"
repeat {
    ! start
    *
    ! end
}

Pattern Blocks

Pattern blocks allow you to combine multiple patterns in different ways:

Repeat

Match a pattern multiple times:

$ printf "a\nb\nc\n"
repeat {
    choice {
        ! a
        ! b
        ! c
    }
}

Choice

Match any one of the specified patterns:

$ echo "pattern1"
choice {
    ! pattern1
    ! pattern2
    ! pattern3
}

Unordered

Match patterns in any order:

$ printf "b\na\nc\n"
unordered {
    ! a
    ! b
    ! c
}

Sequence

Match patterns in strict order:

$ printf "a\nb\nc\n"
sequence {
    ! a
    ! b
    ! c
}

Optional

Make a pattern optional:

$ echo "optional output"
optional {
    ! optional output
}

Ignore

Ignore blocks are supported at the command and global level. Global ignore blocks are applied to all commands in the test, while command-level ignore blocks are applied to the command only.

Skip certain output:

$ printf "WARNING: Something happened\nHello World\n"
ignore {
    ? WARNING: %{DATA}
}
! Hello World

Reject

Reject blocks are supported at the command and global level. Global reject blocks are applied to all commands in the test, while command-level reject blocks are applied to the command only.

Ensure certain patterns don't appear:

$ echo "Hello World"
reject {
    ! ERROR
}
! Hello World

Conditional Patterns

You can use if blocks in patterns to conditionally match output:

if $TARGET_OS == "linux" {
    $ echo Linux specific output
    ? Linux specific %{GREEDYDATA}
}

Note that pattern if blocks and control if blocks have identical syntax, but one contains patterns and the other contains commands.

Pattern Examples

Matching Log Lines

$ printf "[INFO] User logged in\n[ERROR] Connection failed\n"
repeat {
    ! [%{WORD}] %{GREEDYDATA}
}

Matching Numbers

$ echo "Count: 42"
? Count: %{NUMBER}

Matching Dates

$ echo "Date: 20-03-2024"
? Date: %{DATE}