github.com/wmuizelaar/kpt@v0.0.0-20221018115725-bd564717b2ed/pkg/live/inventoryrg_test.go (about)

     1  // Copyright 2020 Google LLC
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //      http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package live
    16  
    17  import (
    18  	"testing"
    19  
    20  	"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
    21  	"k8s.io/apimachinery/pkg/runtime/schema"
    22  	"sigs.k8s.io/cli-utils/pkg/apis/actuation"
    23  	"sigs.k8s.io/cli-utils/pkg/common"
    24  	"sigs.k8s.io/cli-utils/pkg/inventory"
    25  	"sigs.k8s.io/cli-utils/pkg/object"
    26  )
    27  
    28  var testNamespace = "test-inventory-namespace"
    29  var inventoryObjName = "test-inventory-obj"
    30  var testInventoryLabel = "test-inventory-label"
    31  
    32  var inventoryObj = &unstructured.Unstructured{
    33  	Object: map[string]interface{}{
    34  		"apiVersion": "kpt.dev/v1alpha1",
    35  		"kind":       "ResourceGroup",
    36  		"metadata": map[string]interface{}{
    37  			"name":      inventoryObjName,
    38  			"namespace": testNamespace,
    39  			"labels": map[string]interface{}{
    40  				common.InventoryLabel: testInventoryLabel,
    41  			},
    42  		},
    43  		"spec": map[string]interface{}{
    44  			"resources": []interface{}{},
    45  		},
    46  	},
    47  }
    48  
    49  var testDeployment = object.ObjMetadata{
    50  	Namespace: testNamespace,
    51  	Name:      "test-deployment",
    52  	GroupKind: schema.GroupKind{
    53  		Group: "apps",
    54  		Kind:  "Deployment",
    55  	},
    56  }
    57  
    58  var testService = object.ObjMetadata{
    59  	Namespace: testNamespace,
    60  	Name:      "test-deployment",
    61  	GroupKind: schema.GroupKind{
    62  		Group: "apps",
    63  		Kind:  "Service",
    64  	},
    65  }
    66  
    67  var testPod = object.ObjMetadata{
    68  	Namespace: testNamespace,
    69  	Name:      "test-pod",
    70  	GroupKind: schema.GroupKind{
    71  		Group: "",
    72  		Kind:  "Pod",
    73  	},
    74  }
    75  
    76  func TestLoadStore(t *testing.T) {
    77  	tests := map[string]struct {
    78  		inv       *unstructured.Unstructured
    79  		objs      []object.ObjMetadata
    80  		objStatus []actuation.ObjectStatus
    81  		isError   bool
    82  	}{
    83  		"Nil inventory is error": {
    84  			inv:     nil,
    85  			objs:    []object.ObjMetadata{},
    86  			isError: true,
    87  		},
    88  		"No inventory objects is valid": {
    89  			inv:     inventoryObj,
    90  			objs:    []object.ObjMetadata{},
    91  			isError: false,
    92  		},
    93  		"Simple test": {
    94  			inv:  inventoryObj,
    95  			objs: []object.ObjMetadata{testPod},
    96  			objStatus: []actuation.ObjectStatus{
    97  				{
    98  					ObjectReference: inventory.ObjectReferenceFromObjMetadata(testPod),
    99  					Strategy:        actuation.ActuationStrategyApply,
   100  					Actuation:       actuation.ActuationPending,
   101  					Reconcile:       actuation.ReconcilePending,
   102  				},
   103  			},
   104  			isError: false,
   105  		},
   106  		"Test two objects": {
   107  			inv:  inventoryObj,
   108  			objs: []object.ObjMetadata{testDeployment, testService},
   109  			objStatus: []actuation.ObjectStatus{
   110  				{
   111  					ObjectReference: inventory.ObjectReferenceFromObjMetadata(testDeployment),
   112  					Strategy:        actuation.ActuationStrategyApply,
   113  					Actuation:       actuation.ActuationSucceeded,
   114  					Reconcile:       actuation.ReconcileSucceeded,
   115  				},
   116  				{
   117  					ObjectReference: inventory.ObjectReferenceFromObjMetadata(testService),
   118  					Strategy:        actuation.ActuationStrategyApply,
   119  					Actuation:       actuation.ActuationSucceeded,
   120  					Reconcile:       actuation.ReconcileSucceeded,
   121  				},
   122  			},
   123  			isError: false,
   124  		},
   125  		"Test three objects": {
   126  			inv:  inventoryObj,
   127  			objs: []object.ObjMetadata{testDeployment, testService, testPod},
   128  			objStatus: []actuation.ObjectStatus{
   129  				{
   130  					ObjectReference: inventory.ObjectReferenceFromObjMetadata(testDeployment),
   131  					Strategy:        actuation.ActuationStrategyApply,
   132  					Actuation:       actuation.ActuationSucceeded,
   133  					Reconcile:       actuation.ReconcileSucceeded,
   134  				},
   135  				{
   136  					ObjectReference: inventory.ObjectReferenceFromObjMetadata(testService),
   137  					Strategy:        actuation.ActuationStrategyApply,
   138  					Actuation:       actuation.ActuationSucceeded,
   139  					Reconcile:       actuation.ReconcileSucceeded,
   140  				},
   141  				{
   142  					ObjectReference: inventory.ObjectReferenceFromObjMetadata(testPod),
   143  					Strategy:        actuation.ActuationStrategyApply,
   144  					Actuation:       actuation.ActuationPending,
   145  					Reconcile:       actuation.ReconcilePending,
   146  				},
   147  			},
   148  			isError: false,
   149  		},
   150  	}
   151  
   152  	for name, tc := range tests {
   153  		t.Run(name, func(t *testing.T) {
   154  			wrapped := WrapInventoryObj(tc.inv)
   155  			_ = wrapped.Store(tc.objs, tc.objStatus)
   156  			invStored, err := wrapped.GetObject()
   157  			if tc.isError {
   158  				if err == nil {
   159  					t.Fatalf("expected error but received none")
   160  				}
   161  				return
   162  			}
   163  			if !tc.isError && err != nil {
   164  				t.Fatalf("unexpected error %v received", err)
   165  				return
   166  			}
   167  			wrapped = WrapInventoryObj(invStored)
   168  			objs, err := wrapped.Load()
   169  			if !tc.isError && err != nil {
   170  				t.Fatalf("unexpected error %v received", err)
   171  				return
   172  			}
   173  			if !objs.Equal(tc.objs) {
   174  				t.Fatalf("expected inventory objs (%v), got (%v)", tc.objs, objs)
   175  			}
   176  			resourceStatus, _, err := unstructured.NestedSlice(invStored.Object, "status", "resourceStatuses")
   177  			if err != nil {
   178  				t.Fatalf("unexpected error %v received", err)
   179  			}
   180  			if len(resourceStatus) != len(tc.objStatus) {
   181  				t.Fatalf("expected %d resource status but got %d", len(tc.objStatus), len(resourceStatus))
   182  			}
   183  		})
   184  	}
   185  }
   186  
   187  var cmInvObj = &unstructured.Unstructured{
   188  	Object: map[string]interface{}{
   189  		"apiVersion": "v1",
   190  		"kind":       "ConfigMap",
   191  		"metadata": map[string]interface{}{
   192  			"name":      inventoryObjName,
   193  			"namespace": testNamespace,
   194  			"labels": map[string]interface{}{
   195  				common.InventoryLabel: testInventoryLabel,
   196  			},
   197  		},
   198  	},
   199  }
   200  
   201  func TestIsResourceGroupInventory(t *testing.T) {
   202  	tests := map[string]struct {
   203  		invObj   *unstructured.Unstructured
   204  		expected bool
   205  		isError  bool
   206  	}{
   207  		"Nil inventory is error": {
   208  			invObj:   nil,
   209  			expected: false,
   210  			isError:  true,
   211  		},
   212  		"ConfigMap inventory is false": {
   213  			invObj:   cmInvObj,
   214  			expected: false,
   215  			isError:  false,
   216  		},
   217  		"ResourceGroup inventory is false": {
   218  			invObj:   inventoryObj,
   219  			expected: true,
   220  			isError:  false,
   221  		},
   222  	}
   223  
   224  	for name, tc := range tests {
   225  		t.Run(name, func(t *testing.T) {
   226  			actual, err := IsResourceGroupInventory(tc.invObj)
   227  			if tc.isError {
   228  				if err == nil {
   229  					t.Fatalf("expected error but received none")
   230  				}
   231  				return
   232  			}
   233  			if !tc.isError && err != nil {
   234  				t.Fatalf("unexpected error %v received", err)
   235  				return
   236  			}
   237  			if tc.expected != actual {
   238  				t.Errorf("expected inventory as (%t), got (%t)", tc.expected, actual)
   239  			}
   240  		})
   241  	}
   242  }