123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279 |
- /*
- Copyright 2016 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 e2e
- import (
- "fmt"
- "time"
- "k8s.io/kubernetes/pkg/api"
- "k8s.io/kubernetes/pkg/api/unversioned"
- "k8s.io/kubernetes/pkg/api/v1"
- clientset "k8s.io/kubernetes/pkg/client/clientset_generated/release_1_3"
- "k8s.io/kubernetes/pkg/metrics"
- "k8s.io/kubernetes/pkg/util/wait"
- "k8s.io/kubernetes/test/e2e/framework"
- . "github.com/onsi/ginkgo"
- )
- func getOrphanOptions() *api.DeleteOptions {
- var trueVar = true
- return &api.DeleteOptions{OrphanDependents: &trueVar}
- }
- func getNonOrphanOptions() *api.DeleteOptions {
- var falseVar = false
- return &api.DeleteOptions{OrphanDependents: &falseVar}
- }
- func newOwnerRC(f *framework.Framework, name string) *v1.ReplicationController {
- var replicas int32
- replicas = 2
- return &v1.ReplicationController{
- TypeMeta: unversioned.TypeMeta{
- Kind: "ReplicationController",
- APIVersion: "v1",
- },
- ObjectMeta: v1.ObjectMeta{
- Namespace: f.Namespace.Name,
- Name: name,
- },
- Spec: v1.ReplicationControllerSpec{
- Replicas: &replicas,
- Selector: map[string]string{"app": "gc-test"},
- Template: &v1.PodTemplateSpec{
- ObjectMeta: v1.ObjectMeta{
- Labels: map[string]string{"app": "gc-test"},
- },
- Spec: v1.PodSpec{
- Containers: []v1.Container{
- {
- Name: "nginx",
- Image: "gcr.io/google_containers/nginx:1.7.9",
- },
- },
- },
- },
- },
- }
- }
- // verifyRemainingObjects verifies if the number of the remaining replication
- // controllers and pods are rcNum and podNum. It returns error if the
- // communication with the API server fails.
- func verifyRemainingObjects(f *framework.Framework, clientSet clientset.Interface, rcNum, podNum int) (bool, error) {
- rcClient := clientSet.Core().ReplicationControllers(f.Namespace.Name)
- pods, err := clientSet.Core().Pods(f.Namespace.Name).List(api.ListOptions{})
- if err != nil {
- return false, fmt.Errorf("Failed to list pods: %v", err)
- }
- var ret = true
- if len(pods.Items) != podNum {
- ret = false
- By(fmt.Sprintf("expected %d pods, got %d pods", podNum, len(pods.Items)))
- }
- rcs, err := rcClient.List(api.ListOptions{})
- if err != nil {
- return false, fmt.Errorf("Failed to list replication controllers: %v", err)
- }
- if len(rcs.Items) != rcNum {
- ret = false
- By(fmt.Sprintf("expected %d RCs, got %d RCs", rcNum, len(rcs.Items)))
- }
- return ret, nil
- }
- func gatherMetrics(f *framework.Framework) {
- By("Gathering metrics")
- var summary framework.TestDataSummary
- grabber, err := metrics.NewMetricsGrabber(f.Client, false, false, true, false)
- if err != nil {
- framework.Logf("Failed to create MetricsGrabber. Skipping metrics gathering.")
- } else {
- received, err := grabber.Grab()
- if err != nil {
- framework.Logf("MetricsGrabber failed grab metrics. Skipping metrics gathering.")
- } else {
- summary = (*framework.MetricsForE2E)(&received)
- framework.Logf(summary.PrintHumanReadable())
- }
- }
- }
- var _ = framework.KubeDescribe("Garbage collector", func() {
- f := framework.NewDefaultFramework("gc")
- It("[Feature:GarbageCollector] should delete pods created by rc when not orphaning", func() {
- clientSet := f.Clientset_1_3
- rcClient := clientSet.Core().ReplicationControllers(f.Namespace.Name)
- podClient := clientSet.Core().Pods(f.Namespace.Name)
- rcName := "simpletest.rc"
- rc := newOwnerRC(f, rcName)
- By("create the rc")
- rc, err := rcClient.Create(rc)
- if err != nil {
- framework.Failf("Failed to create replication controller: %v", err)
- }
- // wait for rc to create some pods
- if err := wait.Poll(5*time.Second, 30*time.Second, func() (bool, error) {
- pods, err := podClient.List(api.ListOptions{})
- if err != nil {
- return false, fmt.Errorf("Failed to list pods: %v", err)
- }
- // We intentionally don't wait the number of pods to reach
- // rc.Spec.Replicas. We want to see if the garbage collector and the
- // rc manager work properly if the rc is deleted before it reaches
- // stasis.
- if len(pods.Items) > 0 {
- return true, nil
- } else {
- return false, nil
- }
- }); err != nil {
- framework.Failf("failed to wait for the rc to create some pods: %v", err)
- }
- By("delete the rc")
- deleteOptions := getNonOrphanOptions()
- deleteOptions.Preconditions = api.NewUIDPreconditions(string(rc.UID))
- if err := rcClient.Delete(rc.ObjectMeta.Name, deleteOptions); err != nil {
- framework.Failf("failed to delete the rc: %v", err)
- }
- By("wait for all pods to be garbage collected")
- // wait for the RCs and Pods to reach the expected numbers.
- if err := wait.Poll(5*time.Second, 60*time.Second, func() (bool, error) {
- return verifyRemainingObjects(f, clientSet, 0, 0)
- }); err != nil {
- framework.Failf("failed to wait for all pods to be deleted: %v", err)
- remainingPods, err := podClient.List(api.ListOptions{})
- if err != nil {
- framework.Failf("failed to list pods post mortem: %v", err)
- } else {
- framework.Failf("remaining pods are: %#v", remainingPods)
- }
- }
- gatherMetrics(f)
- })
- It("[Feature:GarbageCollector] should orphan pods created by rc if delete options say so", func() {
- clientSet := f.Clientset_1_3
- rcClient := clientSet.Core().ReplicationControllers(f.Namespace.Name)
- podClient := clientSet.Core().Pods(f.Namespace.Name)
- rcName := "simpletest.rc"
- rc := newOwnerRC(f, rcName)
- replicas := int32(100)
- rc.Spec.Replicas = &replicas
- By("create the rc")
- rc, err := rcClient.Create(rc)
- if err != nil {
- framework.Failf("Failed to create replication controller: %v", err)
- }
- // wait for rc to create pods
- if err := wait.Poll(5*time.Second, 30*time.Second, func() (bool, error) {
- rc, err := rcClient.Get(rc.Name)
- if err != nil {
- return false, fmt.Errorf("Failed to get rc: %v", err)
- }
- if rc.Status.Replicas == *rc.Spec.Replicas {
- return true, nil
- } else {
- return false, nil
- }
- }); err != nil {
- framework.Failf("failed to wait for the rc.Status.Replicas to reach rc.Spec.Replicas: %v", err)
- }
- By("delete the rc")
- deleteOptions := getOrphanOptions()
- deleteOptions.Preconditions = api.NewUIDPreconditions(string(rc.UID))
- if err := rcClient.Delete(rc.ObjectMeta.Name, deleteOptions); err != nil {
- framework.Failf("failed to delete the rc: %v", err)
- }
- By("wait for the rc to be deleted")
- if err := wait.Poll(5*time.Second, 30*time.Second, func() (bool, error) {
- rcs, err := rcClient.List(api.ListOptions{})
- if err != nil {
- return false, fmt.Errorf("Failed to list rcs: %v", err)
- }
- if len(rcs.Items) != 0 {
- return false, nil
- }
- return true, nil
- }); err != nil && err != wait.ErrWaitTimeout {
- framework.Failf("%v", err)
- }
- By("wait for 30 seconds to see if the garbage collector mistakenly deletes the pods")
- if err := wait.Poll(5*time.Second, 30*time.Second, func() (bool, error) {
- pods, err := podClient.List(api.ListOptions{})
- if err != nil {
- return false, fmt.Errorf("Failed to list pods: %v", err)
- }
- if e, a := int(*(rc.Spec.Replicas)), len(pods.Items); e != a {
- return false, fmt.Errorf("expect %d pods, got %d pods", e, a)
- }
- return false, nil
- }); err != nil && err != wait.ErrWaitTimeout {
- framework.Failf("%v", err)
- }
- gatherMetrics(f)
- })
- It("[Feature:GarbageCollector] should orphan pods created by rc if deleteOptions.OrphanDependents is nil", func() {
- clientSet := f.Clientset_1_3
- rcClient := clientSet.Core().ReplicationControllers(f.Namespace.Name)
- podClient := clientSet.Core().Pods(f.Namespace.Name)
- rcName := "simpletest.rc"
- rc := newOwnerRC(f, rcName)
- By("create the rc")
- rc, err := rcClient.Create(rc)
- if err != nil {
- framework.Failf("Failed to create replication controller: %v", err)
- }
- // wait for rc to create some pods
- if err := wait.Poll(5*time.Second, 30*time.Second, func() (bool, error) {
- rc, err := rcClient.Get(rc.Name)
- if err != nil {
- return false, fmt.Errorf("Failed to get rc: %v", err)
- }
- if rc.Status.Replicas == *rc.Spec.Replicas {
- return true, nil
- } else {
- return false, nil
- }
- }); err != nil {
- framework.Failf("failed to wait for the rc.Status.Replicas to reach rc.Spec.Replicas: %v", err)
- }
- By("delete the rc")
- deleteOptions := &api.DeleteOptions{}
- deleteOptions.Preconditions = api.NewUIDPreconditions(string(rc.UID))
- if err := rcClient.Delete(rc.ObjectMeta.Name, deleteOptions); err != nil {
- framework.Failf("failed to delete the rc: %v", err)
- }
- By("wait for 30 seconds to see if the garbage collector mistakenly deletes the pods")
- if err := wait.Poll(5*time.Second, 30*time.Second, func() (bool, error) {
- pods, err := podClient.List(api.ListOptions{})
- if err != nil {
- return false, fmt.Errorf("Failed to list pods: %v", err)
- }
- if e, a := int(*(rc.Spec.Replicas)), len(pods.Items); e != a {
- return false, fmt.Errorf("expect %d pods, got %d pods", e, a)
- }
- return false, nil
- }); err != nil && err != wait.ErrWaitTimeout {
- framework.Failf("%v", err)
- }
- gatherMetrics(f)
- })
- })
|