Skip to content

Commit

Permalink
add memory filter lable select
Browse files Browse the repository at this point in the history
Signed-off-by: lengrongfu <1275177125@qq.com>
  • Loading branch information
lengrongfu committed Jul 6, 2023
1 parent 5b250f9 commit 77d09f2
Show file tree
Hide file tree
Showing 2 changed files with 332 additions and 1 deletion.
29 changes: 28 additions & 1 deletion pkg/storage/memorystorage/watchcache/watch_cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,19 @@ func GetKeyFunc(gvr schema.GroupVersionResource, isNamespaced bool) keyFunc {
return kc
}

func GetAttrsFunc(obj runtime.Object) (labels.Set, fields.Set, error) {
accessor, err := meta.Accessor(obj)
if err != nil {
return nil, nil, err
}
objLabels := accessor.GetLabels()
if objLabels == nil {
objLabels = make(map[string]string)
}
labelSet := labels.Set(objLabels)
return labelSet, nil, nil
}

func storeElementKey(obj interface{}) (string, error) {
elem, ok := obj.(*StoreElement)
if !ok {
Expand Down Expand Up @@ -153,7 +166,7 @@ func NewWatchCache(capacity int, gvr schema.GroupVersionResource, isNamespaced b
wc := &WatchCache{
capacity: capacity,
KeyFunc: GetKeyFunc(gvr, isNamespaced),
getAttrsFunc: nil,
getAttrsFunc: GetAttrsFunc,
cache: make([]*watch.Event, capacity),
startIndex: 0,
endIndex: 0,
Expand Down Expand Up @@ -305,12 +318,26 @@ func (w *WatchCache) WaitUntilFreshAndList(opts *internal.ListOptions) ([]*Store
continue
}
}
if filterLabelSelector(opts.LabelSelector, se.Labels) {
continue
}
result = append(result, se)
}
}
return result, w.resourceVersion, nil
}

// filterLabelSelector returns true if the given label selector matches the given label set. else false.
func filterLabelSelector(labelSelector labels.Selector, label labels.Set) bool {
if labelSelector != nil && label == nil {
return true
}
if labelSelector != nil && label != nil && !labelSelector.Matches(label) {
return true
}
return false
}

