Code

parser_test: Add testcases covering operand type checks.
[sysdb.git] / t / unit / frontend / parser_test.c
index b3d5c8bf5b6c45eb9933170bdda72a7e57d0237a..4926f7662271cf21459bd886631b93cf64ddbdf5 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * SysDB - t/unit/frontend/parser_test.c
- * Copyright (C) 2013 Sebastian 'tokkee' Harl <sh@tokkee.org>
+ * Copyright (C) 2013-2015 Sebastian 'tokkee' Harl <sh@tokkee.org>
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -52,150 +52,232 @@ START_TEST(test_parse)
                { ";",                   -1,  0, 0 },
                { ";;",                  -1,  0, 0 },
 
-               /* valid commands */
-               { "FETCH host 'host'",   -1,  1, CONNECTION_FETCH  },
+               /* FETCH commands */
+               { "FETCH host 'host'",   -1,  1, SDB_CONNECTION_FETCH  },
                { "FETCH host 'host' FILTER "
-                 "age > 60s",           -1,  1, CONNECTION_FETCH  },
+                 "age > 60s",           -1,  1, SDB_CONNECTION_FETCH  },
                { "FETCH service "
-                 "'host'.'service'",    -1,  1, CONNECTION_FETCH  },
+                 "'host'.'service'",    -1,  1, SDB_CONNECTION_FETCH  },
                { "FETCH metric "
-                 "'host'.'metric'",     -1,  1, CONNECTION_FETCH  },
+                 "'host'.'metric'",     -1,  1, SDB_CONNECTION_FETCH  },
 
-               { "LIST hosts",          -1,  1, CONNECTION_LIST   },
-               { "LIST hosts -- foo",   -1,  1, CONNECTION_LIST   },
-               { "LIST hosts;",         -1,  1, CONNECTION_LIST   },
-               { "LIST hosts; INVALID", 11,  1, CONNECTION_LIST   },
+               /* LIST commands */
+               { "LIST hosts",          -1,  1, SDB_CONNECTION_LIST   },
+               { "LIST hosts -- foo",   -1,  1, SDB_CONNECTION_LIST   },
+               { "LIST hosts;",         -1,  1, SDB_CONNECTION_LIST   },
+               { "LIST hosts; INVALID", 11,  1, SDB_CONNECTION_LIST   },
                { "LIST hosts FILTER "
-                 "age > 60s",           -1,  1, CONNECTION_LIST   },
-               { "LIST services",       -1,  1, CONNECTION_LIST   },
+                 "age > 60s",           -1,  1, SDB_CONNECTION_LIST   },
+               { "LIST services",       -1,  1, SDB_CONNECTION_LIST   },
                { "LIST services FILTER "
-                 "age > 60s",           -1,  1, CONNECTION_LIST   },
-               { "LIST metrics",        -1,  1, CONNECTION_LIST   },
+                 "age > 60s",           -1,  1, SDB_CONNECTION_LIST   },
+               { "LIST metrics",        -1,  1, SDB_CONNECTION_LIST   },
                { "LIST metrics FILTER "
-                 "age > 60s",           -1,  1, CONNECTION_LIST   },
+                 "age > 60s",           -1,  1, SDB_CONNECTION_LIST   },
 
