github.com/operator-framework/operator-lifecycle-manager@v0.30.0/pkg/lib/controller-runtime/client/ssa_test.go (about)

     1  package client
     2  
     3  import (
     4  	"context"
     5  	"strings"
     6  	"testing"
     7  
     8  	"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
     9  
    10  	"github.com/operator-framework/operator-lifecycle-manager/pkg/lib/testobj"
    11  	"github.com/stretchr/testify/require"
    12  	corev1 "k8s.io/api/core/v1"
    13  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    14  	"k8s.io/apimachinery/pkg/runtime"
    15  	"k8s.io/apimachinery/pkg/runtime/schema"
    16  )
    17  
    18  func TestSetDefaultGroupVersionKind(t *testing.T) {
    19  	tests := []struct {
    20  		name          string
    21  		schemebuilder runtime.SchemeBuilder
    22  		obj           Object
    23  		want          schema.GroupVersionKind
    24  	}{
    25  		{
    26  			name:          "DefaultGVK",
    27  			schemebuilder: corev1.SchemeBuilder,
    28  			obj:           &corev1.ServiceAccount{},
    29  			want: schema.GroupVersionKind{
    30  				Group:   "",
    31  				Version: "v1",
    32  				Kind:    "ServiceAccount",
    33  			},
    34  		},
    35  	}
    36  	for _, tt := range tests {
    37  		t.Run(tt.name, func(t *testing.T) {
    38  			s := runtime.NewScheme()
    39  			err := tt.schemebuilder.AddToScheme(s)
    40  			require.NoError(t, err)
    41  
    42  			SetDefaultGroupVersionKind(tt.obj, s)
    43  			require.EqualValues(t, tt.want, tt.obj.GetObjectKind().GroupVersionKind())
    44  		})
    45  	}
    46  }
    47  
    48  // fake client doesn't support Server Side Apply
    49  func applyError(err error) bool {
    50  	if err == nil {
    51  		return false
    52  	}
    53  	return strings.Contains(err.Error(), "/issues/115598")
    54  }
    55  
    56  func TestServerSideApply(t *testing.T) {
    57  	tests := []struct {
    58  		name          string
    59  		obj           Object
    60  		schemebuilder *runtime.SchemeBuilder
    61  		changeFunc    interface{}
    62  		want          Object
    63  	}{
    64  		{
    65  			name: "ServerSideMetadataApply",
    66  			obj: &corev1.Pod{
    67  				ObjectMeta: metav1.ObjectMeta{
    68  					Name:      "testpod",
    69  					Namespace: "testns",
    70  					Labels: map[string]string{
    71  						"testlabel": "oldvalue",
    72  					},
    73  				},
    74  			},
    75  			schemebuilder: &corev1.SchemeBuilder,
    76  			changeFunc: func(p *corev1.Pod) error {
    77  				p.Labels["testlabel"] = "newvalue"
    78  				return nil
    79  			},
    80  			want: &corev1.Pod{
    81  				TypeMeta: metav1.TypeMeta{
    82  					Kind:       "Pod",
    83  					APIVersion: "v1",
    84  				},
    85  				ObjectMeta: metav1.ObjectMeta{
    86  					Name:      "testpod",
    87  					Namespace: "testns",
    88  					Labels: map[string]string{
    89  						"testlabel": "newvalue",
    90  					},
    91  				},
    92  			},
    93  		},
    94  		{
    95  			name: "ServerSideStatusApply",
    96  			obj: &corev1.Pod{
    97  				ObjectMeta: metav1.ObjectMeta{
    98  					Name:      "testpod",
    99  					Namespace: "testns",
   100  				},
   101  				Status: corev1.PodStatus{Message: "new"},
   102  			},
   103  			schemebuilder: &corev1.SchemeBuilder,
   104  			changeFunc: func(p *corev1.Pod) error {
   105  				p.Status.Message = "new"
   106  				return nil
   107  			},
   108  			want: &corev1.Pod{
   109  				TypeMeta: metav1.TypeMeta{
   110  					Kind:       "Pod",
   111  					APIVersion: "v1",
   112  				},
   113  				ObjectMeta: metav1.ObjectMeta{
   114  					Name:      "testpod",
   115  					Namespace: "testns",
   116  				},
   117  				Status: corev1.PodStatus{Message: "new"},
   118  			},
   119  		},
   120  		{
   121  			name: "ServerSideUnstructuredApply",
   122  			obj: &unstructured.Unstructured{
   123  				Object: map[string]interface{}{
   124  					"kind":       "Pod",
   125  					"apiVersion": "v1",
   126  					"metadata": map[string]interface{}{
   127  						"name":      "testpod",
   128  						"namespace": "testns",
   129  					},
   130  					"status": map[string]interface{}{
   131  						"message": "old",
   132  					},
   133  				},
   134  			},
   135  			schemebuilder: &corev1.SchemeBuilder,
   136  			changeFunc: func(u *unstructured.Unstructured) error {
   137  				return unstructured.SetNestedField(u.Object, "new", "status", "message")
   138  			},
   139  			want: &corev1.Pod{
   140  				TypeMeta: metav1.TypeMeta{
   141  					Kind:       "Pod",
   142  					APIVersion: "v1",
   143  				},
   144  				ObjectMeta: metav1.ObjectMeta{
   145  					Name:      "testpod",
   146  					Namespace: "testns",
   147  				},
   148  				Status: corev1.PodStatus{Message: "new"},
   149  			},
   150  		},
   151  	}
   152  	for _, tt := range tests {
   153  		t.Run(tt.name, func(t *testing.T) {
   154  			s := runtime.NewScheme()
   155  			require.NoError(t, tt.schemebuilder.AddToScheme(s))
   156  
   157  			applier := NewFakeApplier(s, "testowner", tt.obj)
   158  			err := applier.Apply(context.TODO(), tt.obj, tt.changeFunc)()
   159  			if applyError(err) {
   160  				return
   161  			}
   162  			require.NoError(t, err)
   163  
   164  			newObj := corev1.Pod{}
   165  			require.NoError(t, applier.client.Get(context.TODO(), testobj.NamespacedName(tt.obj), &newObj))
   166  
   167  			newObj.ResourceVersion = ""
   168  			require.EqualValues(t, tt.want, &newObj)
   169  		})
   170  	}
   171  }