github.com/projectcontour/contour@v1.28.2/cmd/contour/serve_test.go (about) 1 // Copyright Project Contour Authors 2 // Licensed under the Apache License, Version 2.0 (the "License"); 3 // you may not use this file except in compliance with the License. 4 // You may obtain a copy of the License at 5 // 6 // http://www.apache.org/licenses/LICENSE-2.0 7 // 8 // Unless required by applicable law or agreed to in writing, software 9 // distributed under the License is distributed on an "AS IS" BASIS, 10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 // See the License for the specific language governing permissions and 12 // limitations under the License. 13 14 package main 15 16 import ( 17 "testing" 18 19 contour_api_v1alpha1 "github.com/projectcontour/contour/apis/projectcontour/v1alpha1" 20 "github.com/projectcontour/contour/internal/dag" 21 "github.com/projectcontour/contour/internal/ref" 22 "github.com/sirupsen/logrus" 23 "github.com/stretchr/testify/assert" 24 "github.com/stretchr/testify/require" 25 "k8s.io/apimachinery/pkg/types" 26 ) 27 28 func TestGetDAGBuilder(t *testing.T) { 29 commonAssertions := func(t *testing.T, builder *dag.Builder) { 30 t.Helper() 31 32 // note that these first two assertions will not hold when a gateway 33 // is configured, but we don't currently have test cases that cover 34 // that so it's OK to keep them in the "common" assertions for now. 35 assert.Len(t, builder.Processors, 4) 36 assert.IsType(t, &dag.ListenerProcessor{}, builder.Processors[0]) 37 38 ingressProcessor := mustGetIngressProcessor(t, builder) 39 assert.True(t, ingressProcessor.SetSourceMetadataOnRoutes) 40 41 httpProxyProcessor := mustGetHTTPProxyProcessor(t, builder) 42 assert.True(t, httpProxyProcessor.SetSourceMetadataOnRoutes) 43 } 44 45 t.Run("all default options", func(t *testing.T) { 46 serve := &Server{ 47 log: logrus.StandardLogger(), 48 } 49 got := serve.getDAGBuilder(dagBuilderConfig{rootNamespaces: []string{}, dnsLookupFamily: contour_api_v1alpha1.AutoClusterDNSFamily}) 50 commonAssertions(t, got) 51 assert.Empty(t, got.Source.ConfiguredSecretRefs) 52 }) 53 54 t.Run("client cert specified", func(t *testing.T) { 55 clientCert := &types.NamespacedName{Namespace: "client-ns", Name: "client-name"} 56 57 serve := &Server{ 58 log: logrus.StandardLogger(), 59 } 60 got := serve.getDAGBuilder(dagBuilderConfig{rootNamespaces: []string{}, dnsLookupFamily: contour_api_v1alpha1.AutoClusterDNSFamily, clientCert: clientCert}) 61 commonAssertions(t, got) 62 assert.ElementsMatch(t, got.Source.ConfiguredSecretRefs, []*types.NamespacedName{clientCert}) 63 }) 64 65 t.Run("fallback cert specified", func(t *testing.T) { 66 fallbackCert := &types.NamespacedName{Namespace: "fallback-ns", Name: "fallback-name"} 67 68 serve := &Server{ 69 log: logrus.StandardLogger(), 70 } 71 got := serve.getDAGBuilder(dagBuilderConfig{rootNamespaces: []string{}, dnsLookupFamily: contour_api_v1alpha1.AutoClusterDNSFamily, fallbackCert: fallbackCert}) 72 commonAssertions(t, got) 73 assert.ElementsMatch(t, got.Source.ConfiguredSecretRefs, []*types.NamespacedName{fallbackCert}) 74 }) 75 76 t.Run("client and fallback certs specified", func(t *testing.T) { 77 clientCert := &types.NamespacedName{Namespace: "client-ns", Name: "client-name"} 78 fallbackCert := &types.NamespacedName{Namespace: "fallback-ns", Name: "fallback-name"} 79 80 serve := &Server{ 81 log: logrus.StandardLogger(), 82 } 83 got := serve.getDAGBuilder(dagBuilderConfig{rootNamespaces: []string{}, dnsLookupFamily: contour_api_v1alpha1.AutoClusterDNSFamily, clientCert: clientCert, fallbackCert: fallbackCert}) 84 commonAssertions(t, got) 85 assert.ElementsMatch(t, got.Source.ConfiguredSecretRefs, []*types.NamespacedName{clientCert, fallbackCert}) 86 }) 87 88 t.Run("request and response headers policy specified", func(t *testing.T) { 89 policy := &contour_api_v1alpha1.PolicyConfig{ 90 RequestHeadersPolicy: &contour_api_v1alpha1.HeadersPolicy{ 91 Set: map[string]string{ 92 "req-set-key-1": "req-set-val-1", 93 "req-set-key-2": "req-set-val-2", 94 }, 95 Remove: []string{"req-remove-key-1", "req-remove-key-2"}, 96 }, 97 ResponseHeadersPolicy: &contour_api_v1alpha1.HeadersPolicy{ 98 Set: map[string]string{ 99 "res-set-key-1": "res-set-val-1", 100 "res-set-key-2": "res-set-val-2", 101 }, 102 Remove: []string{"res-remove-key-1", "res-remove-key-2"}, 103 }, 104 ApplyToIngress: ref.To(false), 105 } 106 107 serve := &Server{ 108 log: logrus.StandardLogger(), 109 } 110 got := serve.getDAGBuilder(dagBuilderConfig{rootNamespaces: []string{}, dnsLookupFamily: contour_api_v1alpha1.AutoClusterDNSFamily, headersPolicy: policy}) 111 commonAssertions(t, got) 112 113 httpProxyProcessor := mustGetHTTPProxyProcessor(t, got) 114 assert.EqualValues(t, policy.RequestHeadersPolicy.Set, httpProxyProcessor.RequestHeadersPolicy.Set) 115 assert.ElementsMatch(t, policy.RequestHeadersPolicy.Remove, httpProxyProcessor.RequestHeadersPolicy.Remove) 116 assert.EqualValues(t, policy.ResponseHeadersPolicy.Set, httpProxyProcessor.ResponseHeadersPolicy.Set) 117 assert.ElementsMatch(t, policy.ResponseHeadersPolicy.Remove, httpProxyProcessor.ResponseHeadersPolicy.Remove) 118 119 ingressProcessor := mustGetIngressProcessor(t, got) 120 assert.EqualValues(t, map[string]string(nil), ingressProcessor.RequestHeadersPolicy.Set) 121 assert.ElementsMatch(t, map[string]string(nil), ingressProcessor.RequestHeadersPolicy.Remove) 122 assert.EqualValues(t, map[string]string(nil), ingressProcessor.ResponseHeadersPolicy.Set) 123 assert.ElementsMatch(t, map[string]string(nil), ingressProcessor.ResponseHeadersPolicy.Remove) 124 }) 125 126 t.Run("GlobalCircuitBreakerDefaults specified for all processors", func(t *testing.T) { 127 g := contour_api_v1alpha1.GlobalCircuitBreakerDefaults{ 128 MaxConnections: 100, 129 } 130 131 serve := &Server{ 132 log: logrus.StandardLogger(), 133 } 134 got := serve.getDAGBuilder(dagBuilderConfig{ 135 gatewayControllerName: "projectcontour.io/gateway-controller", 136 rootNamespaces: []string{}, 137 dnsLookupFamily: contour_api_v1alpha1.AutoClusterDNSFamily, 138 globalCircuitBreakerDefaults: &g, 139 }) 140 141 iProcessor := mustGetIngressProcessor(t, got) 142 assert.EqualValues(t, iProcessor.GlobalCircuitBreakerDefaults, &g) 143 144 hProcessor := mustGetHTTPProxyProcessor(t, got) 145 assert.EqualValues(t, hProcessor.GlobalCircuitBreakerDefaults, &g) 146 147 gProcessor := mustGetGatewayAPIProcessor(t, got) 148 assert.EqualValues(t, gProcessor.GlobalCircuitBreakerDefaults, &g) 149 }) 150 151 t.Run("request and response headers policy specified for ingress", func(t *testing.T) { 152 policy := &contour_api_v1alpha1.PolicyConfig{ 153 RequestHeadersPolicy: &contour_api_v1alpha1.HeadersPolicy{ 154 Set: map[string]string{ 155 "req-set-key-1": "req-set-val-1", 156 "req-set-key-2": "req-set-val-2", 157 }, 158 Remove: []string{"req-remove-key-1", "req-remove-key-2"}, 159 }, 160 ResponseHeadersPolicy: &contour_api_v1alpha1.HeadersPolicy{ 161 Set: map[string]string{ 162 "res-set-key-1": "res-set-val-1", 163 "res-set-key-2": "res-set-val-2", 164 }, 165 Remove: []string{"res-remove-key-1", "res-remove-key-2"}, 166 }, 167 ApplyToIngress: ref.To(true), 168 } 169 170 serve := &Server{ 171 log: logrus.StandardLogger(), 172 } 173 got := serve.getDAGBuilder(dagBuilderConfig{ 174 rootNamespaces: []string{}, 175 dnsLookupFamily: contour_api_v1alpha1.AutoClusterDNSFamily, 176 headersPolicy: policy, 177 }) 178 commonAssertions(t, got) 179 180 ingressProcessor := mustGetIngressProcessor(t, got) 181 assert.EqualValues(t, policy.RequestHeadersPolicy.Set, ingressProcessor.RequestHeadersPolicy.Set) 182 assert.ElementsMatch(t, policy.RequestHeadersPolicy.Remove, ingressProcessor.RequestHeadersPolicy.Remove) 183 assert.EqualValues(t, policy.ResponseHeadersPolicy.Set, ingressProcessor.ResponseHeadersPolicy.Set) 184 assert.ElementsMatch(t, policy.ResponseHeadersPolicy.Remove, ingressProcessor.ResponseHeadersPolicy.Remove) 185 }) 186 187 t.Run("single ingress class specified", func(t *testing.T) { 188 ingressClassNames := []string{"aclass"} 189 190 serve := &Server{ 191 log: logrus.StandardLogger(), 192 } 193 got := serve.getDAGBuilder(dagBuilderConfig{ 194 rootNamespaces: []string{}, 195 dnsLookupFamily: contour_api_v1alpha1.AutoClusterDNSFamily, 196 ingressClassNames: ingressClassNames, 197 }) 198 commonAssertions(t, got) 199 assert.EqualValues(t, ingressClassNames, got.Source.IngressClassNames) 200 }) 201 202 t.Run("multiple comma-separated ingress classes specified", func(t *testing.T) { 203 ingressClassNames := []string{"aclass", "bclass", "cclass"} 204 205 serve := &Server{ 206 log: logrus.StandardLogger(), 207 } 208 got := serve.getDAGBuilder(dagBuilderConfig{ 209 rootNamespaces: []string{}, 210 dnsLookupFamily: contour_api_v1alpha1.AutoClusterDNSFamily, 211 ingressClassNames: ingressClassNames, 212 }) 213 commonAssertions(t, got) 214 assert.EqualValues(t, ingressClassNames, got.Source.IngressClassNames) 215 }) 216 217 // TODO(3453): test additional properties of the DAG builder (processor fields, cache fields, Gateway tests (requires a client fake)) 218 } 219 220 func mustGetGatewayAPIProcessor(t *testing.T, builder *dag.Builder) *dag.GatewayAPIProcessor { 221 t.Helper() 222 for i := range builder.Processors { 223 found, ok := builder.Processors[i].(*dag.GatewayAPIProcessor) 224 if ok { 225 return found 226 } 227 } 228 229 require.FailNow(t, "GatewayAPIProcessor not found in list of DAG builder's processors") 230 return nil 231 } 232 233 func mustGetHTTPProxyProcessor(t *testing.T, builder *dag.Builder) *dag.HTTPProxyProcessor { 234 t.Helper() 235 for i := range builder.Processors { 236 found, ok := builder.Processors[i].(*dag.HTTPProxyProcessor) 237 if ok { 238 return found 239 } 240 } 241 242 require.FailNow(t, "HTTPProxyProcessor not found in list of DAG builder's processors") 243 return nil 244 } 245 246 func mustGetIngressProcessor(t *testing.T, builder *dag.Builder) *dag.IngressProcessor { 247 t.Helper() 248 for i := range builder.Processors { 249 found, ok := builder.Processors[i].(*dag.IngressProcessor) 250 if ok { 251 return found 252 } 253 } 254 255 require.FailNow(t, "IngressProcessor not found in list of DAG builder's processors") 256 return nil 257 }