-               { "LOOKUP hosts",        -1,  1, CONNECTION_LOOKUP },
+               /* LOOKUP commands */
+               { "LOOKUP hosts",        -1,  1, SDB_CONNECTION_LOOKUP },
                { "LOOKUP hosts MATCHING "
-                 "name = 'host'",       -1,  1, CONNECTION_LOOKUP },
+                 "name = 'host'",       -1,  1, SDB_CONNECTION_LOOKUP },
                { "LOOKUP hosts MATCHING NOT "
-                 "name = 'host'",       -1,  1, CONNECTION_LOOKUP },
+                 "name = 'host'",       -1,  1, SDB_CONNECTION_LOOKUP },
                { "LOOKUP hosts MATCHING "
                  "name =~ 'p' AND "
-                 "ANY service =~ 'p'",  -1,  1, CONNECTION_LOOKUP },
+                 "ANY service =~ 'p'",  -1,  1, SDB_CONNECTION_LOOKUP },
                { "LOOKUP hosts MATCHING NOT "
                  "name =~ 'p' AND "
-                 "ANY service =~ 'p'",  -1,  1, CONNECTION_LOOKUP },
+                 "ANY service =~ 'p'",  -1,  1, SDB_CONNECTION_LOOKUP },
                { "LOOKUP hosts MATCHING "
                  "name =~ 'p' AND "
                  "ANY service =~ 'p' OR "
-                 "ANY service =~ 'r'",  -1,  1, CONNECTION_LOOKUP },
+                 "ANY service =~ 'r'",  -1,  1, SDB_CONNECTION_LOOKUP },
                { "LOOKUP hosts MATCHING NOT "
                  "name =~ 'p' AND "
                  "ANY service =~ 'p' OR "
-                 "ANY service =~ 'r'",  -1,  1, CONNECTION_LOOKUP },
+                 "ANY service =~ 'r'",  -1,  1, SDB_CONNECTION_LOOKUP },
                { "LOOKUP hosts MATCHING "
                  "name =~ 'p' "
-                 "FILTER age > 1D",    -1,   1, CONNECTION_LOOKUP },
+                 "FILTER age > 1D",    -1,   1, SDB_CONNECTION_LOOKUP },
                { "LOOKUP hosts MATCHING "
                  "name =~ 'p' "
                  "FILTER age > 1D AND "
-                 "interval < 240s" ,   -1,   1, CONNECTION_LOOKUP },
+                 "interval < 240s" ,   -1,   1, SDB_CONNECTION_LOOKUP },
                { "LOOKUP hosts MATCHING "
                  "name =~ 'p' "
-                 "FILTER NOT age>1D",  -1,   1, CONNECTION_LOOKUP },
+                 "FILTER NOT age>1D",  -1,   1, SDB_CONNECTION_LOOKUP },
                { "LOOKUP hosts MATCHING "
                  "name =~ 'p' "
                  "FILTER age>"
-                 "interval",           -1,   1, CONNECTION_LOOKUP },
-               { "LOOKUP services",    -1,   1, CONNECTION_LOOKUP },
+                 "interval",           -1,   1, SDB_CONNECTION_LOOKUP },
+               { "LOOKUP hosts MATCHING "
+                 "host.name =~ 'p'",   -1,   1, SDB_CONNECTION_LOOKUP },
+               { "LOOKUP services",    -1,   1, SDB_CONNECTION_LOOKUP },
                { "LOOKUP services MATCHING ANY "
-                 "attribute =~ 'a'",   -1,   1, CONNECTION_LOOKUP },
-               { "LOOKUP metrics",     -1,   1, CONNECTION_LOOKUP },
+                 "attribute =~ 'a'",   -1,   1, SDB_CONNECTION_LOOKUP },
+               { "LOOKUP services MATCHING "
+                 "host.name = 'p'",    -1,   1, SDB_CONNECTION_LOOKUP },
+               { "LOOKUP services MATCHING "
+                 "service.name = 'p'", -1,   1, SDB_CONNECTION_LOOKUP },
+               { "LOOKUP metrics",     -1,   1, SDB_CONNECTION_LOOKUP },
                { "LOOKUP metrics MATCHING ANY "
-                 "attribute =~ 'a'",   -1,   1, CONNECTION_LOOKUP },
+                 "attribute =~ 'a'",   -1,   1, SDB_CONNECTION_LOOKUP },
+               { "LOOKUP metrics MATCHING "
+                 "host.name = 'p'",    -1,   1, SDB_CONNECTION_LOOKUP },
+               { "LOOKUP metrics MATCHING "
+                 "metric.name = 'p'",  -1,   1, SDB_CONNECTION_LOOKUP },
 
+               /* TIMESERIES commands */
                { "TIMESERIES 'host'.'metric' "
                  "START 2014-01-01 "
                  "END 2014-12-31 "
-                 "23:59:59",            -1,  1, CONNECTION_TIMESERIES },
+                 "23:59:59",            -1,  1, SDB_CONNECTION_TIMESERIES },
                { "TIMESERIES 'host'.'metric' "
                  "START 2014-02-02 "
-                 "14:02",               -1,  1, CONNECTION_TIMESERIES },
+                 "14:02",               -1,  1, SDB_CONNECTION_TIMESERIES },
                { "TIMESERIES 'host'.'metric' "
-                 "END 2014-02-02",      -1,  1, CONNECTION_TIMESERIES },
+                 "END 2014-02-02",      -1,  1, SDB_CONNECTION_TIMESERIES },
                { "TIMESERIES "
-                 "'host'.'metric'",     -1,  1, CONNECTION_TIMESERIES },
+                 "'host'.'metric'",     -1,  1, SDB_CONNECTION_TIMESERIES },
+
+               /* STORE commands */
+               { "STORE host 'host'",   -1,  1, SDB_CONNECTION_STORE_HOST },
+               { "STORE host 'host' "
+                 "LAST UPDATE "
+                 "2015-02-01",          -1,  1, SDB_CONNECTION_STORE_HOST },
+               { "STORE host attribute "
+                 "'host'.'key' 123",    -1,  1, SDB_CONNECTION_STORE_ATTRIBUTE },
+               { "STORE host attribute "
+                 "'host'.'key' 123 "
+                 "LAST UPDATE "
+                 "2015-02-01",          -1,  1, SDB_CONNECTION_STORE_ATTRIBUTE },
+               { "STORE service "
+                 "'host'.'svc'",        -1,  1, SDB_CONNECTION_STORE_SERVICE },
+               { "STORE service "
+                 "'host'.'svc' "
+                 "LAST UPDATE "
+                 "2015-02-01",          -1,  1, SDB_CONNECTION_STORE_SERVICE },
+               { "STORE service attribute "
+                 "'host'.'svc'.'key' "
+                 "123",                 -1,  1, SDB_CONNECTION_STORE_ATTRIBUTE },
+               { "STORE service attribute "
+                 "'host'.'svc'.'key' "
+                 "123 "
+                 "LAST UPDATE "
+                 "2015-02-01",          -1,  1, SDB_CONNECTION_STORE_ATTRIBUTE },
+               { "STORE metric "
+                 "'host'.'metric'",     -1,  1, SDB_CONNECTION_STORE_METRIC },
+               { "STORE metric "
+                 "'host'.'metric' "
+                 "LAST UPDATE "
+                 "2015-02-01",          -1,  1, SDB_CONNECTION_STORE_METRIC },
+               { "STORE metric "
+                 "'host'.'metric' "
+                 "STORE 'typ' 'id' "
+                 "LAST UPDATE "
+                 "2015-02-01",          -1,  1, SDB_CONNECTION_STORE_METRIC },
+               { "STORE metric attribute "
+                 "'host'.'metric'.'key' "
+                 "123",                 -1,  1, SDB_CONNECTION_STORE_ATTRIBUTE },
+               { "STORE metric attribute "
+                 "'host'.'metric'.'key' "
+                 "123 "
+                 "LAST UPDATE "
+                 "2015-02-01",          -1,  1, SDB_CONNECTION_STORE_ATTRIBUTE },
 
                /* string constants */
                { "LOOKUP hosts MATCHING "
-                 "name = ''''",         -1,  1, CONNECTION_LOOKUP },
+                 "name = ''''",         -1,  1, SDB_CONNECTION_LOOKUP },
                { "LOOKUP hosts MATCHING "
-                 "name = '''foo'",      -1,  1, CONNECTION_LOOKUP },
+                 "name = '''foo'",      -1,  1, SDB_CONNECTION_LOOKUP },
                { "LOOKUP hosts MATCHING "
-                 "name = 'f''oo'",      -1,  1, CONNECTION_LOOKUP },
+                 "name = 'f''oo'",      -1,  1, SDB_CONNECTION_LOOKUP },
                { "LOOKUP hosts MATCHING "
-                 "name = 'foo'''",      -1,  1, CONNECTION_LOOKUP },
+                 "name = 'foo'''",      -1,  1, SDB_CONNECTION_LOOKUP },
                { "LOOKUP hosts MATCHING "
                  "name = '''",          -1, -1, 0 },
 
                /* numeric constants */
                { "LOOKUP hosts MATCHING "
                  "attribute['foo'] = "
-                 "1234",                -1,  1, CONNECTION_LOOKUP },
+                 "1234",                -1,  1, SDB_CONNECTION_LOOKUP },
                { "LOOKUP hosts MATCHING "
                  "attribute['foo'] != "
-                 "+234",                -1,  1, CONNECTION_LOOKUP },
+                 "+234",                -1,  1, SDB_CONNECTION_LOOKUP },
                { "LOOKUP hosts MATCHING "
                  "attribute['foo'] < "
-                 "-234",                -1,  1, CONNECTION_LOOKUP },
+                 "-234",                -1,  1, SDB_CONNECTION_LOOKUP },
                { "LOOKUP hosts MATCHING "
                  "attribute['foo'] > "
-                 "12.4",                -1,  1, CONNECTION_LOOKUP },
+                 "12.4",                -1,  1, SDB_CONNECTION_LOOKUP },
                { "LOOKUP hosts MATCHING "
                  "attribute['foo'] <= "
-                 "12. + .3",            -1,  1, CONNECTION_LOOKUP },
+                 "12. + .3",            -1,  1, SDB_CONNECTION_LOOKUP },
                { "LOOKUP hosts MATCHING "
                  "attribute['foo'] <= "
-                 "'f' || 'oo'",         -1,  1, CONNECTION_LOOKUP },
+                 "'f' || 'oo'",         -1,  1, SDB_CONNECTION_LOOKUP },
                { "LOOKUP hosts MATCHING "
                  "attribute['foo'] >= "
-                 ".4",                  -1,  1, CONNECTION_LOOKUP },
+                 ".4",                  -1,  1, SDB_CONNECTION_LOOKUP },
                { "LOOKUP hosts MATCHING "
                  "attribute['foo'] = "
-                 "+12e3",               -1,  1, CONNECTION_LOOKUP },
+                 "+12e3",               -1,  1, SDB_CONNECTION_LOOKUP },
                { "LOOKUP hosts MATCHING "
                  "attribute['foo'] = "
-                 "+12e-3",              -1,  1, CONNECTION_LOOKUP },
+                 "+12e-3",              -1,  1, SDB_CONNECTION_LOOKUP },
                { "LOOKUP hosts MATCHING "
                  "attribute['foo'] = "
-                 "-12e+3",              -1,  1, CONNECTION_LOOKUP },
+                 "-12e+3",              -1,  1, SDB_CONNECTION_LOOKUP },
 
                /* date, time, interval constants */
                { "LOOKUP hosts MATCHING "
                  "attribute['foo'] = "
-                 "1 Y 42D",             -1,  1, CONNECTION_LOOKUP },
+                 "1 Y 42D",             -1,  1, SDB_CONNECTION_LOOKUP },
                { "LOOKUP hosts MATCHING "
                  "attribute['foo'] = "
-                 "1s 42D",              -1,  1, CONNECTION_LOOKUP },
+                 "1s 42D",              -1,  1, SDB_CONNECTION_LOOKUP },
                /*
                 * TODO: Something like 1Y42D should work as well but it doesn't since
                 * the scanner will tokenize it into {digit}{identifier} :-/
                 *
                { "LOOKUP hosts MATCHING "
                  "attribute['foo'] = "
-                 "1Y42D",               -1,  1, CONNECTION_LOOKUP },
+                 "1Y42D",               -1,  1, SDB_CONNECTION_LOOKUP },
                 */
 
+               /* array constants */
+               { "LOOKUP hosts MATCHING "
+                 "backend = ['foo']",   -1,  1, SDB_CONNECTION_LOOKUP },
+               { "LOOKUP hosts MATCHING "
+                 "backend = ['a','b']", -1,  1, SDB_CONNECTION_LOOKUP },
+
+               /* valid operand types */
+               { "LOOKUP hosts MATCHING "
+                 "age * 1 > 0s",        -1,  1, SDB_CONNECTION_LOOKUP },
+               { "LOOKUP hosts MATCHING "
+                 "age / 1 > 0s",        -1,  1, SDB_CONNECTION_LOOKUP },
+               { "LOOKUP hosts MATCHING "
+                 "name > ''",           -1,  1, SDB_CONNECTION_LOOKUP },
+               { "LOOKUP hosts MATCHING "
+                 "name >= ''",          -1,  1, SDB_CONNECTION_LOOKUP },
+               { "LOOKUP hosts MATCHING "
+                 "name != ''",          -1,  1, SDB_CONNECTION_LOOKUP },
+               { "LOOKUP hosts MATCHING "
+                 "name = ''",           -1,  1, SDB_CONNECTION_LOOKUP },
+               { "LOOKUP hosts MATCHING "
+                 "name <= ''",          -1,  1, SDB_CONNECTION_LOOKUP },
+               { "LOOKUP hosts MATCHING "
+                 "name < ''",           -1,  1, SDB_CONNECTION_LOOKUP },
+
                /* NULL */
                { "LOOKUP hosts MATCHING "
                  "attribute['foo'] "
-                 "IS NULL",             -1,  1, CONNECTION_LOOKUP },
+                 "IS NULL",             -1,  1, SDB_CONNECTION_LOOKUP },
                { "LOOKUP hosts MATCHING "
                  "attribute['foo'] "
-                 "IS NOT NULL",         -1,  1, CONNECTION_LOOKUP },
+                 "IS NOT NULL",         -1,  1, SDB_CONNECTION_LOOKUP },
                { "LOOKUP hosts MATCHING "
                  "NOT attribute['foo'] "
-                 "IS NULL",             -1,  1, CONNECTION_LOOKUP },
+                 "IS NULL",             -1,  1, SDB_CONNECTION_LOOKUP },
                { "LOOKUP hosts MATCHING "
                  "ANY service IS NULL", -1, -1, 0 },
 
