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  }