Skip to content

Commit 20379c1

Browse files
authored
Merge pull request vmware-tanzu#839 from TaoZou1/commonut
Add ut for services/common
2 parents 1095ae7 + 65152d6 commit 20379c1

File tree

3 files changed

+629
-0
lines changed

3 files changed

+629
-0
lines changed
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
package common
2+
3+
import (
4+
"testing"
5+
6+
"github.com/stretchr/testify/assert"
7+
"github.com/vmware/vsphere-automation-sdk-go/runtime/data"
8+
)
9+
10+
type mockComparable struct {
11+
key string
12+
value data.DataValue
13+
}
14+
15+
func (m mockComparable) Key() string {
16+
return m.key
17+
}
18+
19+
func (m mockComparable) Value() data.DataValue {
20+
return m.value
21+
}
22+
23+
func TestCompareResources(t *testing.T) {
24+
tests := []struct {
25+
name string
26+
existing []Comparable
27+
expected []Comparable
28+
wantChanged []Comparable
29+
wantStale []Comparable
30+
}{
31+
{
32+
name: "No changes",
33+
existing: []Comparable{
34+
mockComparable{key: "key1", value: data.NewStringValue("value1")},
35+
mockComparable{key: "key2", value: data.NewStringValue("value2")},
36+
},
37+
expected: []Comparable{
38+
mockComparable{key: "key1", value: data.NewStringValue("value1")},
39+
mockComparable{key: "key2", value: data.NewStringValue("value2")},
40+
},
41+
wantChanged: []Comparable{},
42+
wantStale: []Comparable{},
43+
},
44+
{
45+
name: "Changed resources",
46+
existing: []Comparable{
47+
mockComparable{key: "key1", value: data.NewStringValue("value1")},
48+
mockComparable{key: "key2", value: data.NewStringValue("value2")},
49+
},
50+
expected: []Comparable{
51+
mockComparable{key: "key1", value: data.NewStringValue("value1")},
52+
mockComparable{key: "key2", value: data.NewStringValue("value2_changed")},
53+
},
54+
wantChanged: []Comparable{
55+
mockComparable{key: "key2", value: data.NewStringValue("value2_changed")},
56+
},
57+
wantStale: []Comparable{},
58+
},
59+
{
60+
name: "Stale resources",
61+
existing: []Comparable{
62+
mockComparable{key: "key1", value: data.NewStringValue("value1")},
63+
mockComparable{key: "key2", value: data.NewStringValue("value2")},
64+
},
65+
expected: []Comparable{
66+
mockComparable{key: "key1", value: data.NewStringValue("value1")},
67+
},
68+
wantChanged: []Comparable{},
69+
wantStale: []Comparable{
70+
mockComparable{key: "key2", value: data.NewStringValue("value2")},
71+
},
72+
},
73+
{
74+
name: "Changed and stale resources",
75+
existing: []Comparable{
76+
mockComparable{key: "key1", value: data.NewStringValue("value1")},
77+
mockComparable{key: "key2", value: data.NewStringValue("value2")},
78+
},
79+
expected: []Comparable{
80+
mockComparable{key: "key1", value: data.NewStringValue("value1_changed")},
81+
},
82+
wantChanged: []Comparable{
83+
mockComparable{key: "key1", value: data.NewStringValue("value1_changed")},
84+
},
85+
wantStale: []Comparable{
86+
mockComparable{key: "key2", value: data.NewStringValue("value2")},
87+
},
88+
},
89+
}
90+
91+
for _, tt := range tests {
92+
t.Run(tt.name, func(t *testing.T) {
93+
gotChanged, gotStale := CompareResources(tt.existing, tt.expected)
94+
assert.Equal(t, tt.wantChanged, gotChanged)
95+
assert.Equal(t, tt.wantStale, gotStale)
96+
})
97+
}
98+
}

pkg/nsx/services/common/store_test.go

Lines changed: 272 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,20 @@
11
package common
22

33
import (
4+
"fmt"
45
"reflect"
56
"sync"
67
"testing"
78

89
"github.com/agiledragon/gomonkey/v2"
10+
"github.com/openlyinc/pointy"
911
"github.com/stretchr/testify/assert"
1012
"github.com/vmware/vsphere-automation-sdk-go/lib/vapi/std/errors"
1113
"github.com/vmware/vsphere-automation-sdk-go/runtime/bindings"
1214
"github.com/vmware/vsphere-automation-sdk-go/runtime/data"
15+
mp_model "github.com/vmware/vsphere-automation-sdk-go/services/nsxt-mp/nsx/model"
1316
"github.com/vmware/vsphere-automation-sdk-go/services/nsxt/model"
17+
"k8s.io/apimachinery/pkg/util/sets"
1418
"k8s.io/client-go/tools/cache"
1519

1620
"github.com/vmware-tanzu/nsx-operator/pkg/config"
@@ -187,3 +191,271 @@ func Test_InitializeResourceStore(t *testing.T) {
187191
assert.Empty(t, fatalErrors)
188192
assert.Equal(t, []string{"11111"}, ruleStore.ListKeys())
189193
}
194+
195+
func TestService_SearchResource(t *testing.T) {
196+
type args struct {
197+
resourceTypeValue string
198+
queryParam string
199+
store Store
200+
filter Filter
201+
}
202+
tests := []struct {
203+
name string
204+
args args
205+
want uint64
206+
wantErr bool
207+
}{
208+
{
209+
name: "Policy API with results",
210+
args: args{
211+
resourceTypeValue: "testResourceType",
212+
queryParam: "testQueryParam",
213+
store: &fakeStore{
214+
isPolicyAPI: true,
215+
},
216+
filter: nil,
217+
},
218+
want: 1,
219+
wantErr: false,
220+
},
221+
{
222+
name: "MP API with results",
223+
args: args{
224+
resourceTypeValue: "testResourceType",
225+
queryParam: "testQueryParam",
226+
store: &fakeStore{
227+
isPolicyAPI: false,
228+
},
229+
filter: nil,
230+
},
231+
want: 1,
232+
wantErr: false,
233+
},
234+
{
235+
name: "Policy API with error",
236+
args: args{
237+
resourceTypeValue: "testResourceType",
238+
queryParam: "testQueryParam",
239+
store: &fakeStore{
240+
isPolicyAPI: true,
241+
transError: true,
242+
},
243+
filter: nil,
244+
},
245+
want: 0,
246+
wantErr: true,
247+
},
248+
{
249+
name: "MP API with error",
250+
args: args{
251+
resourceTypeValue: "testResourceType",
252+
queryParam: "testQueryParam",
253+
store: &fakeStore{
254+
isPolicyAPI: false,
255+
transError: true,
256+
},
257+
filter: nil,
258+
},
259+
want: 0,
260+
wantErr: true,
261+
},
262+
}
263+
264+
for _, tt := range tests {
265+
t.Run(tt.name, func(t *testing.T) {
266+
service := &Service{
267+
NSXClient: &nsx.Client{
268+
QueryClient: &fakeQueryClient{},
269+
MPQueryClient: &fakeMPQueryClient{},
270+
},
271+
}
272+
got, err := service.SearchResource(tt.args.resourceTypeValue, tt.args.queryParam, tt.args.store, tt.args.filter)
273+
if (err != nil) != tt.wantErr {
274+
t.Errorf("SearchResource() error = %v, wantErr %v", err, tt.wantErr)
275+
return
276+
}
277+
if got != tt.want {
278+
t.Errorf("SearchResource() got = %v, want %v", got, tt.want)
279+
}
280+
})
281+
}
282+
}
283+
284+
func Test_containsTagScope(t *testing.T) {
285+
tests := []struct {
286+
name string
287+
tags []model.Tag
288+
scopes []string
289+
want bool
290+
}{
291+
{
292+
name: "Tag with matching scope",
293+
tags: []model.Tag{
294+
{Scope: pointy.String("scope1")},
295+
{Scope: pointy.String("scope2")},
296+
},
297+
scopes: []string{"scope1"},
298+
want: true,
299+
},
300+
{
301+
name: "Tag without matching scope",
302+
tags: []model.Tag{
303+
{Scope: pointy.String("scope1")},
304+
{Scope: pointy.String("scope2")},
305+
},
306+
scopes: []string{"scope3"},
307+
want: false,
308+
},
309+
{
310+
name: "Empty tags",
311+
tags: []model.Tag{},
312+
scopes: []string{"scope1"},
313+
want: false,
314+
},
315+
{
316+
name: "Empty scopes",
317+
tags: []model.Tag{
318+
{Scope: pointy.String("scope1")},
319+
{Scope: pointy.String("scope2")},
320+
},
321+
scopes: []string{},
322+
want: false,
323+
},
324+
{
325+
name: "Nil scope in tag",
326+
tags: []model.Tag{
327+
{Scope: nil},
328+
{Scope: pointy.String("scope2")},
329+
},
330+
scopes: []string{"scope1"},
331+
want: false,
332+
},
333+
}
334+
335+
for _, tt := range tests {
336+
t.Run(tt.name, func(t *testing.T) {
337+
if got := containsTagScope(tt.tags, tt.scopes...); got != tt.want {
338+
t.Errorf("containsTagScope() = %v, want %v", got, tt.want)
339+
}
340+
})
341+
}
342+
}
343+
344+
type fakeStore struct {
345+
isPolicyAPI bool
346+
transError bool
347+
}
348+
349+
func (f *fakeStore) TransResourceToStore(obj *data.StructValue) error {
350+
if f.transError {
351+
return fmt.Errorf("transformation error")
352+
}
353+
return nil
354+
}
355+
356+
func (f *fakeStore) ListIndexFuncValues(key string) sets.Set[string] {
357+
return sets.New[string]()
358+
}
359+
360+
func (f *fakeStore) Apply(obj interface{}) error {
361+
return nil
362+
}
363+
364+
func (f *fakeStore) IsPolicyAPI() bool {
365+
return f.isPolicyAPI
366+
}
367+
368+
type fakeMPQueryClient struct{}
369+
370+
func (_ *fakeMPQueryClient) List(_ string, _ *string, _ *string, _ *int64, _ *bool, _ *string) (mp_model.SearchResponse, error) {
371+
cursor := "2"
372+
resultCount := int64(2)
373+
return mp_model.SearchResponse{
374+
Results: []*data.StructValue{{}},
375+
Cursor: &cursor, ResultCount: &resultCount,
376+
}, nil
377+
}
378+
379+
func Test_formatTagParamScope(t *testing.T) {
380+
tests := []struct {
381+
name string
382+
paramType string
383+
value string
384+
want string
385+
}{
386+
{
387+
name: "Simple value",
388+
paramType: "tags.scope",
389+
value: "simpleValue",
390+
want: "tags.scope:simpleValue",
391+
},
392+
{
393+
name: "Value with slash",
394+
paramType: "tags.scope",
395+
value: "value/with/slash",
396+
want: "tags.scope:value\\/with\\/slash",
397+
},
398+
{
399+
name: "Empty value",
400+
paramType: "tags.scope",
401+
value: "",
402+
want: "tags.scope:",
403+
},
404+
{
405+
name: "Value with multiple slashes",
406+
paramType: "tags.scope",
407+
value: "value/with/multiple/slashes",
408+
want: "tags.scope:value\\/with\\/multiple\\/slashes",
409+
},
410+
}
411+
412+
for _, tt := range tests {
413+
t.Run(tt.name, func(t *testing.T) {
414+
if got := formatTagParamScope(tt.paramType, tt.value); got != tt.want {
415+
t.Errorf("formatTagParamScope() = %v, want %v", got, tt.want)
416+
}
417+
})
418+
}
419+
}
420+
421+
func Test_formatTagParamTag(t *testing.T) {
422+
tests := []struct {
423+
name string
424+
paramType string
425+
value string
426+
want string
427+
}{
428+
{
429+
name: "Simple value",
430+
paramType: "tags.tag",
431+
value: "simpleValue",
432+
want: "tags.tag:simpleValue",
433+
},
434+
{
435+
name: "Value with colon",
436+
paramType: "tags.tag",
437+
value: "value:with:colon",
438+
want: "tags.tag:value\\:with\\:colon",
439+
},
440+
{
441+
name: "Empty value",
442+
paramType: "tags.tag",
443+
value: "",
444+
want: "tags.tag:",
445+
},
446+
{
447+
name: "Value with multiple colons",
448+
paramType: "tags.tag",
449+
value: "value:with:multiple:colons",
450+
want: "tags.tag:value\\:with\\:multiple\\:colons",
451+
},
452+
}
453+
454+
for _, tt := range tests {
455+
t.Run(tt.name, func(t *testing.T) {
456+
if got := formatTagParamTag(tt.paramType, tt.value); got != tt.want {
457+
t.Errorf("formatTagParamTag() = %v, want %v", got, tt.want)
458+
}
459+
})
460+
}
461+
}

0 commit comments

Comments
 (0)