@@ -226,6 +308,37 @@ START_TEST(test_parse)
                { "LOOKUP hosts MATCHING "
                  "attr['foo'] IS NULL", -1, -1, 0 },
 
+               /* type mismatches */
+               { "LOOKUP hosts MATCHING "
+                 "age > 0",             -1, -1, 0 },
+               { "LOOKUP hosts MATCHING "
+                 "age >= 0",            -1, -1, 0 },
+               { "LOOKUP hosts MATCHING "
+                 "age = 0",             -1, -1, 0 },
+               { "LOOKUP hosts MATCHING "
+                 "age != 0",            -1, -1, 0 },
+               { "LOOKUP hosts MATCHING "
+                 "age <= 0",            -1, -1, 0 },
+               { "LOOKUP hosts MATCHING "
+                 "age < 0",             -1, -1, 0 },
+               { "LOOKUP hosts MATCHING "
+                 "age + 1 > 0s",        -1, -1, 0 },
+               { "LOOKUP hosts MATCHING "
+                 "age - 1 > 0s",        -1, -1, 0 },
+               /* datetime <mul/div> integer is allowed */
+               { "LOOKUP hosts MATCHING "
+                 "age || 1 > 0s",       -1, -1, 0 },
+               { "LOOKUP hosts MATCHING "
+                 "name + 1 = ''",       -1, -1, 0 },
+               { "LOOKUP hosts MATCHING "
+                 "name - 1 = ''",       -1, -1, 0 },
+               { "LOOKUP hosts MATCHING "
+                 "name * 1 = ''",       -1, -1, 0 },
+               { "LOOKUP hosts MATCHING "
+                 "name / 1 = ''",       -1, -1, 0 },
+               { "LOOKUP hosts MATCHING "
+                 "name % 1 = ''",       -1, -1, 0 },
+
                /* comments */
                { "/* some comment */",  -1,  0, 0 },
                { "-- another comment",  -1,  0, 0 },
@@ -237,13 +350,15 @@ START_TEST(test_parse)
                { "LIST hosts; INVALID", -1, -1, 0 },
                { "/* some incomplete",  -1, -1, 0 },
 
-               /* invalid commands */
+               /* invalid LIST commands */
                { "LIST",                -1, -1, 0 },
                { "LIST foo",            -1, -1, 0 },
                { "LIST hosts MATCHING "
                  "name = 'host'",       -1, -1, 0 },
                { "LIST foo FILTER "
                  "age > 60s",           -1, -1, 0 },
+
+               /* invalid FETCH commands */
                { "FETCH host 'host' MATCHING "
                  "name = 'host'",       -1, -1, 0 },
                { "FETCH service 'host'",-1, -1, 0 },
@@ -254,6 +369,7 @@ START_TEST(test_parse)
                { "FETCH foo 'host' FILTER "
                  "age > 60s",           -1, -1, 0 },
 
+               /* invalid LOOKUP commands */
                { "LOOKUP foo",          -1, -1, 0 },
                { "LOOKUP foo MATCHING "
                  "name = 'host'",       -1, -1, 0 },
@@ -270,18 +386,48 @@ START_TEST(test_parse)
                  "'f' || oo",           -1, -1, 0 },
                { "LOOKUP hosts MATCHING "
                  "ANY host = 'host'",   -1, -1, 0 },
+               { "LOOKUP hosts MATCHING "
+                 "service.name = 's'",  -1, -1, 0 },
                { "LOOKUP services MATCHING "
                  "ANY host = 'host'",   -1, -1, 0 },
                { "LOOKUP services MATCHING "
                  "ANY service = 'svc'", -1, -1, 0 },
                { "LOOKUP services MATCHING "
                  "ANY metric = 'm'",    -1, -1, 0 },
+               { "LOOKUP services MATCHING "
+                 "metric.name = 'm'",   -1, -1, 0 },
                { "LOOKUP metrics MATCHING "
                  "ANY host = 'host'",   -1, -1, 0 },
                { "LOOKUP metrics MATCHING "
                  "ANY service = 'svc'", -1, -1, 0 },
                { "LOOKUP metrics MATCHING "
                  "ANY metric = 'm'",    -1, -1, 0 },
+               { "LOOKUP metrics MATCHING "
+                 "service.name = 'm'",  -1, -1, 0 },
+
+               /* invalid STORE commands */
+               { "STORE host "
+                 "'obj'.'host'",        -1, -1, 0 },
+               { "STORE host attribute "
+                 ".'key' 123",          -1, -1, 0 },
+               { "STORE host attribute "
+                 "'o'.'h'.'key' 123",   -1, -1, 0 },
+               { "STORE service 'svc'", -1, -1, 0 },
+               { "STORE service "
+                 "'host'.'svc' "
+                 "STORE 'typ' 'id' "
+                 "LAST UPDATE "
+                 "2015-02-01",          -1, -1, 0 },
+               { "STORE service attribute "
+                 "'svc'.'key' 123",     -1, -1, 0 },
+               { "STORE metric 'm'",    -1, -1, 0 },
+               { "STORE metric "
+                 "'host'.'metric' "
+                 "STORE 'typ'.'id' "
+                 "LAST UPDATE "
+                 "2015-02-01",          -1, -1, 0 },
+               { "STORE metric attribute "
+                 "'metric'.'key' 123",  -1, -1, 0 },
        };
 
        sdb_strbuf_t *errbuf = sdb_strbuf_create(64);
@@ -350,6 +496,20 @@ START_TEST(test_parse_matcher)
                { "name = 'localhost' -- foo",    -1,  MATCHER_EQ },
                { "name = 'host' <garbage>",      13,  MATCHER_EQ },
                { "name &^ 'localhost'",          -1,  -1 },
+               /* match by backend */
+               { "ANY backend < 'be'",           -1,  MATCHER_ANY },
+               { "ANY backend <= 'be'",          -1,  MATCHER_ANY },
+               { "ANY backend = 'be'",           -1,  MATCHER_ANY },
+               { "ANY backend != 'be'",          -1,  MATCHER_ANY },
+               { "ANY backend >= 'be'",          -1,  MATCHER_ANY },
+               { "ANY backend > 'be'",           -1,  MATCHER_ANY },
+               { "ALL backend < 'be'",           -1,  MATCHER_ALL },
+               { "ALL backend <= 'be'",          -1,  MATCHER_ALL },
+               { "ALL backend = 'be'",           -1,  MATCHER_ALL },
+               { "ALL backend != 'be'",          -1,  MATCHER_ALL },
+               { "ALL backend >= 'be'",          -1,  MATCHER_ALL },
+               { "ALL backend > 'be'",           -1,  MATCHER_ALL },
+               { "ANY backend &^ 'be'",          -1,  -1 },
                /* match hosts by service */
                { "ANY service < 'name'",         -1,  MATCHER_ANY },
                { "ANY service <= 'name'",        -1,  MATCHER_ANY },
@@ -360,6 +520,15 @@ START_TEST(test_parse_matcher)
                { "ANY service =~ 'pattern'",     -1,  MATCHER_ANY },
                { "ANY service !~ 'pattern'",     -1,  MATCHER_ANY },
                { "ANY service &^ 'name'",        -1,  -1 },
+               { "ALL service < 'name'",         -1,  MATCHER_ALL },
+               { "ALL service <= 'name'",        -1,  MATCHER_ALL },
+               { "ALL service = 'name'",         -1,  MATCHER_ALL },
+               { "ALL service != 'name'",        -1,  MATCHER_ALL },
+               { "ALL service >= 'name'",        -1,  MATCHER_ALL },
+               { "ALL service > 'name'",         -1,  MATCHER_ALL },
+               { "ALL service =~ 'pattern'",     -1,  MATCHER_ALL },
+               { "ALL service !~ 'pattern'",     -1,  MATCHER_ALL },
+               { "ALL service &^ 'name'",        -1,  -1 },
                /* match hosts by metric */
                { "ANY metric < 'name'",          -1,  MATCHER_ANY },
                { "ANY metric <= 'name'",         -1,  MATCHER_ANY },
@@ -369,6 +538,16 @@ START_TEST(test_parse_matcher)
                { "ANY metric > 'name'",          -1,  MATCHER_ANY },
                { "ANY metric =~ 'pattern'",      -1,  MATCHER_ANY },
                { "ANY metric !~ 'pattern'",      -1,  MATCHER_ANY },
+               { "ANY metric &^ 'pattern'",      -1,  -1 },
+               { "ALL metric < 'name'",          -1,  MATCHER_ALL },
+               { "ALL metric <= 'name'",         -1,  MATCHER_ALL },
+               { "ALL metric = 'name'",          -1,  MATCHER_ALL },
+               { "ALL metric != 'name'",         -1,  MATCHER_ALL },
+               { "ALL metric >= 'name'",         -1,  MATCHER_ALL },
+               { "ALL metric > 'name'",          -1,  MATCHER_ALL },
+               { "ALL metric =~ 'pattern'",      -1,  MATCHER_ALL },
+               { "ALL metric !~ 'pattern'",      -1,  MATCHER_ALL },
+               { "ALL metric &^ 'pattern'",      -1,  -1 },
                /* match hosts by attribute */
                { "ANY attribute < 'name'",       -1,  MATCHER_ANY },
                { "ANY attribute <= 'name'",      -1,  MATCHER_ANY },
@@ -379,6 +558,15 @@ START_TEST(test_parse_matcher)
                { "ANY attribute =~ 'pattern'",   -1,  MATCHER_ANY },
                { "ANY attribute !~ 'pattern'",   -1,  MATCHER_ANY },
                { "ANY attribute &^ 'pattern'",   -1,  -1 },
+               { "ALL attribute < 'name'",       -1,  MATCHER_ALL },
+               { "ALL attribute <= 'name'",      -1,  MATCHER_ALL },
+               { "ALL attribute = 'name'",       -1,  MATCHER_ALL },
+               { "ALL attribute != 'name'",      -1,  MATCHER_ALL },
+               { "ALL attribute >= 'name'",      -1,  MATCHER_ALL },
+               { "ALL attribute > 'name'",       -1,  MATCHER_ALL },
+               { "ALL attribute =~ 'pattern'",   -1,  MATCHER_ALL },
+               { "ALL attribute !~ 'pattern'",   -1,  MATCHER_ALL },
+               { "ALL attribute &^ 'pattern'",   -1,  -1 },
                /* composite expressions */
                { "name =~ 'pattern' AND "
                  "ANY service =~ 'pattern'",     -1,  MATCHER_AND },
@@ -410,6 +598,14 @@ START_TEST(test_parse_matcher)
                 * IS NULL currently maps to an equality matcher */
                { "attribute['foo'] IS NULL",     -1,  MATCHER_ISNULL },
                { "attribute['foo'] IS NOT NULL", -1,  MATCHER_ISNNULL },
+               /* array expressions */
+               { "backend < ['a']",              -1,  MATCHER_LT },
+               { "backend <= ['a']",             -1,  MATCHER_LE },
+               { "backend = ['a']",              -1,  MATCHER_EQ },
+               { "backend != ['a']",             -1,  MATCHER_NE },
+               { "backend >= ['a']",             -1,  MATCHER_GE },
+               { "backend > ['a']",              -1,  MATCHER_GT },
+               { "backend &^ ['a']",             -1,  -1 },
 
                /* object field matchers */
                { "name < 'a'",                   -1,  MATCHER_LT },