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 }