Add integration test
This commit is contained in:
		| @@ -39,9 +39,14 @@ import ( | |||||||
| 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||||||
| 	"k8s.io/apimachinery/pkg/runtime" | 	"k8s.io/apimachinery/pkg/runtime" | ||||||
| 	"k8s.io/apimachinery/pkg/types" | 	"k8s.io/apimachinery/pkg/types" | ||||||
|  | 	"k8s.io/apimachinery/pkg/util/intstr" | ||||||
| 	"k8s.io/apimachinery/pkg/util/wait" | 	"k8s.io/apimachinery/pkg/util/wait" | ||||||
| 	yamlutil "k8s.io/apimachinery/pkg/util/yaml" | 	yamlutil "k8s.io/apimachinery/pkg/util/yaml" | ||||||
|  | 	appsv1ac "k8s.io/client-go/applyconfigurations/apps/v1" | ||||||
|  | 	corev1ac "k8s.io/client-go/applyconfigurations/core/v1" | ||||||
|  | 	metav1ac "k8s.io/client-go/applyconfigurations/meta/v1" | ||||||
| 	clientset "k8s.io/client-go/kubernetes" | 	clientset "k8s.io/client-go/kubernetes" | ||||||
|  | 	"k8s.io/client-go/kubernetes/fake" | ||||||
| 	restclient "k8s.io/client-go/rest" | 	restclient "k8s.io/client-go/rest" | ||||||
| 	kubeapiservertesting "k8s.io/kubernetes/cmd/kube-apiserver/app/testing" | 	kubeapiservertesting "k8s.io/kubernetes/cmd/kube-apiserver/app/testing" | ||||||
| 	"k8s.io/kubernetes/test/integration/framework" | 	"k8s.io/kubernetes/test/integration/framework" | ||||||
| @@ -4421,6 +4426,109 @@ spec: | |||||||
| `) | `) | ||||||
| } | } | ||||||
|  |  | ||||||
|  | func TestApplyMatchesFakeClientsetApply(t *testing.T) { | ||||||
|  | 	client, closeFn := setup(t) | ||||||
|  | 	defer closeFn() | ||||||
|  | 	fakeClient := fake.NewClientset() | ||||||
|  |  | ||||||
|  | 	// The fake client does not default fields, so we set all defaulted fields directly. | ||||||
|  | 	deployment := appsv1ac.Deployment("deployment", "default"). | ||||||
|  | 		WithLabels(map[string]string{"app": "nginx"}). | ||||||
|  | 		WithSpec(appsv1ac.DeploymentSpec(). | ||||||
|  | 			WithReplicas(3). | ||||||
|  | 			WithStrategy(appsv1ac.DeploymentStrategy(). | ||||||
|  | 				WithType(appsv1.RollingUpdateDeploymentStrategyType). | ||||||
|  | 				WithRollingUpdate(appsv1ac.RollingUpdateDeployment(). | ||||||
|  | 					WithMaxUnavailable(intstr.FromString("25%")). | ||||||
|  | 					WithMaxSurge(intstr.FromString("25%")))). | ||||||
|  | 			WithRevisionHistoryLimit(10). | ||||||
|  | 			WithProgressDeadlineSeconds(600). | ||||||
|  | 			WithSelector(metav1ac.LabelSelector(). | ||||||
|  | 				WithMatchLabels(map[string]string{"app": "nginx"})). | ||||||
|  | 			WithTemplate(corev1ac.PodTemplateSpec(). | ||||||
|  | 				WithLabels(map[string]string{"app": "nginx"}). | ||||||
|  | 				WithSpec(corev1ac.PodSpec(). | ||||||
|  | 					WithRestartPolicy(v1.RestartPolicyAlways). | ||||||
|  | 					WithTerminationGracePeriodSeconds(30). | ||||||
|  | 					WithDNSPolicy(v1.DNSClusterFirst). | ||||||
|  | 					WithSecurityContext(corev1ac.PodSecurityContext()). | ||||||
|  | 					WithSchedulerName("default-scheduler"). | ||||||
|  | 					WithContainers(corev1ac.Container(). | ||||||
|  | 						WithName("nginx"). | ||||||
|  | 						WithImage("nginx:latest"). | ||||||
|  | 						WithTerminationMessagePath("/dev/termination-log"). | ||||||
|  | 						WithTerminationMessagePolicy("File"). | ||||||
|  | 						WithImagePullPolicy(v1.PullAlways))))) | ||||||
|  | 	fieldManager := "m-1" | ||||||
|  |  | ||||||
|  | 	realCreated, err := client.AppsV1().Deployments("default").Apply(context.TODO(), deployment, metav1.ApplyOptions{FieldManager: fieldManager}) | ||||||
|  | 	if err != nil { | ||||||
|  | 		t.Fatalf("Failed to create object using Apply patch: %v", err) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	fakeCreated, err := fakeClient.AppsV1().Deployments("default").Apply(context.TODO(), deployment, metav1.ApplyOptions{FieldManager: fieldManager}) | ||||||
|  | 	if err != nil { | ||||||
|  | 		t.Fatalf("Failed to create object using Apply patch: %v", err) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// wipe metadata except name, namespace, labels and managedFields (but wipe timestamps in managedFields) | ||||||
|  | 	realCreated.ObjectMeta = wipeMetadataForFakeClientTests(realCreated.ObjectMeta) | ||||||
|  | 	fakeCreated.ObjectMeta = wipeMetadataForFakeClientTests(fakeCreated.ObjectMeta) | ||||||
|  | 	// wipe status | ||||||
|  | 	realCreated.Status = appsv1.DeploymentStatus{} | ||||||
|  | 	fakeCreated.Status = appsv1.DeploymentStatus{} | ||||||
|  | 	// TODO: Remove once https://github.com/kubernetes/kubernetes/issues/125671 is fixed. | ||||||
|  | 	fakeCreated.TypeMeta = metav1.TypeMeta{} | ||||||
|  |  | ||||||
|  | 	if diff := cmp.Diff(realCreated, fakeCreated); diff != "" { | ||||||
|  | 		t.Errorf("Unexpected fake created: (-want +got): %v", diff) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// Force apply with a different field manager | ||||||
|  | 	deploymentUpdate := appsv1ac.Deployment("deployment", "default"). | ||||||
|  | 		WithSpec(appsv1ac.DeploymentSpec(). | ||||||
|  | 			WithReplicas(4)) | ||||||
|  | 	updateManager := "m-2" | ||||||
|  | 	realUpdated, err := client.AppsV1().Deployments("default").Apply(context.TODO(), deploymentUpdate, metav1.ApplyOptions{FieldManager: updateManager, Force: true}) | ||||||
|  | 	if err != nil { | ||||||
|  | 		t.Fatalf("Failed to create object using Apply patch: %v", err) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	fakeUpdated, err := fakeClient.AppsV1().Deployments("default").Apply(context.TODO(), deploymentUpdate, metav1.ApplyOptions{FieldManager: updateManager, Force: true}) | ||||||
|  | 	if err != nil { | ||||||
|  | 		t.Fatalf("Failed to create object using Apply patch: %v", err) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// wipe metadata except name, namespace, labels and managedFields (but wipe timestamps in managedFields) | ||||||
|  | 	realUpdated.ObjectMeta = wipeMetadataForFakeClientTests(realUpdated.ObjectMeta) | ||||||
|  | 	fakeUpdated.ObjectMeta = wipeMetadataForFakeClientTests(fakeUpdated.ObjectMeta) | ||||||
|  | 	// wipe status | ||||||
|  | 	realUpdated.Status = appsv1.DeploymentStatus{} | ||||||
|  | 	fakeUpdated.Status = appsv1.DeploymentStatus{} | ||||||
|  | 	// TODO: Remove once https://github.com/kubernetes/kubernetes/issues/125671 is fixed. | ||||||
|  | 	fakeUpdated.TypeMeta = metav1.TypeMeta{} | ||||||
|  |  | ||||||
|  | 	if diff := cmp.Diff(realUpdated, fakeUpdated); diff != "" { | ||||||
|  | 		t.Errorf("Unexpected fake updated: (-want +got): %v", diff) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | var wipeTime = metav1.NewTime(time.Date(2000, 1, 1, 0, 0, 0, 0, time.FixedZone("EDT", -4*60*60))) | ||||||
|  |  | ||||||
|  | func wipeMetadataForFakeClientTests(meta metav1.ObjectMeta) metav1.ObjectMeta { | ||||||
|  | 	wipedManagedFields := make([]metav1.ManagedFieldsEntry, len(meta.ManagedFields)) | ||||||
|  | 	copy(meta.ManagedFields, wipedManagedFields) | ||||||
|  | 	for _, mf := range wipedManagedFields { | ||||||
|  | 		mf.Time = &wipeTime | ||||||
|  | 	} | ||||||
|  | 	return metav1.ObjectMeta{ | ||||||
|  | 		Name:          meta.Name, | ||||||
|  | 		Namespace:     meta.Namespace, | ||||||
|  | 		Labels:        meta.Labels, | ||||||
|  | 		ManagedFields: wipedManagedFields, | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
| func expectManagedFields(t *testing.T, managedFields []metav1.ManagedFieldsEntry, expect string) { | func expectManagedFields(t *testing.T, managedFields []metav1.ManagedFieldsEntry, expect string) { | ||||||
| 	t.Helper() | 	t.Helper() | ||||||
| 	for i := range managedFields { | 	for i := range managedFields { | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Joe Betz
					Joe Betz