Unverified Commit 0a3884e1 authored by Kubernetes Prow Robot's avatar Kubernetes Prow Robot Committed by GitHub

Merge pull request #77714 from danielqsj/t1

cleanup dot imports and make test error checking more readable in test/e2e/scheduling
parents 116f06e9 ccecc67a
...@@ -605,7 +605,6 @@ test/e2e/common ...@@ -605,7 +605,6 @@ test/e2e/common
test/e2e/framework test/e2e/framework
test/e2e/lifecycle/bootstrap test/e2e/lifecycle/bootstrap
test/e2e/scalability test/e2e/scalability
test/e2e/scheduling
test/e2e/storage/drivers test/e2e/storage/drivers
test/e2e/storage/testsuites test/e2e/storage/testsuites
test/e2e/storage/utils test/e2e/storage/utils
......
...@@ -31,8 +31,9 @@ import ( ...@@ -31,8 +31,9 @@ import (
testutils "k8s.io/kubernetes/test/utils" testutils "k8s.io/kubernetes/test/utils"
imageutils "k8s.io/kubernetes/test/utils/image" imageutils "k8s.io/kubernetes/test/utils/image"
. "github.com/onsi/ginkgo" "github.com/onsi/ginkgo"
. "github.com/onsi/gomega" "github.com/onsi/gomega"
// ensure libs have a chance to initialize
_ "github.com/stretchr/testify/assert" _ "github.com/stretchr/testify/assert"
) )
...@@ -48,7 +49,7 @@ var _ = framework.KubeDescribe("EquivalenceCache [Serial]", func() { ...@@ -48,7 +49,7 @@ var _ = framework.KubeDescribe("EquivalenceCache [Serial]", func() {
var ns string var ns string
f := framework.NewDefaultFramework("equivalence-cache") f := framework.NewDefaultFramework("equivalence-cache")
BeforeEach(func() { ginkgo.BeforeEach(func() {
cs = f.ClientSet cs = f.ClientSet
ns = f.Namespace.Name ns = f.Namespace.Name
...@@ -61,7 +62,7 @@ var _ = framework.KubeDescribe("EquivalenceCache [Serial]", func() { ...@@ -61,7 +62,7 @@ var _ = framework.KubeDescribe("EquivalenceCache [Serial]", func() {
// cannot be run in parallel with any other test that touches Nodes or Pods. // cannot be run in parallel with any other test that touches Nodes or Pods.
// It is so because we need to have precise control on what's running in the cluster. // It is so because we need to have precise control on what's running in the cluster.
systemPods, err := framework.GetPodsInNamespace(cs, ns, map[string]string{}) systemPods, err := framework.GetPodsInNamespace(cs, ns, map[string]string{})
Expect(err).NotTo(HaveOccurred()) gomega.Expect(err).NotTo(gomega.HaveOccurred())
systemPodsNo = 0 systemPodsNo = 0
for _, pod := range systemPods { for _, pod := range systemPods {
if !masterNodes.Has(pod.Spec.NodeName) && pod.DeletionTimestamp == nil { if !masterNodes.Has(pod.Spec.NodeName) && pod.DeletionTimestamp == nil {
...@@ -70,7 +71,7 @@ var _ = framework.KubeDescribe("EquivalenceCache [Serial]", func() { ...@@ -70,7 +71,7 @@ var _ = framework.KubeDescribe("EquivalenceCache [Serial]", func() {
} }
err = framework.WaitForPodsRunningReady(cs, api.NamespaceSystem, int32(systemPodsNo), int32(systemPodsNo), framework.PodReadyBeforeTimeout, map[string]string{}) err = framework.WaitForPodsRunningReady(cs, api.NamespaceSystem, int32(systemPodsNo), int32(systemPodsNo), framework.PodReadyBeforeTimeout, map[string]string{})
Expect(err).NotTo(HaveOccurred()) gomega.Expect(err).NotTo(gomega.HaveOccurred())
for _, node := range nodeList.Items { for _, node := range nodeList.Items {
e2elog.Logf("\nLogging pods the kubelet thinks is on node %v before test", node.Name) e2elog.Logf("\nLogging pods the kubelet thinks is on node %v before test", node.Name)
...@@ -83,16 +84,16 @@ var _ = framework.KubeDescribe("EquivalenceCache [Serial]", func() { ...@@ -83,16 +84,16 @@ var _ = framework.KubeDescribe("EquivalenceCache [Serial]", func() {
// When a replica pod (with HostPorts) is scheduled to a node, it will invalidate GeneralPredicates cache on this node, // When a replica pod (with HostPorts) is scheduled to a node, it will invalidate GeneralPredicates cache on this node,
// so that subsequent replica pods with same host port claim will be rejected. // so that subsequent replica pods with same host port claim will be rejected.
// We enforce all replica pods bind to the same node so there will always be conflicts. // We enforce all replica pods bind to the same node so there will always be conflicts.
It("validates GeneralPredicates is properly invalidated when a pod is scheduled [Slow]", func() { ginkgo.It("validates GeneralPredicates is properly invalidated when a pod is scheduled [Slow]", func() {
By("Launching a RC with two replica pods with HostPorts") ginkgo.By("Launching a RC with two replica pods with HostPorts")
nodeName := getNodeThatCanRunPodWithoutToleration(f) nodeName := getNodeThatCanRunPodWithoutToleration(f)
rcName := "host-port" rcName := "host-port"
// bind all replicas to same node // bind all replicas to same node
nodeSelector := map[string]string{"kubernetes.io/hostname": nodeName} nodeSelector := map[string]string{"kubernetes.io/hostname": nodeName}
By("One pod should be scheduled, the other should be rejected") ginkgo.By("One pod should be scheduled, the other should be rejected")
// CreateNodeSelectorPods creates RC with host port 4312 // CreateNodeSelectorPods creates RC with host port 4321
WaitForSchedulerAfterAction(f, func() error { WaitForSchedulerAfterAction(f, func() error {
err := CreateNodeSelectorPods(f, rcName, 2, nodeSelector, false) err := CreateNodeSelectorPods(f, rcName, 2, nodeSelector, false)
return err return err
...@@ -105,11 +106,11 @@ var _ = framework.KubeDescribe("EquivalenceCache [Serial]", func() { ...@@ -105,11 +106,11 @@ var _ = framework.KubeDescribe("EquivalenceCache [Serial]", func() {
// This test verifies that MatchInterPodAffinity works as expected. // This test verifies that MatchInterPodAffinity works as expected.
// In equivalence cache, it does not handle inter pod affinity (anti-affinity) specially (unless node label changed), // In equivalence cache, it does not handle inter pod affinity (anti-affinity) specially (unless node label changed),
// because current predicates algorithm will ensure newly scheduled pod does not break existing affinity in cluster. // because current predicates algorithm will ensure newly scheduled pod does not break existing affinity in cluster.
It("validates pod affinity works properly when new replica pod is scheduled", func() { ginkgo.It("validates pod affinity works properly when new replica pod is scheduled", func() {
// create a pod running with label {security: S1}, and choose this node // create a pod running with label {security: S1}, and choose this node
nodeName, _ := runAndKeepPodWithLabelAndGetNodeName(f) nodeName, _ := runAndKeepPodWithLabelAndGetNodeName(f)
By("Trying to apply a random label on the found node.") ginkgo.By("Trying to apply a random label on the found node.")
// we need to use real failure domains, since scheduler only know them // we need to use real failure domains, since scheduler only know them
k := "failure-domain.beta.kubernetes.io/zone" k := "failure-domain.beta.kubernetes.io/zone"
v := "equivalence-e2e-test" v := "equivalence-e2e-test"
...@@ -118,7 +119,7 @@ var _ = framework.KubeDescribe("EquivalenceCache [Serial]", func() { ...@@ -118,7 +119,7 @@ var _ = framework.KubeDescribe("EquivalenceCache [Serial]", func() {
// restore the node label // restore the node label
defer framework.AddOrUpdateLabelOnNode(cs, nodeName, k, oldValue) defer framework.AddOrUpdateLabelOnNode(cs, nodeName, k, oldValue)
By("Trying to schedule RC with Pod Affinity should success.") ginkgo.By("Trying to schedule RC with Pod Affinity should success.")
framework.WaitForStableCluster(cs, masterNodes) framework.WaitForStableCluster(cs, masterNodes)
affinityRCName := "with-pod-affinity-" + string(uuid.NewUUID()) affinityRCName := "with-pod-affinity-" + string(uuid.NewUUID())
replica := 2 replica := 2
...@@ -154,10 +155,10 @@ var _ = framework.KubeDescribe("EquivalenceCache [Serial]", func() { ...@@ -154,10 +155,10 @@ var _ = framework.KubeDescribe("EquivalenceCache [Serial]", func() {
framework.ExpectNoError(err) framework.ExpectNoError(err)
framework.ExpectNoError(framework.WaitForControlledPodsRunning(cs, ns, affinityRCName, api.Kind("ReplicationController"))) framework.ExpectNoError(framework.WaitForControlledPodsRunning(cs, ns, affinityRCName, api.Kind("ReplicationController")))
By("Remove node failure domain label") ginkgo.By("Remove node failure domain label")
framework.RemoveLabelOffNode(cs, nodeName, k) framework.RemoveLabelOffNode(cs, nodeName, k)
By("Trying to schedule another equivalent Pod should fail due to node label has been removed.") ginkgo.By("Trying to schedule another equivalent Pod should fail due to node label has been removed.")
// use scale to create another equivalent pod and wait for failure event // use scale to create another equivalent pod and wait for failure event
WaitForSchedulerAfterAction(f, func() error { WaitForSchedulerAfterAction(f, func() error {
err := framework.ScaleRC(f.ClientSet, f.ScalesGetter, ns, affinityRCName, uint(replica+1), false) err := framework.ScaleRC(f.ClientSet, f.ScalesGetter, ns, affinityRCName, uint(replica+1), false)
...@@ -168,17 +169,17 @@ var _ = framework.KubeDescribe("EquivalenceCache [Serial]", func() { ...@@ -168,17 +169,17 @@ var _ = framework.KubeDescribe("EquivalenceCache [Serial]", func() {
}) })
// This test verifies that MatchInterPodAffinity (anti-affinity) is respected as expected. // This test verifies that MatchInterPodAffinity (anti-affinity) is respected as expected.
It("validates pod anti-affinity works properly when new replica pod is scheduled", func() { ginkgo.It("validates pod anti-affinity works properly when new replica pod is scheduled", func() {
By("Launching two pods on two distinct nodes to get two node names") ginkgo.By("Launching two pods on two distinct nodes to get two node names")
CreateHostPortPods(f, "host-port", 2, true) CreateHostPortPods(f, "host-port", 2, true)
defer framework.DeleteRCAndWaitForGC(f.ClientSet, ns, "host-port") defer framework.DeleteRCAndWaitForGC(f.ClientSet, ns, "host-port")
podList, err := cs.CoreV1().Pods(ns).List(metav1.ListOptions{}) podList, err := cs.CoreV1().Pods(ns).List(metav1.ListOptions{})
framework.ExpectNoError(err) framework.ExpectNoError(err)
Expect(len(podList.Items)).To(Equal(2)) gomega.Expect(len(podList.Items)).To(gomega.Equal(2))
nodeNames := []string{podList.Items[0].Spec.NodeName, podList.Items[1].Spec.NodeName} nodeNames := []string{podList.Items[0].Spec.NodeName, podList.Items[1].Spec.NodeName}
Expect(nodeNames[0]).ToNot(Equal(nodeNames[1])) gomega.Expect(nodeNames[0]).ToNot(gomega.Equal(nodeNames[1]))
By("Applying a random label to both nodes.") ginkgo.By("Applying a random label to both nodes.")
k := "e2e.inter-pod-affinity.kubernetes.io/zone" k := "e2e.inter-pod-affinity.kubernetes.io/zone"
v := "equivalence-e2etest" v := "equivalence-e2etest"
for _, nodeName := range nodeNames { for _, nodeName := range nodeNames {
...@@ -187,7 +188,7 @@ var _ = framework.KubeDescribe("EquivalenceCache [Serial]", func() { ...@@ -187,7 +188,7 @@ var _ = framework.KubeDescribe("EquivalenceCache [Serial]", func() {
defer framework.RemoveLabelOffNode(cs, nodeName, k) defer framework.RemoveLabelOffNode(cs, nodeName, k)
} }
By("Trying to launch a pod with the service label on the selected nodes.") ginkgo.By("Trying to launch a pod with the service label on the selected nodes.")
// run a pod with label {"service": "S1"} and expect it to be running // run a pod with label {"service": "S1"} and expect it to be running
runPausePod(f, pausePodConfig{ runPausePod(f, pausePodConfig{
Name: "with-label-" + string(uuid.NewUUID()), Name: "with-label-" + string(uuid.NewUUID()),
...@@ -195,7 +196,7 @@ var _ = framework.KubeDescribe("EquivalenceCache [Serial]", func() { ...@@ -195,7 +196,7 @@ var _ = framework.KubeDescribe("EquivalenceCache [Serial]", func() {
NodeSelector: map[string]string{k: v}, // only launch on our two nodes NodeSelector: map[string]string{k: v}, // only launch on our two nodes
}) })
By("Trying to launch RC with podAntiAffinity on these two nodes should be rejected.") ginkgo.By("Trying to launch RC with podAntiAffinity on these two nodes should be rejected.")
labelRCName := "with-podantiaffinity-" + string(uuid.NewUUID()) labelRCName := "with-podantiaffinity-" + string(uuid.NewUUID())
replica := 2 replica := 2
labelsMap := map[string]string{ labelsMap := map[string]string{
...@@ -269,8 +270,9 @@ func getRCWithInterPodAffinityNodeSelector(name string, labelsMap map[string]str ...@@ -269,8 +270,9 @@ func getRCWithInterPodAffinityNodeSelector(name string, labelsMap map[string]str
} }
} }
// CreateNodeSelectorPods creates RC with host port 4321 and defines node selector
func CreateNodeSelectorPods(f *framework.Framework, id string, replicas int, nodeSelector map[string]string, expectRunning bool) error { func CreateNodeSelectorPods(f *framework.Framework, id string, replicas int, nodeSelector map[string]string, expectRunning bool) error {
By(fmt.Sprintf("Running RC which reserves host port and defines node selector")) ginkgo.By(fmt.Sprintf("Running RC which reserves host port and defines node selector"))
config := &testutils.RCConfig{ config := &testutils.RCConfig{
Client: f.ClientSet, Client: f.ClientSet,
......
...@@ -18,6 +18,7 @@ package scheduling ...@@ -18,6 +18,7 @@ package scheduling
import "github.com/onsi/ginkgo" import "github.com/onsi/ginkgo"
// SIGDescribe annotates the test with the SIG label.
func SIGDescribe(text string, body func()) bool { func SIGDescribe(text string, body func()) bool {
return ginkgo.Describe("[sig-scheduling] "+text, body) return ginkgo.Describe("[sig-scheduling] "+text, body)
} }
...@@ -30,8 +30,8 @@ import ( ...@@ -30,8 +30,8 @@ import (
"k8s.io/kubernetes/test/e2e/framework" "k8s.io/kubernetes/test/e2e/framework"
e2elog "k8s.io/kubernetes/test/e2e/framework/log" e2elog "k8s.io/kubernetes/test/e2e/framework/log"
. "github.com/onsi/ginkgo" "github.com/onsi/ginkgo"
. "github.com/onsi/gomega" "github.com/onsi/gomega"
) )
const ( const (
...@@ -41,8 +41,8 @@ const ( ...@@ -41,8 +41,8 @@ const (
var _ = SIGDescribe("LimitRange", func() { var _ = SIGDescribe("LimitRange", func() {
f := framework.NewDefaultFramework("limitrange") f := framework.NewDefaultFramework("limitrange")
It("should create a LimitRange with defaults and ensure pod has those defaults applied.", func() { ginkgo.It("should create a LimitRange with defaults and ensure pod has those defaults applied.", func() {
By("Creating a LimitRange") ginkgo.By("Creating a LimitRange")
min := getResourceList("50m", "100Mi", "100Gi") min := getResourceList("50m", "100Mi", "100Gi")
max := getResourceList("500m", "500Mi", "500Gi") max := getResourceList("500m", "500Mi", "500Gi")
...@@ -54,24 +54,24 @@ var _ = SIGDescribe("LimitRange", func() { ...@@ -54,24 +54,24 @@ var _ = SIGDescribe("LimitRange", func() {
defaultLimit, defaultRequest, defaultLimit, defaultRequest,
maxLimitRequestRatio) maxLimitRequestRatio)
By("Setting up watch") ginkgo.By("Setting up watch")
selector := labels.SelectorFromSet(labels.Set(map[string]string{"name": limitRange.Name})) selector := labels.SelectorFromSet(labels.Set(map[string]string{"name": limitRange.Name}))
options := metav1.ListOptions{LabelSelector: selector.String()} options := metav1.ListOptions{LabelSelector: selector.String()}
limitRanges, err := f.ClientSet.CoreV1().LimitRanges(f.Namespace.Name).List(options) limitRanges, err := f.ClientSet.CoreV1().LimitRanges(f.Namespace.Name).List(options)
Expect(err).NotTo(HaveOccurred(), "failed to query for limitRanges") gomega.Expect(err).NotTo(gomega.HaveOccurred(), "failed to query for limitRanges")
Expect(len(limitRanges.Items)).To(Equal(0)) gomega.Expect(len(limitRanges.Items)).To(gomega.Equal(0))
options = metav1.ListOptions{ options = metav1.ListOptions{
LabelSelector: selector.String(), LabelSelector: selector.String(),
ResourceVersion: limitRanges.ListMeta.ResourceVersion, ResourceVersion: limitRanges.ListMeta.ResourceVersion,
} }
w, err := f.ClientSet.CoreV1().LimitRanges(f.Namespace.Name).Watch(metav1.ListOptions{}) w, err := f.ClientSet.CoreV1().LimitRanges(f.Namespace.Name).Watch(metav1.ListOptions{})
Expect(err).NotTo(HaveOccurred(), "failed to set up watch") gomega.Expect(err).NotTo(gomega.HaveOccurred(), "failed to set up watch")
By("Submitting a LimitRange") ginkgo.By("Submitting a LimitRange")
limitRange, err = f.ClientSet.CoreV1().LimitRanges(f.Namespace.Name).Create(limitRange) limitRange, err = f.ClientSet.CoreV1().LimitRanges(f.Namespace.Name).Create(limitRange)
Expect(err).NotTo(HaveOccurred()) gomega.Expect(err).NotTo(gomega.HaveOccurred())
By("Verifying LimitRange creation was observed") ginkgo.By("Verifying LimitRange creation was observed")
select { select {
case event, _ := <-w.ResultChan(): case event, _ := <-w.ResultChan():
if event.Type != watch.Added { if event.Type != watch.Added {
...@@ -81,39 +81,39 @@ var _ = SIGDescribe("LimitRange", func() { ...@@ -81,39 +81,39 @@ var _ = SIGDescribe("LimitRange", func() {
framework.Failf("Timeout while waiting for LimitRange creation") framework.Failf("Timeout while waiting for LimitRange creation")
} }
By("Fetching the LimitRange to ensure it has proper values") ginkgo.By("Fetching the LimitRange to ensure it has proper values")
limitRange, err = f.ClientSet.CoreV1().LimitRanges(f.Namespace.Name).Get(limitRange.Name, metav1.GetOptions{}) limitRange, err = f.ClientSet.CoreV1().LimitRanges(f.Namespace.Name).Get(limitRange.Name, metav1.GetOptions{})
Expect(err).NotTo(HaveOccurred()) gomega.Expect(err).NotTo(gomega.HaveOccurred())
expected := v1.ResourceRequirements{Requests: defaultRequest, Limits: defaultLimit} expected := v1.ResourceRequirements{Requests: defaultRequest, Limits: defaultLimit}
actual := v1.ResourceRequirements{Requests: limitRange.Spec.Limits[0].DefaultRequest, Limits: limitRange.Spec.Limits[0].Default} actual := v1.ResourceRequirements{Requests: limitRange.Spec.Limits[0].DefaultRequest, Limits: limitRange.Spec.Limits[0].Default}
err = equalResourceRequirement(expected, actual) err = equalResourceRequirement(expected, actual)
Expect(err).NotTo(HaveOccurred()) gomega.Expect(err).NotTo(gomega.HaveOccurred())
By("Creating a Pod with no resource requirements") ginkgo.By("Creating a Pod with no resource requirements")
pod := f.NewTestPod("pod-no-resources", v1.ResourceList{}, v1.ResourceList{}) pod := f.NewTestPod("pod-no-resources", v1.ResourceList{}, v1.ResourceList{})
pod, err = f.ClientSet.CoreV1().Pods(f.Namespace.Name).Create(pod) pod, err = f.ClientSet.CoreV1().Pods(f.Namespace.Name).Create(pod)
Expect(err).NotTo(HaveOccurred()) gomega.Expect(err).NotTo(gomega.HaveOccurred())
By("Ensuring Pod has resource requirements applied from LimitRange") ginkgo.By("Ensuring Pod has resource requirements applied from LimitRange")
pod, err = f.ClientSet.CoreV1().Pods(f.Namespace.Name).Get(pod.Name, metav1.GetOptions{}) pod, err = f.ClientSet.CoreV1().Pods(f.Namespace.Name).Get(pod.Name, metav1.GetOptions{})
Expect(err).NotTo(HaveOccurred()) gomega.Expect(err).NotTo(gomega.HaveOccurred())
for i := range pod.Spec.Containers { for i := range pod.Spec.Containers {
err = equalResourceRequirement(expected, pod.Spec.Containers[i].Resources) err = equalResourceRequirement(expected, pod.Spec.Containers[i].Resources)
if err != nil { if err != nil {
// Print the pod to help in debugging. // Print the pod to help in debugging.
e2elog.Logf("Pod %+v does not have the expected requirements", pod) e2elog.Logf("Pod %+v does not have the expected requirements", pod)
Expect(err).NotTo(HaveOccurred()) gomega.Expect(err).NotTo(gomega.HaveOccurred())
} }
} }
By("Creating a Pod with partial resource requirements") ginkgo.By("Creating a Pod with partial resource requirements")
pod = f.NewTestPod("pod-partial-resources", getResourceList("", "150Mi", "150Gi"), getResourceList("300m", "", "")) pod = f.NewTestPod("pod-partial-resources", getResourceList("", "150Mi", "150Gi"), getResourceList("300m", "", ""))
pod, err = f.ClientSet.CoreV1().Pods(f.Namespace.Name).Create(pod) pod, err = f.ClientSet.CoreV1().Pods(f.Namespace.Name).Create(pod)
Expect(err).NotTo(HaveOccurred()) gomega.Expect(err).NotTo(gomega.HaveOccurred())
By("Ensuring Pod has merged resource requirements applied from LimitRange") ginkgo.By("Ensuring Pod has merged resource requirements applied from LimitRange")
pod, err = f.ClientSet.CoreV1().Pods(f.Namespace.Name).Get(pod.Name, metav1.GetOptions{}) pod, err = f.ClientSet.CoreV1().Pods(f.Namespace.Name).Get(pod.Name, metav1.GetOptions{})
Expect(err).NotTo(HaveOccurred()) gomega.Expect(err).NotTo(gomega.HaveOccurred())
// This is an interesting case, so it's worth a comment // This is an interesting case, so it's worth a comment
// If you specify a Limit, and no Request, the Limit will default to the Request // If you specify a Limit, and no Request, the Limit will default to the Request
// This means that the LimitRange.DefaultRequest will ONLY take affect if a container.resources.limit is not supplied // This means that the LimitRange.DefaultRequest will ONLY take affect if a container.resources.limit is not supplied
...@@ -123,49 +123,49 @@ var _ = SIGDescribe("LimitRange", func() { ...@@ -123,49 +123,49 @@ var _ = SIGDescribe("LimitRange", func() {
if err != nil { if err != nil {
// Print the pod to help in debugging. // Print the pod to help in debugging.
e2elog.Logf("Pod %+v does not have the expected requirements", pod) e2elog.Logf("Pod %+v does not have the expected requirements", pod)
Expect(err).NotTo(HaveOccurred()) gomega.Expect(err).NotTo(gomega.HaveOccurred())
} }
} }
By("Failing to create a Pod with less than min resources") ginkgo.By("Failing to create a Pod with less than min resources")
pod = f.NewTestPod(podName, getResourceList("10m", "50Mi", "50Gi"), v1.ResourceList{}) pod = f.NewTestPod(podName, getResourceList("10m", "50Mi", "50Gi"), v1.ResourceList{})
pod, err = f.ClientSet.CoreV1().Pods(f.Namespace.Name).Create(pod) pod, err = f.ClientSet.CoreV1().Pods(f.Namespace.Name).Create(pod)
Expect(err).To(HaveOccurred()) framework.ExpectError(err)
By("Failing to create a Pod with more than max resources") ginkgo.By("Failing to create a Pod with more than max resources")
pod = f.NewTestPod(podName, getResourceList("600m", "600Mi", "600Gi"), v1.ResourceList{}) pod = f.NewTestPod(podName, getResourceList("600m", "600Mi", "600Gi"), v1.ResourceList{})
pod, err = f.ClientSet.CoreV1().Pods(f.Namespace.Name).Create(pod) pod, err = f.ClientSet.CoreV1().Pods(f.Namespace.Name).Create(pod)
Expect(err).To(HaveOccurred()) framework.ExpectError(err)
By("Updating a LimitRange") ginkgo.By("Updating a LimitRange")
newMin := getResourceList("9m", "49Mi", "49Gi") newMin := getResourceList("9m", "49Mi", "49Gi")
limitRange.Spec.Limits[0].Min = newMin limitRange.Spec.Limits[0].Min = newMin
limitRange, err = f.ClientSet.CoreV1().LimitRanges(f.Namespace.Name).Update(limitRange) limitRange, err = f.ClientSet.CoreV1().LimitRanges(f.Namespace.Name).Update(limitRange)
Expect(err).NotTo(HaveOccurred()) gomega.Expect(err).NotTo(gomega.HaveOccurred())
By("Verifying LimitRange updating is effective") ginkgo.By("Verifying LimitRange updating is effective")
Expect(wait.Poll(time.Second*2, time.Second*20, func() (bool, error) { gomega.Expect(wait.Poll(time.Second*2, time.Second*20, func() (bool, error) {
limitRange, err = f.ClientSet.CoreV1().LimitRanges(f.Namespace.Name).Get(limitRange.Name, metav1.GetOptions{}) limitRange, err = f.ClientSet.CoreV1().LimitRanges(f.Namespace.Name).Get(limitRange.Name, metav1.GetOptions{})
Expect(err).NotTo(HaveOccurred()) gomega.Expect(err).NotTo(gomega.HaveOccurred())
return reflect.DeepEqual(limitRange.Spec.Limits[0].Min, newMin), nil return reflect.DeepEqual(limitRange.Spec.Limits[0].Min, newMin), nil
})).NotTo(HaveOccurred()) })).NotTo(gomega.HaveOccurred())
By("Creating a Pod with less than former min resources") ginkgo.By("Creating a Pod with less than former min resources")
pod = f.NewTestPod(podName, getResourceList("10m", "50Mi", "50Gi"), v1.ResourceList{}) pod = f.NewTestPod(podName, getResourceList("10m", "50Mi", "50Gi"), v1.ResourceList{})
pod, err = f.ClientSet.CoreV1().Pods(f.Namespace.Name).Create(pod) pod, err = f.ClientSet.CoreV1().Pods(f.Namespace.Name).Create(pod)
Expect(err).NotTo(HaveOccurred()) gomega.Expect(err).NotTo(gomega.HaveOccurred())
By("Failing to create a Pod with more than max resources") ginkgo.By("Failing to create a Pod with more than max resources")
pod = f.NewTestPod(podName, getResourceList("600m", "600Mi", "600Gi"), v1.ResourceList{}) pod = f.NewTestPod(podName, getResourceList("600m", "600Mi", "600Gi"), v1.ResourceList{})
pod, err = f.ClientSet.CoreV1().Pods(f.Namespace.Name).Create(pod) pod, err = f.ClientSet.CoreV1().Pods(f.Namespace.Name).Create(pod)
Expect(err).To(HaveOccurred()) framework.ExpectError(err)
By("Deleting a LimitRange") ginkgo.By("Deleting a LimitRange")
err = f.ClientSet.CoreV1().LimitRanges(f.Namespace.Name).Delete(limitRange.Name, metav1.NewDeleteOptions(30)) err = f.ClientSet.CoreV1().LimitRanges(f.Namespace.Name).Delete(limitRange.Name, metav1.NewDeleteOptions(30))
Expect(err).NotTo(HaveOccurred()) gomega.Expect(err).NotTo(gomega.HaveOccurred())
By("Verifying the LimitRange was deleted") ginkgo.By("Verifying the LimitRange was deleted")
Expect(wait.Poll(time.Second*5, time.Second*30, func() (bool, error) { gomega.Expect(wait.Poll(time.Second*5, time.Second*30, func() (bool, error) {
selector := labels.SelectorFromSet(labels.Set(map[string]string{"name": limitRange.Name})) selector := labels.SelectorFromSet(labels.Set(map[string]string{"name": limitRange.Name}))
options := metav1.ListOptions{LabelSelector: selector.String()} options := metav1.ListOptions{LabelSelector: selector.String()}
limitRanges, err := f.ClientSet.CoreV1().LimitRanges(f.Namespace.Name).List(options) limitRanges, err := f.ClientSet.CoreV1().LimitRanges(f.Namespace.Name).List(options)
...@@ -190,12 +190,12 @@ var _ = SIGDescribe("LimitRange", func() { ...@@ -190,12 +190,12 @@ var _ = SIGDescribe("LimitRange", func() {
return false, nil return false, nil
})).NotTo(HaveOccurred(), "kubelet never observed the termination notice") })).NotTo(gomega.HaveOccurred(), "kubelet never observed the termination notice")
By("Creating a Pod with more than former max resources") ginkgo.By("Creating a Pod with more than former max resources")
pod = f.NewTestPod(podName+"2", getResourceList("600m", "600Mi", "600Gi"), v1.ResourceList{}) pod = f.NewTestPod(podName+"2", getResourceList("600m", "600Mi", "600Gi"), v1.ResourceList{})
pod, err = f.ClientSet.CoreV1().Pods(f.Namespace.Name).Create(pod) pod, err = f.ClientSet.CoreV1().Pods(f.Namespace.Name).Create(pod)
Expect(err).NotTo(HaveOccurred()) gomega.Expect(err).NotTo(gomega.HaveOccurred())
}) })
}) })
......
...@@ -30,8 +30,8 @@ import ( ...@@ -30,8 +30,8 @@ import (
e2elog "k8s.io/kubernetes/test/e2e/framework/log" e2elog "k8s.io/kubernetes/test/e2e/framework/log"
imageutils "k8s.io/kubernetes/test/utils/image" imageutils "k8s.io/kubernetes/test/utils/image"
. "github.com/onsi/ginkgo" "github.com/onsi/ginkgo"
. "github.com/onsi/gomega" "github.com/onsi/gomega"
) )
const ( const (
...@@ -42,7 +42,7 @@ const ( ...@@ -42,7 +42,7 @@ const (
var ( var (
gpuResourceName v1.ResourceName gpuResourceName v1.ResourceName
dsYamlUrl string dsYamlURL string
) )
func makeCudaAdditionDevicePluginTestPod() *v1.Pod { func makeCudaAdditionDevicePluginTestPod() *v1.Pod {
...@@ -116,21 +116,22 @@ func getGPUsAvailable(f *framework.Framework) int64 { ...@@ -116,21 +116,22 @@ func getGPUsAvailable(f *framework.Framework) int64 {
return gpusAvailable return gpusAvailable
} }
// SetupNVIDIAGPUNode install Nvidia Drivers and wait for Nvidia GPUs to be available on nodes
func SetupNVIDIAGPUNode(f *framework.Framework, setupResourceGatherer bool) *framework.ContainerResourceGatherer { func SetupNVIDIAGPUNode(f *framework.Framework, setupResourceGatherer bool) *framework.ContainerResourceGatherer {
logOSImages(f) logOSImages(f)
dsYamlUrlFromEnv := os.Getenv("NVIDIA_DRIVER_INSTALLER_DAEMONSET") dsYamlURLFromEnv := os.Getenv("NVIDIA_DRIVER_INSTALLER_DAEMONSET")
if dsYamlUrlFromEnv != "" { if dsYamlURLFromEnv != "" {
dsYamlUrl = dsYamlUrlFromEnv dsYamlURL = dsYamlURLFromEnv
} else { } else {
dsYamlUrl = "https://raw.githubusercontent.com/GoogleCloudPlatform/container-engine-accelerators/master/daemonset.yaml" dsYamlURL = "https://raw.githubusercontent.com/GoogleCloudPlatform/container-engine-accelerators/master/daemonset.yaml"
} }
gpuResourceName = gpu.NVIDIAGPUResourceName gpuResourceName = gpu.NVIDIAGPUResourceName
e2elog.Logf("Using %v", dsYamlUrl) e2elog.Logf("Using %v", dsYamlURL)
// Creates the DaemonSet that installs Nvidia Drivers. // Creates the DaemonSet that installs Nvidia Drivers.
ds, err := framework.DsFromManifest(dsYamlUrl) ds, err := framework.DsFromManifest(dsYamlURL)
Expect(err).NotTo(HaveOccurred()) gomega.Expect(err).NotTo(gomega.HaveOccurred())
ds.Namespace = f.Namespace.Name ds.Namespace = f.Namespace.Name
_, err = f.ClientSet.AppsV1().DaemonSets(f.Namespace.Name).Create(ds) _, err = f.ClientSet.AppsV1().DaemonSets(f.Namespace.Name).Create(ds)
framework.ExpectNoError(err, "failed to create nvidia-driver-installer daemonset") framework.ExpectNoError(err, "failed to create nvidia-driver-installer daemonset")
...@@ -155,9 +156,9 @@ func SetupNVIDIAGPUNode(f *framework.Framework, setupResourceGatherer bool) *fra ...@@ -155,9 +156,9 @@ func SetupNVIDIAGPUNode(f *framework.Framework, setupResourceGatherer bool) *fra
// Wait for Nvidia GPUs to be available on nodes // Wait for Nvidia GPUs to be available on nodes
e2elog.Logf("Waiting for drivers to be installed and GPUs to be available in Node Capacity...") e2elog.Logf("Waiting for drivers to be installed and GPUs to be available in Node Capacity...")
Eventually(func() bool { gomega.Eventually(func() bool {
return areGPUsAvailableOnAllSchedulableNodes(f) return areGPUsAvailableOnAllSchedulableNodes(f)
}, driverInstallTimeout, time.Second).Should(BeTrue()) }, driverInstallTimeout, time.Second).Should(gomega.BeTrue())
return rsgather return rsgather
} }
...@@ -185,7 +186,7 @@ func testNvidiaGPUs(f *framework.Framework) { ...@@ -185,7 +186,7 @@ func testNvidiaGPUs(f *framework.Framework) {
var _ = SIGDescribe("[Feature:GPUDevicePlugin]", func() { var _ = SIGDescribe("[Feature:GPUDevicePlugin]", func() {
f := framework.NewDefaultFramework("device-plugin-gpus") f := framework.NewDefaultFramework("device-plugin-gpus")
It("run Nvidia GPU Device Plugin tests", func() { ginkgo.It("run Nvidia GPU Device Plugin tests", func() {
testNvidiaGPUs(f) testNvidiaGPUs(f)
}) })
}) })
...@@ -28,7 +28,7 @@ import ( ...@@ -28,7 +28,7 @@ import (
schedulerapi "k8s.io/kubernetes/pkg/scheduler/api" schedulerapi "k8s.io/kubernetes/pkg/scheduler/api"
"k8s.io/kubernetes/test/e2e/framework" "k8s.io/kubernetes/test/e2e/framework"
. "github.com/onsi/ginkgo" "github.com/onsi/ginkgo"
) )
func newUnreachableNoExecuteTaint() *v1.Taint { func newUnreachableNoExecuteTaint() *v1.Taint {
...@@ -52,7 +52,7 @@ var _ = SIGDescribe("TaintBasedEvictions [Serial]", func() { ...@@ -52,7 +52,7 @@ var _ = SIGDescribe("TaintBasedEvictions [Serial]", func() {
var cs clientset.Interface var cs clientset.Interface
var ns string var ns string
BeforeEach(func() { ginkgo.BeforeEach(func() {
cs = f.ClientSet cs = f.ClientSet
ns = f.Namespace.Name ns = f.Namespace.Name
// skip if TaintBasedEvictions is not enabled // skip if TaintBasedEvictions is not enabled
...@@ -72,10 +72,10 @@ var _ = SIGDescribe("TaintBasedEvictions [Serial]", func() { ...@@ -72,10 +72,10 @@ var _ = SIGDescribe("TaintBasedEvictions [Serial]", func() {
// When network issue recovers, it's expected to see: // When network issue recovers, it's expected to see:
// 5. node lifecycle manager generate a status change: [NodeReady=true, status=ConditionTrue] // 5. node lifecycle manager generate a status change: [NodeReady=true, status=ConditionTrue]
// 6. node.kubernetes.io/unreachable=:NoExecute taint is taken off the node // 6. node.kubernetes.io/unreachable=:NoExecute taint is taken off the node
It("Checks that the node becomes unreachable", func() { ginkgo.It("Checks that the node becomes unreachable", func() {
// find an available node // find an available node
nodeName := GetNodeThatCanRunPod(f) nodeName := GetNodeThatCanRunPod(f)
By("Finding an available node " + nodeName) ginkgo.By("Finding an available node " + nodeName)
// pod0 is a pod with unschedulable=:NoExecute toleration, and tolerationSeconds=0s // pod0 is a pod with unschedulable=:NoExecute toleration, and tolerationSeconds=0s
// pod1 is a pod with unschedulable=:NoExecute toleration, and tolerationSeconds=200s // pod1 is a pod with unschedulable=:NoExecute toleration, and tolerationSeconds=200s
...@@ -83,7 +83,7 @@ var _ = SIGDescribe("TaintBasedEvictions [Serial]", func() { ...@@ -83,7 +83,7 @@ var _ = SIGDescribe("TaintBasedEvictions [Serial]", func() {
base := "taint-based-eviction" base := "taint-based-eviction"
tolerationSeconds := []int64{0, 200} tolerationSeconds := []int64{0, 200}
numPods := len(tolerationSeconds) + 1 numPods := len(tolerationSeconds) + 1
By(fmt.Sprintf("Preparing %v pods", numPods)) ginkgo.By(fmt.Sprintf("Preparing %v pods", numPods))
pods := make([]*v1.Pod, numPods) pods := make([]*v1.Pod, numPods)
zero := int64(0) zero := int64(0)
// build pod0, pod1 // build pod0, pod1
...@@ -108,7 +108,7 @@ var _ = SIGDescribe("TaintBasedEvictions [Serial]", func() { ...@@ -108,7 +108,7 @@ var _ = SIGDescribe("TaintBasedEvictions [Serial]", func() {
NodeName: nodeName, NodeName: nodeName,
}) })
By("Verifying all pods are running properly") ginkgo.By("Verifying all pods are running properly")
for _, pod := range pods { for _, pod := range pods {
framework.ExpectNoError(framework.WaitForPodRunningInNamespace(cs, pod)) framework.ExpectNoError(framework.WaitForPodRunningInNamespace(cs, pod))
} }
...@@ -121,7 +121,7 @@ var _ = SIGDescribe("TaintBasedEvictions [Serial]", func() { ...@@ -121,7 +121,7 @@ var _ = SIGDescribe("TaintBasedEvictions [Serial]", func() {
} }
node := nodeList.Items[0] node := nodeList.Items[0]
By(fmt.Sprintf("Blocking traffic from node %s to the master", nodeName)) ginkgo.By(fmt.Sprintf("Blocking traffic from node %s to the master", nodeName))
host, err := framework.GetNodeExternalIP(&node) host, err := framework.GetNodeExternalIP(&node)
// TODO(Huang-Wei): make this case work for local provider // TODO(Huang-Wei): make this case work for local provider
// if err != nil { // if err != nil {
...@@ -132,19 +132,19 @@ var _ = SIGDescribe("TaintBasedEvictions [Serial]", func() { ...@@ -132,19 +132,19 @@ var _ = SIGDescribe("TaintBasedEvictions [Serial]", func() {
taint := newUnreachableNoExecuteTaint() taint := newUnreachableNoExecuteTaint()
defer func() { defer func() {
By(fmt.Sprintf("Unblocking traffic from node %s to the master", node.Name)) ginkgo.By(fmt.Sprintf("Unblocking traffic from node %s to the master", node.Name))
for _, masterAddress := range masterAddresses { for _, masterAddress := range masterAddresses {
framework.UnblockNetwork(host, masterAddress) framework.UnblockNetwork(host, masterAddress)
} }
if CurrentGinkgoTestDescription().Failed { if ginkgo.CurrentGinkgoTestDescription().Failed {
framework.Failf("Current e2e test has failed, so return from here.") framework.Failf("Current e2e test has failed, so return from here.")
return return
} }
By(fmt.Sprintf("Expecting to see node %q becomes Ready", nodeName)) ginkgo.By(fmt.Sprintf("Expecting to see node %q becomes Ready", nodeName))
framework.WaitForNodeToBeReady(cs, nodeName, time.Minute*1) framework.WaitForNodeToBeReady(cs, nodeName, time.Minute*1)
By("Expecting to see unreachable=:NoExecute taint is taken off") ginkgo.By("Expecting to see unreachable=:NoExecute taint is taken off")
err := framework.WaitForNodeHasTaintOrNot(cs, nodeName, taint, false, time.Second*30) err := framework.WaitForNodeHasTaintOrNot(cs, nodeName, taint, false, time.Second*30)
framework.ExpectNoError(err) framework.ExpectNoError(err)
}() }()
...@@ -153,15 +153,15 @@ var _ = SIGDescribe("TaintBasedEvictions [Serial]", func() { ...@@ -153,15 +153,15 @@ var _ = SIGDescribe("TaintBasedEvictions [Serial]", func() {
framework.BlockNetwork(host, masterAddress) framework.BlockNetwork(host, masterAddress)
} }
By(fmt.Sprintf("Expecting to see node %q becomes NotReady", nodeName)) ginkgo.By(fmt.Sprintf("Expecting to see node %q becomes NotReady", nodeName))
if !framework.WaitForNodeToBeNotReady(cs, nodeName, time.Minute*3) { if !framework.WaitForNodeToBeNotReady(cs, nodeName, time.Minute*3) {
framework.Failf("node %q doesn't turn to NotReady after 3 minutes", nodeName) framework.Failf("node %q doesn't turn to NotReady after 3 minutes", nodeName)
} }
By("Expecting to see unreachable=:NoExecute taint is applied") ginkgo.By("Expecting to see unreachable=:NoExecute taint is applied")
err = framework.WaitForNodeHasTaintOrNot(cs, nodeName, taint, true, time.Second*30) err = framework.WaitForNodeHasTaintOrNot(cs, nodeName, taint, true, time.Second*30)
framework.ExpectNoError(err) framework.ExpectNoError(err)
By("Expecting pod0 to be evicted immediately") ginkgo.By("Expecting pod0 to be evicted immediately")
err = framework.WaitForPodCondition(cs, ns, pods[0].Name, "pod0 terminating", time.Second*15, func(pod *v1.Pod) (bool, error) { err = framework.WaitForPodCondition(cs, ns, pods[0].Name, "pod0 terminating", time.Second*15, func(pod *v1.Pod) (bool, error) {
// as node is unreachable, pod0 is expected to be in Terminating status // as node is unreachable, pod0 is expected to be in Terminating status
// rather than getting deleted // rather than getting deleted
...@@ -172,7 +172,7 @@ var _ = SIGDescribe("TaintBasedEvictions [Serial]", func() { ...@@ -172,7 +172,7 @@ var _ = SIGDescribe("TaintBasedEvictions [Serial]", func() {
}) })
framework.ExpectNoError(err) framework.ExpectNoError(err)
By("Expecting pod2 to be updated with a toleration with tolerationSeconds=300") ginkgo.By("Expecting pod2 to be updated with a toleration with tolerationSeconds=300")
err = framework.WaitForPodCondition(cs, ns, pods[2].Name, "pod2 updated with tolerationSeconds=300", time.Second*15, func(pod *v1.Pod) (bool, error) { err = framework.WaitForPodCondition(cs, ns, pods[2].Name, "pod2 updated with tolerationSeconds=300", time.Second*15, func(pod *v1.Pod) (bool, error) {
if seconds, err := getTolerationSeconds(pod.Spec.Tolerations); err == nil { if seconds, err := getTolerationSeconds(pod.Spec.Tolerations); err == nil {
return seconds == 300, nil return seconds == 300, nil
...@@ -181,7 +181,7 @@ var _ = SIGDescribe("TaintBasedEvictions [Serial]", func() { ...@@ -181,7 +181,7 @@ var _ = SIGDescribe("TaintBasedEvictions [Serial]", func() {
}) })
framework.ExpectNoError(err) framework.ExpectNoError(err)
By("Expecting pod1 to be unchanged") ginkgo.By("Expecting pod1 to be unchanged")
livePod1, err := cs.CoreV1().Pods(pods[1].Namespace).Get(pods[1].Name, metav1.GetOptions{}) livePod1, err := cs.CoreV1().Pods(pods[1].Namespace).Get(pods[1].Name, metav1.GetOptions{})
framework.ExpectNoError(err) framework.ExpectNoError(err)
seconds, err := getTolerationSeconds(livePod1.Spec.Tolerations) seconds, err := getTolerationSeconds(livePod1.Spec.Tolerations)
......
...@@ -20,8 +20,8 @@ import ( ...@@ -20,8 +20,8 @@ import (
"fmt" "fmt"
"math" "math"
. "github.com/onsi/ginkgo" "github.com/onsi/ginkgo"
. "github.com/onsi/gomega" "github.com/onsi/gomega"
"k8s.io/api/core/v1" "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/labels"
...@@ -39,27 +39,28 @@ var _ = SIGDescribe("Multi-AZ Clusters", func() { ...@@ -39,27 +39,28 @@ var _ = SIGDescribe("Multi-AZ Clusters", func() {
var zoneCount int var zoneCount int
var err error var err error
image := framework.ServeHostnameImage image := framework.ServeHostnameImage
BeforeEach(func() { ginkgo.BeforeEach(func() {
framework.SkipUnlessProviderIs("gce", "gke", "aws") framework.SkipUnlessProviderIs("gce", "gke", "aws")
if zoneCount <= 0 { if zoneCount <= 0 {
zoneCount, err = getZoneCount(f.ClientSet) zoneCount, err = getZoneCount(f.ClientSet)
Expect(err).NotTo(HaveOccurred()) gomega.Expect(err).NotTo(gomega.HaveOccurred())
} }
By(fmt.Sprintf("Checking for multi-zone cluster. Zone count = %d", zoneCount)) ginkgo.By(fmt.Sprintf("Checking for multi-zone cluster. Zone count = %d", zoneCount))
msg := fmt.Sprintf("Zone count is %d, only run for multi-zone clusters, skipping test", zoneCount) msg := fmt.Sprintf("Zone count is %d, only run for multi-zone clusters, skipping test", zoneCount)
framework.SkipUnlessAtLeast(zoneCount, 2, msg) framework.SkipUnlessAtLeast(zoneCount, 2, msg)
// TODO: SkipUnlessDefaultScheduler() // Non-default schedulers might not spread // TODO: SkipUnlessDefaultScheduler() // Non-default schedulers might not spread
}) })
It("should spread the pods of a service across zones", func() { ginkgo.It("should spread the pods of a service across zones", func() {
SpreadServiceOrFail(f, (2*zoneCount)+1, image) SpreadServiceOrFail(f, (2*zoneCount)+1, image)
}) })
It("should spread the pods of a replication controller across zones", func() { ginkgo.It("should spread the pods of a replication controller across zones", func() {
SpreadRCOrFail(f, int32((2*zoneCount)+1), image) SpreadRCOrFail(f, int32((2*zoneCount)+1), image)
}) })
}) })
// Check that the pods comprising a service get spread evenly across available zones // SpreadServiceOrFail check that the pods comprising a service
// get spread evenly across available zones
func SpreadServiceOrFail(f *framework.Framework, replicaCount int, image string) { func SpreadServiceOrFail(f *framework.Framework, replicaCount int, image string) {
// First create the service // First create the service
serviceName := "test-service" serviceName := "test-service"
...@@ -79,7 +80,7 @@ func SpreadServiceOrFail(f *framework.Framework, replicaCount int, image string) ...@@ -79,7 +80,7 @@ func SpreadServiceOrFail(f *framework.Framework, replicaCount int, image string)
}, },
} }
_, err := f.ClientSet.CoreV1().Services(f.Namespace.Name).Create(serviceSpec) _, err := f.ClientSet.CoreV1().Services(f.Namespace.Name).Create(serviceSpec)
Expect(err).NotTo(HaveOccurred()) gomega.Expect(err).NotTo(gomega.HaveOccurred())
// Now create some pods behind the service // Now create some pods behind the service
podSpec := &v1.Pod{ podSpec := &v1.Pod{
...@@ -106,12 +107,12 @@ func SpreadServiceOrFail(f *framework.Framework, replicaCount int, image string) ...@@ -106,12 +107,12 @@ func SpreadServiceOrFail(f *framework.Framework, replicaCount int, image string)
// Wait for all of them to be scheduled // Wait for all of them to be scheduled
selector := labels.SelectorFromSet(labels.Set(map[string]string{"service": serviceName})) selector := labels.SelectorFromSet(labels.Set(map[string]string{"service": serviceName}))
pods, err := framework.WaitForPodsWithLabelScheduled(f.ClientSet, f.Namespace.Name, selector) pods, err := framework.WaitForPodsWithLabelScheduled(f.ClientSet, f.Namespace.Name, selector)
Expect(err).NotTo(HaveOccurred()) gomega.Expect(err).NotTo(gomega.HaveOccurred())
// Now make sure they're spread across zones // Now make sure they're spread across zones
zoneNames, err := framework.GetClusterZones(f.ClientSet) zoneNames, err := framework.GetClusterZones(f.ClientSet)
Expect(err).NotTo(HaveOccurred()) gomega.Expect(err).NotTo(gomega.HaveOccurred())
Expect(checkZoneSpreading(f.ClientSet, pods, zoneNames.List())).To(Equal(true)) gomega.Expect(checkZoneSpreading(f.ClientSet, pods, zoneNames.List())).To(gomega.Equal(true))
} }
// Find the name of the zone in which a Node is running // Find the name of the zone in which a Node is running
...@@ -136,9 +137,9 @@ func getZoneCount(c clientset.Interface) (int, error) { ...@@ -136,9 +137,9 @@ func getZoneCount(c clientset.Interface) (int, error) {
// Find the name of the zone in which the pod is scheduled // Find the name of the zone in which the pod is scheduled
func getZoneNameForPod(c clientset.Interface, pod v1.Pod) (string, error) { func getZoneNameForPod(c clientset.Interface, pod v1.Pod) (string, error) {
By(fmt.Sprintf("Getting zone name for pod %s, on node %s", pod.Name, pod.Spec.NodeName)) ginkgo.By(fmt.Sprintf("Getting zone name for pod %s, on node %s", pod.Name, pod.Spec.NodeName))
node, err := c.CoreV1().Nodes().Get(pod.Spec.NodeName, metav1.GetOptions{}) node, err := c.CoreV1().Nodes().Get(pod.Spec.NodeName, metav1.GetOptions{})
Expect(err).NotTo(HaveOccurred()) gomega.Expect(err).NotTo(gomega.HaveOccurred())
return getZoneNameForNode(*node) return getZoneNameForNode(*node)
} }
...@@ -154,7 +155,7 @@ func checkZoneSpreading(c clientset.Interface, pods *v1.PodList, zoneNames []str ...@@ -154,7 +155,7 @@ func checkZoneSpreading(c clientset.Interface, pods *v1.PodList, zoneNames []str
continue continue
} }
zoneName, err := getZoneNameForPod(c, pod) zoneName, err := getZoneNameForPod(c, pod)
Expect(err).NotTo(HaveOccurred()) gomega.Expect(err).NotTo(gomega.HaveOccurred())
podsPerZone[zoneName] = podsPerZone[zoneName] + 1 podsPerZone[zoneName] = podsPerZone[zoneName] + 1
} }
minPodsPerZone := math.MaxInt32 minPodsPerZone := math.MaxInt32
...@@ -167,16 +168,17 @@ func checkZoneSpreading(c clientset.Interface, pods *v1.PodList, zoneNames []str ...@@ -167,16 +168,17 @@ func checkZoneSpreading(c clientset.Interface, pods *v1.PodList, zoneNames []str
maxPodsPerZone = podCount maxPodsPerZone = podCount
} }
} }
Expect(minPodsPerZone).To(BeNumerically("~", maxPodsPerZone, 1), gomega.Expect(minPodsPerZone).To(gomega.BeNumerically("~", maxPodsPerZone, 1),
"Pods were not evenly spread across zones. %d in one zone and %d in another zone", "Pods were not evenly spread across zones. %d in one zone and %d in another zone",
minPodsPerZone, maxPodsPerZone) minPodsPerZone, maxPodsPerZone)
return true, nil return true, nil
} }
// Check that the pods comprising a replication controller get spread evenly across available zones // SpreadRCOrFail Check that the pods comprising a replication
// controller get spread evenly across available zones
func SpreadRCOrFail(f *framework.Framework, replicaCount int32, image string) { func SpreadRCOrFail(f *framework.Framework, replicaCount int32, image string) {
name := "ubelite-spread-rc-" + string(uuid.NewUUID()) name := "ubelite-spread-rc-" + string(uuid.NewUUID())
By(fmt.Sprintf("Creating replication controller %s", name)) ginkgo.By(fmt.Sprintf("Creating replication controller %s", name))
controller, err := f.ClientSet.CoreV1().ReplicationControllers(f.Namespace.Name).Create(&v1.ReplicationController{ controller, err := f.ClientSet.CoreV1().ReplicationControllers(f.Namespace.Name).Create(&v1.ReplicationController{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
Namespace: f.Namespace.Name, Namespace: f.Namespace.Name,
...@@ -203,7 +205,7 @@ func SpreadRCOrFail(f *framework.Framework, replicaCount int32, image string) { ...@@ -203,7 +205,7 @@ func SpreadRCOrFail(f *framework.Framework, replicaCount int32, image string) {
}, },
}, },
}) })
Expect(err).NotTo(HaveOccurred()) gomega.Expect(err).NotTo(gomega.HaveOccurred())
// Cleanup the replication controller when we are done. // Cleanup the replication controller when we are done.
defer func() { defer func() {
// Resize the replication controller to zero to get rid of pods. // Resize the replication controller to zero to get rid of pods.
...@@ -214,15 +216,15 @@ func SpreadRCOrFail(f *framework.Framework, replicaCount int32, image string) { ...@@ -214,15 +216,15 @@ func SpreadRCOrFail(f *framework.Framework, replicaCount int32, image string) {
// List the pods, making sure we observe all the replicas. // List the pods, making sure we observe all the replicas.
selector := labels.SelectorFromSet(labels.Set(map[string]string{"name": name})) selector := labels.SelectorFromSet(labels.Set(map[string]string{"name": name}))
pods, err := framework.PodsCreated(f.ClientSet, f.Namespace.Name, name, replicaCount) pods, err := framework.PodsCreated(f.ClientSet, f.Namespace.Name, name, replicaCount)
Expect(err).NotTo(HaveOccurred()) gomega.Expect(err).NotTo(gomega.HaveOccurred())
// Wait for all of them to be scheduled // Wait for all of them to be scheduled
By(fmt.Sprintf("Waiting for %d replicas of %s to be scheduled. Selector: %v", replicaCount, name, selector)) ginkgo.By(fmt.Sprintf("Waiting for %d replicas of %s to be scheduled. Selector: %v", replicaCount, name, selector))
pods, err = framework.WaitForPodsWithLabelScheduled(f.ClientSet, f.Namespace.Name, selector) pods, err = framework.WaitForPodsWithLabelScheduled(f.ClientSet, f.Namespace.Name, selector)
Expect(err).NotTo(HaveOccurred()) gomega.Expect(err).NotTo(gomega.HaveOccurred())
// Now make sure they're spread across zones // Now make sure they're spread across zones
zoneNames, err := framework.GetClusterZones(f.ClientSet) zoneNames, err := framework.GetClusterZones(f.ClientSet)
Expect(err).NotTo(HaveOccurred()) gomega.Expect(err).NotTo(gomega.HaveOccurred())
Expect(checkZoneSpreading(f.ClientSet, pods, zoneNames.List())).To(Equal(true)) gomega.Expect(checkZoneSpreading(f.ClientSet, pods, zoneNames.List())).To(gomega.Equal(true))
} }
...@@ -20,8 +20,8 @@ import ( ...@@ -20,8 +20,8 @@ import (
"fmt" "fmt"
"strconv" "strconv"
. "github.com/onsi/ginkgo" "github.com/onsi/ginkgo"
. "github.com/onsi/gomega" "github.com/onsi/gomega"
compute "google.golang.org/api/compute/v1" compute "google.golang.org/api/compute/v1"
"k8s.io/api/core/v1" "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/resource" "k8s.io/apimachinery/pkg/api/resource"
...@@ -38,22 +38,22 @@ var _ = SIGDescribe("Multi-AZ Cluster Volumes [sig-storage]", func() { ...@@ -38,22 +38,22 @@ var _ = SIGDescribe("Multi-AZ Cluster Volumes [sig-storage]", func() {
var zoneCount int var zoneCount int
var err error var err error
image := framework.ServeHostnameImage image := framework.ServeHostnameImage
BeforeEach(func() { ginkgo.BeforeEach(func() {
framework.SkipUnlessProviderIs("gce", "gke") framework.SkipUnlessProviderIs("gce", "gke")
if zoneCount <= 0 { if zoneCount <= 0 {
zoneCount, err = getZoneCount(f.ClientSet) zoneCount, err = getZoneCount(f.ClientSet)
Expect(err).NotTo(HaveOccurred()) gomega.Expect(err).NotTo(gomega.HaveOccurred())
} }
By(fmt.Sprintf("Checking for multi-zone cluster. Zone count = %d", zoneCount)) ginkgo.By(fmt.Sprintf("Checking for multi-zone cluster. Zone count = %d", zoneCount))
msg := fmt.Sprintf("Zone count is %d, only run for multi-zone clusters, skipping test", zoneCount) msg := fmt.Sprintf("Zone count is %d, only run for multi-zone clusters, skipping test", zoneCount)
framework.SkipUnlessAtLeast(zoneCount, 2, msg) framework.SkipUnlessAtLeast(zoneCount, 2, msg)
// TODO: SkipUnlessDefaultScheduler() // Non-default schedulers might not spread // TODO: SkipUnlessDefaultScheduler() // Non-default schedulers might not spread
}) })
It("should schedule pods in the same zones as statically provisioned PVs", func() { ginkgo.It("should schedule pods in the same zones as statically provisioned PVs", func() {
PodsUseStaticPVsOrFail(f, (2*zoneCount)+1, image) PodsUseStaticPVsOrFail(f, (2*zoneCount)+1, image)
}) })
It("should only be allowed to provision PDs in zones where nodes exist", func() { ginkgo.It("should only be allowed to provision PDs in zones where nodes exist", func() {
OnlyAllowNodeZones(f, zoneCount, image) OnlyAllowNodeZones(f, zoneCount, image)
}) })
}) })
...@@ -61,17 +61,17 @@ var _ = SIGDescribe("Multi-AZ Cluster Volumes [sig-storage]", func() { ...@@ -61,17 +61,17 @@ var _ = SIGDescribe("Multi-AZ Cluster Volumes [sig-storage]", func() {
// OnlyAllowNodeZones tests that GetAllCurrentZones returns only zones with Nodes // OnlyAllowNodeZones tests that GetAllCurrentZones returns only zones with Nodes
func OnlyAllowNodeZones(f *framework.Framework, zoneCount int, image string) { func OnlyAllowNodeZones(f *framework.Framework, zoneCount int, image string) {
gceCloud, err := gce.GetGCECloud() gceCloud, err := gce.GetGCECloud()
Expect(err).NotTo(HaveOccurred()) gomega.Expect(err).NotTo(gomega.HaveOccurred())
// Get all the zones that the nodes are in // Get all the zones that the nodes are in
expectedZones, err := gceCloud.GetAllZonesFromCloudProvider() expectedZones, err := gceCloud.GetAllZonesFromCloudProvider()
Expect(err).NotTo(HaveOccurred()) gomega.Expect(err).NotTo(gomega.HaveOccurred())
e2elog.Logf("Expected zones: %v", expectedZones) e2elog.Logf("Expected zones: %v", expectedZones)
// Get all the zones in this current region // Get all the zones in this current region
region := gceCloud.Region() region := gceCloud.Region()
allZonesInRegion, err := gceCloud.ListZonesInRegion(region) allZonesInRegion, err := gceCloud.ListZonesInRegion(region)
Expect(err).NotTo(HaveOccurred()) gomega.Expect(err).NotTo(gomega.HaveOccurred())
var extraZone string var extraZone string
for _, zone := range allZonesInRegion { for _, zone := range allZonesInRegion {
...@@ -80,9 +80,9 @@ func OnlyAllowNodeZones(f *framework.Framework, zoneCount int, image string) { ...@@ -80,9 +80,9 @@ func OnlyAllowNodeZones(f *framework.Framework, zoneCount int, image string) {
break break
} }
} }
Expect(extraZone).NotTo(Equal(""), fmt.Sprintf("No extra zones available in region %s", region)) gomega.Expect(extraZone).NotTo(gomega.Equal(""), fmt.Sprintf("No extra zones available in region %s", region))
By(fmt.Sprintf("starting a compute instance in unused zone: %v\n", extraZone)) ginkgo.By(fmt.Sprintf("starting a compute instance in unused zone: %v\n", extraZone))
project := framework.TestContext.CloudConfig.ProjectID project := framework.TestContext.CloudConfig.ProjectID
zone := extraZone zone := extraZone
myuuid := string(uuid.NewUUID()) myuuid := string(uuid.NewUUID())
...@@ -117,16 +117,16 @@ func OnlyAllowNodeZones(f *framework.Framework, zoneCount int, image string) { ...@@ -117,16 +117,16 @@ func OnlyAllowNodeZones(f *framework.Framework, zoneCount int, image string) {
} }
err = gceCloud.InsertInstance(project, zone, rb) err = gceCloud.InsertInstance(project, zone, rb)
Expect(err).NotTo(HaveOccurred()) gomega.Expect(err).NotTo(gomega.HaveOccurred())
defer func() { defer func() {
// Teardown of the compute instance // Teardown of the compute instance
e2elog.Logf("Deleting compute resource: %v", name) e2elog.Logf("Deleting compute resource: %v", name)
err := gceCloud.DeleteInstance(project, zone, name) err := gceCloud.DeleteInstance(project, zone, name)
Expect(err).NotTo(HaveOccurred()) gomega.Expect(err).NotTo(gomega.HaveOccurred())
}() }()
By("Creating zoneCount+1 PVCs and making sure PDs are only provisioned in zones with nodes") ginkgo.By("Creating zoneCount+1 PVCs and making sure PDs are only provisioned in zones with nodes")
// Create some (zoneCount+1) PVCs with names of form "pvc-x" where x is 1...zoneCount+1 // Create some (zoneCount+1) PVCs with names of form "pvc-x" where x is 1...zoneCount+1
// This will exploit ChooseZoneForVolume in pkg/volume/util.go to provision them in all the zones it "sees" // This will exploit ChooseZoneForVolume in pkg/volume/util.go to provision them in all the zones it "sees"
var pvcList []*v1.PersistentVolumeClaim var pvcList []*v1.PersistentVolumeClaim
...@@ -136,7 +136,7 @@ func OnlyAllowNodeZones(f *framework.Framework, zoneCount int, image string) { ...@@ -136,7 +136,7 @@ func OnlyAllowNodeZones(f *framework.Framework, zoneCount int, image string) {
for index := 1; index <= zoneCount+1; index++ { for index := 1; index <= zoneCount+1; index++ {
pvc := newNamedDefaultClaim(ns, index) pvc := newNamedDefaultClaim(ns, index)
pvc, err = framework.CreatePVC(c, ns, pvc) pvc, err = framework.CreatePVC(c, ns, pvc)
Expect(err).NotTo(HaveOccurred()) gomega.Expect(err).NotTo(gomega.HaveOccurred())
pvcList = append(pvcList, pvc) pvcList = append(pvcList, pvc)
// Defer the cleanup // Defer the cleanup
...@@ -152,25 +152,25 @@ func OnlyAllowNodeZones(f *framework.Framework, zoneCount int, image string) { ...@@ -152,25 +152,25 @@ func OnlyAllowNodeZones(f *framework.Framework, zoneCount int, image string) {
// Wait for all claims bound // Wait for all claims bound
for _, claim := range pvcList { for _, claim := range pvcList {
err = framework.WaitForPersistentVolumeClaimPhase(v1.ClaimBound, c, claim.Namespace, claim.Name, framework.Poll, framework.ClaimProvisionTimeout) err = framework.WaitForPersistentVolumeClaimPhase(v1.ClaimBound, c, claim.Namespace, claim.Name, framework.Poll, framework.ClaimProvisionTimeout)
Expect(err).NotTo(HaveOccurred()) gomega.Expect(err).NotTo(gomega.HaveOccurred())
} }
pvZones := sets.NewString() pvZones := sets.NewString()
By("Checking that PDs have been provisioned in only the expected zones") ginkgo.By("Checking that PDs have been provisioned in only the expected zones")
for _, claim := range pvcList { for _, claim := range pvcList {
// Get a new copy of the claim to have all fields populated // Get a new copy of the claim to have all fields populated
claim, err = c.CoreV1().PersistentVolumeClaims(claim.Namespace).Get(claim.Name, metav1.GetOptions{}) claim, err = c.CoreV1().PersistentVolumeClaims(claim.Namespace).Get(claim.Name, metav1.GetOptions{})
Expect(err).NotTo(HaveOccurred()) gomega.Expect(err).NotTo(gomega.HaveOccurred())
// Get the related PV // Get the related PV
pv, err := c.CoreV1().PersistentVolumes().Get(claim.Spec.VolumeName, metav1.GetOptions{}) pv, err := c.CoreV1().PersistentVolumes().Get(claim.Spec.VolumeName, metav1.GetOptions{})
Expect(err).NotTo(HaveOccurred()) gomega.Expect(err).NotTo(gomega.HaveOccurred())
pvZone, ok := pv.ObjectMeta.Labels[v1.LabelZoneFailureDomain] pvZone, ok := pv.ObjectMeta.Labels[v1.LabelZoneFailureDomain]
Expect(ok).To(BeTrue(), "PV has no LabelZone to be found") gomega.Expect(ok).To(gomega.BeTrue(), "PV has no LabelZone to be found")
pvZones.Insert(pvZone) pvZones.Insert(pvZone)
} }
Expect(pvZones.Equal(expectedZones)).To(BeTrue(), fmt.Sprintf("PDs provisioned in unwanted zones. We want zones: %v, got: %v", expectedZones, pvZones)) gomega.Expect(pvZones.Equal(expectedZones)).To(gomega.BeTrue(), fmt.Sprintf("PDs provisioned in unwanted zones. We want zones: %v, got: %v", expectedZones, pvZones))
} }
type staticPVTestConfig struct { type staticPVTestConfig struct {
...@@ -180,23 +180,24 @@ type staticPVTestConfig struct { ...@@ -180,23 +180,24 @@ type staticPVTestConfig struct {
pod *v1.Pod pod *v1.Pod
} }
// Check that the pods using statically created PVs get scheduled to the same zone that the PV is in. // PodsUseStaticPVsOrFail Check that the pods using statically
// created PVs get scheduled to the same zone that the PV is in.
func PodsUseStaticPVsOrFail(f *framework.Framework, podCount int, image string) { func PodsUseStaticPVsOrFail(f *framework.Framework, podCount int, image string) {
var err error var err error
c := f.ClientSet c := f.ClientSet
ns := f.Namespace.Name ns := f.Namespace.Name
zones, err := framework.GetClusterZones(c) zones, err := framework.GetClusterZones(c)
Expect(err).NotTo(HaveOccurred()) gomega.Expect(err).NotTo(gomega.HaveOccurred())
zonelist := zones.List() zonelist := zones.List()
By("Creating static PVs across zones") ginkgo.By("Creating static PVs across zones")
configs := make([]*staticPVTestConfig, podCount) configs := make([]*staticPVTestConfig, podCount)
for i := range configs { for i := range configs {
configs[i] = &staticPVTestConfig{} configs[i] = &staticPVTestConfig{}
} }
defer func() { defer func() {
By("Cleaning up pods and PVs") ginkgo.By("Cleaning up pods and PVs")
for _, config := range configs { for _, config := range configs {
framework.DeletePodOrFail(c, ns, config.pod.Name) framework.DeletePodOrFail(c, ns, config.pod.Name)
} }
...@@ -204,14 +205,14 @@ func PodsUseStaticPVsOrFail(f *framework.Framework, podCount int, image string) ...@@ -204,14 +205,14 @@ func PodsUseStaticPVsOrFail(f *framework.Framework, podCount int, image string)
framework.WaitForPodNoLongerRunningInNamespace(c, config.pod.Name, ns) framework.WaitForPodNoLongerRunningInNamespace(c, config.pod.Name, ns)
framework.PVPVCCleanup(c, ns, config.pv, config.pvc) framework.PVPVCCleanup(c, ns, config.pv, config.pvc)
err = framework.DeletePVSource(config.pvSource) err = framework.DeletePVSource(config.pvSource)
Expect(err).NotTo(HaveOccurred()) gomega.Expect(err).NotTo(gomega.HaveOccurred())
} }
}() }()
for i, config := range configs { for i, config := range configs {
zone := zonelist[i%len(zones)] zone := zonelist[i%len(zones)]
config.pvSource, err = framework.CreatePVSource(zone) config.pvSource, err = framework.CreatePVSource(zone)
Expect(err).NotTo(HaveOccurred()) gomega.Expect(err).NotTo(gomega.HaveOccurred())
pvConfig := framework.PersistentVolumeConfig{ pvConfig := framework.PersistentVolumeConfig{
NamePrefix: "multizone-pv", NamePrefix: "multizone-pv",
...@@ -222,25 +223,25 @@ func PodsUseStaticPVsOrFail(f *framework.Framework, podCount int, image string) ...@@ -222,25 +223,25 @@ func PodsUseStaticPVsOrFail(f *framework.Framework, podCount int, image string)
pvcConfig := framework.PersistentVolumeClaimConfig{StorageClassName: &className} pvcConfig := framework.PersistentVolumeClaimConfig{StorageClassName: &className}
config.pv, config.pvc, err = framework.CreatePVPVC(c, pvConfig, pvcConfig, ns, true) config.pv, config.pvc, err = framework.CreatePVPVC(c, pvConfig, pvcConfig, ns, true)
Expect(err).NotTo(HaveOccurred()) gomega.Expect(err).NotTo(gomega.HaveOccurred())
} }
By("Waiting for all PVCs to be bound") ginkgo.By("Waiting for all PVCs to be bound")
for _, config := range configs { for _, config := range configs {
framework.WaitOnPVandPVC(c, ns, config.pv, config.pvc) framework.WaitOnPVandPVC(c, ns, config.pv, config.pvc)
} }
By("Creating pods for each static PV") ginkgo.By("Creating pods for each static PV")
for _, config := range configs { for _, config := range configs {
podConfig := framework.MakePod(ns, nil, []*v1.PersistentVolumeClaim{config.pvc}, false, "") podConfig := framework.MakePod(ns, nil, []*v1.PersistentVolumeClaim{config.pvc}, false, "")
config.pod, err = c.CoreV1().Pods(ns).Create(podConfig) config.pod, err = c.CoreV1().Pods(ns).Create(podConfig)
Expect(err).NotTo(HaveOccurred()) gomega.Expect(err).NotTo(gomega.HaveOccurred())
} }
By("Waiting for all pods to be running") ginkgo.By("Waiting for all pods to be running")
for _, config := range configs { for _, config := range configs {
err = framework.WaitForPodRunningInNamespace(c, config.pod) err = framework.WaitForPodRunningInNamespace(c, config.pod)
Expect(err).NotTo(HaveOccurred()) gomega.Expect(err).NotTo(gomega.HaveOccurred())
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment