Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
K
k3s
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Jacklull
k3s
Commits
7946c6e2
Commit
7946c6e2
authored
Aug 31, 2018
by
Deep Debroy
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Implement semantic comparison of VolumeNodeAffinity for unit tests
Signed-off-by:
Deep Debroy
<
ddebroy@docker.com
>
parent
ed3c32c3
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
95 additions
and
4 deletions
+95
-4
BUILD
pkg/controller/cloud/BUILD
+1
-0
pvlcontroller_test.go
pkg/controller/cloud/pvlcontroller_test.go
+94
-4
No files found.
pkg/controller/cloud/BUILD
View file @
7946c6e2
...
@@ -66,6 +66,7 @@ go_test(
...
@@ -66,6 +66,7 @@ go_test(
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/types:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/types:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/wait:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/wait:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library",
"//staging/src/k8s.io/client-go/informers:go_default_library",
"//staging/src/k8s.io/client-go/informers:go_default_library",
...
...
pkg/controller/cloud/pvlcontroller_test.go
View file @
7946c6e2
...
@@ -18,7 +18,6 @@ package cloud
...
@@ -18,7 +18,6 @@ package cloud
import
(
import
(
"encoding/json"
"encoding/json"
"reflect"
"testing"
"testing"
"time"
"time"
...
@@ -27,6 +26,7 @@ import (
...
@@ -27,6 +26,7 @@ import (
metav1
"k8s.io/apimachinery/pkg/apis/meta/v1"
metav1
"k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime"
sets
"k8s.io/apimachinery/pkg/util/sets"
utilfeature
"k8s.io/apiserver/pkg/util/feature"
utilfeature
"k8s.io/apiserver/pkg/util/feature"
"k8s.io/client-go/kubernetes/fake"
"k8s.io/client-go/kubernetes/fake"
core
"k8s.io/client-go/testing"
core
"k8s.io/client-go/testing"
...
@@ -36,6 +36,96 @@ import (
...
@@ -36,6 +36,96 @@ import (
fakecloud
"k8s.io/kubernetes/pkg/cloudprovider/providers/fake"
fakecloud
"k8s.io/kubernetes/pkg/cloudprovider/providers/fake"
)
)
func
nodeSelectorRequirementsEqual
(
r1
,
r2
v1
.
NodeSelectorRequirement
)
bool
{
if
r1
.
Key
!=
r2
.
Key
{
return
false
}
if
r1
.
Operator
!=
r2
.
Operator
{
return
false
}
vals1
:=
sets
.
NewString
(
r1
.
Values
...
)
vals2
:=
sets
.
NewString
(
r2
.
Values
...
)
if
vals1
.
Equal
(
vals2
)
{
return
true
}
return
false
}
func
nodeSelectorTermsEqual
(
t1
,
t2
v1
.
NodeSelectorTerm
)
bool
{
exprs1
:=
t1
.
MatchExpressions
exprs2
:=
t2
.
MatchExpressions
fields1
:=
t1
.
MatchFields
fields2
:=
t2
.
MatchFields
if
len
(
exprs1
)
!=
len
(
exprs2
)
{
return
false
}
if
len
(
fields1
)
!=
len
(
fields2
)
{
return
false
}
match
:=
func
(
reqs1
,
reqs2
[]
v1
.
NodeSelectorRequirement
)
bool
{
for
_
,
req1
:=
range
reqs1
{
reqMatched
:=
false
for
_
,
req2
:=
range
reqs2
{
if
nodeSelectorRequirementsEqual
(
req1
,
req2
)
{
reqMatched
=
true
break
}
}
if
!
reqMatched
{
return
false
}
}
return
true
}
return
match
(
exprs1
,
exprs2
)
&&
match
(
exprs2
,
exprs1
)
&&
match
(
fields1
,
fields2
)
&&
match
(
fields2
,
fields1
)
}
// volumeNodeAffinitiesEqual performs a highly semantic comparison of two VolumeNodeAffinity data structures
// It ignores ordering of instances of NodeSelectorRequirements in a VolumeNodeAffinity's NodeSelectorTerms as well as
// orderding of strings in Values of NodeSelectorRequirements when matching two VolumeNodeAffinity structures.
// Note that in most equality functions, Go considers two slices to be not equal if the order of elements in a slice do not
// match - so reflect.DeepEqual as well as Semantic.DeepEqual do not work for comparing VolumeNodeAffinity semantically.
// e.g. these two NodeSelectorTerms are considered semantically equal by volumeNodeAffinitiesEqual
// &VolumeNodeAffinity{Required:&NodeSelector{NodeSelectorTerms:[{[{a In [1]} {b In [2 3]}] []}],},}
// &VolumeNodeAffinity{Required:&NodeSelector{NodeSelectorTerms:[{[{b In [3 2]} {a In [1]}] []}],},}
// TODO: move volumeNodeAffinitiesEqual to utils so other can use it too
func
volumeNodeAffinitiesEqual
(
n1
,
n2
*
v1
.
VolumeNodeAffinity
)
bool
{
if
(
n1
==
nil
)
!=
(
n2
==
nil
)
{
return
false
}
if
n1
==
nil
||
n2
==
nil
{
return
true
}
ns1
:=
n1
.
Required
ns2
:=
n2
.
Required
if
(
ns1
==
nil
)
!=
(
ns2
==
nil
)
{
return
false
}
if
(
ns1
==
nil
)
&&
(
ns2
==
nil
)
{
return
true
}
if
len
(
ns1
.
NodeSelectorTerms
)
!=
len
(
ns1
.
NodeSelectorTerms
)
{
return
false
}
match
:=
func
(
terms1
,
terms2
[]
v1
.
NodeSelectorTerm
)
bool
{
for
_
,
term1
:=
range
terms1
{
termMatched
:=
false
for
_
,
term2
:=
range
terms2
{
if
nodeSelectorTermsEqual
(
term1
,
term2
)
{
termMatched
=
true
break
}
}
if
!
termMatched
{
return
false
}
}
return
true
}
return
match
(
ns1
.
NodeSelectorTerms
,
ns2
.
NodeSelectorTerms
)
&&
match
(
ns2
.
NodeSelectorTerms
,
ns1
.
NodeSelectorTerms
)
}
func
TestCreatePatch
(
t
*
testing
.
T
)
{
func
TestCreatePatch
(
t
*
testing
.
T
)
{
ignoredPV
:=
v1
.
PersistentVolume
{
ignoredPV
:=
v1
.
PersistentVolume
{
ObjectMeta
:
metav1
.
ObjectMeta
{
ObjectMeta
:
metav1
.
ObjectMeta
{
...
@@ -288,12 +378,12 @@ func TestCreatePatch(t *testing.T) {
...
@@ -288,12 +378,12 @@ func TestCreatePatch(t *testing.T) {
{
{
Key
:
"e"
,
Key
:
"e"
,
Operator
:
v1
.
NodeSelectorOpIn
,
Operator
:
v1
.
NodeSelectorOpIn
,
Values
:
[]
string
{
"val
4"
,
"val5
"
},
Values
:
[]
string
{
"val
5"
,
"val4
"
},
},
},
{
{
Key
:
kubeletapis
.
LabelZoneFailureDomain
,
Key
:
kubeletapis
.
LabelZoneFailureDomain
,
Operator
:
v1
.
NodeSelectorOpIn
,
Operator
:
v1
.
NodeSelectorOpIn
,
Values
:
[]
string
{
"
1"
,
"2"
,
"3
"
},
Values
:
[]
string
{
"
3"
,
"2"
,
"1
"
},
},
},
},
},
},
},
...
@@ -382,7 +472,7 @@ func TestCreatePatch(t *testing.T) {
...
@@ -382,7 +472,7 @@ func TestCreatePatch(t *testing.T) {
t
.
Errorf
(
"%s: label %s expected %s got %s"
,
d
,
k
,
v
,
obj
.
ObjectMeta
.
Labels
[
k
])
t
.
Errorf
(
"%s: label %s expected %s got %s"
,
d
,
k
,
v
,
obj
.
ObjectMeta
.
Labels
[
k
])
}
}
}
}
if
!
reflect
.
Deep
Equal
(
tc
.
expectedAffinity
,
obj
.
Spec
.
NodeAffinity
)
{
if
!
volumeNodeAffinities
Equal
(
tc
.
expectedAffinity
,
obj
.
Spec
.
NodeAffinity
)
{
t
.
Errorf
(
"Expected affinity %v does not match target affinity %v"
,
tc
.
expectedAffinity
,
obj
.
Spec
.
NodeAffinity
)
t
.
Errorf
(
"Expected affinity %v does not match target affinity %v"
,
tc
.
expectedAffinity
,
obj
.
Spec
.
NodeAffinity
)
}
}
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment