sigs.k8s.io/external-dns@v0.14.1/internal/testutils/endpoint.go (about)

     1  /*
     2  Copyright 2017 The Kubernetes Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package testutils
    18  
    19  import (
    20  	"reflect"
    21  	"sort"
    22  
    23  	"sigs.k8s.io/external-dns/endpoint"
    24  )
    25  
    26  /** test utility functions for endpoints verifications */
    27  
    28  type byNames endpoint.ProviderSpecific
    29  
    30  func (p byNames) Len() int           { return len(p) }
    31  func (p byNames) Swap(i, j int)      { p[i], p[j] = p[j], p[i] }
    32  func (p byNames) Less(i, j int) bool { return p[i].Name < p[j].Name }
    33  
    34  type byAllFields []*endpoint.Endpoint
    35  
    36  func (b byAllFields) Len() int      { return len(b) }
    37  func (b byAllFields) Swap(i, j int) { b[i], b[j] = b[j], b[i] }
    38  func (b byAllFields) Less(i, j int) bool {
    39  	if b[i].DNSName < b[j].DNSName {
    40  		return true
    41  	}
    42  	if b[i].DNSName == b[j].DNSName {
    43  		// This rather bad, we need a more complex comparison for Targets, which considers all elements
    44  		if b[i].Targets.Same(b[j].Targets) {
    45  			if b[i].RecordType == (b[j].RecordType) {
    46  				sa := b[i].ProviderSpecific
    47  				sb := b[j].ProviderSpecific
    48  				sort.Sort(byNames(sa))
    49  				sort.Sort(byNames(sb))
    50  				return reflect.DeepEqual(sa, sb)
    51  			}
    52  			return b[i].RecordType <= b[j].RecordType
    53  		}
    54  		return b[i].Targets.String() <= b[j].Targets.String()
    55  	}
    56  	return false
    57  }
    58  
    59  // SameEndpoint returns true if two endpoints are same
    60  // considers example.org. and example.org DNSName/Target as different endpoints
    61  func SameEndpoint(a, b *endpoint.Endpoint) bool {
    62  	return a.DNSName == b.DNSName && a.Targets.Same(b.Targets) && a.RecordType == b.RecordType && a.SetIdentifier == b.SetIdentifier &&
    63  		a.Labels[endpoint.OwnerLabelKey] == b.Labels[endpoint.OwnerLabelKey] && a.RecordTTL == b.RecordTTL &&
    64  		a.Labels[endpoint.ResourceLabelKey] == b.Labels[endpoint.ResourceLabelKey] &&
    65  		a.Labels[endpoint.OwnedRecordLabelKey] == b.Labels[endpoint.OwnedRecordLabelKey] &&
    66  		SameProviderSpecific(a.ProviderSpecific, b.ProviderSpecific)
    67  }
    68  
    69  // SameEndpoints compares two slices of endpoints regardless of order
    70  // [x,y,z] == [z,x,y]
    71  // [x,x,z] == [x,z,x]
    72  // [x,y,y] != [x,x,y]
    73  // [x,x,x] != [x,x,z]
    74  func SameEndpoints(a, b []*endpoint.Endpoint) bool {
    75  	if len(a) != len(b) {
    76  		return false
    77  	}
    78  
    79  	sa := a
    80  	sb := b
    81  	sort.Sort(byAllFields(sa))
    82  	sort.Sort(byAllFields(sb))
    83  
    84  	for i := range sa {
    85  		if !SameEndpoint(sa[i], sb[i]) {
    86  			return false
    87  		}
    88  	}
    89  	return true
    90  }
    91  
    92  // SameEndpointLabels verifies that labels of the two slices of endpoints are the same
    93  func SameEndpointLabels(a, b []*endpoint.Endpoint) bool {
    94  	if len(a) != len(b) {
    95  		return false
    96  	}
    97  
    98  	sa := a
    99  	sb := b
   100  	sort.Sort(byAllFields(sa))
   101  	sort.Sort(byAllFields(sb))
   102  
   103  	for i := range sa {
   104  		if !reflect.DeepEqual(sa[i].Labels, sb[i].Labels) {
   105  			return false
   106  		}
   107  	}
   108  	return true
   109  }
   110  
   111  // SamePlanChanges verifies that two set of changes are the same
   112  func SamePlanChanges(a, b map[string][]*endpoint.Endpoint) bool {
   113  	return SameEndpoints(a["Create"], b["Create"]) && SameEndpoints(a["Delete"], b["Delete"]) &&
   114  		SameEndpoints(a["UpdateOld"], b["UpdateOld"]) && SameEndpoints(a["UpdateNew"], b["UpdateNew"])
   115  }
   116  
   117  // SameProviderSpecific verifies that two maps contain the same string/string key/value pairs
   118  func SameProviderSpecific(a, b endpoint.ProviderSpecific) bool {
   119  	sa := a
   120  	sb := b
   121  	sort.Sort(byNames(sa))
   122  	sort.Sort(byNames(sb))
   123  	return reflect.DeepEqual(sa, sb)
   124  }