Skip to content

Commit 9e796ae

Browse files
committed
apis/nfd: no error on ops that never match
Return false (i.e. "did not match") but no error when evaluating a match expression against a "flag" type feature (which don't have any associated value, just the name) if a MatchOp that never matches is used. This is preparation for supporting multi-type features, i.e. one feature, like "cpu.cpuid", having e.g. "flag" and "attribute" type features.
1 parent 81bdf1d commit 9e796ae

File tree

3 files changed

+31
-27
lines changed

3 files changed

+31
-27
lines changed

pkg/apis/nfd/nodefeaturerule/expression-api_test.go

+18-6
Original file line numberDiff line numberDiff line change
@@ -43,34 +43,46 @@ func TestMatchKeys(t *testing.T) {
4343
}
4444

4545
tcs := []TC{
46-
{output: O{}, result: assert.True, err: assert.Nil},
46+
{name: "1", output: O{}, result: assert.True, err: assert.Nil},
4747

48-
{input: I{}, output: O{}, result: assert.True, err: assert.Nil},
48+
{name: "2", input: I{}, output: O{}, result: assert.True, err: assert.Nil},
4949

50-
{input: I{"foo": {}}, output: O{}, result: assert.True, err: assert.Nil},
50+
{name: "3", input: I{"foo": {}}, output: O{}, result: assert.True, err: assert.Nil},
5151

52-
{mes: `
52+
{name: "4",
53+
mes: `
5354
foo: { op: DoesNotExist }
5455
bar: { op: Exists }
5556
`,
5657
input: I{"bar": {}, "baz": {}, "buzz": {}},
5758
output: O{{"Name": "bar"}, {"Name": "foo"}},
5859
result: assert.True, err: assert.Nil},
5960

60-
{mes: `
61+
{name: "5",
62+
mes: `
6163
foo: { op: DoesNotExist }
6264
bar: { op: Exists }
6365
`,
6466
input: I{"foo": {}, "bar": {}, "baz": {}},
6567
output: nil,
6668
result: assert.False, err: assert.Nil},
6769

68-
{mes: `
70+
{name: "6",
71+
mes: `
6972
foo: { op: In, value: ["bar"] }
7073
bar: { op: Exists }
7174
`,
7275
input: I{"bar": {}, "baz": {}},
7376
output: nil,
77+
result: assert.False, err: assert.Nil},
78+
79+
{name: "7",
80+
mes: `
81+
foo: { op: Exists, value: ["bar"] }
82+
bar: { op: Exists }
83+
`,
84+
input: I{"bar": {}},
85+
output: nil,
7486
result: assert.False, err: assert.NotNil},
7587
}
7688

pkg/apis/nfd/nodefeaturerule/expression.go

+4-12
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ func evaluateMatchExpression(m *nfdv1alpha1.MatchExpression, valid bool, value i
6767
return !valid, nil
6868
}
6969

70-
if valid {
70+
if valid && value != nil {
7171
value := fmt.Sprintf("%v", value)
7272
switch m.Op {
7373
case nfdv1alpha1.MatchIn:
@@ -161,18 +161,10 @@ func evaluateMatchExpression(m *nfdv1alpha1.MatchExpression, valid bool, value i
161161

162162
// evaluateMatchExpressionKeys evaluates the MatchExpression against a set of keys.
163163
func evaluateMatchExpressionKeys(m *nfdv1alpha1.MatchExpression, name string, keys map[string]nfdv1alpha1.Nil) (bool, error) {
164-
matched := false
165-
166164
_, ok := keys[name]
167-
switch m.Op {
168-
case nfdv1alpha1.MatchAny:
169-
matched = true
170-
case nfdv1alpha1.MatchExists:
171-
matched = ok
172-
case nfdv1alpha1.MatchDoesNotExist:
173-
matched = !ok
174-
default:
175-
return false, fmt.Errorf("invalid Op %q when matching keys", m.Op)
165+
matched, err := evaluateMatchExpression(m, ok, nil)
166+
if err != nil {
167+
return false, err
176168
}
177169

178170
if klogV := klog.V(3); klogV.Enabled() {

pkg/apis/nfd/nodefeaturerule/expression_test.go

+9-9
Original file line numberDiff line numberDiff line change
@@ -171,15 +171,15 @@ func TestEvaluateMatchExpressionKeys(t *testing.T) {
171171
{name: "7", op: nfdv1alpha1.MatchDoesNotExist, key: "foo", input: I{"bar": {}}, result: assert.True, err: assert.Nil},
172172
{name: "8", op: nfdv1alpha1.MatchDoesNotExist, key: "foo", input: I{"bar": {}, "foo": {}}, result: assert.False, err: assert.Nil},
173173

174-
// All other ops should return an error
175-
{name: "9", op: nfdv1alpha1.MatchIn, values: V{"foo"}, key: "foo", result: assert.False, err: assert.NotNil},
176-
{name: "10", op: nfdv1alpha1.MatchNotIn, values: V{"foo"}, key: "foo", result: assert.False, err: assert.NotNil},
177-
{name: "11", op: nfdv1alpha1.MatchInRegexp, values: V{"foo"}, key: "foo", result: assert.False, err: assert.NotNil},
178-
{name: "12", op: nfdv1alpha1.MatchGt, values: V{"1"}, key: "foo", result: assert.False, err: assert.NotNil},
179-
{name: "13", op: nfdv1alpha1.MatchLt, values: V{"1"}, key: "foo", result: assert.False, err: assert.NotNil},
180-
{name: "14", op: nfdv1alpha1.MatchGtLt, values: V{"1", "10"}, key: "foo", result: assert.False, err: assert.NotNil},
181-
{name: "15", op: nfdv1alpha1.MatchIsTrue, key: "foo", result: assert.False, err: assert.NotNil},
182-
{name: "16", op: nfdv1alpha1.MatchIsFalse, key: "foo", result: assert.False, err: assert.NotNil},
174+
// All other ops should be nop (and return false) for "key" features
175+
{name: "9", op: nfdv1alpha1.MatchIn, values: V{"foo"}, key: "foo", result: assert.False, err: assert.Nil},
176+
{name: "10", op: nfdv1alpha1.MatchNotIn, values: V{"foo"}, key: "foo", result: assert.False, err: assert.Nil},
177+
{name: "11", op: nfdv1alpha1.MatchInRegexp, values: V{"foo"}, key: "foo", result: assert.False, err: assert.Nil},
178+
{name: "12", op: nfdv1alpha1.MatchGt, values: V{"1"}, key: "foo", result: assert.False, err: assert.Nil},
179+
{name: "13", op: nfdv1alpha1.MatchLt, values: V{"1"}, key: "foo", result: assert.False, err: assert.Nil},
180+
{name: "14", op: nfdv1alpha1.MatchGtLt, values: V{"1", "10"}, key: "foo", result: assert.False, err: assert.Nil},
181+
{name: "15", op: nfdv1alpha1.MatchIsTrue, key: "foo", result: assert.False, err: assert.Nil},
182+
{name: "16", op: nfdv1alpha1.MatchIsFalse, key: "foo", result: assert.False, err: assert.Nil},
183183
}
184184

185185
for _, tc := range tcs {

0 commit comments

Comments
 (0)