2017-07-14 10:45:10 +00:00
/ *
Copyright 2017 The Kubernetes Authors .
Licensed under the Apache License , Version 2.0 ( the "License" ) ;
you may not use this file except in compliance with the License .
You may obtain a copy of the License at
http : //www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing , software
distributed under the License is distributed on an "AS IS" BASIS ,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND , either express or implied .
See the License for the specific language governing permissions and
limitations under the License .
* /
package scheduler
import (
"testing"
"time"
"k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/wait"
"k8s.io/kubernetes/test/integration/framework"
testutils "k8s.io/kubernetes/test/utils"
)
// This file tests the scheduler predicates functionality.
2017-10-17 17:32:46 +00:00
const pollInterval = 100 * time . Millisecond
2017-07-14 10:45:10 +00:00
// TestInterPodAffinity verifies that scheduler's inter pod affinity and
// anti-affinity predicate functions works correctly.
func TestInterPodAffinity ( t * testing . T ) {
context := initTest ( t , "inter-pod-affinity" )
defer cleanupTest ( t , context )
// Add a few nodes.
nodes , err := createNodes ( context . clientSet , "testnode" , nil , 2 )
if err != nil {
t . Fatalf ( "Cannot create nodes: %v" , err )
}
// Add labels to the nodes.
labels1 := map [ string ] string {
"region" : "r1" ,
"zone" : "z11" ,
}
for _ , node := range nodes {
if err = testutils . AddLabelsToNode ( context . clientSet , node . Name , labels1 ) ; err != nil {
t . Fatalf ( "Cannot add labels to node: %v" , err )
}
if err = waitForNodeLabels ( context . clientSet , node . Name , labels1 ) ; err != nil {
t . Fatalf ( "Adding labels to node didn't succeed: %v" , err )
}
}
cs := context . clientSet
podLabel := map [ string ] string { "service" : "securityscan" }
2017-11-08 01:09:21 +00:00
// podLabel2 := map[string]string{"security": "S1"}
2017-07-14 10:45:10 +00:00
tests := [ ] struct {
pod * v1 . Pod
pods [ ] * v1 . Pod
node * v1 . Node
fits bool
errorType string
test string
} {
2017-11-08 01:09:21 +00:00
/ * {
2017-07-14 10:45:10 +00:00
pod : & v1 . Pod {
ObjectMeta : metav1 . ObjectMeta {
Name : "fakename" ,
Labels : podLabel2 ,
} ,
Spec : v1 . PodSpec {
Containers : [ ] v1 . Container { { Name : "container" , Image : framework . GetPauseImageName ( cs ) } } ,
Affinity : & v1 . Affinity {
PodAffinity : & v1 . PodAffinity {
RequiredDuringSchedulingIgnoredDuringExecution : [ ] v1 . PodAffinityTerm {
{
LabelSelector : & metav1 . LabelSelector {
MatchExpressions : [ ] metav1 . LabelSelectorRequirement {
{
Key : "security" ,
Operator : metav1 . LabelSelectorOpDoesNotExist ,
Values : [ ] string { "securityscan" } ,
} ,
} ,
} ,
TopologyKey : "region" ,
} ,
} ,
} ,
} ,
} ,
} ,
node : nodes [ 0 ] ,
fits : false ,
errorType : "invalidPod" ,
test : "validates that a pod with an invalid podAffinity is rejected because of the LabelSelectorRequirement is invalid" ,
} ,
{
pod : & v1 . Pod {
ObjectMeta : metav1 . ObjectMeta {
Name : "fakename" ,
Labels : podLabel2 ,
} ,
Spec : v1 . PodSpec {
Containers : [ ] v1 . Container { { Name : "container" , Image : framework . GetPauseImageName ( cs ) } } ,
Affinity : & v1 . Affinity {
PodAffinity : & v1 . PodAffinity {
RequiredDuringSchedulingIgnoredDuringExecution : [ ] v1 . PodAffinityTerm {
{
LabelSelector : & metav1 . LabelSelector {
MatchExpressions : [ ] metav1 . LabelSelectorRequirement {
{
Key : "security" ,
Operator : metav1 . LabelSelectorOpIn ,
Values : [ ] string { "securityscan" } ,
} ,
} ,
} ,
TopologyKey : "region" ,
} ,
} ,
} ,
} ,
} ,
} ,
node : nodes [ 0 ] ,
fits : false ,
test : "validates that Inter-pod-Affinity is respected if not matching" ,
} ,
{
pod : & v1 . Pod {
ObjectMeta : metav1 . ObjectMeta {
Name : "fakename" ,
Labels : podLabel2 ,
} ,
Spec : v1 . PodSpec {
Containers : [ ] v1 . Container { { Name : "container" , Image : framework . GetPauseImageName ( cs ) } } ,
Affinity : & v1 . Affinity {
PodAffinity : & v1 . PodAffinity {
RequiredDuringSchedulingIgnoredDuringExecution : [ ] v1 . PodAffinityTerm {
{
LabelSelector : & metav1 . LabelSelector {
MatchExpressions : [ ] metav1 . LabelSelectorRequirement {
{
Key : "service" ,
Operator : metav1 . LabelSelectorOpIn ,
Values : [ ] string { "securityscan" , "value2" } ,
} ,
} ,
} ,
TopologyKey : "region" ,
} ,
} ,
} ,
} ,
} ,
} ,
pods : [ ] * v1 . Pod { {
ObjectMeta : metav1 . ObjectMeta {
Name : "fakename2" ,
Labels : podLabel ,
} ,
Spec : v1 . PodSpec {
Containers : [ ] v1 . Container { { Name : "container" , Image : framework . GetPauseImageName ( cs ) } } ,
NodeName : nodes [ 0 ] . Name ,
} ,
} ,
} ,
node : nodes [ 0 ] ,
fits : true ,
test : "validates that InterPodAffinity is respected if matching. requiredDuringSchedulingIgnoredDuringExecution in PodAffinity using In operator that matches the existing pod" ,
} ,
{
pod : & v1 . Pod {
ObjectMeta : metav1 . ObjectMeta {
Name : "fakename" ,
Labels : podLabel2 ,
} ,
Spec : v1 . PodSpec {
Containers : [ ] v1 . Container { { Name : "container" , Image : framework . GetPauseImageName ( cs ) } } ,
Affinity : & v1 . Affinity {
PodAffinity : & v1 . PodAffinity {
RequiredDuringSchedulingIgnoredDuringExecution : [ ] v1 . PodAffinityTerm {
{
LabelSelector : & metav1 . LabelSelector {
MatchExpressions : [ ] metav1 . LabelSelectorRequirement {
{
Key : "service" ,
Operator : metav1 . LabelSelectorOpNotIn ,
Values : [ ] string { "securityscan3" , "value3" } ,
} ,
} ,
} ,
TopologyKey : "region" ,
} ,
} ,
} ,
} ,
} ,
} ,
pods : [ ] * v1 . Pod { { Spec : v1 . PodSpec {
Containers : [ ] v1 . Container { { Name : "container" , Image : framework . GetPauseImageName ( cs ) } } ,
NodeName : nodes [ 0 ] . Name } ,
ObjectMeta : metav1 . ObjectMeta {
Name : "fakename2" ,
Labels : podLabel } } } ,
node : nodes [ 0 ] ,
fits : true ,
test : "validates that InterPodAffinity is respected if matching. requiredDuringSchedulingIgnoredDuringExecution in PodAffinity using not in operator in labelSelector that matches the existing pod" ,
} ,
{
pod : & v1 . Pod {
ObjectMeta : metav1 . ObjectMeta {
Name : "fakename" ,
Labels : podLabel2 ,
} ,
Spec : v1 . PodSpec {
Containers : [ ] v1 . Container { { Name : "container" , Image : framework . GetPauseImageName ( cs ) } } ,
Affinity : & v1 . Affinity {
PodAffinity : & v1 . PodAffinity {
RequiredDuringSchedulingIgnoredDuringExecution : [ ] v1 . PodAffinityTerm {
{
LabelSelector : & metav1 . LabelSelector {
MatchExpressions : [ ] metav1 . LabelSelectorRequirement {
{
Key : "service" ,
Operator : metav1 . LabelSelectorOpIn ,
Values : [ ] string { "securityscan" , "value2" } ,
} ,
} ,
} ,
TopologyKey : "region" ,
Namespaces : [ ] string { "diff-namespace" } ,
} ,
} ,
} ,
} ,
} ,
} ,
pods : [ ] * v1 . Pod { { Spec : v1 . PodSpec {
Containers : [ ] v1 . Container { { Name : "container" , Image : framework . GetPauseImageName ( cs ) } } ,
NodeName : nodes [ 0 ] . Name } ,
ObjectMeta : metav1 . ObjectMeta {
Name : "fakename2" ,
Labels : podLabel , Namespace : "ns" } } } ,
node : nodes [ 0 ] ,
fits : false ,
test : "validates that inter-pod-affinity is respected when pods have different Namespaces" ,
} ,
{
pod : & v1 . Pod {
ObjectMeta : metav1 . ObjectMeta {
Name : "fakename" ,
Labels : podLabel ,
} ,
Spec : v1 . PodSpec {
Containers : [ ] v1 . Container { { Name : "container" , Image : framework . GetPauseImageName ( cs ) } } ,
Affinity : & v1 . Affinity {
PodAffinity : & v1 . PodAffinity {
RequiredDuringSchedulingIgnoredDuringExecution : [ ] v1 . PodAffinityTerm {
{
LabelSelector : & metav1 . LabelSelector {
MatchExpressions : [ ] metav1 . LabelSelectorRequirement {
{
Key : "service" ,
Operator : metav1 . LabelSelectorOpIn ,
Values : [ ] string { "antivirusscan" , "value2" } ,
} ,
} ,
} ,
TopologyKey : "region" ,
} ,
} ,
} ,
} ,
} ,
} ,
pods : [ ] * v1 . Pod { { Spec : v1 . PodSpec {
Containers : [ ] v1 . Container { { Name : "container" , Image : framework . GetPauseImageName ( cs ) } } ,
NodeName : nodes [ 0 ] . Name } , ObjectMeta : metav1 . ObjectMeta {
Name : "fakename2" ,
Labels : podLabel } } } ,
node : nodes [ 0 ] ,
fits : false ,
test : "Doesn't satisfy the PodAffinity because of unmatching labelSelector with the existing pod" ,
} ,
{
pod : & v1 . Pod {
ObjectMeta : metav1 . ObjectMeta {
Name : "fakename" ,
Labels : podLabel2 ,
} ,
Spec : v1 . PodSpec {
Containers : [ ] v1 . Container { { Name : "container" , Image : framework . GetPauseImageName ( cs ) } } ,
Affinity : & v1 . Affinity {
PodAffinity : & v1 . PodAffinity {
RequiredDuringSchedulingIgnoredDuringExecution : [ ] v1 . PodAffinityTerm {
{
LabelSelector : & metav1 . LabelSelector {
MatchExpressions : [ ] metav1 . LabelSelectorRequirement {
{
Key : "service" ,
Operator : metav1 . LabelSelectorOpExists ,
} , {
Key : "wrongkey" ,
Operator : metav1 . LabelSelectorOpDoesNotExist ,
} ,
} ,
} ,
TopologyKey : "region" ,
} , {
LabelSelector : & metav1 . LabelSelector {
MatchExpressions : [ ] metav1 . LabelSelectorRequirement {
{
Key : "service" ,
Operator : metav1 . LabelSelectorOpIn ,
Values : [ ] string { "securityscan" } ,
} , {
Key : "service" ,
Operator : metav1 . LabelSelectorOpNotIn ,
Values : [ ] string { "WrongValue" } ,
} ,
} ,
} ,
TopologyKey : "region" ,
} ,
} ,
} ,
} ,
} ,
} ,
pods : [ ] * v1 . Pod { { Spec : v1 . PodSpec {
Containers : [ ] v1 . Container { { Name : "container" , Image : framework . GetPauseImageName ( cs ) } } ,
NodeName : nodes [ 0 ] . Name } , ObjectMeta : metav1 . ObjectMeta {
Name : "fakename2" ,
Labels : podLabel } } } ,
node : nodes [ 0 ] ,
fits : true ,
test : "validates that InterPodAffinity is respected if matching with multiple affinities in multiple RequiredDuringSchedulingIgnoredDuringExecution " ,
} ,
{
pod : & v1 . Pod {
ObjectMeta : metav1 . ObjectMeta {
Labels : podLabel2 ,
Name : "fakename" ,
} ,
Spec : v1 . PodSpec {
Containers : [ ] v1 . Container { { Name : "container" , Image : framework . GetPauseImageName ( cs ) } } ,
Affinity : & v1 . Affinity {
PodAffinity : & v1 . PodAffinity {
RequiredDuringSchedulingIgnoredDuringExecution : [ ] v1 . PodAffinityTerm {
{
LabelSelector : & metav1 . LabelSelector {
MatchExpressions : [ ] metav1 . LabelSelectorRequirement {
{
Key : "service" ,
Operator : metav1 . LabelSelectorOpExists ,
} , {
Key : "wrongkey" ,
Operator : metav1 . LabelSelectorOpDoesNotExist ,
} ,
} ,
} ,
TopologyKey : "region" ,
} , {
LabelSelector : & metav1 . LabelSelector {
MatchExpressions : [ ] metav1 . LabelSelectorRequirement {
{
Key : "service" ,
Operator : metav1 . LabelSelectorOpIn ,
Values : [ ] string { "securityscan2" } ,
} , {
Key : "service" ,
Operator : metav1 . LabelSelectorOpNotIn ,
Values : [ ] string { "WrongValue" } ,
} ,
} ,
} ,
TopologyKey : "region" ,
} ,
} ,
} ,
} ,
} ,
} ,
pods : [ ] * v1 . Pod { { Spec : v1 . PodSpec {
Containers : [ ] v1 . Container { { Name : "container" , Image : framework . GetPauseImageName ( cs ) } } ,
NodeName : nodes [ 0 ] . Name } , ObjectMeta : metav1 . ObjectMeta {
Name : "fakename2" ,
Labels : podLabel } } } ,
node : nodes [ 0 ] ,
fits : false ,
test : "The labelSelector requirements(items of matchExpressions) are ANDed, the pod cannot schedule onto the node because one of the matchExpression items doesn't match." ,
} ,
{
pod : & v1 . Pod {
ObjectMeta : metav1 . ObjectMeta {
Name : "fakename" ,
Labels : podLabel2 ,
} ,
Spec : v1 . PodSpec {
Containers : [ ] v1 . Container { { Name : "container" , Image : framework . GetPauseImageName ( cs ) } } ,
Affinity : & v1 . Affinity {
PodAffinity : & v1 . PodAffinity {
RequiredDuringSchedulingIgnoredDuringExecution : [ ] v1 . PodAffinityTerm {
{
LabelSelector : & metav1 . LabelSelector {
MatchExpressions : [ ] metav1 . LabelSelectorRequirement {
{
Key : "service" ,
Operator : metav1 . LabelSelectorOpIn ,
Values : [ ] string { "securityscan" , "value2" } ,
} ,
} ,
} ,
TopologyKey : "region" ,
} ,
} ,
} ,
PodAntiAffinity : & v1 . PodAntiAffinity {
RequiredDuringSchedulingIgnoredDuringExecution : [ ] v1 . PodAffinityTerm {
{
LabelSelector : & metav1 . LabelSelector {
MatchExpressions : [ ] metav1 . LabelSelectorRequirement {
{
Key : "service" ,
Operator : metav1 . LabelSelectorOpIn ,
Values : [ ] string { "antivirusscan" , "value2" } ,
} ,
} ,
} ,
TopologyKey : "node" ,
} ,
} ,
} ,
} ,
} ,
} ,
pods : [ ] * v1 . Pod { { Spec : v1 . PodSpec {
Containers : [ ] v1 . Container { { Name : "container" , Image : framework . GetPauseImageName ( cs ) } } ,
NodeName : nodes [ 0 ] . Name } , ObjectMeta : metav1 . ObjectMeta {
Name : "fakename2" ,
Labels : podLabel } } } ,
node : nodes [ 0 ] ,
fits : true ,
test : "validates that InterPod Affinity and AntiAffinity is respected if matching" ,
} ,
{
pod : & v1 . Pod {
ObjectMeta : metav1 . ObjectMeta {
Name : "fakename" ,
Labels : podLabel2 ,
} ,
Spec : v1 . PodSpec {
Containers : [ ] v1 . Container { { Name : "container" , Image : framework . GetPauseImageName ( cs ) } } ,
Affinity : & v1 . Affinity {
PodAffinity : & v1 . PodAffinity {
RequiredDuringSchedulingIgnoredDuringExecution : [ ] v1 . PodAffinityTerm {
{
LabelSelector : & metav1 . LabelSelector {
MatchExpressions : [ ] metav1 . LabelSelectorRequirement {
{
Key : "service" ,
Operator : metav1 . LabelSelectorOpIn ,
Values : [ ] string { "securityscan" , "value2" } ,
} ,
} ,
} ,
TopologyKey : "region" ,
} ,
} ,
} ,
PodAntiAffinity : & v1 . PodAntiAffinity {
RequiredDuringSchedulingIgnoredDuringExecution : [ ] v1 . PodAffinityTerm {
{
LabelSelector : & metav1 . LabelSelector {
MatchExpressions : [ ] metav1 . LabelSelectorRequirement {
{
Key : "service" ,
Operator : metav1 . LabelSelectorOpIn ,
Values : [ ] string { "antivirusscan" , "value2" } ,
} ,
} ,
} ,
TopologyKey : "node" ,
} ,
} ,
} ,
} ,
} ,
} ,
pods : [ ] * v1 . Pod {
{
Spec : v1 . PodSpec {
Containers : [ ] v1 . Container { { Name : "container" , Image : framework . GetPauseImageName ( cs ) } } ,
NodeName : nodes [ 0 ] . Name ,
Affinity : & v1 . Affinity {
PodAntiAffinity : & v1 . PodAntiAffinity {
RequiredDuringSchedulingIgnoredDuringExecution : [ ] v1 . PodAffinityTerm {
{
LabelSelector : & metav1 . LabelSelector {
MatchExpressions : [ ] metav1 . LabelSelectorRequirement {
{
Key : "service" ,
Operator : metav1 . LabelSelectorOpIn ,
Values : [ ] string { "antivirusscan" , "value2" } ,
} ,
} ,
} ,
TopologyKey : "node" ,
} ,
} ,
} ,
} ,
} ,
ObjectMeta : metav1 . ObjectMeta {
Name : "fakename2" ,
Labels : podLabel } ,
} ,
} ,
node : nodes [ 0 ] ,
fits : true ,
test : "satisfies the PodAffinity and PodAntiAffinity and PodAntiAffinity symmetry with the existing pod" ,
} ,
{
pod : & v1 . Pod {
ObjectMeta : metav1 . ObjectMeta {
Name : "fakename" ,
Labels : podLabel2 ,
} ,
Spec : v1 . PodSpec {
Containers : [ ] v1 . Container { { Name : "container" , Image : framework . GetPauseImageName ( cs ) } } ,
Affinity : & v1 . Affinity {
PodAffinity : & v1 . PodAffinity {
RequiredDuringSchedulingIgnoredDuringExecution : [ ] v1 . PodAffinityTerm {
{
LabelSelector : & metav1 . LabelSelector {
MatchExpressions : [ ] metav1 . LabelSelectorRequirement {
{
Key : "service" ,
Operator : metav1 . LabelSelectorOpIn ,
Values : [ ] string { "securityscan" , "value2" } ,
} ,
} ,
} ,
TopologyKey : "region" ,
} ,
} ,
} ,
PodAntiAffinity : & v1 . PodAntiAffinity {
RequiredDuringSchedulingIgnoredDuringExecution : [ ] v1 . PodAffinityTerm {
{
LabelSelector : & metav1 . LabelSelector {
MatchExpressions : [ ] metav1 . LabelSelectorRequirement {
{
Key : "service" ,
Operator : metav1 . LabelSelectorOpIn ,
Values : [ ] string { "securityscan" , "value2" } ,
} ,
} ,
} ,
TopologyKey : "zone" ,
} ,
} ,
} ,
} ,
} ,
} ,
pods : [ ] * v1 . Pod { { Spec : v1 . PodSpec {
Containers : [ ] v1 . Container { { Name : "container" , Image : framework . GetPauseImageName ( cs ) } } ,
NodeName : nodes [ 0 ] . Name } , ObjectMeta : metav1 . ObjectMeta {
Name : "fakename2" ,
Labels : podLabel } } } ,
node : nodes [ 0 ] ,
fits : false ,
test : "satisfies the PodAffinity but doesn't satisfies the PodAntiAffinity with the existing pod" ,
2017-11-08 01:09:21 +00:00
} , * /
2017-07-14 10:45:10 +00:00
{
pod : & v1 . Pod {
ObjectMeta : metav1 . ObjectMeta {
Name : "fakename" ,
Labels : podLabel ,
} ,
Spec : v1 . PodSpec {
Containers : [ ] v1 . Container { { Name : "container" , Image : framework . GetPauseImageName ( cs ) } } ,
Affinity : & v1 . Affinity {
PodAffinity : & v1 . PodAffinity {
RequiredDuringSchedulingIgnoredDuringExecution : [ ] v1 . PodAffinityTerm {
{
LabelSelector : & metav1 . LabelSelector {
MatchExpressions : [ ] metav1 . LabelSelectorRequirement {
{
Key : "service" ,
Operator : metav1 . LabelSelectorOpIn ,
Values : [ ] string { "securityscan" , "value2" } ,
} ,
} ,
} ,
TopologyKey : "region" ,
} ,
} ,
} ,
PodAntiAffinity : & v1 . PodAntiAffinity {
RequiredDuringSchedulingIgnoredDuringExecution : [ ] v1 . PodAffinityTerm {
{
LabelSelector : & metav1 . LabelSelector {
MatchExpressions : [ ] metav1 . LabelSelectorRequirement {
{
Key : "service" ,
Operator : metav1 . LabelSelectorOpIn ,
Values : [ ] string { "antivirusscan" , "value2" } ,
} ,
} ,
} ,
TopologyKey : "node" ,
} ,
} ,
} ,
} ,
} ,
} ,
pods : [ ] * v1 . Pod {
{
Spec : v1 . PodSpec {
NodeName : nodes [ 0 ] . Name ,
Containers : [ ] v1 . Container { { Name : "container" , Image : framework . GetPauseImageName ( cs ) } } ,
Affinity : & v1 . Affinity {
PodAntiAffinity : & v1 . PodAntiAffinity {
RequiredDuringSchedulingIgnoredDuringExecution : [ ] v1 . PodAffinityTerm {
{
LabelSelector : & metav1 . LabelSelector {
MatchExpressions : [ ] metav1 . LabelSelectorRequirement {
{
Key : "service" ,
Operator : metav1 . LabelSelectorOpIn ,
Values : [ ] string { "securityscan" , "value3" } ,
} ,
} ,
} ,
TopologyKey : "zone" ,
} ,
} ,
} ,
} ,
} ,
ObjectMeta : metav1 . ObjectMeta {
Name : "fakename2" ,
Labels : podLabel } ,
} ,
} ,
node : nodes [ 0 ] ,
fits : false ,
test : "satisfies the PodAffinity and PodAntiAffinity but doesn't satisfies PodAntiAffinity symmetry with the existing pod" ,
} ,
{
pod : & v1 . Pod {
ObjectMeta : metav1 . ObjectMeta {
Name : "fakename" ,
Labels : podLabel ,
} ,
Spec : v1 . PodSpec {
Containers : [ ] v1 . Container { { Name : "container" , Image : framework . GetPauseImageName ( cs ) } } ,
Affinity : & v1 . Affinity {
PodAffinity : & v1 . PodAffinity {
RequiredDuringSchedulingIgnoredDuringExecution : [ ] v1 . PodAffinityTerm {
{
LabelSelector : & metav1 . LabelSelector {
MatchExpressions : [ ] metav1 . LabelSelectorRequirement {
{
Key : "service" ,
Operator : metav1 . LabelSelectorOpNotIn ,
Values : [ ] string { "securityscan" , "value2" } ,
} ,
} ,
} ,
TopologyKey : "region" ,
} ,
} ,
} ,
} ,
} ,
} ,
pods : [ ] * v1 . Pod { { Spec : v1 . PodSpec {
Containers : [ ] v1 . Container { { Name : "container" , Image : framework . GetPauseImageName ( cs ) } } ,
NodeName : "machine2" } , ObjectMeta : metav1 . ObjectMeta {
Name : "fakename2" ,
Labels : podLabel } } } ,
node : nodes [ 0 ] ,
fits : false ,
test : "pod matches its own Label in PodAffinity and that matches the existing pod Labels" ,
} ,
{
pod : & v1 . Pod {
ObjectMeta : metav1 . ObjectMeta {
Name : "fakename" ,
Labels : podLabel ,
} ,
Spec : v1 . PodSpec { Containers : [ ] v1 . Container { { Name : "container" , Image : framework . GetPauseImageName ( cs ) } } } ,
} ,
pods : [ ] * v1 . Pod {
{
Spec : v1 . PodSpec { NodeName : nodes [ 0 ] . Name ,
Containers : [ ] v1 . Container { { Name : "container" , Image : framework . GetPauseImageName ( cs ) } } ,
Affinity : & v1 . Affinity {
PodAntiAffinity : & v1 . PodAntiAffinity {
RequiredDuringSchedulingIgnoredDuringExecution : [ ] v1 . PodAffinityTerm {
{
LabelSelector : & metav1 . LabelSelector {
MatchExpressions : [ ] metav1 . LabelSelectorRequirement {
{
Key : "service" ,
Operator : metav1 . LabelSelectorOpIn ,
Values : [ ] string { "securityscan" , "value2" } ,
} ,
} ,
} ,
TopologyKey : "zone" ,
} ,
} ,
} ,
} ,
} ,
ObjectMeta : metav1 . ObjectMeta {
Name : "fakename2" ,
Labels : podLabel } ,
} ,
} ,
node : nodes [ 0 ] ,
fits : false ,
test : "Verify that PodAntiAffinity of an existing pod is respected when PodAntiAffinity symmetry is not satisfied with the existing pod" ,
} ,
{
pod : & v1 . Pod {
ObjectMeta : metav1 . ObjectMeta {
Name : "fake-name" ,
Labels : podLabel ,
} ,
Spec : v1 . PodSpec { Containers : [ ] v1 . Container { { Name : "container" , Image : framework . GetPauseImageName ( cs ) } } } ,
} ,
pods : [ ] * v1 . Pod {
{
Spec : v1 . PodSpec { NodeName : nodes [ 0 ] . Name ,
Containers : [ ] v1 . Container { { Name : "container" , Image : framework . GetPauseImageName ( cs ) } } ,
Affinity : & v1 . Affinity {
PodAntiAffinity : & v1 . PodAntiAffinity {
RequiredDuringSchedulingIgnoredDuringExecution : [ ] v1 . PodAffinityTerm {
{
LabelSelector : & metav1 . LabelSelector {
MatchExpressions : [ ] metav1 . LabelSelectorRequirement {
{
Key : "service" ,
Operator : metav1 . LabelSelectorOpNotIn ,
Values : [ ] string { "securityscan" , "value2" } ,
} ,
} ,
} ,
TopologyKey : "zone" ,
} ,
} ,
} ,
} ,
} ,
ObjectMeta : metav1 . ObjectMeta {
Name : "fake-name2" ,
Labels : podLabel } ,
} ,
} ,
node : nodes [ 0 ] ,
fits : true ,
test : "Verify that PodAntiAffinity from existing pod is respected when pod statisfies PodAntiAffinity symmetry with the existing pod" ,
} ,
{
pod : & v1 . Pod {
ObjectMeta : metav1 . ObjectMeta { Name : "fake-name2" } ,
Spec : v1 . PodSpec {
Containers : [ ] v1 . Container { { Name : "container" , Image : framework . GetPauseImageName ( cs ) } } ,
NodeSelector : map [ string ] string { "region" : "r1" } ,
Affinity : & v1 . Affinity {
PodAntiAffinity : & v1 . PodAntiAffinity {
RequiredDuringSchedulingIgnoredDuringExecution : [ ] v1 . PodAffinityTerm {
{
LabelSelector : & metav1 . LabelSelector {
MatchExpressions : [ ] metav1 . LabelSelectorRequirement {
{
Key : "foo" ,
Operator : metav1 . LabelSelectorOpIn ,
Values : [ ] string { "abc" } ,
} ,
} ,
} ,
TopologyKey : "region" ,
} ,
} ,
} ,
} ,
} ,
} ,
pods : [ ] * v1 . Pod {
{ Spec : v1 . PodSpec {
Containers : [ ] v1 . Container { { Name : "container" , Image : framework . GetPauseImageName ( cs ) } } ,
NodeName : nodes [ 0 ] . Name } , ObjectMeta : metav1 . ObjectMeta { Name : "fakename" , Labels : map [ string ] string { "foo" : "abc" } } } ,
} ,
fits : false ,
test : "nodes[0] and nodes[1] have same topologyKey and label value. nodes[0] has an existing pod that matches the inter pod affinity rule. The new pod can not be scheduled onto either of the two nodes." ,
} ,
}
2017-10-17 17:32:46 +00:00
2017-07-14 10:45:10 +00:00
for _ , test := range tests {
for _ , pod := range test . pods {
var nsName string
if pod . Namespace != "" {
nsName = pod . Namespace
} else {
nsName = context . ns . Name
}
2017-08-13 09:07:29 +00:00
createdPod , err := cs . CoreV1 ( ) . Pods ( nsName ) . Create ( pod )
2017-07-14 10:45:10 +00:00
if err != nil {
t . Fatalf ( "Test Failed: error, %v, while creating pod during test: %v" , err , test . test )
}
2017-10-17 17:32:46 +00:00
err = wait . Poll ( pollInterval , wait . ForeverTestTimeout , podScheduled ( cs , createdPod . Namespace , createdPod . Name ) )
2017-07-14 10:45:10 +00:00
if err != nil {
t . Errorf ( "Test Failed: error, %v, while waiting for pod during test, %v" , err , test )
}
}
2017-08-13 09:07:29 +00:00
testPod , err := cs . CoreV1 ( ) . Pods ( context . ns . Name ) . Create ( test . pod )
2017-07-14 10:45:10 +00:00
if err != nil {
if ! ( test . errorType == "invalidPod" && errors . IsInvalid ( err ) ) {
t . Fatalf ( "Test Failed: error, %v, while creating pod during test: %v" , err , test . test )
}
2017-11-08 01:09:21 +00:00
}
if test . fits {
err = wait . Poll ( pollInterval , wait . ForeverTestTimeout , podScheduled ( cs , testPod . Namespace , testPod . Name ) )
2017-07-14 10:45:10 +00:00
} else {
2017-11-08 01:09:21 +00:00
err = wait . Poll ( pollInterval , wait . ForeverTestTimeout , podUnschedulable ( cs , testPod . Namespace , testPod . Name ) )
}
if err != nil {
t . Errorf ( "Test Failed: %v, err %v, test.fits %v" , test . test , err , test . fits )
}
2017-10-17 17:32:46 +00:00
2017-11-08 01:09:21 +00:00
err = cs . CoreV1 ( ) . Pods ( context . ns . Name ) . Delete ( test . pod . Name , metav1 . NewDeleteOptions ( 0 ) )
if err != nil {
t . Errorf ( "Test Failed: error, %v, while deleting pod during test: %v" , err , test . test )
}
err = wait . Poll ( pollInterval , wait . ForeverTestTimeout , podDeleted ( cs , context . ns . Name , test . pod . Name ) )
if err != nil {
t . Errorf ( "Test Failed: error, %v, while waiting for pod to get deleted, %v" , err , test . test )
}
for _ , pod := range test . pods {
var nsName string
if pod . Namespace != "" {
nsName = pod . Namespace
2017-10-17 17:32:46 +00:00
} else {
2017-11-08 01:09:21 +00:00
nsName = context . ns . Name
2017-07-14 10:45:10 +00:00
}
2017-11-08 01:09:21 +00:00
err = cs . CoreV1 ( ) . Pods ( nsName ) . Delete ( pod . Name , metav1 . NewDeleteOptions ( 0 ) )
2017-07-14 10:45:10 +00:00
if err != nil {
t . Errorf ( "Test Failed: error, %v, while deleting pod during test: %v" , err , test . test )
}
2017-11-08 01:09:21 +00:00
err = wait . Poll ( pollInterval , wait . ForeverTestTimeout , podDeleted ( cs , nsName , pod . Name ) )
2017-07-14 10:45:10 +00:00
if err != nil {
t . Errorf ( "Test Failed: error, %v, while waiting for pod to get deleted, %v" , err , test . test )
}
}
}
}