github.com/interconnectedcloud/qdr-operator@v0.0.0-20210826174505-576d2b33dac7/test/e2e/spec_address.go (about) 1 package e2e 2 3 import ( 4 "context" 5 "github.com/interconnectedcloud/qdr-operator/pkg/apis/interconnectedcloud/v1alpha1" 6 "github.com/interconnectedcloud/qdr-operator/test/e2e/framework" 7 "github.com/interconnectedcloud/qdr-operator/test/e2e/framework/qdrmanagement" 8 "github.com/interconnectedcloud/qdr-operator/test/e2e/framework/qdrmanagement/entities" 9 "github.com/interconnectedcloud/qdr-operator/test/e2e/validation" 10 "github.com/onsi/ginkgo" 11 "github.com/onsi/gomega" 12 v1 "k8s.io/api/core/v1" 13 ) 14 15 var _ = ginkgo.Describe("[spec_address] Address manipulation tests", func() { 16 var ( 17 icName = "address" 18 size = 3 19 newAddressesMap = map[string]map[string]interface{}{ 20 "multicastprefix": { 21 "Prefix": "multicastprefix", 22 "Distribution": entities.DistributionMulticast, 23 }, 24 "multicastpattern/*": { 25 "Pattern": "multicastpattern/*", 26 "Distribution": entities.DistributionMulticast, 27 }, 28 "waypoint": { 29 "Prefix": "waypoint", 30 "Distribution": entities.DistributionBalanced, 31 "Waypoint": true, 32 }, 33 "fallback": { 34 "Prefix": "fallback", 35 "Distribution": entities.DistributionBalanced, 36 "Waypoint": true, 37 "EnableFallback": true, 38 }, 39 "priority": { 40 "Prefix": "priority", 41 "Priority": 5, 42 }, 43 "ingressegress": { 44 "Prefix": "ingressegress", 45 "IngressPhase": 5, 46 "EgressPhase": 6, 47 }, 48 } 49 modifiedAddressesMap = map[string]map[string]interface{}{ 50 "modified/multicastprefix": { 51 "Prefix": "modified/multicastprefix", 52 "Distribution": entities.DistributionMulticast, 53 "Priority": 4, 54 }, 55 "modified/multicastpattern/*": { 56 "Pattern": "modified/multicastpattern/*", 57 "Distribution": entities.DistributionMulticast, 58 "Priority": 4, 59 }, 60 "modified/waypoint": { 61 "Prefix": "modified/waypoint", 62 "Distribution": entities.DistributionBalanced, 63 "Waypoint": true, 64 "Priority": 4, 65 }, 66 "modified/fallback": { 67 "Prefix": "modified/fallback", 68 "Distribution": entities.DistributionBalanced, 69 "Waypoint": true, 70 "EnableFallback": true, 71 "Priority": 4, 72 }, 73 "modified/priority": { 74 "Prefix": "modified/priority", 75 "Priority": 4, 76 }, 77 "modified/ingressegress": { 78 "Prefix": "modified/ingressegress", 79 "IngressPhase": 5, 80 "EgressPhase": 6, 81 "Priority": 4, 82 }, 83 } 84 afterRemovalAddressesMap = map[string]map[string]interface{}{ 85 "multicastprefix": { 86 "Prefix": "multicastprefix", 87 "Distribution": entities.DistributionMulticast, 88 }, 89 "multicastpattern/*": { 90 "Pattern": "multicastpattern/*", 91 "Distribution": entities.DistributionMulticast, 92 }, 93 "waypoint": { 94 "Prefix": "waypoint", 95 "Distribution": entities.DistributionBalanced, 96 "Waypoint": true, 97 }, 98 } 99 ) 100 101 // Create the framework instance 102 f := framework.NewFramework(icName, nil) 103 104 ginkgo.It("Should be able to define addresses", func() { 105 // Deploy and validate deployment 106 ic, err := f.CreateInterconnect(f.Namespace, int32(size), func(ic *v1alpha1.Interconnect) { 107 ic.Spec.Addresses = getSpecAddresses() 108 }) 109 gomega.Expect(err).NotTo(gomega.HaveOccurred()) 110 gomega.Expect(ic).NotTo(gomega.BeNil()) 111 112 // Wait till interconnect instance is ready 113 err = framework.WaitForDeployment(f.KubeClient, f.Namespace, ic.Name, size, framework.RetryInterval, framework.Timeout) 114 gomega.Expect(err).NotTo(gomega.HaveOccurred()) 115 116 // Validating addresses 117 validateAddresses(f, ic, newAddressesMap) 118 }) 119 120 ginkgo.It("Should be able to modify defined addresses", func() { 121 // Deploy and validate deployment 122 ginkgo.By("Deploying an Interconnect using pre-defined address list") 123 ic, err := f.CreateInterconnect(f.Namespace, int32(size), func(ic *v1alpha1.Interconnect) { 124 ic.Spec.Addresses = getSpecAddresses() 125 }) 126 gomega.Expect(err).NotTo(gomega.HaveOccurred()) 127 gomega.Expect(ic).NotTo(gomega.BeNil()) 128 129 // Wait till interconnect instance is ready 130 err = framework.WaitForDeployment(f.KubeClient, f.Namespace, ic.Name, size, framework.RetryInterval, framework.Timeout) 131 gomega.Expect(ic).NotTo(gomega.BeNil()) 132 133 // Get the Interconnect instance 134 ic, err = f.GetInterconnect(ic.Name) 135 gomega.Expect(err).NotTo(gomega.HaveOccurred()) 136 137 // Get pods 138 pods, err := f.GetInterconnectPodNames(ic) 139 gomega.Expect(int32(len(pods))).To(gomega.Equal(ic.Spec.DeploymentPlan.Size)) 140 141 // Modify Prefix/Pattern and Priority of all addresses 142 newAddresses := []v1alpha1.Address{} 143 for _, addr := range ic.Spec.Addresses { 144 if addr.Pattern != "" { 145 addr.Pattern = "modified/" + addr.Pattern 146 } else { 147 addr.Prefix = "modified/" + addr.Prefix 148 } 149 priority := int32(4) 150 addr.Priority = &priority 151 newAddresses = append(newAddresses, addr) 152 } 153 ic.Spec.Addresses = newAddresses 154 155 // Updating Interconnect resource 156 ginkgo.By("Modifying addresses and updating Interconnect instance") 157 ic, err = f.UpdateInterconnect(ic) 158 gomega.Expect(err).NotTo(gomega.HaveOccurred()) 159 160 // Waiting for new pods 161 ctx, fn := context.WithTimeout(context.Background(), framework.Timeout) 162 defer fn() 163 err = f.WaitForNewInterconnectPods(ctx, pods, ic, framework.RetryInterval, framework.Timeout) 164 gomega.Expect(err).NotTo(gomega.HaveOccurred()) 165 166 // Wait till interconnect instance is ready 167 ic, err = f.GetInterconnect(ic.Name) 168 gomega.Expect(err).NotTo(gomega.HaveOccurred()) 169 170 // Waiting for deployment to be ready 171 err = framework.WaitForDeployment(f.KubeClient, f.Namespace, ic.Name, size, framework.RetryInterval, framework.Timeout) 172 gomega.Expect(err).NotTo(gomega.HaveOccurred()) 173 174 // Validating addresses 175 ginkgo.By("Asserting that addresses have been updated accordingly") 176 validateAddresses(f, ic, modifiedAddressesMap) 177 }) 178 179 ginkgo.It("Should be able to remove defined addresses", func() { 180 // Deploy and validate deployment 181 ginkgo.By("Deploying an Interconnect using pre-defined address list") 182 ic, err := f.CreateInterconnect(f.Namespace, int32(size), func(ic *v1alpha1.Interconnect) { 183 ic.Spec.Addresses = getSpecAddresses() 184 }) 185 gomega.Expect(err).NotTo(gomega.HaveOccurred()) 186 gomega.Expect(ic).NotTo(gomega.BeNil()) 187 188 // Wait till interconnect instance is ready 189 err = framework.WaitForDeployment(f.KubeClient, f.Namespace, ic.Name, size, framework.RetryInterval, framework.Timeout) 190 gomega.Expect(ic).NotTo(gomega.BeNil()) 191 192 // Get the Interconnect instance 193 ic, err = f.GetInterconnect(ic.Name) 194 gomega.Expect(err).NotTo(gomega.HaveOccurred()) 195 196 // Get pods 197 pods, err := f.GetInterconnectPodNames(ic) 198 gomega.Expect(int32(len(pods))).To(gomega.Equal(ic.Spec.DeploymentPlan.Size)) 199 200 // Keeping just the first 3 addresses 201 validateAddresses(f, ic, newAddressesMap) 202 203 // Updating the list of addresses 204 newAddrList := getSpecAddresses()[:3] 205 ic.Spec.Addresses = newAddrList 206 207 // Updating Interconnect resource 208 ginkgo.By("Modifying addresses and updating Interconnect instance") 209 ic, err = f.UpdateInterconnect(ic) 210 gomega.Expect(err).NotTo(gomega.HaveOccurred()) 211 212 // Waiting for new pods 213 ctx, fn := context.WithTimeout(context.Background(), framework.Timeout) 214 defer fn() 215 err = f.WaitForNewInterconnectPods(ctx, pods, ic, framework.RetryInterval, framework.Timeout) 216 gomega.Expect(err).NotTo(gomega.HaveOccurred()) 217 218 // Wait till interconnect instance is ready 219 ic, err = f.GetInterconnect(ic.Name) 220 gomega.Expect(err).NotTo(gomega.HaveOccurred()) 221 222 // Waiting for deployment to be ready 223 err = framework.WaitForDeployment(f.KubeClient, f.Namespace, ic.Name, size, framework.RetryInterval, framework.Timeout) 224 gomega.Expect(err).NotTo(gomega.HaveOccurred()) 225 226 // Validating addresses 227 ginkgo.By("Asserting that addresses have been updated accordingly") 228 validateAddresses(f, ic, afterRemovalAddressesMap) 229 }) 230 }) 231 232 // validateAddresses asserts that the Address entities available across all 233 // pods of the given Interconnect instance match the definitions from addrMap. 234 func validateAddresses(f *framework.Framework, ic *v1alpha1.Interconnect, addrMap map[string]map[string]interface{}) { 235 // Validating defined addresses/ 236 ic, err := f.GetInterconnect(ic.Name) 237 gomega.Expect(err).NotTo(gomega.HaveOccurred()) 238 239 // Retrieve pod list 240 pods, err := f.GetInterconnectPods(ic) 241 gomega.Expect(err).NotTo(gomega.HaveOccurred()) 242 243 // Iterate through pods 244 for _, pod := range pods { 245 // Wait for pod to be Running 246 _, err := f.WaitForPodStatus(pod.Name, v1.PodRunning, framework.Timeout, framework.RetryInterval) 247 gomega.Expect(err).To(gomega.BeNil()) 248 249 addresses, err := qdrmanagement.QdmanageQuery(f, pod.Name, entities.Address{}, nil) 250 gomega.Expect(err).To(gomega.BeNil()) 251 // Assert number of addresses match expected count 252 gomega.Expect(len(addrMap)).To(gomega.Equal(len(addresses))) 253 254 // Validating all addresses 255 for _, address := range addresses { 256 a := getAddressMapForPrefixPattern(addrMap, address.(entities.Address)) 257 gomega.Expect(len(addrMap)).To(gomega.BeNumerically(">", 0)) 258 validation.ValidateEntityValues(address, a) 259 } 260 } 261 } 262 263 func getSpecAddresses() []v1alpha1.Address { 264 265 priority := int32(5) 266 ingress := int32(5) 267 egress := int32(6) 268 269 return []v1alpha1.Address{ 270 { 271 Prefix: "multicastprefix", 272 Distribution: "multicast", 273 }, 274 { 275 Pattern: "multicastpattern/*", 276 Distribution: "multicast", 277 }, 278 { 279 Prefix: "waypoint", 280 Distribution: "balanced", 281 Waypoint: true, 282 }, 283 { 284 Prefix: "fallback", 285 Distribution: "balanced", 286 Waypoint: true, 287 EnableFallback: true, 288 }, 289 { 290 Prefix: "priority", 291 Priority: &priority, 292 }, 293 { 294 Prefix: "ingressegress", 295 IngressPhase: &ingress, 296 EgressPhase: &egress, 297 }, 298 } 299 } 300 301 func getAddressMapForPrefixPattern(m map[string]map[string]interface{}, address entities.Address) map[string]interface{} { 302 for k, v := range m { 303 if k == address.Prefix || k == address.Pattern { 304 return v 305 } 306 } 307 return map[string]interface{}{} 308 }