Skip to content

Commit 9de86b0

Browse files
authored
Merge pull request #1508 from marquiz/devel/api-refactor
apis/nfd: split rule processing into a separate package
2 parents e162540 + 97bf841 commit 9de86b0

File tree

8 files changed

+687
-651
lines changed

8 files changed

+687
-651
lines changed

pkg/apis/nfd/v1alpha1/expression_test.go

Lines changed: 0 additions & 457 deletions
This file was deleted.
Lines changed: 225 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,225 @@
1+
/*
2+
Copyright 2021 The Kubernetes Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package nodefeaturerule_test
18+
19+
import (
20+
"testing"
21+
22+
"github.com/stretchr/testify/assert"
23+
"sigs.k8s.io/yaml"
24+
25+
nfdv1alpha1 "sigs.k8s.io/node-feature-discovery/pkg/apis/nfd/v1alpha1"
26+
api "sigs.k8s.io/node-feature-discovery/pkg/apis/nfd/v1alpha1/nodefeaturerule"
27+
)
28+
29+
type BoolAssertionFunc func(assert.TestingT, bool, ...interface{}) bool
30+
31+
type ValueAssertionFunc func(assert.TestingT, interface{}, ...interface{}) bool
32+
33+
func TestMatchKeys(t *testing.T) {
34+
type I = map[string]nfdv1alpha1.Nil
35+
type O = []api.MatchedElement
36+
type TC struct {
37+
name string
38+
mes string
39+
input I
40+
output O
41+
result BoolAssertionFunc
42+
err ValueAssertionFunc
43+
}
44+
45+
tcs := []TC{
46+
{output: O{}, result: assert.True, err: assert.Nil},
47+
48+
{input: I{}, output: O{}, result: assert.True, err: assert.Nil},
49+
50+
{input: I{"foo": {}}, output: O{}, result: assert.True, err: assert.Nil},
51+
52+
{mes: `
53+
foo: { op: DoesNotExist }
54+
bar: { op: Exists }
55+
`,
56+
input: I{"bar": {}, "baz": {}, "buzz": {}},
57+
output: O{{"Name": "bar"}, {"Name": "foo"}},
58+
result: assert.True, err: assert.Nil},
59+
60+
{mes: `
61+
foo: { op: DoesNotExist }
62+
bar: { op: Exists }
63+
`,
64+
input: I{"foo": {}, "bar": {}, "baz": {}},
65+
output: nil,
66+
result: assert.False, err: assert.Nil},
67+
68+
{mes: `
69+
foo: { op: In, value: ["bar"] }
70+
bar: { op: Exists }
71+
`,
72+
input: I{"bar": {}, "baz": {}},
73+
output: nil,
74+
result: assert.False, err: assert.NotNil},
75+
}
76+
77+
for _, tc := range tcs {
78+
t.Run(tc.name, func(t *testing.T) {
79+
mes := &nfdv1alpha1.MatchExpressionSet{}
80+
if err := yaml.Unmarshal([]byte(tc.mes), mes); err != nil {
81+
t.Fatal("failed to parse data of test case")
82+
}
83+
84+
res, out, err := api.MatchGetKeys(mes, tc.input)
85+
tc.result(t, res)
86+
assert.Equal(t, tc.output, out)
87+
tc.err(t, err)
88+
89+
res, err = api.MatchKeys(mes, tc.input)
90+
tc.result(t, res)
91+
tc.err(t, err)
92+
})
93+
}
94+
}
95+
96+
func TestMatchValues(t *testing.T) {
97+
type I = map[string]string
98+
type O = []api.MatchedElement
99+
type TC struct {
100+
name string
101+
mes string
102+
input I
103+
output O
104+
result BoolAssertionFunc
105+
err ValueAssertionFunc
106+
}
107+
108+
tcs := []TC{
109+
{name: "1", output: O{}, result: assert.True, err: assert.Nil},
110+
111+
{name: "2", input: I{}, output: O{}, result: assert.True, err: assert.Nil},
112+
113+
{name: "3", input: I{"foo": "bar"}, output: O{}, result: assert.True, err: assert.Nil},
114+
115+
{name: "4",
116+
mes: `
117+
foo: { op: Exists }
118+
bar: { op: In, value: ["val", "wal"] }
119+
baz: { op: Gt, value: ["10"] }
120+
`,
121+
input: I{"bar": "val"},
122+
result: assert.False, err: assert.Nil},
123+
124+
{name: "5",
125+
mes: `
126+
foo: { op: Exists }
127+
bar: { op: In, value: ["val", "wal"] }
128+
baz: { op: Gt, value: ["10"] }
129+
`,
130+
input: I{"foo": "1", "bar": "val", "baz": "123", "buzz": "light"},
131+
output: O{{"Name": "bar", "Value": "val"}, {"Name": "baz", "Value": "123"}, {"Name": "foo", "Value": "1"}},
132+
result: assert.True, err: assert.Nil},
133+
134+
{name: "5",
135+
mes: `
136+
foo: { op: Exists }
137+
bar: { op: In, value: ["val"] }
138+
baz: { op: Gt, value: ["10"] }
139+
`,
140+
input: I{"foo": "1", "bar": "val", "baz": "123.0"},
141+
result: assert.False, err: assert.NotNil},
142+
}
143+
144+
for _, tc := range tcs {
145+
t.Run(tc.name, func(t *testing.T) {
146+
mes := &nfdv1alpha1.MatchExpressionSet{}
147+
if err := yaml.Unmarshal([]byte(tc.mes), mes); err != nil {
148+
t.Fatal("failed to parse data of test case")
149+
}
150+
151+
res, out, err := api.MatchGetValues(mes, tc.input)
152+
tc.result(t, res)
153+
assert.Equal(t, tc.output, out)
154+
tc.err(t, err)
155+
156+
res, err = api.MatchValues(mes, tc.input)
157+
tc.result(t, res)
158+
tc.err(t, err)
159+
})
160+
}
161+
}
162+
163+
func TestMatchInstances(t *testing.T) {
164+
type I = nfdv1alpha1.InstanceFeature
165+
type O = []api.MatchedElement
166+
type A = map[string]string
167+
type TC struct {
168+
name string
169+
mes string
170+
input []I
171+
output O
172+
result BoolAssertionFunc
173+
err ValueAssertionFunc
174+
}
175+
176+
tcs := []TC{
177+
{name: "1", output: O{}, result: assert.False, err: assert.Nil}, // nil instances -> false
178+
179+
{name: "2", input: []I{}, output: O{}, result: assert.False, err: assert.Nil}, // zero instances -> false
180+
181+
{name: "3", input: []I{I{Attributes: A{}}}, output: O{A{}}, result: assert.True, err: assert.Nil}, // one "empty" instance
182+
183+
{name: "4",
184+
mes: `
185+
foo: { op: Exists }
186+
bar: { op: Lt, value: ["10"] }
187+
`,
188+
input: []I{I{Attributes: A{"foo": "1"}}, I{Attributes: A{"bar": "1"}}},
189+
output: O{},
190+
result: assert.False, err: assert.Nil},
191+
192+
{name: "5",
193+
mes: `
194+
foo: { op: Exists }
195+
bar: { op: Lt, value: ["10"] }
196+
`,
197+
input: []I{I{Attributes: A{"foo": "1"}}, I{Attributes: A{"foo": "2", "bar": "1"}}},
198+
output: O{A{"foo": "2", "bar": "1"}},
199+
result: assert.True, err: assert.Nil},
200+
201+
{name: "6",
202+
mes: `
203+
bar: { op: Lt, value: ["10"] }
204+
`,
205+
input: []I{I{Attributes: A{"foo": "1"}}, I{Attributes: A{"bar": "0x1"}}},
206+
result: assert.False, err: assert.NotNil},
207+
}
208+
209+
for _, tc := range tcs {
210+
t.Run(tc.name, func(t *testing.T) {
211+
mes := &nfdv1alpha1.MatchExpressionSet{}
212+
if err := yaml.Unmarshal([]byte(tc.mes), mes); err != nil {
213+
t.Fatal("failed to parse data of test case")
214+
}
215+
216+
out, err := api.MatchGetInstances(mes, tc.input)
217+
assert.Equal(t, tc.output, out)
218+
tc.err(t, err)
219+
220+
res, err := api.MatchInstances(mes, tc.input)
221+
tc.result(t, res)
222+
tc.err(t, err)
223+
})
224+
}
225+
}

0 commit comments

Comments
 (0)