123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207 |
- /*
- 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 statefulset
- import (
- "testing"
- metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
- genericapirequest "k8s.io/apiserver/pkg/endpoints/request"
- "k8s.io/apiserver/pkg/registry/rest"
- "k8s.io/kubernetes/pkg/apis/apps"
- api "k8s.io/kubernetes/pkg/apis/core"
- )
- func TestStatefulSetStrategy(t *testing.T) {
- ctx := genericapirequest.NewDefaultContext()
- if !Strategy.NamespaceScoped() {
- t.Errorf("StatefulSet must be namespace scoped")
- }
- if Strategy.AllowCreateOnUpdate() {
- t.Errorf("StatefulSet should not allow create on update")
- }
- validSelector := map[string]string{"a": "b"}
- validPodTemplate := api.PodTemplate{
- Template: api.PodTemplateSpec{
- ObjectMeta: metav1.ObjectMeta{
- Labels: validSelector,
- },
- Spec: api.PodSpec{
- RestartPolicy: api.RestartPolicyAlways,
- DNSPolicy: api.DNSClusterFirst,
- Containers: []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent"}},
- },
- },
- }
- ps := &apps.StatefulSet{
- ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault},
- Spec: apps.StatefulSetSpec{
- PodManagementPolicy: apps.OrderedReadyPodManagement,
- Selector: &metav1.LabelSelector{MatchLabels: validSelector},
- Template: validPodTemplate.Template,
- UpdateStrategy: apps.StatefulSetUpdateStrategy{Type: apps.RollingUpdateStatefulSetStrategyType},
- },
- Status: apps.StatefulSetStatus{Replicas: 3},
- }
- Strategy.PrepareForCreate(ctx, ps)
- if ps.Status.Replicas != 0 {
- t.Error("StatefulSet should not allow setting status.replicas on create")
- }
- errs := Strategy.Validate(ctx, ps)
- if len(errs) != 0 {
- t.Errorf("unexpected error validating %v", errs)
- }
- // Just Spec.Replicas is allowed to change
- validPs := &apps.StatefulSet{
- ObjectMeta: metav1.ObjectMeta{Name: ps.Name, Namespace: ps.Namespace, ResourceVersion: "1", Generation: 1},
- Spec: apps.StatefulSetSpec{
- PodManagementPolicy: apps.OrderedReadyPodManagement,
- Selector: ps.Spec.Selector,
- Template: validPodTemplate.Template,
- UpdateStrategy: apps.StatefulSetUpdateStrategy{Type: apps.RollingUpdateStatefulSetStrategyType},
- },
- Status: apps.StatefulSetStatus{Replicas: 4},
- }
- Strategy.PrepareForUpdate(ctx, validPs, ps)
- errs = Strategy.ValidateUpdate(ctx, validPs, ps)
- if len(errs) != 0 {
- t.Errorf("updating spec.Replicas is allowed on a statefulset: %v", errs)
- }
- validPs.Spec.Selector = &metav1.LabelSelector{MatchLabels: map[string]string{"a": "bar"}}
- Strategy.PrepareForUpdate(ctx, validPs, ps)
- errs = Strategy.ValidateUpdate(ctx, validPs, ps)
- if len(errs) == 0 {
- t.Errorf("expected a validation error since updates are disallowed on statefulsets.")
- }
- }
- func TestStatefulsetDefaultGarbageCollectionPolicy(t *testing.T) {
- // Make sure we correctly implement the interface.
- // Otherwise a typo could silently change the default.
- var gcds rest.GarbageCollectionDeleteStrategy = Strategy
- tests := []struct {
- requestInfo genericapirequest.RequestInfo
- expectedGCPolicy rest.GarbageCollectionPolicy
- isNilRequestInfo bool
- }{
- {
- genericapirequest.RequestInfo{
- APIGroup: "apps",
- APIVersion: "v1beta1",
- Resource: "statefulsets",
- },
- rest.OrphanDependents,
- false,
- },
- {
- genericapirequest.RequestInfo{
- APIGroup: "apps",
- APIVersion: "v1beta2",
- Resource: "statefulsets",
- },
- rest.OrphanDependents,
- false,
- },
- {
- genericapirequest.RequestInfo{
- APIGroup: "apps",
- APIVersion: "v1",
- Resource: "statefulsets",
- },
- rest.DeleteDependents,
- false,
- },
- {
- expectedGCPolicy: rest.DeleteDependents,
- isNilRequestInfo: true,
- },
- }
- for _, test := range tests {
- context := genericapirequest.NewContext()
- if !test.isNilRequestInfo {
- context = genericapirequest.WithRequestInfo(context, &test.requestInfo)
- }
- if got, want := gcds.DefaultGarbageCollectionPolicy(context), test.expectedGCPolicy; got != want {
- t.Errorf("%s/%s: DefaultGarbageCollectionPolicy() = %#v, want %#v", test.requestInfo.APIGroup,
- test.requestInfo.APIVersion, got, want)
- }
- }
- }
- func TestStatefulSetStatusStrategy(t *testing.T) {
- ctx := genericapirequest.NewDefaultContext()
- if !StatusStrategy.NamespaceScoped() {
- t.Errorf("StatefulSet must be namespace scoped")
- }
- if StatusStrategy.AllowCreateOnUpdate() {
- t.Errorf("StatefulSet should not allow create on update")
- }
- validSelector := map[string]string{"a": "b"}
- validPodTemplate := api.PodTemplate{
- Template: api.PodTemplateSpec{
- ObjectMeta: metav1.ObjectMeta{
- Labels: validSelector,
- },
- Spec: api.PodSpec{
- RestartPolicy: api.RestartPolicyAlways,
- DNSPolicy: api.DNSClusterFirst,
- Containers: []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent"}},
- },
- },
- }
- oldPS := &apps.StatefulSet{
- ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault, ResourceVersion: "10"},
- Spec: apps.StatefulSetSpec{
- Replicas: 3,
- Selector: &metav1.LabelSelector{MatchLabels: validSelector},
- Template: validPodTemplate.Template,
- UpdateStrategy: apps.StatefulSetUpdateStrategy{Type: apps.RollingUpdateStatefulSetStrategyType},
- },
- Status: apps.StatefulSetStatus{
- Replicas: 1,
- },
- }
- newPS := &apps.StatefulSet{
- ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault, ResourceVersion: "9"},
- Spec: apps.StatefulSetSpec{
- Replicas: 1,
- Selector: &metav1.LabelSelector{MatchLabels: validSelector},
- Template: validPodTemplate.Template,
- UpdateStrategy: apps.StatefulSetUpdateStrategy{Type: apps.RollingUpdateStatefulSetStrategyType},
- },
- Status: apps.StatefulSetStatus{
- Replicas: 2,
- },
- }
- StatusStrategy.PrepareForUpdate(ctx, newPS, oldPS)
- if newPS.Status.Replicas != 2 {
- t.Errorf("StatefulSet status updates should allow change of pods: %v", newPS.Status.Replicas)
- }
- if newPS.Spec.Replicas != 3 {
- t.Errorf("StatefulSet status updates should not clobber spec: %v", newPS.Spec)
- }
- errs := StatusStrategy.ValidateUpdate(ctx, newPS, oldPS)
- if len(errs) != 0 {
- t.Errorf("unexpected error %v", errs)
- }
- }
|