istio.io/istio@v0.0.0-20240520182934-d79c90f27776/operator/pkg/translate/strategic_port_merge_test.go (about) 1 // Copyright Istio Authors 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 translate 16 17 import ( 18 "testing" 19 20 "github.com/google/go-cmp/cmp" 21 v1 "k8s.io/api/core/v1" 22 "k8s.io/apimachinery/pkg/util/intstr" 23 ) 24 25 var ( 26 httpsPort = &v1.ServicePort{ 27 Name: "https", 28 Protocol: v1.ProtocolTCP, 29 Port: 443, 30 TargetPort: intstr.IntOrString{IntVal: 8443}, 31 } 32 quicPort = &v1.ServicePort{ 33 Name: "http3-quic", 34 Protocol: v1.ProtocolUDP, 35 Port: 443, 36 TargetPort: intstr.IntOrString{IntVal: 8443}, 37 } 38 httpPort = &v1.ServicePort{ 39 Name: "http-port", 40 Protocol: v1.ProtocolTCP, 41 Port: 80, 42 TargetPort: intstr.IntOrString{IntVal: 8080}, 43 } 44 httpNoProtoPort = &v1.ServicePort{ 45 Name: "http-port", 46 Port: 80, 47 TargetPort: intstr.IntOrString{IntVal: 8080}, 48 } 49 mysqlPort = &v1.ServicePort{ 50 Name: "mysql-port", 51 Protocol: v1.ProtocolTCP, 52 Port: 3306, 53 } 54 istioHealthcheckPort = &v1.ServicePort{ 55 Name: "status-port", 56 Protocol: v1.ProtocolTCP, 57 Port: 15021, 58 } 59 istioMetricsPort = &v1.ServicePort{ 60 Name: "metrics-port", 61 Protocol: v1.ProtocolTCP, 62 Port: 15020, 63 } 64 httpBaseBarPort = &v1.ServicePort{ 65 Name: "http-bar-base", 66 Protocol: v1.ProtocolTCP, 67 Port: 9000, 68 } 69 httpOverlayBarPort = &v1.ServicePort{ 70 Name: "http-bar-overlay", 71 Protocol: v1.ProtocolTCP, 72 Port: 9000, 73 } 74 httpOverlayDiffProtocolBarPort = &v1.ServicePort{ 75 Name: "http3-bar-overlay", 76 Protocol: v1.ProtocolUDP, 77 Port: 9000, 78 } 79 httpFooPort = &v1.ServicePort{ 80 Name: "http-foo", 81 Protocol: v1.ProtocolTCP, 82 Port: 8080, 83 } 84 httpFooProtocolOmittedPort = &v1.ServicePort{ 85 Name: "http-foo", 86 Port: 8080, 87 } 88 ) 89 90 func TestStrategicPortMergeByPortAndProtocol(t *testing.T) { 91 for _, tt := range []struct { 92 name string 93 basePorts []*v1.ServicePort 94 overlayPorts []*v1.ServicePort 95 expectedMergedPorts []*v1.ServicePort 96 }{ 97 { 98 name: "both base and overlay are nil", 99 basePorts: nil, 100 overlayPorts: nil, 101 expectedMergedPorts: nil, 102 }, 103 { 104 name: "overlay is nil", 105 basePorts: []*v1.ServicePort{httpPort, httpsPort, quicPort}, 106 overlayPorts: nil, 107 expectedMergedPorts: []*v1.ServicePort{httpPort, httpsPort, quicPort}, 108 }, 109 { 110 name: "base is nil", 111 basePorts: nil, 112 overlayPorts: []*v1.ServicePort{httpPort, httpsPort, quicPort}, 113 expectedMergedPorts: []*v1.ServicePort{httpPort, httpsPort, quicPort}, 114 }, 115 { 116 name: "same base and overlay", 117 basePorts: []*v1.ServicePort{httpPort, httpsPort}, 118 overlayPorts: []*v1.ServicePort{httpsPort, httpPort}, 119 expectedMergedPorts: []*v1.ServicePort{httpPort, httpsPort}, 120 }, 121 { 122 name: "base and overlay for the same port, different protocol", 123 basePorts: []*v1.ServicePort{httpPort, httpsPort, mysqlPort}, 124 overlayPorts: []*v1.ServicePort{quicPort}, 125 expectedMergedPorts: []*v1.ServicePort{httpPort, httpsPort, mysqlPort, quicPort}, 126 }, 127 { 128 name: "base and overlay with different ports", 129 basePorts: []*v1.ServicePort{httpPort}, 130 overlayPorts: []*v1.ServicePort{httpsPort}, 131 expectedMergedPorts: []*v1.ServicePort{httpPort, httpsPort}, 132 }, 133 { 134 name: "implicit ports", 135 basePorts: []*v1.ServicePort{httpPort}, 136 overlayPorts: []*v1.ServicePort{httpNoProtoPort}, 137 expectedMergedPorts: []*v1.ServicePort{httpPort}, 138 }, 139 { 140 name: "status and metrics port are present", 141 basePorts: []*v1.ServicePort{istioHealthcheckPort, istioMetricsPort, httpsPort}, 142 overlayPorts: []*v1.ServicePort{httpsPort, httpPort}, 143 expectedMergedPorts: []*v1.ServicePort{istioHealthcheckPort, istioMetricsPort, httpsPort, httpPort}, 144 }, 145 { 146 name: "status port is present", 147 basePorts: []*v1.ServicePort{istioHealthcheckPort, httpsPort, httpPort}, 148 overlayPorts: []*v1.ServicePort{httpsPort, httpPort}, 149 expectedMergedPorts: []*v1.ServicePort{istioHealthcheckPort, httpsPort, httpPort}, 150 }, 151 { 152 name: "metrics port is present", 153 basePorts: []*v1.ServicePort{istioMetricsPort, httpsPort, httpPort}, 154 overlayPorts: []*v1.ServicePort{httpsPort, httpPort}, 155 expectedMergedPorts: []*v1.ServicePort{istioMetricsPort, httpsPort, httpPort}, 156 }, 157 { 158 name: "overlay with port name changed", 159 basePorts: []*v1.ServicePort{httpBaseBarPort}, 160 overlayPorts: []*v1.ServicePort{httpOverlayBarPort}, 161 expectedMergedPorts: []*v1.ServicePort{httpOverlayBarPort}, 162 }, 163 { 164 name: "overlay with different protocol", 165 basePorts: []*v1.ServicePort{httpBaseBarPort}, 166 overlayPorts: []*v1.ServicePort{httpOverlayDiffProtocolBarPort}, 167 expectedMergedPorts: []*v1.ServicePort{httpBaseBarPort, httpOverlayDiffProtocolBarPort}, 168 }, 169 { 170 name: "same base and overlay with protocol omitted for overlay", 171 basePorts: []*v1.ServicePort{httpFooPort}, 172 overlayPorts: []*v1.ServicePort{httpFooProtocolOmittedPort}, 173 expectedMergedPorts: []*v1.ServicePort{httpFooPort}, 174 }, 175 { 176 name: "same base and overlay with protocol omitted for base", 177 basePorts: []*v1.ServicePort{httpFooProtocolOmittedPort}, 178 overlayPorts: []*v1.ServicePort{httpFooPort}, 179 expectedMergedPorts: []*v1.ServicePort{httpFooPort}, 180 }, 181 } { 182 t.Run(tt.name, func(t *testing.T) { 183 actualMergedPorts := strategicMergePorts(tt.basePorts, tt.overlayPorts) 184 if diff := cmp.Diff(actualMergedPorts, tt.expectedMergedPorts); diff != "" { 185 t.Fatalf("expected differs from actual. Diff:\n%s", diff) 186 } 187 }) 188 } 189 }