Skip to content
Permalink
Browse files

Refactor FieldManager tests to make them simpler

This is the first step on this, but there are a few improvements that
I'd like to do here.
  • Loading branch information
apelisse committed Sep 10, 2019
1 parent 7351f1a commit f2dcdc20bf95fe4bad379181fd4095f610d66779
Showing with 80 additions and 83 deletions.
  1. +80 −83 staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/fieldmanager_test.go
@@ -21,7 +21,6 @@ import (
"fmt"
"net/http"
"testing"

"time"

corev1 "k8s.io/api/core/v1"
@@ -54,104 +53,116 @@ type fakeObjectDefaulter struct{}

func (d *fakeObjectDefaulter) Default(in runtime.Object) {}

func NewTestFieldManager() *fieldmanager.FieldManager {
type TestFieldManager struct {
fieldManager *fieldmanager.FieldManager
liveObj runtime.Object
}

func NewTestFieldManager() TestFieldManager {
gv := schema.GroupVersion{
Group: "apps",
Version: "v1",
}

f, _ := fieldmanager.NewCRDFieldManager(
f, err := fieldmanager.NewCRDFieldManager(
nil,
&fakeObjectConvertor{},
&fakeObjectDefaulter{},
gv,
gv,
true,
)
return f
if err != nil {
panic(err)
}
return TestFieldManager{
fieldManager: f,
liveObj: &unstructured.Unstructured{},
}
}

func (f *TestFieldManager) Reset() {
f.liveObj = &unstructured.Unstructured{}
}

func (f *TestFieldManager) Apply(obj []byte, manager string, force bool) error {
var err error
f.liveObj, err = f.fieldManager.Apply(f.liveObj, obj, manager, force)
return err
}

func (f *TestFieldManager) Update(obj runtime.Object, manager string) error {
var err error
f.liveObj, err = f.fieldManager.Update(f.liveObj, obj, manager)
return err
}

func (f *TestFieldManager) CompareObject(obj runtime.Object) error {
return nil
}

func TestFieldManagerCreation(t *testing.T) {
if NewTestFieldManager() == nil {
t.Fatal("failed to create FieldManager")
func (f *TestFieldManager) ManagedFields() []metav1.ManagedFieldsEntry {
accessor, err := meta.Accessor(f.liveObj)
if err != nil {
panic(fmt.Errorf("couldn't get accessor: %v", err))
}

return accessor.GetManagedFields()
}

func TestUpdateOnlyDoesNotTrackManagedFields(t *testing.T) {
f := NewTestFieldManager()

liveObj := &corev1.Pod{}

updatedObj := liveObj.DeepCopy()
updatedObj := &corev1.Pod{}
updatedObj.ObjectMeta.Labels = map[string]string{"k": "v"}

newObj, err := f.Update(liveObj, updatedObj, "fieldmanager_test")
if err != nil {
if err := f.Update(updatedObj, "fieldmanager_test"); err != nil {
t.Fatalf("failed to update object: %v", err)
}

accessor, err := meta.Accessor(newObj)
if err != nil {
t.Fatalf("couldn't get accessor: %v", err)
}

if m := accessor.GetManagedFields(); len(m) != 0 {
if m := f.ManagedFields(); len(m) != 0 {
t.Fatalf("managedFields were tracked on update only: %v", m)
}
}

func TestApplyStripsFields(t *testing.T) {
f := NewTestFieldManager()

obj := &corev1.Pod{}
obj.ObjectMeta.ManagedFields = []metav1.ManagedFieldsEntry{{}}

newObj := &corev1.Pod{
TypeMeta: metav1.TypeMeta{
APIVersion: "apps/v1",
Kind: "Deployment",
},
ObjectMeta: metav1.ObjectMeta{
Name: "b",
Namespace: "b",
CreationTimestamp: metav1.NewTime(time.Now()),
SelfLink: "b",
UID: "b",
ClusterName: "b",
Generation: 0,
ManagedFields: []metav1.ManagedFieldsEntry{
{
Manager: "update",
Operation: metav1.ManagedFieldsOperationApply,
APIVersion: "apps/v1",
},
},
ResourceVersion: "b",
newObj := &unstructured.Unstructured{
Object: map[string]interface{}{
"apiVersion": "apps/v1",
"kind": "Deployment",
},
}

updatedObj, err := f.Update(obj, newObj, "fieldmanager_test")
if err != nil {
newObj.SetName("b")
newObj.SetNamespace("b")
newObj.SetUID("b")
newObj.SetClusterName("b")
newObj.SetGeneration(0)
newObj.SetResourceVersion("b")
newObj.SetCreationTimestamp(metav1.NewTime(time.Now()))
newObj.SetManagedFields([]metav1.ManagedFieldsEntry{
{
Manager: "update",
Operation: metav1.ManagedFieldsOperationApply,
APIVersion: "apps/v1",
},
})
if err := f.Update(newObj, "fieldmanager_test"); err != nil {
t.Fatalf("failed to apply object: %v", err)
}

accessor, err := meta.Accessor(updatedObj)
if err != nil {
t.Fatalf("couldn't get accessor: %v", err)
}

if m := accessor.GetManagedFields(); len(m) != 0 {
t.Fatalf("fields did not get stripped on apply: %v", m)
if m := f.ManagedFields(); len(m) != 0 {
t.Fatalf("fields did not get stripped: %v", m)
}
}

func TestVersionCheck(t *testing.T) {
f := NewTestFieldManager()

obj := &corev1.Pod{}

// patch has 'apiVersion: apps/v1' and live version is apps/v1 -> no errors
_, err := f.Apply(obj, []byte(`{
err := f.Apply([]byte(`{
"apiVersion": "apps/v1",
"kind": "Deployment",
}`), "fieldmanager_test", false)
@@ -160,7 +171,7 @@ func TestVersionCheck(t *testing.T) {
}

// patch has 'apiVersion: apps/v2' but live version is apps/v1 -> error
_, err = f.Apply(obj, []byte(`{
err = f.Apply([]byte(`{
"apiVersion": "apps/v2",
"kind": "Deployment",
}`), "fieldmanager_test", false)
@@ -181,10 +192,7 @@ func TestVersionCheck(t *testing.T) {
func TestApplyDoesNotStripLabels(t *testing.T) {
f := NewTestFieldManager()

obj := &corev1.Pod{}
obj.ObjectMeta.ManagedFields = []metav1.ManagedFieldsEntry{{}}

newObj, err := f.Apply(obj, []byte(`{
err := f.Apply([]byte(`{
"apiVersion": "apps/v1",
"kind": "Pod",
"metadata": {
@@ -197,30 +205,23 @@ func TestApplyDoesNotStripLabels(t *testing.T) {
t.Fatalf("failed to apply object: %v", err)
}

accessor, err := meta.Accessor(newObj)
if err != nil {
t.Fatalf("couldn't get accessor: %v", err)
}

if m := accessor.GetManagedFields(); len(m) != 1 {
if m := f.ManagedFields(); len(m) != 1 {
t.Fatalf("labels shouldn't get stripped on apply: %v", m)
}
}

func BenchmarkApplyNewObject(b *testing.B) {
f := NewTestFieldManager()

obj := &corev1.Pod{}

b.ReportAllocs()
b.ResetTimer()
for n := 0; n < b.N; n++ {
_, err := f.Apply(obj, []byte(`{
err := f.Apply([]byte(`{
"apiVersion": "apps/v1",
"kind": "Pod",
"metadata": {
"name": "b",
"namespace": "b",
"namespace": "b"
"creationTimestamp": "2016-05-19T09:59:00Z",
},
"map": {
@@ -253,13 +254,13 @@ func BenchmarkApplyNewObject(b *testing.B) {
if err != nil {
b.Fatal(err)
}
f.Reset()
}
}

func BenchmarkUpdateNewObject(b *testing.B) {
f := NewTestFieldManager()

oldObj := &corev1.Pod{}
y := `{
"apiVersion": "apps/v1",
"kind": "Deployment",
@@ -304,18 +305,17 @@ func BenchmarkUpdateNewObject(b *testing.B) {
b.ReportAllocs()
b.ResetTimer()
for n := 0; n < b.N; n++ {
_, err := f.Update(oldObj, newObj, "fieldmanager_test")
err := f.Update(newObj, "fieldmanager_test")
if err != nil {
b.Fatal(err)
}
f.Reset()
}
}

func BenchmarkRepeatedUpdate(b *testing.B) {
f := NewTestFieldManager()

var oldObj runtime.Object
oldObj = &unstructured.Unstructured{Object: map[string]interface{}{}}
y1 := `{
"apiVersion": "apps/v1",
"kind": "Deployment",
@@ -444,36 +444,33 @@ func BenchmarkRepeatedUpdate(b *testing.B) {

objs := []*unstructured.Unstructured{obj1, obj2, obj3}

var err error
oldObj, err = f.Update(oldObj, objs[0], "fieldmanager_0")
if err != nil {
if err := f.Update(objs[0], "fieldmanager_0"); err != nil {
b.Fatal(err)
}

oldObj, err = f.Update(oldObj, objs[1], "fieldmanager_1")
if err != nil {
if err := f.Update(objs[1], "fieldmanager_1"); err != nil {
b.Fatal(err)
}

oldObj, err = f.Update(oldObj, objs[2], "fieldmanager_2")
if err != nil {
if err := f.Update(objs[2], "fieldmanager_2"); err != nil {
b.Fatal(err)
}

b.ReportAllocs()
b.ResetTimer()
for n := 0; n < b.N; n++ {
oldObj, err = f.Update(oldObj, objs[n%3], fmt.Sprintf("fieldmanager_%d", n%3))
err := f.Update(objs[n%3], fmt.Sprintf("fieldmanager_%d", n%3))
if err != nil {
b.Fatal(err)
}
f.Reset()
}
}

func TestApplyFailsWithManagedFields(t *testing.T) {
f := NewTestFieldManager()

_, err := f.Apply(&corev1.Pod{}, []byte(`{
err := f.Apply([]byte(`{
"apiVersion": "apps/v1",
"kind": "Pod",
"metadata": {
@@ -493,7 +490,7 @@ func TestApplyFailsWithManagedFields(t *testing.T) {
func TestApplySuccessWithNoManagedFields(t *testing.T) {
f := NewTestFieldManager()

_, err := f.Apply(&corev1.Pod{}, []byte(`{
err := f.Apply([]byte(`{
"apiVersion": "apps/v1",
"kind": "Pod",
"metadata": {

0 comments on commit f2dcdc2

Please sign in to comment.
You can’t perform that action at this time.