// WaitUntilFreshAndGet returns list of pointers to <storeElement> objects.
func (w *WatchCache) WaitUntilFreshAndGet(cluster, namespace, name string) (*StoreElement, error) {
w.RLock()
Expand Down
304 changes: 304 additions & 0 deletions pkg/storage/memorystorage/watchcache/watch_cache_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,304 @@
package watchcache

import (
"testing"

"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/selection"
)

func Test_filterLabelSelector(t *testing.T) {
type request struct {
labelSelector labels.Selector
label labels.Set
}
var tests = []struct {
name string
req request
before func(req *request)
want bool
}{
{
name: "empty label selector",
req: struct {
labelSelector labels.Selector
label labels.Set
}{
labelSelector: nil,
label: labels.Set{},
},
want: false,
},
{
name: "empty label",
req: struct {
labelSelector labels.Selector
label labels.Set
}{
labelSelector: labels.Everything(),
label: nil,
},
want: true,
},
{
name: "lable exist operator,but exist",
req: struct {
labelSelector labels.Selector
label labels.Set
}{

labelSelector: labels.NewSelector(),
label: labels.Set{
"env": "dev",
},
},
before: func(req *request) {
requirement, err := labels.NewRequirement("env", selection.Exists, nil)
if err != nil {
t.Fatal(err)
}
req.labelSelector = req.labelSelector.Add(labels.Requirements{*requirement}...)
},
want: false,
},
{
name: "lable exist operator,but not exist",
req: struct {
labelSelector labels.Selector
label labels.Set
}{

labelSelector: labels.NewSelector(),
label: labels.Set{
"env": "dev",
},
},
before: func(req *request) {
requirement, err := labels.NewRequirement("app", selection.Exists, nil)
if err != nil {
t.Fatal(err)
}
req.labelSelector = req.labelSelector.Add(labels.Requirements{*requirement}...)
},
want: true,
},
{
name: "lable not exist operator,but exist",
req: struct {
labelSelector labels.Selector
label labels.Set
}{

labelSelector: labels.NewSelector(),
label: labels.Set{
"env": "dev",
},
},
before: func(req *request) {
requirement, err := labels.NewRequirement("env", selection.DoesNotExist, nil)
if err != nil {
t.Fatal(err)
}
req.labelSelector = req.labelSelector.Add(labels.Requirements{*requirement}...)
},
want: true,
},
{
name: "lable not exist operator,but not exist",
req: struct {
labelSelector labels.Selector
label labels.Set
}{

labelSelector: labels.NewSelector(),
label: labels.Set{
"env": "dev",
},
},
before: func(req *request) {
requirement, err := labels.NewRequirement("app", selection.DoesNotExist, nil)
if err != nil {
t.Fatal(err)
}
req.labelSelector = req.labelSelector.Add(labels.Requirements{*requirement}...)
},
want: false,
},
{
name: "lable Equals operator,but not equals",
req: struct {
labelSelector labels.Selector
label labels.Set
}{

labelSelector: labels.NewSelector(),
label: labels.Set{
"env": "dev",
},
},
before: func(req *request) {
requirement, err := labels.NewRequirement("env", selection.Equals, []string{"prod"})
if err != nil {
t.Fatal(err)
}
req.labelSelector = req.labelSelector.Add(labels.Requirements{*requirement}...)
},
want: true,
},
{
name: "lable Equals operator,but equals",
req: struct {
labelSelector labels.Selector
label labels.Set
}{

labelSelector: labels.NewSelector(),
label: labels.Set{
"env": "dev",
},
},
before: func(req *request) {
requirement, err := labels.NewRequirement("env", selection.Equals, []string{"dev"})
if err != nil {
t.Fatal(err)
}
req.labelSelector = req.labelSelector.Add(labels.Requirements{*requirement}...)
},
want: false,
},
{
name: "lable NotEquals operator,but equals",
req: struct {
labelSelector labels.Selector
label labels.Set
}{

labelSelector: labels.NewSelector(),
label: labels.Set{
"env": "dev",
},
},
before: func(req *request) {
requirement, err := labels.NewRequirement("env", selection.NotEquals, []string{"dev"})
if err != nil {
t.Fatal(err)
}
req.labelSelector = req.labelSelector.Add(labels.Requirements{*requirement}...)
},
want: true,
},
{
name: "lable NotEquals operator,but not equals",
req: struct {
labelSelector labels.Selector
label labels.Set
}{

labelSelector: labels.NewSelector(),
label: labels.Set{
"env": "dev",
},
},
before: func(req *request) {
requirement, err := labels.NewRequirement("env", selection.NotEquals, []string{"prod"})
if err != nil {
t.Fatal(err)
}
req.labelSelector = req.labelSelector.Add(labels.Requirements{*requirement}...)
},
want: false,
},
{
name: "lable IN operator,but not in",
req: struct {
labelSelector labels.Selector
label labels.Set
}{

labelSelector: labels.NewSelector(),
label: labels.Set{
"env": "dev",
},
},
before: func(req *request) {
requirement, err := labels.NewRequirement("env", selection.In, []string{"prod", "test"})
if err != nil {
t.Fatal(err)
}
req.labelSelector = req.labelSelector.Add(labels.Requirements{*requirement}...)
},
want: true,
},
{
name: "lable IN operator,but in",
req: struct {
labelSelector labels.Selector
label labels.Set
}{

labelSelector: labels.NewSelector(),
label: labels.Set{
"env": "dev",
},
},
before: func(req *request) {
requirement, err := labels.NewRequirement("env", selection.In, []string{"prod", "test", "dev"})
if err != nil {
t.Fatal(err)
}
req.labelSelector = req.labelSelector.Add(labels.Requirements{*requirement}...)
},
want: false,
},
{
name: "lable NotIn operator,but in",
req: struct {
labelSelector labels.Selector
label labels.Set
}{
labelSelector: labels.NewSelector(),
label: labels.Set{
"env": "dev",
},
},
before: func(req *request) {
requirement, err := labels.NewRequirement("env", selection.NotIn, []string{"prod", "test", "dev"})
if err != nil {
t.Fatal(err)
}
req.labelSelector = req.labelSelector.Add(labels.Requirements{*requirement}...)
},
want: true,
},
{
name: "lable NotIn operator,but not in",
req: struct {
labelSelector labels.Selector
label labels.Set
}{
labelSelector: labels.NewSelector(),
label: labels.Set{
"env": "dev",
},
},
before: func(req *request) {
requirement, err := labels.NewRequirement("env", selection.NotIn, []string{"prod", "test"})
if err != nil {
t.Fatal(err)
}
req.labelSelector = req.labelSelector.Add(labels.Requirements{*requirement}...)
},
want: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if tt.before != nil {
tt.before(&tt.req)
}
if got := filterLabelSelector(tt.req.labelSelector, tt.req.label); got != tt.want {
t.Errorf("filterLabelSelector() = %v, want %v", got, tt.want)
}
})
}
}

0 comments on commit 77d09f2

Please sign in to comment.