mirror of
				https://github.com/optim-enterprises-bv/kubernetes.git
				synced 2025-11-03 19:58:17 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			1687 lines
		
	
	
		
			45 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			1687 lines
		
	
	
		
			45 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
/*
 | 
						|
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 history
 | 
						|
 | 
						|
import (
 | 
						|
	"bytes"
 | 
						|
	"encoding/json"
 | 
						|
	"fmt"
 | 
						|
	"reflect"
 | 
						|
	"testing"
 | 
						|
 | 
						|
	apps "k8s.io/api/apps/v1beta1"
 | 
						|
	"k8s.io/api/core/v1"
 | 
						|
	"k8s.io/client-go/informers"
 | 
						|
	"k8s.io/client-go/kubernetes/fake"
 | 
						|
	"k8s.io/kubernetes/pkg/api/testapi"
 | 
						|
	"k8s.io/kubernetes/pkg/controller"
 | 
						|
 | 
						|
	"k8s.io/apimachinery/pkg/api/errors"
 | 
						|
	"k8s.io/apimachinery/pkg/api/resource"
 | 
						|
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 | 
						|
	"k8s.io/apimachinery/pkg/labels"
 | 
						|
	"k8s.io/apimachinery/pkg/runtime"
 | 
						|
	"k8s.io/apimachinery/pkg/types"
 | 
						|
	"k8s.io/apimachinery/pkg/util/strategicpatch"
 | 
						|
 | 
						|
	core "k8s.io/client-go/testing"
 | 
						|
)
 | 
						|
 | 
						|
func TestRealHistory_ListControllerRevisions(t *testing.T) {
 | 
						|
	type testcase struct {
 | 
						|
		name      string
 | 
						|
		parent    metav1.Object
 | 
						|
		selector  labels.Selector
 | 
						|
		revisions []*apps.ControllerRevision
 | 
						|
		want      map[string]bool
 | 
						|
	}
 | 
						|
	testFn := func(test *testcase, t *testing.T) {
 | 
						|
		client := fake.NewSimpleClientset()
 | 
						|
		informerFactory := informers.NewSharedInformerFactory(client, controller.NoResyncPeriodFunc())
 | 
						|
 | 
						|
		stop := make(chan struct{})
 | 
						|
		defer close(stop)
 | 
						|
		informerFactory.Start(stop)
 | 
						|
		informer := informerFactory.Apps().V1beta1().ControllerRevisions()
 | 
						|
		informerFactory.WaitForCacheSync(stop)
 | 
						|
		for i := range test.revisions {
 | 
						|
			informer.Informer().GetIndexer().Add(test.revisions[i])
 | 
						|
		}
 | 
						|
 | 
						|
		history := NewHistory(client, informer.Lister())
 | 
						|
		revisions, err := history.ListControllerRevisions(test.parent, test.selector)
 | 
						|
		if err != nil {
 | 
						|
			t.Errorf("%s: %s", test.name, err)
 | 
						|
		}
 | 
						|
		got := make(map[string]bool)
 | 
						|
		for i := range revisions {
 | 
						|
			got[revisions[i].Name] = true
 | 
						|
		}
 | 
						|
		if !reflect.DeepEqual(test.want, got) {
 | 
						|
			t.Errorf("%s: want %v got %v", test.name, test.want, got)
 | 
						|
		}
 | 
						|
	}
 | 
						|
	ss1 := newStatefulSet(3, "ss1", types.UID("ss1"), map[string]string{"foo": "bar"})
 | 
						|
	ss2 := newStatefulSet(3, "ss2", types.UID("ss2"), map[string]string{"goo": "car"})
 | 
						|
	sel1, err := metav1.LabelSelectorAsSelector(ss1.Spec.Selector)
 | 
						|
	if err != nil {
 | 
						|
		t.Fatal(err)
 | 
						|
	}
 | 
						|
	sel2, err := metav1.LabelSelectorAsSelector(ss2.Spec.Selector)
 | 
						|
	if err != nil {
 | 
						|
		t.Fatal(err)
 | 
						|
	}
 | 
						|
	ss1Rev1, err := NewControllerRevision(ss1, parentKind, sel1, rawTemplate(&ss1.Spec.Template), 1)
 | 
						|
	if err != nil {
 | 
						|
		t.Fatal(err)
 | 
						|
	}
 | 
						|
	ss1Rev1.Namespace = ss1.Namespace
 | 
						|
	ss1Rev2, err := NewControllerRevision(ss1, parentKind, sel1, rawTemplate(&ss1.Spec.Template), 2)
 | 
						|
	if err != nil {
 | 
						|
		t.Fatal(err)
 | 
						|
	}
 | 
						|
	ss1Rev2.Namespace = ss1.Namespace
 | 
						|
	ss2Rev1, err := NewControllerRevision(ss2, parentKind, sel2, rawTemplate(&ss2.Spec.Template), 1)
 | 
						|
	if err != nil {
 | 
						|
		t.Fatal(err)
 | 
						|
	}
 | 
						|
	ss2Rev1.Namespace = ss2.Namespace
 | 
						|
	ss1Orphan, err := NewControllerRevision(ss1, parentKind, sel1, rawTemplate(&ss1.Spec.Template), 3)
 | 
						|
	if err != nil {
 | 
						|
		t.Fatal(err)
 | 
						|
	}
 | 
						|
	ss1Orphan.Namespace = ss1.Namespace
 | 
						|
	ss1Orphan.OwnerReferences = nil
 | 
						|
 | 
						|
	tests := []testcase{
 | 
						|
		{
 | 
						|
			name:      "selects none",
 | 
						|
			parent:    &ss1.ObjectMeta,
 | 
						|
			selector:  sel1,
 | 
						|
			revisions: nil,
 | 
						|
			want:      map[string]bool{},
 | 
						|
		},
 | 
						|
		{
 | 
						|
			name:      "selects all",
 | 
						|
			parent:    &ss1.ObjectMeta,
 | 
						|
			selector:  sel1,
 | 
						|
			revisions: []*apps.ControllerRevision{ss1Rev1, ss1Rev2},
 | 
						|
			want:      map[string]bool{ss1Rev1.Name: true, ss1Rev2.Name: true},
 | 
						|
		},
 | 
						|
		{
 | 
						|
			name:      "doesn't select another Objects history",
 | 
						|
			parent:    &ss1.ObjectMeta,
 | 
						|
			selector:  sel1,
 | 
						|
			revisions: []*apps.ControllerRevision{ss1Rev1, ss1Rev2, ss2Rev1},
 | 
						|
			want:      map[string]bool{ss1Rev1.Name: true, ss1Rev2.Name: true},
 | 
						|
		},
 | 
						|
		{
 | 
						|
			name:      "selects orphans",
 | 
						|
			parent:    &ss1.ObjectMeta,
 | 
						|
			selector:  sel1,
 | 
						|
			revisions: []*apps.ControllerRevision{ss1Rev1, ss1Rev2, ss1Orphan},
 | 
						|
			want:      map[string]bool{ss1Rev1.Name: true, ss1Rev2.Name: true, ss1Orphan.Name: true},
 | 
						|
		},
 | 
						|
	}
 | 
						|
	for i := range tests {
 | 
						|
		testFn(&tests[i], t)
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func TestFakeHistory_ListControllerRevisions(t *testing.T) {
 | 
						|
	type testcase struct {
 | 
						|
		name      string
 | 
						|
		parent    metav1.Object
 | 
						|
		selector  labels.Selector
 | 
						|
		revisions []*apps.ControllerRevision
 | 
						|
		want      map[string]bool
 | 
						|
	}
 | 
						|
	testFn := func(test *testcase, t *testing.T) {
 | 
						|
		client := fake.NewSimpleClientset()
 | 
						|
		informerFactory := informers.NewSharedInformerFactory(client, controller.NoResyncPeriodFunc())
 | 
						|
 | 
						|
		stop := make(chan struct{})
 | 
						|
		defer close(stop)
 | 
						|
		informerFactory.Start(stop)
 | 
						|
		informer := informerFactory.Apps().V1beta1().ControllerRevisions()
 | 
						|
		informerFactory.WaitForCacheSync(stop)
 | 
						|
		for i := range test.revisions {
 | 
						|
			informer.Informer().GetIndexer().Add(test.revisions[i])
 | 
						|
		}
 | 
						|
 | 
						|
		history := NewFakeHistory(informer)
 | 
						|
		revisions, err := history.ListControllerRevisions(test.parent, test.selector)
 | 
						|
		if err != nil {
 | 
						|
			t.Errorf("%s: %s", test.name, err)
 | 
						|
		}
 | 
						|
		got := make(map[string]bool)
 | 
						|
		for i := range revisions {
 | 
						|
			got[revisions[i].Name] = true
 | 
						|
		}
 | 
						|
		if !reflect.DeepEqual(test.want, got) {
 | 
						|
			t.Errorf("%s: want %v got %v", test.name, test.want, got)
 | 
						|
		}
 | 
						|
	}
 | 
						|
	ss1 := newStatefulSet(3, "ss1", types.UID("ss1"), map[string]string{"foo": "bar"})
 | 
						|
	ss2 := newStatefulSet(3, "ss2", types.UID("ss2"), map[string]string{"goo": "car"})
 | 
						|
	sel1, err := metav1.LabelSelectorAsSelector(ss1.Spec.Selector)
 | 
						|
	if err != nil {
 | 
						|
		t.Fatal(err)
 | 
						|
	}
 | 
						|
	sel2, err := metav1.LabelSelectorAsSelector(ss2.Spec.Selector)
 | 
						|
	if err != nil {
 | 
						|
		t.Fatal(err)
 | 
						|
	}
 | 
						|
	ss1Rev1, err := NewControllerRevision(ss1, parentKind, sel1, rawTemplate(&ss1.Spec.Template), 1)
 | 
						|
	if err != nil {
 | 
						|
		t.Fatal(err)
 | 
						|
	}
 | 
						|
	ss1Rev1.Namespace = ss1.Namespace
 | 
						|
	ss1Rev2, err := NewControllerRevision(ss1, parentKind, sel1, rawTemplate(&ss1.Spec.Template), 2)
 | 
						|
	if err != nil {
 | 
						|
		t.Fatal(err)
 | 
						|
	}
 | 
						|
	ss1Rev2.Namespace = ss1.Namespace
 | 
						|
	ss2Rev1, err := NewControllerRevision(ss2, parentKind, sel2, rawTemplate(&ss2.Spec.Template), 1)
 | 
						|
	if err != nil {
 | 
						|
		t.Fatal(err)
 | 
						|
	}
 | 
						|
	ss2Rev1.Namespace = ss2.Namespace
 | 
						|
	ss1Orphan, err := NewControllerRevision(ss1, parentKind, sel1, rawTemplate(&ss1.Spec.Template), 3)
 | 
						|
	if err != nil {
 | 
						|
		t.Fatal(err)
 | 
						|
	}
 | 
						|
	ss1Orphan.Namespace = ss1.Namespace
 | 
						|
	ss1Orphan.OwnerReferences = nil
 | 
						|
 | 
						|
	tests := []testcase{
 | 
						|
		{
 | 
						|
			name:      "selects none",
 | 
						|
			parent:    &ss1.ObjectMeta,
 | 
						|
			selector:  sel1,
 | 
						|
			revisions: nil,
 | 
						|
			want:      map[string]bool{},
 | 
						|
		},
 | 
						|
		{
 | 
						|
			name:      "selects all",
 | 
						|
			parent:    &ss1.ObjectMeta,
 | 
						|
			selector:  sel1,
 | 
						|
			revisions: []*apps.ControllerRevision{ss1Rev1, ss1Rev2},
 | 
						|
			want:      map[string]bool{ss1Rev1.Name: true, ss1Rev2.Name: true},
 | 
						|
		},
 | 
						|
		{
 | 
						|
			name:      "doesn't select another Objects history",
 | 
						|
			parent:    &ss1.ObjectMeta,
 | 
						|
			selector:  sel1,
 | 
						|
			revisions: []*apps.ControllerRevision{ss1Rev1, ss1Rev2, ss2Rev1},
 | 
						|
			want:      map[string]bool{ss1Rev1.Name: true, ss1Rev2.Name: true},
 | 
						|
		},
 | 
						|
		{
 | 
						|
			name:      "selects orphans",
 | 
						|
			parent:    &ss1.ObjectMeta,
 | 
						|
			selector:  sel1,
 | 
						|
			revisions: []*apps.ControllerRevision{ss1Rev1, ss1Rev2, ss1Orphan},
 | 
						|
			want:      map[string]bool{ss1Rev1.Name: true, ss1Rev2.Name: true, ss1Orphan.Name: true},
 | 
						|
		},
 | 
						|
	}
 | 
						|
	for i := range tests {
 | 
						|
		testFn(&tests[i], t)
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func TestRealHistory_CreateControllerRevision(t *testing.T) {
 | 
						|
	type testcase struct {
 | 
						|
		name     string
 | 
						|
		parent   metav1.Object
 | 
						|
		revision *apps.ControllerRevision
 | 
						|
		existing []struct {
 | 
						|
			parent   metav1.Object
 | 
						|
			revision *apps.ControllerRevision
 | 
						|
		}
 | 
						|
		rename bool
 | 
						|
	}
 | 
						|
	testFn := func(test *testcase, t *testing.T) {
 | 
						|
		client := fake.NewSimpleClientset()
 | 
						|
		informerFactory := informers.NewSharedInformerFactory(client, controller.NoResyncPeriodFunc())
 | 
						|
 | 
						|
		stop := make(chan struct{})
 | 
						|
		defer close(stop)
 | 
						|
		informerFactory.Start(stop)
 | 
						|
		informer := informerFactory.Apps().V1beta1().ControllerRevisions()
 | 
						|
		informerFactory.WaitForCacheSync(stop)
 | 
						|
		history := NewHistory(client, informer.Lister())
 | 
						|
		for i := range test.existing {
 | 
						|
			_, err := history.CreateControllerRevision(test.existing[i].parent, test.existing[i].revision)
 | 
						|
			if err != nil {
 | 
						|
				t.Fatal(err)
 | 
						|
			}
 | 
						|
		}
 | 
						|
		created, err := history.CreateControllerRevision(test.parent, test.revision)
 | 
						|
		if err != nil {
 | 
						|
			t.Errorf("%s: %s", test.name, err)
 | 
						|
		}
 | 
						|
		if test.rename && created.Name == test.revision.Name {
 | 
						|
			t.Errorf("%s: wanted rename got %s %s", test.name, created.Name, test.revision.Name)
 | 
						|
 | 
						|
		}
 | 
						|
		if !test.rename && created.Name != test.revision.Name {
 | 
						|
			t.Errorf("%s: wanted %s got %s", test.name, test.revision.Name, created.Name)
 | 
						|
		}
 | 
						|
	}
 | 
						|
	ss1 := newStatefulSet(3, "ss1", types.UID("ss1"), map[string]string{"foo": "bar"})
 | 
						|
	ss2 := newStatefulSet(3, "ss2", types.UID("ss2"), map[string]string{"goo": "car"})
 | 
						|
	sel1, err := metav1.LabelSelectorAsSelector(ss1.Spec.Selector)
 | 
						|
	if err != nil {
 | 
						|
		t.Fatal(err)
 | 
						|
	}
 | 
						|
	sel2, err := metav1.LabelSelectorAsSelector(ss2.Spec.Selector)
 | 
						|
	if err != nil {
 | 
						|
		t.Fatal(err)
 | 
						|
	}
 | 
						|
	ss1Rev1, err := NewControllerRevision(ss1, parentKind, sel1, rawTemplate(&ss1.Spec.Template), 1)
 | 
						|
	if err != nil {
 | 
						|
		t.Fatal(err)
 | 
						|
	}
 | 
						|
	ss1Rev1.Namespace = ss1.Namespace
 | 
						|
	ss1Rev2, err := NewControllerRevision(ss1, parentKind, sel1, rawTemplate(&ss1.Spec.Template), 2)
 | 
						|
	if err != nil {
 | 
						|
		t.Fatal(err)
 | 
						|
	}
 | 
						|
	ss1Rev2.Namespace = ss1.Namespace
 | 
						|
	ss2Rev1, err := NewControllerRevision(ss2, parentKind, sel2, rawTemplate(&ss2.Spec.Template), 1)
 | 
						|
	if err != nil {
 | 
						|
		t.Fatal(err)
 | 
						|
	}
 | 
						|
	ss2Rev1.Namespace = ss2.Namespace
 | 
						|
	tests := []testcase{
 | 
						|
		{
 | 
						|
			name:     "creates new",
 | 
						|
			parent:   &ss1.ObjectMeta,
 | 
						|
			revision: ss1Rev1,
 | 
						|
			existing: nil,
 | 
						|
 | 
						|
			rename: false,
 | 
						|
		},
 | 
						|
		{
 | 
						|
			name:     "create doesn't conflict when parents differ",
 | 
						|
			parent:   &ss2.ObjectMeta,
 | 
						|
			revision: ss2Rev1,
 | 
						|
			existing: []struct {
 | 
						|
				parent   metav1.Object
 | 
						|
				revision *apps.ControllerRevision
 | 
						|
			}{
 | 
						|
				{
 | 
						|
					parent:   ss1,
 | 
						|
					revision: ss1Rev1,
 | 
						|
				},
 | 
						|
			},
 | 
						|
 | 
						|
			rename: false,
 | 
						|
		},
 | 
						|
		{
 | 
						|
			name:     "create renames on conflict",
 | 
						|
			parent:   &ss1.ObjectMeta,
 | 
						|
			revision: ss1Rev1,
 | 
						|
			existing: []struct {
 | 
						|
				parent   metav1.Object
 | 
						|
				revision *apps.ControllerRevision
 | 
						|
			}{
 | 
						|
				{
 | 
						|
					parent:   ss1,
 | 
						|
					revision: ss1Rev1,
 | 
						|
				},
 | 
						|
			},
 | 
						|
			rename: true,
 | 
						|
		},
 | 
						|
	}
 | 
						|
	for i := range tests {
 | 
						|
		testFn(&tests[i], t)
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func TestFakeHistory_CreateControllerRevision(t *testing.T) {
 | 
						|
	type testcase struct {
 | 
						|
		name     string
 | 
						|
		parent   metav1.Object
 | 
						|
		revision *apps.ControllerRevision
 | 
						|
		existing []struct {
 | 
						|
			parent   metav1.Object
 | 
						|
			revision *apps.ControllerRevision
 | 
						|
		}
 | 
						|
		rename bool
 | 
						|
	}
 | 
						|
	testFn := func(test *testcase, t *testing.T) {
 | 
						|
		client := fake.NewSimpleClientset()
 | 
						|
		informerFactory := informers.NewSharedInformerFactory(client, controller.NoResyncPeriodFunc())
 | 
						|
 | 
						|
		stop := make(chan struct{})
 | 
						|
		defer close(stop)
 | 
						|
		informerFactory.Start(stop)
 | 
						|
		informer := informerFactory.Apps().V1beta1().ControllerRevisions()
 | 
						|
		informerFactory.WaitForCacheSync(stop)
 | 
						|
		history := NewFakeHistory(informer)
 | 
						|
		for i := range test.existing {
 | 
						|
			_, err := history.CreateControllerRevision(test.existing[i].parent, test.existing[i].revision)
 | 
						|
			if err != nil {
 | 
						|
				t.Fatal(err)
 | 
						|
			}
 | 
						|
		}
 | 
						|
		created, err := history.CreateControllerRevision(test.parent, test.revision)
 | 
						|
		if err != nil {
 | 
						|
			t.Errorf("%s: %s", test.name, err)
 | 
						|
		}
 | 
						|
		if test.rename && created.Name == test.revision.Name {
 | 
						|
			t.Errorf("%s: wanted rename got %s %s", test.name, created.Name, test.revision.Name)
 | 
						|
 | 
						|
		}
 | 
						|
		if !test.rename && created.Name != test.revision.Name {
 | 
						|
			t.Errorf("%s: wanted %s got %s", test.name, test.revision.Name, created.Name)
 | 
						|
		}
 | 
						|
	}
 | 
						|
	ss1 := newStatefulSet(3, "ss1", types.UID("ss1"), map[string]string{"foo": "bar"})
 | 
						|
	ss2 := newStatefulSet(3, "ss2", types.UID("ss2"), map[string]string{"goo": "car"})
 | 
						|
	sel1, err := metav1.LabelSelectorAsSelector(ss1.Spec.Selector)
 | 
						|
	if err != nil {
 | 
						|
		t.Fatal(err)
 | 
						|
	}
 | 
						|
	sel2, err := metav1.LabelSelectorAsSelector(ss2.Spec.Selector)
 | 
						|
	if err != nil {
 | 
						|
		t.Fatal(err)
 | 
						|
	}
 | 
						|
	ss1Rev1, err := NewControllerRevision(ss1, parentKind, sel1, rawTemplate(&ss1.Spec.Template), 1)
 | 
						|
	if err != nil {
 | 
						|
		t.Fatal(err)
 | 
						|
	}
 | 
						|
	ss1Rev1.Namespace = ss1.Namespace
 | 
						|
	ss1Rev2, err := NewControllerRevision(ss1, parentKind, sel1, rawTemplate(&ss1.Spec.Template), 2)
 | 
						|
	if err != nil {
 | 
						|
		t.Fatal(err)
 | 
						|
	}
 | 
						|
	ss1Rev2.Namespace = ss1.Namespace
 | 
						|
	ss2Rev1, err := NewControllerRevision(ss2, parentKind, sel2, rawTemplate(&ss2.Spec.Template), 1)
 | 
						|
	if err != nil {
 | 
						|
		t.Fatal(err)
 | 
						|
	}
 | 
						|
	ss2Rev1.Namespace = ss2.Namespace
 | 
						|
	tests := []testcase{
 | 
						|
		{
 | 
						|
			name:     "creates new",
 | 
						|
			parent:   &ss1.ObjectMeta,
 | 
						|
			revision: ss1Rev1,
 | 
						|
			existing: nil,
 | 
						|
 | 
						|
			rename: false,
 | 
						|
		},
 | 
						|
		{
 | 
						|
			name:     "create doesn't conflict when parents differ",
 | 
						|
			parent:   &ss2.ObjectMeta,
 | 
						|
			revision: ss2Rev1,
 | 
						|
			existing: []struct {
 | 
						|
				parent   metav1.Object
 | 
						|
				revision *apps.ControllerRevision
 | 
						|
			}{
 | 
						|
				{
 | 
						|
					parent:   ss1,
 | 
						|
					revision: ss1Rev1,
 | 
						|
				},
 | 
						|
			},
 | 
						|
 | 
						|
			rename: false,
 | 
						|
		},
 | 
						|
		{
 | 
						|
			name:     "create renames on conflict",
 | 
						|
			parent:   &ss1.ObjectMeta,
 | 
						|
			revision: ss1Rev1,
 | 
						|
			existing: []struct {
 | 
						|
				parent   metav1.Object
 | 
						|
				revision *apps.ControllerRevision
 | 
						|
			}{
 | 
						|
				{
 | 
						|
					parent:   ss1,
 | 
						|
					revision: ss1Rev1,
 | 
						|
				},
 | 
						|
			},
 | 
						|
			rename: true,
 | 
						|
		},
 | 
						|
	}
 | 
						|
	for i := range tests {
 | 
						|
		testFn(&tests[i], t)
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func TestRealHistory_UpdateControllerRevision(t *testing.T) {
 | 
						|
	conflictAttempts := 0
 | 
						|
	type testcase struct {
 | 
						|
		name        string
 | 
						|
		revision    *apps.ControllerRevision
 | 
						|
		newRevision int64
 | 
						|
		existing    []struct {
 | 
						|
			parent   metav1.Object
 | 
						|
			revision *apps.ControllerRevision
 | 
						|
		}
 | 
						|
		reactor core.ReactionFunc
 | 
						|
		err     bool
 | 
						|
	}
 | 
						|
	conflictSuccess := func(action core.Action) (bool, runtime.Object, error) {
 | 
						|
		defer func() {
 | 
						|
			conflictAttempts++
 | 
						|
		}()
 | 
						|
		switch action.(type) {
 | 
						|
 | 
						|
		case core.UpdateActionImpl:
 | 
						|
			update := action.(core.UpdateAction)
 | 
						|
			if conflictAttempts < 2 {
 | 
						|
				return true, update.GetObject(), errors.NewConflict(update.GetResource().GroupResource(), "", fmt.Errorf("conflict"))
 | 
						|
			}
 | 
						|
			return true, update.GetObject(), nil
 | 
						|
		default:
 | 
						|
			return false, nil, nil
 | 
						|
		}
 | 
						|
	}
 | 
						|
	internalError := func(action core.Action) (bool, runtime.Object, error) {
 | 
						|
		switch action.(type) {
 | 
						|
		case core.UpdateActionImpl:
 | 
						|
			return true, nil, errors.NewInternalError(fmt.Errorf("internal error"))
 | 
						|
		default:
 | 
						|
			return false, nil, nil
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	testFn := func(test *testcase, t *testing.T) {
 | 
						|
		client := fake.NewSimpleClientset()
 | 
						|
 | 
						|
		informerFactory := informers.NewSharedInformerFactory(client, controller.NoResyncPeriodFunc())
 | 
						|
		stop := make(chan struct{})
 | 
						|
		defer close(stop)
 | 
						|
		informerFactory.Start(stop)
 | 
						|
		informer := informerFactory.Apps().V1beta1().ControllerRevisions()
 | 
						|
		informerFactory.WaitForCacheSync(stop)
 | 
						|
		history := NewHistory(client, informer.Lister())
 | 
						|
		for i := range test.existing {
 | 
						|
			_, err := history.CreateControllerRevision(test.existing[i].parent, test.existing[i].revision)
 | 
						|
			if err != nil {
 | 
						|
				t.Fatal(err)
 | 
						|
			}
 | 
						|
		}
 | 
						|
		if test.reactor != nil {
 | 
						|
			client.PrependReactor("*", "*", test.reactor)
 | 
						|
		}
 | 
						|
		updated, err := history.UpdateControllerRevision(test.revision, test.newRevision)
 | 
						|
		if !test.err && err != nil {
 | 
						|
			t.Errorf("%s: %s", test.name, err)
 | 
						|
		}
 | 
						|
		if !test.err && updated.Revision != test.newRevision {
 | 
						|
			t.Errorf("%s: got %d want %d", test.name, updated.Revision, test.newRevision)
 | 
						|
		}
 | 
						|
		if test.err && err == nil {
 | 
						|
			t.Errorf("%s: expected error", test.name)
 | 
						|
		}
 | 
						|
	}
 | 
						|
	ss1 := newStatefulSet(3, "ss1", types.UID("ss1"), map[string]string{"foo": "bar"})
 | 
						|
	sel1, err := metav1.LabelSelectorAsSelector(ss1.Spec.Selector)
 | 
						|
	if err != nil {
 | 
						|
		t.Fatal(err)
 | 
						|
	}
 | 
						|
 | 
						|
	ss1Rev1, err := NewControllerRevision(ss1, parentKind, sel1, rawTemplate(&ss1.Spec.Template), 1)
 | 
						|
	if err != nil {
 | 
						|
		t.Fatal(err)
 | 
						|
	}
 | 
						|
	ss1Rev1.Namespace = ss1.Namespace
 | 
						|
	ss1Rev2, err := NewControllerRevision(ss1, parentKind, sel1, rawTemplate(&ss1.Spec.Template), 2)
 | 
						|
	if err != nil {
 | 
						|
		t.Fatal(err)
 | 
						|
	}
 | 
						|
	ss1Rev2.Namespace = ss1.Namespace
 | 
						|
 | 
						|
	tests := []testcase{
 | 
						|
		{
 | 
						|
			name:        "update succeeds",
 | 
						|
			revision:    ss1Rev1,
 | 
						|
			newRevision: ss1Rev1.Revision + 1,
 | 
						|
			existing: []struct {
 | 
						|
				parent   metav1.Object
 | 
						|
				revision *apps.ControllerRevision
 | 
						|
			}{
 | 
						|
				{
 | 
						|
					parent:   ss1,
 | 
						|
					revision: ss1Rev1,
 | 
						|
				},
 | 
						|
			},
 | 
						|
			reactor: nil,
 | 
						|
			err:     false,
 | 
						|
		},
 | 
						|
		{
 | 
						|
			name:        "update succeeds no noop",
 | 
						|
			revision:    ss1Rev1,
 | 
						|
			newRevision: ss1Rev1.Revision,
 | 
						|
			existing: []struct {
 | 
						|
				parent   metav1.Object
 | 
						|
				revision *apps.ControllerRevision
 | 
						|
			}{
 | 
						|
				{
 | 
						|
					parent:   ss1,
 | 
						|
					revision: ss1Rev1,
 | 
						|
				},
 | 
						|
			},
 | 
						|
			reactor: nil,
 | 
						|
			err:     false,
 | 
						|
		}, {
 | 
						|
			name:        "update fails on error",
 | 
						|
			revision:    ss1Rev1,
 | 
						|
			newRevision: ss1Rev1.Revision + 10,
 | 
						|
			existing: []struct {
 | 
						|
				parent   metav1.Object
 | 
						|
				revision *apps.ControllerRevision
 | 
						|
			}{
 | 
						|
				{
 | 
						|
					parent:   ss1,
 | 
						|
					revision: ss1Rev1,
 | 
						|
				},
 | 
						|
			},
 | 
						|
			reactor: internalError,
 | 
						|
			err:     true,
 | 
						|
		},
 | 
						|
		{
 | 
						|
			name:        "update on succeeds on conflict",
 | 
						|
			revision:    ss1Rev1,
 | 
						|
			newRevision: ss1Rev1.Revision + 1,
 | 
						|
			existing: []struct {
 | 
						|
				parent   metav1.Object
 | 
						|
				revision *apps.ControllerRevision
 | 
						|
			}{
 | 
						|
				{
 | 
						|
					parent:   ss1,
 | 
						|
					revision: ss1Rev1,
 | 
						|
				},
 | 
						|
			},
 | 
						|
			reactor: conflictSuccess,
 | 
						|
			err:     false,
 | 
						|
		},
 | 
						|
	}
 | 
						|
	for i := range tests {
 | 
						|
		conflictAttempts = 0
 | 
						|
		testFn(&tests[i], t)
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func TestFakeHistory_UpdateControllerRevision(t *testing.T) {
 | 
						|
	type testcase struct {
 | 
						|
		name        string
 | 
						|
		revision    *apps.ControllerRevision
 | 
						|
		newRevision int64
 | 
						|
		existing    []struct {
 | 
						|
			parent   metav1.Object
 | 
						|
			revision *apps.ControllerRevision
 | 
						|
		}
 | 
						|
		err bool
 | 
						|
	}
 | 
						|
 | 
						|
	testFn := func(test *testcase, t *testing.T) {
 | 
						|
		client := fake.NewSimpleClientset()
 | 
						|
 | 
						|
		informerFactory := informers.NewSharedInformerFactory(client, controller.NoResyncPeriodFunc())
 | 
						|
		stop := make(chan struct{})
 | 
						|
		defer close(stop)
 | 
						|
		informerFactory.Start(stop)
 | 
						|
		informer := informerFactory.Apps().V1beta1().ControllerRevisions()
 | 
						|
		informerFactory.WaitForCacheSync(stop)
 | 
						|
		history := NewFakeHistory(informer)
 | 
						|
		for i := range test.existing {
 | 
						|
			_, err := history.CreateControllerRevision(test.existing[i].parent, test.existing[i].revision)
 | 
						|
			if err != nil {
 | 
						|
				t.Fatal(err)
 | 
						|
			}
 | 
						|
		}
 | 
						|
		updated, err := history.UpdateControllerRevision(test.revision, test.newRevision)
 | 
						|
		if !test.err && err != nil {
 | 
						|
			t.Errorf("%s: %s", test.name, err)
 | 
						|
		}
 | 
						|
		if !test.err && updated.Revision != test.newRevision {
 | 
						|
			t.Errorf("%s: got %d want %d", test.name, updated.Revision, test.newRevision)
 | 
						|
		}
 | 
						|
		if test.err && err == nil {
 | 
						|
			t.Errorf("%s: expected error", test.name)
 | 
						|
		}
 | 
						|
	}
 | 
						|
	ss1 := newStatefulSet(3, "ss1", types.UID("ss1"), map[string]string{"foo": "bar"})
 | 
						|
	sel1, err := metav1.LabelSelectorAsSelector(ss1.Spec.Selector)
 | 
						|
	if err != nil {
 | 
						|
		t.Fatal(err)
 | 
						|
	}
 | 
						|
 | 
						|
	ss1Rev1, err := NewControllerRevision(ss1, parentKind, sel1, rawTemplate(&ss1.Spec.Template), 1)
 | 
						|
	if err != nil {
 | 
						|
		t.Fatal(err)
 | 
						|
	}
 | 
						|
	ss1Rev1.Namespace = ss1.Namespace
 | 
						|
	ss1Rev2, err := NewControllerRevision(ss1, parentKind, sel1, rawTemplate(&ss1.Spec.Template), 2)
 | 
						|
	if err != nil {
 | 
						|
		t.Fatal(err)
 | 
						|
	}
 | 
						|
	ss1Rev2.Namespace = ss1.Namespace
 | 
						|
	tests := []testcase{
 | 
						|
		{
 | 
						|
			name:        "update succeeds",
 | 
						|
			revision:    ss1Rev1,
 | 
						|
			newRevision: ss1Rev1.Revision + 1,
 | 
						|
			existing: []struct {
 | 
						|
				parent   metav1.Object
 | 
						|
				revision *apps.ControllerRevision
 | 
						|
			}{
 | 
						|
				{
 | 
						|
					parent:   ss1,
 | 
						|
					revision: ss1Rev1,
 | 
						|
				},
 | 
						|
			},
 | 
						|
			err: false,
 | 
						|
		},
 | 
						|
		{
 | 
						|
			name:        "update succeeds no noop",
 | 
						|
			revision:    ss1Rev1,
 | 
						|
			newRevision: ss1Rev1.Revision,
 | 
						|
			existing: []struct {
 | 
						|
				parent   metav1.Object
 | 
						|
				revision *apps.ControllerRevision
 | 
						|
			}{
 | 
						|
				{
 | 
						|
					parent:   ss1,
 | 
						|
					revision: ss1Rev1,
 | 
						|
				},
 | 
						|
			},
 | 
						|
			err: false,
 | 
						|
		},
 | 
						|
	}
 | 
						|
	for i := range tests {
 | 
						|
		testFn(&tests[i], t)
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func TestRealHistory_DeleteControllerRevision(t *testing.T) {
 | 
						|
	type testcase struct {
 | 
						|
		name     string
 | 
						|
		revision *apps.ControllerRevision
 | 
						|
		existing []struct {
 | 
						|
			parent   metav1.Object
 | 
						|
			revision *apps.ControllerRevision
 | 
						|
		}
 | 
						|
		err bool
 | 
						|
	}
 | 
						|
	testFn := func(test *testcase, t *testing.T) {
 | 
						|
		client := fake.NewSimpleClientset()
 | 
						|
		informerFactory := informers.NewSharedInformerFactory(client, controller.NoResyncPeriodFunc())
 | 
						|
 | 
						|
		stop := make(chan struct{})
 | 
						|
		defer close(stop)
 | 
						|
		informerFactory.Start(stop)
 | 
						|
		informer := informerFactory.Apps().V1beta1().ControllerRevisions()
 | 
						|
		informerFactory.WaitForCacheSync(stop)
 | 
						|
		history := NewHistory(client, informer.Lister())
 | 
						|
		for i := range test.existing {
 | 
						|
			_, err := history.CreateControllerRevision(test.existing[i].parent, test.existing[i].revision)
 | 
						|
			if err != nil {
 | 
						|
				t.Fatal(err)
 | 
						|
			}
 | 
						|
		}
 | 
						|
		err := history.DeleteControllerRevision(test.revision)
 | 
						|
		if !test.err && err != nil {
 | 
						|
			t.Errorf("%s: %s", test.name, err)
 | 
						|
		}
 | 
						|
		if test.err && err == nil {
 | 
						|
			t.Errorf("%s: expected error", test.name)
 | 
						|
		}
 | 
						|
	}
 | 
						|
	ss1 := newStatefulSet(3, "ss1", types.UID("ss1"), map[string]string{"foo": "bar"})
 | 
						|
	ss2 := newStatefulSet(3, "ss2", types.UID("ss2"), map[string]string{"goo": "car"})
 | 
						|
	sel1, err := metav1.LabelSelectorAsSelector(ss1.Spec.Selector)
 | 
						|
	if err != nil {
 | 
						|
		t.Fatal(err)
 | 
						|
	}
 | 
						|
	sel2, err := metav1.LabelSelectorAsSelector(ss2.Spec.Selector)
 | 
						|
	if err != nil {
 | 
						|
		t.Fatal(err)
 | 
						|
	}
 | 
						|
	ss1Rev1, err := NewControllerRevision(ss1, parentKind, sel1, rawTemplate(&ss1.Spec.Template), 1)
 | 
						|
	if err != nil {
 | 
						|
		t.Fatal(err)
 | 
						|
	}
 | 
						|
	ss1Rev1.Namespace = ss1.Namespace
 | 
						|
	ss1Rev2, err := NewControllerRevision(ss1, parentKind, sel1, rawTemplate(&ss1.Spec.Template), 2)
 | 
						|
	if err != nil {
 | 
						|
		t.Fatal(err)
 | 
						|
	}
 | 
						|
	ss1Rev2.Namespace = ss1.Namespace
 | 
						|
	ss2Rev1, err := NewControllerRevision(ss2, parentKind, sel2, rawTemplate(&ss2.Spec.Template), 1)
 | 
						|
	if err != nil {
 | 
						|
		t.Fatal(err)
 | 
						|
	}
 | 
						|
	ss2Rev1.Namespace = ss2.Namespace
 | 
						|
	ss2Rev2, err := NewControllerRevision(ss2, parentKind, sel2, rawTemplate(&ss2.Spec.Template), 2)
 | 
						|
	if err != nil {
 | 
						|
		t.Fatal(err)
 | 
						|
	}
 | 
						|
	ss2Rev2.Namespace = ss2.Namespace
 | 
						|
	tests := []testcase{
 | 
						|
		{
 | 
						|
			name:     "delete empty fails",
 | 
						|
			revision: ss1Rev1,
 | 
						|
			existing: nil,
 | 
						|
			err:      true,
 | 
						|
		},
 | 
						|
		{
 | 
						|
			name:     "delete existing succeeds",
 | 
						|
			revision: ss1Rev1,
 | 
						|
			existing: []struct {
 | 
						|
				parent   metav1.Object
 | 
						|
				revision *apps.ControllerRevision
 | 
						|
			}{
 | 
						|
				{
 | 
						|
					parent:   ss1,
 | 
						|
					revision: ss1Rev1,
 | 
						|
				},
 | 
						|
			},
 | 
						|
			err: false,
 | 
						|
		}, {
 | 
						|
			name:     "delete non-existing fails",
 | 
						|
			revision: ss1Rev1,
 | 
						|
			existing: []struct {
 | 
						|
				parent   metav1.Object
 | 
						|
				revision *apps.ControllerRevision
 | 
						|
			}{
 | 
						|
				{
 | 
						|
					parent:   ss2,
 | 
						|
					revision: ss2Rev1,
 | 
						|
				},
 | 
						|
				{
 | 
						|
					parent:   ss2,
 | 
						|
					revision: ss2Rev2,
 | 
						|
				},
 | 
						|
			},
 | 
						|
			err: true,
 | 
						|
		},
 | 
						|
	}
 | 
						|
	for i := range tests {
 | 
						|
		testFn(&tests[i], t)
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func TestFakeHistory_DeleteControllerRevision(t *testing.T) {
 | 
						|
	type testcase struct {
 | 
						|
		name     string
 | 
						|
		revision *apps.ControllerRevision
 | 
						|
		existing []struct {
 | 
						|
			parent   metav1.Object
 | 
						|
			revision *apps.ControllerRevision
 | 
						|
		}
 | 
						|
		err bool
 | 
						|
	}
 | 
						|
	testFn := func(test *testcase, t *testing.T) {
 | 
						|
		client := fake.NewSimpleClientset()
 | 
						|
		informerFactory := informers.NewSharedInformerFactory(client, controller.NoResyncPeriodFunc())
 | 
						|
 | 
						|
		stop := make(chan struct{})
 | 
						|
		defer close(stop)
 | 
						|
		informerFactory.Start(stop)
 | 
						|
		informer := informerFactory.Apps().V1beta1().ControllerRevisions()
 | 
						|
		informerFactory.WaitForCacheSync(stop)
 | 
						|
		history := NewFakeHistory(informer)
 | 
						|
		for i := range test.existing {
 | 
						|
			_, err := history.CreateControllerRevision(test.existing[i].parent, test.existing[i].revision)
 | 
						|
			if err != nil {
 | 
						|
				t.Fatal(err)
 | 
						|
			}
 | 
						|
		}
 | 
						|
		err := history.DeleteControllerRevision(test.revision)
 | 
						|
		if !test.err && err != nil {
 | 
						|
			t.Errorf("%s: %s", test.name, err)
 | 
						|
		}
 | 
						|
		if test.err && err == nil {
 | 
						|
			t.Errorf("%s: expected error", test.name)
 | 
						|
		}
 | 
						|
	}
 | 
						|
	ss1 := newStatefulSet(3, "ss1", types.UID("ss1"), map[string]string{"foo": "bar"})
 | 
						|
	ss2 := newStatefulSet(3, "ss2", types.UID("ss2"), map[string]string{"goo": "car"})
 | 
						|
	sel1, err := metav1.LabelSelectorAsSelector(ss1.Spec.Selector)
 | 
						|
	if err != nil {
 | 
						|
		t.Fatal(err)
 | 
						|
	}
 | 
						|
	sel2, err := metav1.LabelSelectorAsSelector(ss2.Spec.Selector)
 | 
						|
	if err != nil {
 | 
						|
		t.Fatal(err)
 | 
						|
	}
 | 
						|
	ss1Rev1, err := NewControllerRevision(ss1, parentKind, sel1, rawTemplate(&ss1.Spec.Template), 1)
 | 
						|
	if err != nil {
 | 
						|
		t.Fatal(err)
 | 
						|
	}
 | 
						|
	ss1Rev1.Namespace = ss1.Namespace
 | 
						|
	ss1Rev2, err := NewControllerRevision(ss1, parentKind, sel1, rawTemplate(&ss1.Spec.Template), 2)
 | 
						|
	if err != nil {
 | 
						|
		t.Fatal(err)
 | 
						|
	}
 | 
						|
	ss1Rev2.Namespace = ss1.Namespace
 | 
						|
	ss2Rev1, err := NewControllerRevision(ss2, parentKind, sel2, rawTemplate(&ss2.Spec.Template), 1)
 | 
						|
	if err != nil {
 | 
						|
		t.Fatal(err)
 | 
						|
	}
 | 
						|
	ss2Rev1.Namespace = ss2.Namespace
 | 
						|
	ss2Rev2, err := NewControllerRevision(ss2, parentKind, sel2, rawTemplate(&ss2.Spec.Template), 2)
 | 
						|
	if err != nil {
 | 
						|
		t.Fatal(err)
 | 
						|
	}
 | 
						|
	ss2Rev2.Namespace = ss2.Namespace
 | 
						|
	tests := []testcase{
 | 
						|
		{
 | 
						|
			name:     "delete empty fails",
 | 
						|
			revision: ss1Rev1,
 | 
						|
			existing: nil,
 | 
						|
			err:      true,
 | 
						|
		},
 | 
						|
		{
 | 
						|
			name:     "delete existing succeeds",
 | 
						|
			revision: ss1Rev1,
 | 
						|
			existing: []struct {
 | 
						|
				parent   metav1.Object
 | 
						|
				revision *apps.ControllerRevision
 | 
						|
			}{
 | 
						|
				{
 | 
						|
					parent:   ss1,
 | 
						|
					revision: ss1Rev1,
 | 
						|
				},
 | 
						|
			},
 | 
						|
			err: false,
 | 
						|
		}, {
 | 
						|
			name:     "delete non-existing fails",
 | 
						|
			revision: ss1Rev1,
 | 
						|
			existing: []struct {
 | 
						|
				parent   metav1.Object
 | 
						|
				revision *apps.ControllerRevision
 | 
						|
			}{
 | 
						|
				{
 | 
						|
					parent:   ss2,
 | 
						|
					revision: ss2Rev1,
 | 
						|
				},
 | 
						|
				{
 | 
						|
					parent:   ss2,
 | 
						|
					revision: ss2Rev2,
 | 
						|
				},
 | 
						|
			},
 | 
						|
			err: true,
 | 
						|
		},
 | 
						|
	}
 | 
						|
	for i := range tests {
 | 
						|
		testFn(&tests[i], t)
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func TestRealHistory_AdoptControllerRevision(t *testing.T) {
 | 
						|
	type testcase struct {
 | 
						|
		name     string
 | 
						|
		parent   metav1.Object
 | 
						|
		revision *apps.ControllerRevision
 | 
						|
		existing []struct {
 | 
						|
			parent   metav1.Object
 | 
						|
			revision *apps.ControllerRevision
 | 
						|
		}
 | 
						|
		err bool
 | 
						|
	}
 | 
						|
	testFn := func(test *testcase, t *testing.T) {
 | 
						|
		client := fake.NewSimpleClientset()
 | 
						|
		client.AddReactor("*", "*", func(action core.Action) (bool, runtime.Object, error) {
 | 
						|
			switch action := action.(type) {
 | 
						|
			case core.PatchActionImpl:
 | 
						|
				var found *apps.ControllerRevision
 | 
						|
				for i := range test.existing {
 | 
						|
					if test.revision.Name == test.existing[i].revision.Name &&
 | 
						|
						test.revision.Namespace == test.existing[i].revision.Namespace {
 | 
						|
						found = test.existing[i].revision
 | 
						|
						break
 | 
						|
					}
 | 
						|
				}
 | 
						|
				if found == nil {
 | 
						|
					return true, nil, errors.NewNotFound(apps.Resource("controllerrevisions"), test.revision.Name)
 | 
						|
				}
 | 
						|
				b, err := strategicpatch.StrategicMergePatch(
 | 
						|
					[]byte(runtime.EncodeOrDie(testapi.Apps.Codec(), test.revision)),
 | 
						|
					action.GetPatch(), test.revision)
 | 
						|
				if err != nil {
 | 
						|
					return true, nil, err
 | 
						|
				}
 | 
						|
				obj, err := runtime.Decode(testapi.Apps.Codec(), b)
 | 
						|
				if err != nil {
 | 
						|
					return true, nil, err
 | 
						|
				}
 | 
						|
				patched, err := testapi.Apps.Converter().ConvertToVersion(obj, apps.SchemeGroupVersion)
 | 
						|
				if err != nil {
 | 
						|
					return true, nil, err
 | 
						|
				}
 | 
						|
				return true, patched, err
 | 
						|
			default:
 | 
						|
				return false, nil, nil
 | 
						|
			}
 | 
						|
 | 
						|
		})
 | 
						|
		informerFactory := informers.NewSharedInformerFactory(client, controller.NoResyncPeriodFunc())
 | 
						|
		stop := make(chan struct{})
 | 
						|
		defer close(stop)
 | 
						|
		informerFactory.Start(stop)
 | 
						|
		informer := informerFactory.Apps().V1beta1().ControllerRevisions()
 | 
						|
		informerFactory.WaitForCacheSync(stop)
 | 
						|
 | 
						|
		history := NewHistory(client, informer.Lister())
 | 
						|
		for i := range test.existing {
 | 
						|
			_, err := history.CreateControllerRevision(test.existing[i].parent, test.existing[i].revision)
 | 
						|
			if err != nil {
 | 
						|
				t.Fatal(err)
 | 
						|
			}
 | 
						|
		}
 | 
						|
		adopted, err := history.AdoptControllerRevision(test.parent, parentKind, test.revision)
 | 
						|
		if !test.err && err != nil {
 | 
						|
			t.Errorf("%s: %s", test.name, err)
 | 
						|
		}
 | 
						|
		if !test.err && !metav1.IsControlledBy(adopted, test.parent) {
 | 
						|
			t.Errorf("%s: adoption failed", test.name)
 | 
						|
		}
 | 
						|
		if test.err && err == nil {
 | 
						|
			t.Errorf("%s: expected error", test.name)
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	ss1 := newStatefulSet(3, "ss1", types.UID("ss1"), map[string]string{"foo": "bar"})
 | 
						|
	ss2 := newStatefulSet(3, "ss2", types.UID("ss2"), map[string]string{"goo": "car"})
 | 
						|
	sel1, err := metav1.LabelSelectorAsSelector(ss1.Spec.Selector)
 | 
						|
	if err != nil {
 | 
						|
		t.Fatal(err)
 | 
						|
	}
 | 
						|
	sel2, err := metav1.LabelSelectorAsSelector(ss2.Spec.Selector)
 | 
						|
	if err != nil {
 | 
						|
		t.Fatal(err)
 | 
						|
	}
 | 
						|
	ss1Rev1, err := NewControllerRevision(ss1, parentKind, sel1, rawTemplate(&ss1.Spec.Template), 1)
 | 
						|
	if err != nil {
 | 
						|
		t.Fatal(err)
 | 
						|
	}
 | 
						|
	ss1Rev1.Namespace = ss1.Namespace
 | 
						|
	ss1Rev2, err := NewControllerRevision(ss1, parentKind, sel1, rawTemplate(&ss1.Spec.Template), 2)
 | 
						|
	if err != nil {
 | 
						|
		t.Fatal(err)
 | 
						|
	}
 | 
						|
	ss1Rev2.Namespace = ss1.Namespace
 | 
						|
	ss1Rev2.OwnerReferences = []metav1.OwnerReference{}
 | 
						|
	ss2Rev1, err := NewControllerRevision(ss2, parentKind, sel2, rawTemplate(&ss2.Spec.Template), 1)
 | 
						|
	if err != nil {
 | 
						|
		t.Fatal(err)
 | 
						|
	}
 | 
						|
	ss2Rev1.Namespace = ss2.Namespace
 | 
						|
	tests := []testcase{
 | 
						|
		{
 | 
						|
			name:     "adopting an orphan succeeds",
 | 
						|
			parent:   ss1,
 | 
						|
			revision: ss1Rev2,
 | 
						|
			existing: []struct {
 | 
						|
				parent   metav1.Object
 | 
						|
				revision *apps.ControllerRevision
 | 
						|
			}{
 | 
						|
				{
 | 
						|
					parent:   ss1,
 | 
						|
					revision: ss1Rev2,
 | 
						|
				},
 | 
						|
			},
 | 
						|
			err: false,
 | 
						|
		},
 | 
						|
		{
 | 
						|
			name:     "adopting an owned revision fails",
 | 
						|
			parent:   ss1,
 | 
						|
			revision: ss2Rev1,
 | 
						|
			existing: []struct {
 | 
						|
				parent   metav1.Object
 | 
						|
				revision *apps.ControllerRevision
 | 
						|
			}{
 | 
						|
				{
 | 
						|
					parent:   ss2,
 | 
						|
					revision: ss2Rev1,
 | 
						|
				},
 | 
						|
			},
 | 
						|
			err: true,
 | 
						|
		},
 | 
						|
		{
 | 
						|
			name:     "adopting a non-existent revision fails",
 | 
						|
			parent:   ss1,
 | 
						|
			revision: ss1Rev2,
 | 
						|
			existing: nil,
 | 
						|
			err:      true,
 | 
						|
		},
 | 
						|
	}
 | 
						|
	for i := range tests {
 | 
						|
		testFn(&tests[i], t)
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func TestFakeHistory_AdoptControllerRevision(t *testing.T) {
 | 
						|
	type testcase struct {
 | 
						|
		name       string
 | 
						|
		parent     metav1.Object
 | 
						|
		parentType *metav1.TypeMeta
 | 
						|
		revision   *apps.ControllerRevision
 | 
						|
		existing   []struct {
 | 
						|
			parent   metav1.Object
 | 
						|
			revision *apps.ControllerRevision
 | 
						|
		}
 | 
						|
		err bool
 | 
						|
	}
 | 
						|
	testFn := func(test *testcase, t *testing.T) {
 | 
						|
		client := fake.NewSimpleClientset()
 | 
						|
 | 
						|
		informerFactory := informers.NewSharedInformerFactory(client, controller.NoResyncPeriodFunc())
 | 
						|
		stop := make(chan struct{})
 | 
						|
		defer close(stop)
 | 
						|
		informerFactory.Start(stop)
 | 
						|
		informer := informerFactory.Apps().V1beta1().ControllerRevisions()
 | 
						|
		informerFactory.WaitForCacheSync(stop)
 | 
						|
 | 
						|
		history := NewFakeHistory(informer)
 | 
						|
		for i := range test.existing {
 | 
						|
			_, err := history.CreateControllerRevision(test.existing[i].parent, test.existing[i].revision)
 | 
						|
			if err != nil {
 | 
						|
				t.Fatal(err)
 | 
						|
			}
 | 
						|
		}
 | 
						|
		adopted, err := history.AdoptControllerRevision(test.parent, parentKind, test.revision)
 | 
						|
		if !test.err && err != nil {
 | 
						|
			t.Errorf("%s: %s", test.name, err)
 | 
						|
		}
 | 
						|
		if !test.err && !metav1.IsControlledBy(adopted, test.parent) {
 | 
						|
			t.Errorf("%s: adoption failed", test.name)
 | 
						|
		}
 | 
						|
		if test.err && err == nil {
 | 
						|
			t.Errorf("%s: expected error", test.name)
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	ss1 := newStatefulSet(3, "ss1", types.UID("ss1"), map[string]string{"foo": "bar"})
 | 
						|
	ss2 := newStatefulSet(3, "ss2", types.UID("ss2"), map[string]string{"goo": "car"})
 | 
						|
	sel1, err := metav1.LabelSelectorAsSelector(ss1.Spec.Selector)
 | 
						|
	if err != nil {
 | 
						|
		t.Fatal(err)
 | 
						|
	}
 | 
						|
	sel2, err := metav1.LabelSelectorAsSelector(ss2.Spec.Selector)
 | 
						|
	if err != nil {
 | 
						|
		t.Fatal(err)
 | 
						|
	}
 | 
						|
	ss1Rev1, err := NewControllerRevision(ss1, parentKind, sel1, rawTemplate(&ss1.Spec.Template), 1)
 | 
						|
	if err != nil {
 | 
						|
		t.Fatal(err)
 | 
						|
	}
 | 
						|
	ss1Rev1.Namespace = ss1.Namespace
 | 
						|
	ss1Rev2, err := NewControllerRevision(ss1, parentKind, sel1, rawTemplate(&ss1.Spec.Template), 2)
 | 
						|
	if err != nil {
 | 
						|
		t.Fatal(err)
 | 
						|
	}
 | 
						|
	ss1Rev2.Namespace = ss1.Namespace
 | 
						|
	ss1Rev2.OwnerReferences = []metav1.OwnerReference{}
 | 
						|
	ss2Rev1, err := NewControllerRevision(ss2, parentKind, sel2, rawTemplate(&ss2.Spec.Template), 1)
 | 
						|
	if err != nil {
 | 
						|
		t.Fatal(err)
 | 
						|
	}
 | 
						|
	ss2Rev1.Namespace = ss2.Namespace
 | 
						|
	tests := []testcase{
 | 
						|
		{
 | 
						|
			name:       "adopting an orphan succeeds",
 | 
						|
			parent:     ss1,
 | 
						|
			parentType: &ss1.TypeMeta,
 | 
						|
			revision:   ss1Rev2,
 | 
						|
			existing: []struct {
 | 
						|
				parent   metav1.Object
 | 
						|
				revision *apps.ControllerRevision
 | 
						|
			}{
 | 
						|
				{
 | 
						|
					parent:   ss1,
 | 
						|
					revision: ss1Rev2,
 | 
						|
				},
 | 
						|
			},
 | 
						|
			err: false,
 | 
						|
		},
 | 
						|
		{
 | 
						|
			name:       "adopting an owned revision fails",
 | 
						|
			parent:     ss1,
 | 
						|
			parentType: &ss1.TypeMeta,
 | 
						|
			revision:   ss2Rev1,
 | 
						|
			existing: []struct {
 | 
						|
				parent   metav1.Object
 | 
						|
				revision *apps.ControllerRevision
 | 
						|
			}{
 | 
						|
				{
 | 
						|
					parent:   ss2,
 | 
						|
					revision: ss2Rev1,
 | 
						|
				},
 | 
						|
			},
 | 
						|
			err: true,
 | 
						|
		},
 | 
						|
		{
 | 
						|
			name:       "adopting a non-existent revision fails",
 | 
						|
			parent:     ss1,
 | 
						|
			parentType: &ss1.TypeMeta,
 | 
						|
			revision:   ss1Rev2,
 | 
						|
			existing:   nil,
 | 
						|
			err:        true,
 | 
						|
		},
 | 
						|
	}
 | 
						|
	for i := range tests {
 | 
						|
		testFn(&tests[i], t)
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func TestRealHistory_ReleaseControllerRevision(t *testing.T) {
 | 
						|
	type testcase struct {
 | 
						|
		name     string
 | 
						|
		parent   metav1.Object
 | 
						|
		revision *apps.ControllerRevision
 | 
						|
		existing []struct {
 | 
						|
			parent   metav1.Object
 | 
						|
			revision *apps.ControllerRevision
 | 
						|
		}
 | 
						|
		err bool
 | 
						|
	}
 | 
						|
	testFn := func(test *testcase, t *testing.T) {
 | 
						|
		client := fake.NewSimpleClientset()
 | 
						|
		client.AddReactor("*", "*", func(action core.Action) (bool, runtime.Object, error) {
 | 
						|
			switch action := action.(type) {
 | 
						|
			case core.PatchActionImpl:
 | 
						|
				var found *apps.ControllerRevision
 | 
						|
				for i := range test.existing {
 | 
						|
					if test.revision.Name == test.existing[i].revision.Name &&
 | 
						|
						test.revision.Namespace == test.existing[i].revision.Namespace {
 | 
						|
						found = test.existing[i].revision
 | 
						|
						break
 | 
						|
					}
 | 
						|
				}
 | 
						|
				if found == nil {
 | 
						|
					return true, nil, errors.NewNotFound(apps.Resource("controllerrevisions"), test.revision.Name)
 | 
						|
				}
 | 
						|
				if !metav1.IsControlledBy(test.revision, test.parent) {
 | 
						|
					return true, nil, errors.NewInvalid(
 | 
						|
						test.revision.GroupVersionKind().GroupKind(), test.revision.Name, nil)
 | 
						|
				}
 | 
						|
				b, err := strategicpatch.StrategicMergePatch(
 | 
						|
					[]byte(runtime.EncodeOrDie(testapi.Apps.Codec(), test.revision)),
 | 
						|
					action.GetPatch(), test.revision)
 | 
						|
				if err != nil {
 | 
						|
					return true, nil, err
 | 
						|
				}
 | 
						|
				obj, err := runtime.Decode(testapi.Apps.Codec(), b)
 | 
						|
				if err != nil {
 | 
						|
					return true, nil, err
 | 
						|
				}
 | 
						|
				patched, err := testapi.Apps.Converter().ConvertToVersion(obj, apps.SchemeGroupVersion)
 | 
						|
				if err != nil {
 | 
						|
					return true, nil, err
 | 
						|
				}
 | 
						|
				return true, patched, err
 | 
						|
			default:
 | 
						|
				return false, nil, nil
 | 
						|
			}
 | 
						|
 | 
						|
		})
 | 
						|
		informerFactory := informers.NewSharedInformerFactory(client, controller.NoResyncPeriodFunc())
 | 
						|
		stop := make(chan struct{})
 | 
						|
		defer close(stop)
 | 
						|
		informerFactory.Start(stop)
 | 
						|
		informer := informerFactory.Apps().V1beta1().ControllerRevisions()
 | 
						|
		informerFactory.WaitForCacheSync(stop)
 | 
						|
 | 
						|
		history := NewHistory(client, informer.Lister())
 | 
						|
		for i := range test.existing {
 | 
						|
			_, err := history.CreateControllerRevision(test.existing[i].parent, test.existing[i].revision)
 | 
						|
			if err != nil {
 | 
						|
				t.Fatal(err)
 | 
						|
			}
 | 
						|
		}
 | 
						|
		adopted, err := history.ReleaseControllerRevision(test.parent, test.revision)
 | 
						|
		if !test.err {
 | 
						|
			if err != nil {
 | 
						|
				t.Errorf("%s: %s", test.name, err)
 | 
						|
			}
 | 
						|
			if adopted == nil {
 | 
						|
				return
 | 
						|
			}
 | 
						|
			if metav1.IsControlledBy(adopted, test.parent) {
 | 
						|
				t.Errorf("%s: release failed", test.name)
 | 
						|
			}
 | 
						|
		}
 | 
						|
		if test.err && err == nil {
 | 
						|
			t.Errorf("%s: expected error", test.name)
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	ss1 := newStatefulSet(3, "ss1", types.UID("ss1"), map[string]string{"foo": "bar"})
 | 
						|
	ss2 := newStatefulSet(3, "ss2", types.UID("ss2"), map[string]string{"goo": "car"})
 | 
						|
	sel1, err := metav1.LabelSelectorAsSelector(ss1.Spec.Selector)
 | 
						|
	if err != nil {
 | 
						|
		t.Fatal(err)
 | 
						|
	}
 | 
						|
	sel2, err := metav1.LabelSelectorAsSelector(ss2.Spec.Selector)
 | 
						|
	if err != nil {
 | 
						|
		t.Fatal(err)
 | 
						|
	}
 | 
						|
	ss1Rev1, err := NewControllerRevision(ss1, parentKind, sel1, rawTemplate(&ss1.Spec.Template), 1)
 | 
						|
	if err != nil {
 | 
						|
		t.Fatal(err)
 | 
						|
	}
 | 
						|
	ss1Rev1.Namespace = ss1.Namespace
 | 
						|
	ss1Rev2, err := NewControllerRevision(ss1, parentKind, sel1, rawTemplate(&ss1.Spec.Template), 2)
 | 
						|
	if err != nil {
 | 
						|
		t.Fatal(err)
 | 
						|
	}
 | 
						|
	ss1Rev2.Namespace = ss1.Namespace
 | 
						|
	ss1Rev2.OwnerReferences = []metav1.OwnerReference{}
 | 
						|
	ss2Rev1, err := NewControllerRevision(ss2, parentKind, sel2, rawTemplate(&ss2.Spec.Template), 1)
 | 
						|
	if err != nil {
 | 
						|
		t.Fatal(err)
 | 
						|
	}
 | 
						|
	ss2Rev1.Namespace = ss2.Namespace
 | 
						|
	tests := []testcase{
 | 
						|
		{
 | 
						|
			name:     "releasing an owned revision succeeds",
 | 
						|
			parent:   ss1,
 | 
						|
			revision: ss1Rev1,
 | 
						|
			existing: []struct {
 | 
						|
				parent   metav1.Object
 | 
						|
				revision *apps.ControllerRevision
 | 
						|
			}{
 | 
						|
				{
 | 
						|
					parent:   ss1,
 | 
						|
					revision: ss1Rev1,
 | 
						|
				},
 | 
						|
			},
 | 
						|
			err: false,
 | 
						|
		},
 | 
						|
		{
 | 
						|
			name:     "releasing an orphan succeeds",
 | 
						|
			parent:   ss1,
 | 
						|
			revision: ss1Rev2,
 | 
						|
			existing: []struct {
 | 
						|
				parent   metav1.Object
 | 
						|
				revision *apps.ControllerRevision
 | 
						|
			}{
 | 
						|
				{
 | 
						|
					parent:   ss1,
 | 
						|
					revision: ss1Rev2,
 | 
						|
				},
 | 
						|
			},
 | 
						|
			err: false,
 | 
						|
		},
 | 
						|
		{
 | 
						|
			name:     "releasing a revision owned by another controller succeeds",
 | 
						|
			parent:   ss1,
 | 
						|
			revision: ss2Rev1,
 | 
						|
			existing: []struct {
 | 
						|
				parent   metav1.Object
 | 
						|
				revision *apps.ControllerRevision
 | 
						|
			}{
 | 
						|
				{
 | 
						|
					parent:   ss2,
 | 
						|
					revision: ss2Rev1,
 | 
						|
				},
 | 
						|
			},
 | 
						|
			err: false,
 | 
						|
		},
 | 
						|
		{
 | 
						|
			name:     "releasing a non-existent revision succeeds",
 | 
						|
			parent:   ss1,
 | 
						|
			revision: ss1Rev1,
 | 
						|
			existing: nil,
 | 
						|
			err:      false,
 | 
						|
		},
 | 
						|
	}
 | 
						|
	for i := range tests {
 | 
						|
		testFn(&tests[i], t)
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func TestFakeHistory_ReleaseControllerRevision(t *testing.T) {
 | 
						|
	type testcase struct {
 | 
						|
		name     string
 | 
						|
		parent   metav1.Object
 | 
						|
		revision *apps.ControllerRevision
 | 
						|
		existing []struct {
 | 
						|
			parent   metav1.Object
 | 
						|
			revision *apps.ControllerRevision
 | 
						|
		}
 | 
						|
		err bool
 | 
						|
	}
 | 
						|
	testFn := func(test *testcase, t *testing.T) {
 | 
						|
		client := fake.NewSimpleClientset()
 | 
						|
		informerFactory := informers.NewSharedInformerFactory(client, controller.NoResyncPeriodFunc())
 | 
						|
		stop := make(chan struct{})
 | 
						|
		defer close(stop)
 | 
						|
		informerFactory.Start(stop)
 | 
						|
		informer := informerFactory.Apps().V1beta1().ControllerRevisions()
 | 
						|
		informerFactory.WaitForCacheSync(stop)
 | 
						|
		history := NewFakeHistory(informer)
 | 
						|
		for i := range test.existing {
 | 
						|
			_, err := history.CreateControllerRevision(test.existing[i].parent, test.existing[i].revision)
 | 
						|
			if err != nil {
 | 
						|
				t.Fatal(err)
 | 
						|
			}
 | 
						|
		}
 | 
						|
		adopted, err := history.ReleaseControllerRevision(test.parent, test.revision)
 | 
						|
		if !test.err {
 | 
						|
			if err != nil {
 | 
						|
				t.Errorf("%s: %s", test.name, err)
 | 
						|
			}
 | 
						|
			if adopted == nil {
 | 
						|
				return
 | 
						|
			}
 | 
						|
			if metav1.IsControlledBy(adopted, test.parent) {
 | 
						|
				t.Errorf("%s: release failed", test.name)
 | 
						|
			}
 | 
						|
		}
 | 
						|
		if test.err && err == nil {
 | 
						|
			t.Errorf("%s: expected error", test.name)
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	ss1 := newStatefulSet(3, "ss1", types.UID("ss1"), map[string]string{"foo": "bar"})
 | 
						|
	ss2 := newStatefulSet(3, "ss2", types.UID("ss2"), map[string]string{"goo": "car"})
 | 
						|
	sel1, err := metav1.LabelSelectorAsSelector(ss1.Spec.Selector)
 | 
						|
	if err != nil {
 | 
						|
		t.Fatal(err)
 | 
						|
	}
 | 
						|
	sel2, err := metav1.LabelSelectorAsSelector(ss2.Spec.Selector)
 | 
						|
	if err != nil {
 | 
						|
		t.Fatal(err)
 | 
						|
	}
 | 
						|
	ss1Rev1, err := NewControllerRevision(ss1, parentKind, sel1, rawTemplate(&ss1.Spec.Template), 1)
 | 
						|
	if err != nil {
 | 
						|
		t.Fatal(err)
 | 
						|
	}
 | 
						|
	ss1Rev1.Namespace = ss1.Namespace
 | 
						|
	ss1Rev2, err := NewControllerRevision(ss1, parentKind, sel1, rawTemplate(&ss1.Spec.Template), 2)
 | 
						|
	if err != nil {
 | 
						|
		t.Fatal(err)
 | 
						|
	}
 | 
						|
	ss1Rev2.Namespace = ss1.Namespace
 | 
						|
	ss1Rev2.OwnerReferences = []metav1.OwnerReference{}
 | 
						|
	ss2Rev1, err := NewControllerRevision(ss2, parentKind, sel2, rawTemplate(&ss2.Spec.Template), 1)
 | 
						|
	if err != nil {
 | 
						|
		t.Fatal(err)
 | 
						|
	}
 | 
						|
	ss2Rev1.Namespace = ss2.Namespace
 | 
						|
	tests := []testcase{
 | 
						|
		{
 | 
						|
			name:     "releasing an owned revision succeeds",
 | 
						|
			parent:   ss1,
 | 
						|
			revision: ss1Rev1,
 | 
						|
			existing: []struct {
 | 
						|
				parent   metav1.Object
 | 
						|
				revision *apps.ControllerRevision
 | 
						|
			}{
 | 
						|
				{
 | 
						|
					parent:   ss1,
 | 
						|
					revision: ss1Rev1,
 | 
						|
				},
 | 
						|
			},
 | 
						|
			err: false,
 | 
						|
		},
 | 
						|
		{
 | 
						|
			name:     "releasing an orphan succeeds",
 | 
						|
			parent:   ss1,
 | 
						|
			revision: ss1Rev2,
 | 
						|
			existing: []struct {
 | 
						|
				parent   metav1.Object
 | 
						|
				revision *apps.ControllerRevision
 | 
						|
			}{
 | 
						|
				{
 | 
						|
					parent:   ss1,
 | 
						|
					revision: ss1Rev2,
 | 
						|
				},
 | 
						|
			},
 | 
						|
			err: false,
 | 
						|
		},
 | 
						|
		{
 | 
						|
			name:     "releasing a revision owned by another controller succeeds",
 | 
						|
			parent:   ss1,
 | 
						|
			revision: ss2Rev1,
 | 
						|
			existing: []struct {
 | 
						|
				parent   metav1.Object
 | 
						|
				revision *apps.ControllerRevision
 | 
						|
			}{
 | 
						|
				{
 | 
						|
					parent:   ss2,
 | 
						|
					revision: ss2Rev1,
 | 
						|
				},
 | 
						|
			},
 | 
						|
			err: false,
 | 
						|
		},
 | 
						|
		{
 | 
						|
			name:     "releasing a non-existent revision succeeds",
 | 
						|
			parent:   ss1,
 | 
						|
			revision: ss1Rev1,
 | 
						|
			existing: nil,
 | 
						|
			err:      false,
 | 
						|
		},
 | 
						|
	}
 | 
						|
	for i := range tests {
 | 
						|
		testFn(&tests[i], t)
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func TestFindEqualRevisions(t *testing.T) {
 | 
						|
	type testcase struct {
 | 
						|
		name      string
 | 
						|
		revision  *apps.ControllerRevision
 | 
						|
		revisions []*apps.ControllerRevision
 | 
						|
		want      map[string]bool
 | 
						|
	}
 | 
						|
	testFn := func(test *testcase, t *testing.T) {
 | 
						|
		found := FindEqualRevisions(test.revisions, test.revision)
 | 
						|
		if len(found) != len(test.want) {
 | 
						|
			t.Errorf("%s: want %d revisions found %d", test.name, len(test.want), len(found))
 | 
						|
		}
 | 
						|
		for i := range found {
 | 
						|
			if !test.want[found[i].Name] {
 | 
						|
				t.Errorf("%s: wanted %s not found", test.name, found[i].Name)
 | 
						|
			}
 | 
						|
 | 
						|
		}
 | 
						|
	}
 | 
						|
	ss1 := newStatefulSet(3, "ss1", types.UID("ss1"), map[string]string{"foo": "bar"})
 | 
						|
	ss2 := newStatefulSet(3, "ss2", types.UID("ss2"), map[string]string{"goo": "car"})
 | 
						|
	sel1, err := metav1.LabelSelectorAsSelector(ss1.Spec.Selector)
 | 
						|
	if err != nil {
 | 
						|
		t.Fatal(err)
 | 
						|
	}
 | 
						|
	sel2, err := metav1.LabelSelectorAsSelector(ss2.Spec.Selector)
 | 
						|
	if err != nil {
 | 
						|
		t.Fatal(err)
 | 
						|
	}
 | 
						|
	ss1Rev1, err := NewControllerRevision(ss1, parentKind, sel1, rawTemplate(&ss1.Spec.Template), 1)
 | 
						|
	if err != nil {
 | 
						|
		t.Fatal(err)
 | 
						|
	}
 | 
						|
	ss1Rev1.Namespace = ss1.Namespace
 | 
						|
	ss1Rev2, err := NewControllerRevision(ss1, parentKind, sel1, rawTemplate(&ss1.Spec.Template), 2)
 | 
						|
	if err != nil {
 | 
						|
		t.Fatal(err)
 | 
						|
	}
 | 
						|
	ss1Rev2.Namespace = ss1.Namespace
 | 
						|
	ss1Rev2.OwnerReferences = []metav1.OwnerReference{}
 | 
						|
	ss2Rev1, err := NewControllerRevision(ss2, parentKind, sel2, rawTemplate(&ss2.Spec.Template), 1)
 | 
						|
	if err != nil {
 | 
						|
		t.Fatal(err)
 | 
						|
	}
 | 
						|
	ss2Rev1.Namespace = ss2.Namespace
 | 
						|
	ss2Rev2, err := NewControllerRevision(ss2, parentKind, sel2, rawTemplate(&ss2.Spec.Template), 2)
 | 
						|
	if err != nil {
 | 
						|
		t.Fatal(err)
 | 
						|
	}
 | 
						|
	ss2Rev2.Namespace = ss2.Namespace
 | 
						|
	tests := []testcase{
 | 
						|
		{
 | 
						|
			name:      "finds equivalent",
 | 
						|
			revision:  ss1Rev1,
 | 
						|
			revisions: []*apps.ControllerRevision{ss1Rev1, ss2Rev1, ss2Rev2},
 | 
						|
			want:      map[string]bool{ss1Rev1.Name: true},
 | 
						|
		},
 | 
						|
		{
 | 
						|
			name:      "finds nothing when empty",
 | 
						|
			revision:  ss1Rev1,
 | 
						|
			revisions: nil,
 | 
						|
			want:      map[string]bool{},
 | 
						|
		},
 | 
						|
		{
 | 
						|
			name:      "finds nothing with no matches",
 | 
						|
			revision:  ss1Rev1,
 | 
						|
			revisions: []*apps.ControllerRevision{ss2Rev2, ss2Rev1},
 | 
						|
			want:      map[string]bool{},
 | 
						|
		},
 | 
						|
	}
 | 
						|
	for i := range tests {
 | 
						|
		testFn(&tests[i], t)
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func TestSortControllerRevisions(t *testing.T) {
 | 
						|
	type testcase struct {
 | 
						|
		name      string
 | 
						|
		revisions []*apps.ControllerRevision
 | 
						|
		want      []string
 | 
						|
	}
 | 
						|
	testFn := func(test *testcase, t *testing.T) {
 | 
						|
		SortControllerRevisions(test.revisions)
 | 
						|
		for i := range test.revisions {
 | 
						|
			if test.revisions[i].Name != test.want[i] {
 | 
						|
				t.Errorf("%s: want %s at %d got %s", test.name, test.want[i], i, test.revisions[i].Name)
 | 
						|
			}
 | 
						|
		}
 | 
						|
	}
 | 
						|
	ss1 := newStatefulSet(3, "ss1", types.UID("ss1"), map[string]string{"foo": "bar"})
 | 
						|
	sel1, err := metav1.LabelSelectorAsSelector(ss1.Spec.Selector)
 | 
						|
	if err != nil {
 | 
						|
		t.Fatal(err)
 | 
						|
	}
 | 
						|
 | 
						|
	ss1Rev1, err := NewControllerRevision(ss1, parentKind, sel1, rawTemplate(&ss1.Spec.Template), 1)
 | 
						|
	if err != nil {
 | 
						|
		t.Fatal(err)
 | 
						|
	}
 | 
						|
	ss1Rev1.Namespace = ss1.Namespace
 | 
						|
	ss1Rev2, err := NewControllerRevision(ss1, parentKind, sel1, rawTemplate(&ss1.Spec.Template), 2)
 | 
						|
	if err != nil {
 | 
						|
		t.Fatal(err)
 | 
						|
	}
 | 
						|
	ss1Rev2.Namespace = ss1.Namespace
 | 
						|
	ss1Rev3, err := NewControllerRevision(ss1, parentKind, sel1, rawTemplate(&ss1.Spec.Template), 2)
 | 
						|
	if err != nil {
 | 
						|
		t.Fatal(err)
 | 
						|
	}
 | 
						|
	ss1Rev3.Namespace = ss1.Namespace
 | 
						|
 | 
						|
	tests := []testcase{
 | 
						|
		{
 | 
						|
			name:      "out of order",
 | 
						|
			revisions: []*apps.ControllerRevision{ss1Rev2, ss1Rev1, ss1Rev3},
 | 
						|
			want:      []string{ss1Rev1.Name, ss1Rev2.Name, ss1Rev3.Name},
 | 
						|
		},
 | 
						|
		{
 | 
						|
			name:      "sorted",
 | 
						|
			revisions: []*apps.ControllerRevision{ss1Rev1, ss1Rev2, ss1Rev3},
 | 
						|
			want:      []string{ss1Rev1.Name, ss1Rev2.Name, ss1Rev3.Name},
 | 
						|
		},
 | 
						|
		{
 | 
						|
			name:      "reversed",
 | 
						|
			revisions: []*apps.ControllerRevision{ss1Rev3, ss1Rev2, ss1Rev1},
 | 
						|
			want:      []string{ss1Rev1.Name, ss1Rev2.Name, ss1Rev3.Name},
 | 
						|
		},
 | 
						|
		{
 | 
						|
			name:      "empty",
 | 
						|
			revisions: nil,
 | 
						|
			want:      nil,
 | 
						|
		},
 | 
						|
	}
 | 
						|
	for i := range tests {
 | 
						|
		testFn(&tests[i], t)
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func newStatefulSet(replicas int, name string, uid types.UID, labels map[string]string) *apps.StatefulSet {
 | 
						|
	return &apps.StatefulSet{
 | 
						|
		TypeMeta: metav1.TypeMeta{
 | 
						|
			Kind:       "StatefulSet",
 | 
						|
			APIVersion: "apps/v1beta1",
 | 
						|
		},
 | 
						|
		ObjectMeta: metav1.ObjectMeta{
 | 
						|
			Name:      name,
 | 
						|
			Namespace: v1.NamespaceDefault,
 | 
						|
			UID:       uid,
 | 
						|
		},
 | 
						|
		Spec: apps.StatefulSetSpec{
 | 
						|
			Selector: &metav1.LabelSelector{
 | 
						|
				MatchLabels: labels,
 | 
						|
			},
 | 
						|
			Replicas: func() *int32 { i := int32(replicas); return &i }(),
 | 
						|
			Template: v1.PodTemplateSpec{
 | 
						|
				ObjectMeta: metav1.ObjectMeta{
 | 
						|
					Labels: labels,
 | 
						|
				},
 | 
						|
				Spec: v1.PodSpec{
 | 
						|
					Containers: []v1.Container{
 | 
						|
						{
 | 
						|
							Name:  "nginx",
 | 
						|
							Image: "nginx",
 | 
						|
							VolumeMounts: []v1.VolumeMount{
 | 
						|
								{Name: "datadir", MountPath: "/tmp/"},
 | 
						|
								{Name: "home", MountPath: "/home"},
 | 
						|
							},
 | 
						|
						},
 | 
						|
					},
 | 
						|
					Volumes: []v1.Volume{{
 | 
						|
						Name: "home",
 | 
						|
						VolumeSource: v1.VolumeSource{
 | 
						|
							HostPath: &v1.HostPathVolumeSource{
 | 
						|
								Path: fmt.Sprintf("/tmp/%v", "home"),
 | 
						|
							},
 | 
						|
						}}},
 | 
						|
				},
 | 
						|
			},
 | 
						|
			VolumeClaimTemplates: []v1.PersistentVolumeClaim{
 | 
						|
				{
 | 
						|
					ObjectMeta: metav1.ObjectMeta{Name: "datadir"},
 | 
						|
					Spec: v1.PersistentVolumeClaimSpec{
 | 
						|
						Resources: v1.ResourceRequirements{
 | 
						|
							Requests: v1.ResourceList{
 | 
						|
								v1.ResourceStorage: *resource.NewQuantity(1, resource.BinarySI),
 | 
						|
							},
 | 
						|
						},
 | 
						|
					},
 | 
						|
				},
 | 
						|
			},
 | 
						|
			ServiceName: "governingsvc",
 | 
						|
		},
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
var parentKind = apps.SchemeGroupVersion.WithKind("StatefulSet")
 | 
						|
 | 
						|
func rawTemplate(template *v1.PodTemplateSpec) runtime.RawExtension {
 | 
						|
	buf := new(bytes.Buffer)
 | 
						|
	enc := json.NewEncoder(buf)
 | 
						|
	if err := enc.Encode(template); err != nil {
 | 
						|
		panic(err)
 | 
						|
	}
 | 
						|
	return runtime.RawExtension{Raw: buf.Bytes()}
 | 
						|
}
 |