1 #include "filter_expr_parser_ast.hpp"
2 #include "filter_expr_printer.hpp"
3
4 #include <optional>
5 #include <string_view>
6
7 #include <gtest/gtest.h>
8
9 namespace redfish
10 {
11
parse(std::string_view filterExpression,std::string_view outputAst)12 static void parse(std::string_view filterExpression, std::string_view outputAst)
13 {
14 std::optional<filter_ast::LogicalAnd> ast = parseFilter(filterExpression);
15 FilterExpressionPrinter pr;
16 EXPECT_TRUE(ast);
17 if (ast)
18 {
19 EXPECT_EQ(pr(*ast), outputAst);
20 }
21 }
22
TEST(FilterParser,SpecificationExamples)23 TEST(FilterParser, SpecificationExamples)
24 {
25 parse("ProcessorSummary/Count eq 2",
26 "unquoted_string(\"ProcessorSummary/Count\") Equals int(2)");
27 parse(
28 "ProcessorSummary/Count ge 2",
29 "unquoted_string(\"ProcessorSummary/Count\") Greater Than Or Equal int(2)");
30 parse("ProcessorSummary/Count gt 2",
31 "unquoted_string(\"ProcessorSummary/Count\") Greater Than int(2)");
32 parse(
33 "MemorySummary/TotalSystemMemoryGiB le 64",
34 "unquoted_string(\"MemorySummary/TotalSystemMemoryGiB\") Less Than Or Equal int(64)");
35 parse(
36 "MemorySummary/TotalSystemMemoryGiB lt 64",
37 "unquoted_string(\"MemorySummary/TotalSystemMemoryGiB\") Less Than int(64)");
38 parse(
39 "SystemType ne 'Physical'",
40 R"(unquoted_string("SystemType") Not Equal quoted_string("Physical"))");
41 parse(
42 "ProcessorSummary/Count eq 2 or ProcessorSummary/Count eq 4",
43 R"((unquoted_string("ProcessorSummary/Count") Equals int(2)) or (unquoted_string("ProcessorSummary/Count") Equals int(4)))");
44 parse("not ProcessorSummary/Count eq 2",
45 "not(unquoted_string(\"ProcessorSummary/Count\") Equals int(2))");
46 parse("not ProcessorSummary/Count eq -2",
47 "not(unquoted_string(\"ProcessorSummary/Count\") Equals int(-2))");
48 parse("Status/State eq 'Enabled')",
49 R"(unquoted_string("Status/State") Equals quoted_string("Enabled"))");
50 parse(
51 "ProcessorSummary/Count eq 2 and MemorySummary/TotalSystemMemoryGiB eq 64",
52 R"((unquoted_string("ProcessorSummary/Count") Equals int(2)) and (unquoted_string("MemorySummary/TotalSystemMemoryGiB") Equals int(64)))");
53 parse(
54 "Status/State eq 'Enabled' and Status/Health eq 'OK' or SystemType eq 'Physical'",
55 R"((unquoted_string("Status/State") Equals quoted_string("Enabled")) and ((unquoted_string("Status/Health") Equals quoted_string("OK")) or (unquoted_string("SystemType") Equals quoted_string("Physical"))))");
56 parse(
57 "(Status/State eq 'Enabled' and Status/Health eq 'OK') or SystemType eq 'Physical'",
58 R"(((unquoted_string("Status/State") Equals quoted_string("Enabled")) and (unquoted_string("Status/Health") Equals quoted_string("OK"))) or (unquoted_string("SystemType") Equals quoted_string("Physical")))");
59 }
60
TEST(FilterParser,BasicOperations)61 TEST(FilterParser, BasicOperations)
62 {
63 // Negation
64 EXPECT_TRUE(parseFilter("not(ProcessorSummary/Count eq 2)"));
65
66 // Negative numbers
67 EXPECT_TRUE(parseFilter("not(ProcessorSummary/Count eq -2)"));
68
69 // Empty strings
70 EXPECT_TRUE(parseFilter("(foo eq '')"));
71
72 // Identity
73 EXPECT_TRUE(parseFilter("1 eq 1"));
74 EXPECT_TRUE(parseFilter("'foo' eq 'foo'"));
75
76 // Inverted params
77 EXPECT_TRUE(parseFilter("2 eq ProcessorSummary/Count"));
78 EXPECT_TRUE(parseFilter("'OK' eq Status/Health"));
79
80 // Floating point
81 EXPECT_TRUE(parseFilter("Reading eq 4.0"));
82 EXPECT_TRUE(parseFilter("Reading eq 1e20"));
83 EXPECT_TRUE(parseFilter("Reading eq 1.575E1"));
84 EXPECT_TRUE(parseFilter("Reading eq -2.5E-3"));
85 EXPECT_TRUE(parseFilter("Reading eq 25E-4"));
86
87 // numeric operators
88 EXPECT_TRUE(parseFilter("ProcessorSummary/Count eq 2"));
89 EXPECT_TRUE(parseFilter("ProcessorSummary/Count ne 2"));
90 EXPECT_TRUE(parseFilter("ProcessorSummary/Count gt 2"));
91 EXPECT_TRUE(parseFilter("ProcessorSummary/Count ge 2"));
92 EXPECT_TRUE(parseFilter("ProcessorSummary/Count lt 2"));
93 EXPECT_TRUE(parseFilter("ProcessorSummary/Count le 2"));
94
95 // String comparison
96 EXPECT_TRUE(parseFilter("ProcessorSummary/Count eq 'foo'"));
97 EXPECT_TRUE(parseFilter("ProcessorSummary/Count ne 'foo'"));
98
99 // Future, datetime values are strings and need to be compared
100 // Make sure they parse
101 EXPECT_TRUE(parseFilter("ProcessorSummary/Count lt 'Physical'"));
102 EXPECT_TRUE(parseFilter("ProcessorSummary/Count le 'Physical'"));
103 EXPECT_TRUE(parseFilter("ProcessorSummary/Count gt 'Physical'"));
104 EXPECT_TRUE(parseFilter("ProcessorSummary/Count ge 'Physical'"));
105 EXPECT_TRUE(parseFilter("'Physical' lt ProcessorSummary/Count"));
106 EXPECT_TRUE(parseFilter("'Physical' le ProcessorSummary/Count"));
107 EXPECT_TRUE(parseFilter("'Physical' gt ProcessorSummary/Count"));
108 EXPECT_TRUE(parseFilter("'Physical' ge ProcessorSummary/Count"));
109 }
110
TEST(FilterParser,Spaces)111 TEST(FilterParser, Spaces)
112 {
113 // Strings with spaces
114 parse("foo eq ' '", R"(unquoted_string("foo") Equals quoted_string(" "))");
115
116 // Lots of spaces between args
117 parse("foo eq ''",
118 R"(unquoted_string("foo") Equals quoted_string(""))");
119
120 // Lots of spaces between parens
121 parse("( foo eq '' )",
122 R"(unquoted_string("foo") Equals quoted_string(""))");
123
124 parse("not foo eq ''",
125 R"(not(unquoted_string("foo") Equals quoted_string("")))");
126 }
127
TEST(FilterParser,Failures)128 TEST(FilterParser, Failures)
129 {
130 // Invalid expressions
131 EXPECT_FALSE(parseFilter("("));
132 EXPECT_FALSE(parseFilter(")"));
133 EXPECT_FALSE(parseFilter("()"));
134 EXPECT_FALSE(parseFilter(""));
135 EXPECT_FALSE(parseFilter(" "));
136 EXPECT_FALSE(parseFilter("ProcessorSummary/Count eq"));
137 EXPECT_FALSE(parseFilter("eq ProcessorSummary/Count"));
138 EXPECT_FALSE(parseFilter("not(ProcessorSummary/Count)"));
139 }
140 } // namespace redfish
141