From b8a1cb5c681459495d5213dd5c0d6cda27843bd8 Mon Sep 17 00:00:00 2001 From: Fernandez Ludovic Date: Wed, 20 Dec 2017 21:48:57 +0100 Subject: [PATCH] refactor(marathon): fix labels and add tests. --- provider/marathon/config.go | 145 ++++++++-------- provider/marathon/config_test.go | 277 +++++++++++++++++++++++++++++++ 2 files changed, 355 insertions(+), 67 deletions(-) diff --git a/provider/marathon/config.go b/provider/marathon/config.go index f1d19647f..b5c51a7f5 100644 --- a/provider/marathon/config.go +++ b/provider/marathon/config.go @@ -20,14 +20,14 @@ import ( func (p *Provider) buildConfiguration() *types.Configuration { var MarathonFuncMap = template.FuncMap{ "getBackend": p.getBackend, - "getDomain": getFuncStringService(label.TraefikDomain, p.Domain), // see https://github.com/containous/traefik/pull/1693 - "getSubDomain": p.getSubDomain, // see https://github.com/containous/traefik/pull/1693 + "getDomain": getFuncStringService(label.SuffixDomain, p.Domain), // see https://github.com/containous/traefik/pull/1693 + "getSubDomain": p.getSubDomain, // see https://github.com/containous/traefik/pull/1693 // Backend functions "getBackendServer": p.getBackendServer, "getPort": getPort, - "getWeight": getFuncStringService(label.TraefikWeight, label.DefaultWeight), - "getProtocol": getFuncStringService(label.TraefikProtocol, label.DefaultProtocol), + "getWeight": getFuncStringService(label.SuffixWeight, label.DefaultWeight), + "getProtocol": getFuncStringService(label.SuffixProtocol, label.DefaultProtocol), "hasCircuitBreakerLabels": hasFunc(label.TraefikBackendCircuitBreakerExpression), "getCircuitBreakerExpression": getFuncString(label.TraefikBackendCircuitBreakerExpression, label.DefaultCircuitBreakerExpression), "hasLoadBalancerLabels": hasLoadBalancerLabels, @@ -44,66 +44,66 @@ func (p *Provider) buildConfiguration() *types.Configuration { "getHealthCheckInterval": getFuncString(label.TraefikBackendHealthCheckInterval, ""), // Frontend functions - "getPassHostHeader": getFuncStringService(label.TraefikFrontendPassHostHeader, label.DefaultPassHostHeader), - "getPassTLSCert": getFuncBoolService(label.TraefikFrontendPassTLSCert, label.DefaultPassTLSCert), - "getPriority": getFuncStringService(label.TraefikFrontendPriority, label.DefaultFrontendPriority), - "getEntryPoints": getFuncSliceStringService(label.TraefikFrontendEntryPoints), + "getPassHostHeader": getFuncStringService(label.SuffixFrontendPassHostHeader, label.DefaultPassHostHeader), + "getPassTLSCert": getFuncBoolService(label.SuffixFrontendPassTLSCert, label.DefaultPassTLSCert), + "getPriority": getFuncStringService(label.SuffixFrontendPriority, label.DefaultFrontendPriority), + "getEntryPoints": getFuncSliceStringService(label.SuffixFrontendEntryPoints), "getFrontendRule": p.getFrontendRule, "getFrontendName": p.getFrontendName, - "getBasicAuth": getFuncSliceStringService(label.TraefikFrontendAuthBasic), + "getBasicAuth": getFuncSliceStringService(label.SuffixFrontendAuthBasic), "getServiceNames": getServiceNames, "getServiceNameSuffix": getServiceNameSuffix, - "getWhitelistSourceRange": getFuncSliceStringService(label.TraefikFrontendWhitelistSourceRange), + "getWhitelistSourceRange": getFuncSliceStringService(label.SuffixFrontendWhitelistSourceRange), "hasRedirect": hasRedirect, - "getRedirectEntryPoint": getFuncStringService(label.TraefikFrontendRedirectEntryPoint, label.DefaultFrontendRedirectEntryPoint), - "getRedirectRegex": getFuncStringService(label.TraefikFrontendRedirectRegex, ""), - "getRedirectReplacement": getFuncStringService(label.TraefikFrontendRedirectReplacement, ""), - "hasErrorPages": hasErrorPages, + "getRedirectEntryPoint": getFuncStringService(label.SuffixFrontendRedirectEntryPoint, label.DefaultFrontendRedirectEntryPoint), + "getRedirectRegex": getFuncStringService(label.SuffixFrontendRedirectRegex, ""), + "getRedirectReplacement": getFuncStringService(label.SuffixFrontendRedirectReplacement, ""), + "hasErrorPages": hasPrefixFuncService(label.BaseFrontendErrorPage), "getErrorPages": getErrorPages, - "hasRateLimits": hasFuncService(label.TraefikFrontendRateLimitExtractorFunc), - "getRateLimitsExtractorFunc": getFuncStringService(label.TraefikFrontendRateLimitExtractorFunc, ""), + "hasRateLimits": hasFuncService(label.SuffixFrontendRateLimitExtractorFunc), + "getRateLimitsExtractorFunc": getFuncStringService(label.SuffixFrontendRateLimitExtractorFunc, ""), "getRateLimits": getRateLimits, // Headers - "hasRequestHeaders": hasFuncService(label.TraefikFrontendRequestHeaders), - "getRequestHeaders": getFuncMapService(label.TraefikFrontendRequestHeaders), - "hasResponseHeaders": hasFuncService(label.TraefikFrontendResponseHeaders), - "getResponseHeaders": getFuncMapService(label.TraefikFrontendResponseHeaders), - "hasAllowedHostsHeaders": hasFuncService(label.TraefikFrontendAllowedHosts), - "getAllowedHostsHeaders": getFuncSliceStringService(label.TraefikFrontendAllowedHosts), - "hasHostsProxyHeaders": hasFuncService(label.TraefikFrontendHostsProxyHeaders), - "getHostsProxyHeaders": getFuncSliceStringService(label.TraefikFrontendHostsProxyHeaders), - "hasSSLRedirectHeaders": hasFuncService(label.TraefikFrontendSSLRedirect), - "getSSLRedirectHeaders": getFuncBoolService(label.TraefikFrontendSSLRedirect, false), - "hasSSLTemporaryRedirectHeaders": hasFuncService(label.TraefikFrontendSSLTemporaryRedirect), - "getSSLTemporaryRedirectHeaders": getFuncBoolService(label.TraefikFrontendSSLTemporaryRedirect, false), - "hasSSLHostHeaders": hasFuncService(label.TraefikFrontendSSLHost), - "getSSLHostHeaders": getFuncStringService(label.TraefikFrontendSSLHost, ""), - "hasSSLProxyHeaders": hasFuncService(label.TraefikFrontendSSLProxyHeaders), - "getSSLProxyHeaders": getFuncMapService(label.TraefikFrontendSSLProxyHeaders), - "hasSTSSecondsHeaders": hasFuncService(label.TraefikFrontendSTSSeconds), - "getSTSSecondsHeaders": getFuncInt64Service(label.TraefikFrontendSTSSeconds, 0), - "hasSTSIncludeSubdomainsHeaders": hasFuncService(label.TraefikFrontendSTSIncludeSubdomains), - "getSTSIncludeSubdomainsHeaders": getFuncBoolService(label.TraefikFrontendSTSIncludeSubdomains, false), - "hasSTSPreloadHeaders": hasFuncService(label.TraefikFrontendSTSPreload), - "getSTSPreloadHeaders": getFuncBoolService(label.TraefikFrontendSTSPreload, false), - "hasForceSTSHeaderHeaders": hasFuncService(label.TraefikFrontendForceSTSHeader), - "getForceSTSHeaderHeaders": getFuncBoolService(label.TraefikFrontendForceSTSHeader, false), - "hasFrameDenyHeaders": hasFuncService(label.TraefikFrontendFrameDeny), - "getFrameDenyHeaders": getFuncBoolService(label.TraefikFrontendFrameDeny, false), - "hasCustomFrameOptionsValueHeaders": hasFuncService(label.TraefikFrontendCustomFrameOptionsValue), - "getCustomFrameOptionsValueHeaders": getFuncStringService(label.TraefikFrontendCustomFrameOptionsValue, ""), - "hasContentTypeNosniffHeaders": hasFuncService(label.TraefikFrontendContentTypeNosniff), - "getContentTypeNosniffHeaders": getFuncBoolService(label.TraefikFrontendContentTypeNosniff, false), - "hasBrowserXSSFilterHeaders": hasFuncService(label.TraefikFrontendBrowserXSSFilter), - "getBrowserXSSFilterHeaders": getFuncBoolService(label.TraefikFrontendBrowserXSSFilter, false), - "hasContentSecurityPolicyHeaders": hasFuncService(label.TraefikFrontendContentSecurityPolicy), - "getContentSecurityPolicyHeaders": getFuncStringService(label.TraefikFrontendContentSecurityPolicy, ""), - "hasPublicKeyHeaders": hasFuncService(label.TraefikFrontendPublicKey), - "getPublicKeyHeaders": getFuncStringService(label.TraefikFrontendPublicKey, ""), - "hasReferrerPolicyHeaders": hasFuncService(label.TraefikFrontendReferrerPolicy), - "getReferrerPolicyHeaders": getFuncStringService(label.TraefikFrontendReferrerPolicy, ""), - "hasIsDevelopmentHeaders": hasFuncService(label.TraefikFrontendIsDevelopment), - "getIsDevelopmentHeaders": getFuncBoolService(label.TraefikFrontendIsDevelopment, false), + "hasRequestHeaders": hasFuncService(label.SuffixFrontendRequestHeaders), + "getRequestHeaders": getFuncMapService(label.SuffixFrontendRequestHeaders), + "hasResponseHeaders": hasFuncService(label.SuffixFrontendResponseHeaders), + "getResponseHeaders": getFuncMapService(label.SuffixFrontendResponseHeaders), + "hasAllowedHostsHeaders": hasFuncService(label.SuffixFrontendHeadersAllowedHosts), + "getAllowedHostsHeaders": getFuncSliceStringService(label.SuffixFrontendHeadersAllowedHosts), + "hasHostsProxyHeaders": hasFuncService(label.SuffixFrontendHeadersHostsProxyHeaders), + "getHostsProxyHeaders": getFuncSliceStringService(label.SuffixFrontendHeadersHostsProxyHeaders), + "hasSSLRedirectHeaders": hasFuncService(label.SuffixFrontendHeadersSSLRedirect), + "getSSLRedirectHeaders": getFuncBoolService(label.SuffixFrontendHeadersSSLRedirect, false), + "hasSSLTemporaryRedirectHeaders": hasFuncService(label.SuffixFrontendHeadersSSLTemporaryRedirect), + "getSSLTemporaryRedirectHeaders": getFuncBoolService(label.SuffixFrontendHeadersSSLTemporaryRedirect, false), + "hasSSLHostHeaders": hasFuncService(label.SuffixFrontendHeadersSSLHost), + "getSSLHostHeaders": getFuncStringService(label.SuffixFrontendHeadersSSLHost, ""), + "hasSSLProxyHeaders": hasFuncService(label.SuffixFrontendHeadersSSLProxyHeaders), + "getSSLProxyHeaders": getFuncMapService(label.SuffixFrontendHeadersSSLProxyHeaders), + "hasSTSSecondsHeaders": hasFuncService(label.SuffixFrontendHeadersSTSSeconds), + "getSTSSecondsHeaders": getFuncInt64Service(label.SuffixFrontendHeadersSTSSeconds, 0), + "hasSTSIncludeSubdomainsHeaders": hasFuncService(label.SuffixFrontendHeadersSTSIncludeSubdomains), + "getSTSIncludeSubdomainsHeaders": getFuncBoolService(label.SuffixFrontendHeadersSTSIncludeSubdomains, false), + "hasSTSPreloadHeaders": hasFuncService(label.SuffixFrontendHeadersSTSPreload), + "getSTSPreloadHeaders": getFuncBoolService(label.SuffixFrontendHeadersSTSPreload, false), + "hasForceSTSHeaderHeaders": hasFuncService(label.SuffixFrontendHeadersForceSTSHeader), + "getForceSTSHeaderHeaders": getFuncBoolService(label.SuffixFrontendHeadersForceSTSHeader, false), + "hasFrameDenyHeaders": hasFuncService(label.SuffixFrontendHeadersFrameDeny), + "getFrameDenyHeaders": getFuncBoolService(label.SuffixFrontendHeadersFrameDeny, false), + "hasCustomFrameOptionsValueHeaders": hasFuncService(label.SuffixFrontendHeadersCustomFrameOptionsValue), + "getCustomFrameOptionsValueHeaders": getFuncStringService(label.SuffixFrontendHeadersCustomFrameOptionsValue, ""), + "hasContentTypeNosniffHeaders": hasFuncService(label.SuffixFrontendHeadersContentTypeNosniff), + "getContentTypeNosniffHeaders": getFuncBoolService(label.SuffixFrontendHeadersContentTypeNosniff, false), + "hasBrowserXSSFilterHeaders": hasFuncService(label.SuffixFrontendHeadersBrowserXSSFilter), + "getBrowserXSSFilterHeaders": getFuncBoolService(label.SuffixFrontendHeadersBrowserXSSFilter, false), + "hasContentSecurityPolicyHeaders": hasFuncService(label.SuffixFrontendHeadersContentSecurityPolicy), + "getContentSecurityPolicyHeaders": getFuncStringService(label.SuffixFrontendHeadersContentSecurityPolicy, ""), + "hasPublicKeyHeaders": hasFuncService(label.SuffixFrontendHeadersPublicKey), + "getPublicKeyHeaders": getFuncStringService(label.SuffixFrontendHeadersPublicKey, ""), + "hasReferrerPolicyHeaders": hasFuncService(label.SuffixFrontendHeadersReferrerPolicy), + "getReferrerPolicyHeaders": getFuncStringService(label.SuffixFrontendHeadersReferrerPolicy, ""), + "hasIsDevelopmentHeaders": hasFuncService(label.SuffixFrontendHeadersIsDevelopment), + "getIsDevelopmentHeaders": getFuncBoolService(label.SuffixFrontendHeadersIsDevelopment, false), } v := url.Values{} @@ -341,7 +341,8 @@ func hasMaxConnLabels(application marathon.Application) bool { } // TODO: Deprecated -// Deprecated replaced by Stickiness +// replaced by Stickiness +// Deprecated func getSticky(application marathon.Application) string { if label.HasP(application.Labels, label.TraefikBackendLoadBalancerSticky) { log.Warnf("Deprecated configuration found: %s. Please use %s.", label.TraefikBackendLoadBalancerSticky, label.TraefikBackendLoadBalancerStickiness) @@ -421,29 +422,30 @@ func retrieveAvailablePorts(application marathon.Application, task marathon.Task func hasRedirect(application marathon.Application, serviceName string) bool { labels := getLabels(application, serviceName) - frep := label.Has(labels, getLabelName(serviceName, label.TraefikFrontendRedirectEntryPoint)) - frrg := label.Has(labels, getLabelName(serviceName, label.TraefikFrontendRedirectRegex)) - frrp := label.Has(labels, getLabelName(serviceName, label.TraefikFrontendRedirectReplacement)) + frep := label.Has(labels, getLabelName(serviceName, label.SuffixFrontendRedirectEntryPoint)) + frrg := label.Has(labels, getLabelName(serviceName, label.SuffixFrontendRedirectRegex)) + frrp := label.Has(labels, getLabelName(serviceName, label.SuffixFrontendRedirectReplacement)) return frep || frrg && frrp } -func hasErrorPages(application marathon.Application, serviceName string) bool { - labels := getLabels(application, serviceName) - return label.HasPrefix(labels, label.Prefix+label.BaseFrontendErrorPage) -} - func getErrorPages(application marathon.Application, serviceName string) map[string]*types.ErrorPage { labels := getLabels(application, serviceName) + prefix := getLabelName(serviceName, label.BaseFrontendErrorPage) - prefix := label.Prefix + label.BaseFrontendErrorPage + if len(serviceName) > 0 { + return label.ParseErrorPages(labels, prefix, label.RegexpBaseFrontendErrorPage) + } return label.ParseErrorPages(labels, prefix, label.RegexpFrontendErrorPage) } func getRateLimits(application marathon.Application, serviceName string) map[string]*types.Rate { labels := getLabels(application, serviceName) + prefix := getLabelName(serviceName, label.BaseFrontendRateLimit) - prefix := label.Prefix + label.BaseFrontendRateLimit + if len(serviceName) > 0 { + return label.ParseRateSets(labels, prefix, label.RegexpBaseFrontendRateLimit) + } return label.ParseRateSets(labels, prefix, label.RegexpFrontendRateLimit) } @@ -484,6 +486,15 @@ func hasFuncService(labelName string) func(application marathon.Application, ser } } +func hasPrefixFuncService(prefix string) func(application marathon.Application, serviceName string) bool { + return func(application marathon.Application, serviceName string) bool { + labels := getLabels(application, serviceName) + lbName := getLabelName(serviceName, prefix) + + return label.HasPrefix(labels, lbName) + } +} + func getFuncStringService(labelName string, defaultValue string) func(application marathon.Application, serviceName string) string { return func(application marathon.Application, serviceName string) string { labels := getLabels(application, serviceName) diff --git a/provider/marathon/config_test.go b/provider/marathon/config_test.go index ad429318a..7347c8ea8 100644 --- a/provider/marathon/config_test.go +++ b/provider/marathon/config_test.go @@ -4,7 +4,9 @@ import ( "errors" "fmt" "testing" + "time" + "github.com/containous/flaeg" "github.com/containous/traefik/provider/label" "github.com/containous/traefik/provider/marathon/mocks" "github.com/containous/traefik/types" @@ -1001,3 +1003,278 @@ func TestGetBackendServer(t *testing.T) { }) } } + +func TestHasRedirect(t *testing.T) { + testCases := []struct { + desc string + application marathon.Application + serviceName string + expected bool + }{ + { + desc: "without redirect labels", + application: application(), + expected: false, + }, + { + desc: "with entry point redirect label", + application: application( + withLabel(label.TraefikFrontendRedirectEntryPoint, "bar"), + ), + expected: true, + }, + { + desc: "with regex redirect labels", + application: application( + withLabel(label.TraefikFrontendRedirectRegex, "bar"), + withLabel(label.TraefikFrontendRedirectReplacement, "bar"), + ), + expected: true, + }, + { + desc: "with entry point redirect label on service", + application: application( + withLabel(label.Prefix+"foo."+label.SuffixFrontendRedirectEntryPoint, "bar"), + ), + serviceName: "foo", + expected: true, + }, + { + desc: "with entry point redirect label on service but not the same service", + application: application( + withLabel(label.Prefix+"foo."+label.SuffixFrontendRedirectEntryPoint, "bar"), + ), + serviceName: "foofoo", + expected: false, + }, + { + desc: "with regex redirect label on service", + application: application( + withLabel(label.Prefix+"foo."+label.SuffixFrontendRedirectRegex, "bar"), + withLabel(label.Prefix+"foo."+label.SuffixFrontendRedirectReplacement, "bar"), + ), + serviceName: "foo", + expected: true, + }, + { + desc: "with regex redirect label on service but not the same service", + application: application( + withLabel(label.Prefix+"foo."+label.SuffixFrontendRedirectRegex, "bar"), + withLabel(label.Prefix+"foo."+label.SuffixFrontendRedirectReplacement, "bar"), + ), + serviceName: "foofoo", + expected: false, + }, + } + + for _, test := range testCases { + test := test + t.Run(test.desc, func(t *testing.T) { + t.Parallel() + + actual := hasRedirect(test.application, test.serviceName) + + assert.Equal(t, test.expected, actual) + }) + } +} + +func TestHasPrefixFuncService(t *testing.T) { + testCases := []struct { + desc string + application marathon.Application + serviceName string + expected bool + }{ + { + desc: "with one label", + application: application( + withLabel(label.Prefix+label.BaseFrontendErrorPage+"goo"+label.SuffixErrorPageBackend, "bar"), + ), + expected: true, + }, + { + desc: "with one label on service", + application: application( + withLabel(label.Prefix+"foo."+label.BaseFrontendErrorPage+"goo"+label.SuffixErrorPageBackend, "bar"), + ), + serviceName: "foo", + expected: true, + }, + { + desc: "with one label on service but not the same service", + application: application( + withLabel(label.Prefix+"foo."+label.BaseFrontendErrorPage+"goo"+label.SuffixErrorPageBackend, "bar"), + ), + serviceName: "foofoo", + expected: false, + }, + } + + for _, test := range testCases { + test := test + t.Run(test.desc, func(t *testing.T) { + t.Parallel() + + actual := hasPrefixFuncService(label.BaseFrontendErrorPage)(test.application, test.serviceName) + + assert.Equal(t, test.expected, actual) + }) + } +} + +func TestGetErrorPages(t *testing.T) { + testCases := []struct { + desc string + application marathon.Application + serviceName string + expected map[string]*types.ErrorPage + }{ + { + desc: "with 2 error pages", + application: application( + withLabel(label.Prefix+label.BaseFrontendErrorPage+"goo."+label.SuffixErrorPageBackend, "bar1"), + withLabel(label.Prefix+label.BaseFrontendErrorPage+"goo."+label.SuffixErrorPageStatus, "bar2"), + withLabel(label.Prefix+label.BaseFrontendErrorPage+"goo."+label.SuffixErrorPageQuery, "bar3"), + withLabel(label.Prefix+label.BaseFrontendErrorPage+"hoo."+label.SuffixErrorPageBackend, "bar4"), + withLabel(label.Prefix+label.BaseFrontendErrorPage+"hoo."+label.SuffixErrorPageStatus, "bar5"), + withLabel(label.Prefix+label.BaseFrontendErrorPage+"hoo."+label.SuffixErrorPageQuery, "bar6"), + ), + expected: map[string]*types.ErrorPage{ + "goo": { + Backend: "bar1", + Query: "bar3", + Status: []string{"bar2"}, + }, + "hoo": { + Backend: "bar4", + Query: "bar6", + Status: []string{"bar5"}, + }, + }, + }, + { + desc: "with 2 error pages on service", + application: application( + withLabel(label.Prefix+"foo."+label.BaseFrontendErrorPage+"goo."+label.SuffixErrorPageBackend, "bar1"), + withLabel(label.Prefix+"foo."+label.BaseFrontendErrorPage+"goo."+label.SuffixErrorPageStatus, "bar2"), + withLabel(label.Prefix+"foo."+label.BaseFrontendErrorPage+"goo."+label.SuffixErrorPageQuery, "bar3"), + withLabel(label.Prefix+"foo."+label.BaseFrontendErrorPage+"hoo."+label.SuffixErrorPageBackend, "bar4"), + withLabel(label.Prefix+"foo."+label.BaseFrontendErrorPage+"hoo."+label.SuffixErrorPageStatus, "bar5"), + withLabel(label.Prefix+"foo."+label.BaseFrontendErrorPage+"hoo."+label.SuffixErrorPageQuery, "bar6"), + ), + serviceName: "foo", + expected: map[string]*types.ErrorPage{ + "goo": { + Backend: "bar1", + Query: "bar3", + Status: []string{"bar2"}, + }, + "hoo": { + Backend: "bar4", + Query: "bar6", + Status: []string{"bar5"}, + }, + }, + }, + { + desc: "with 1 error page on service but not the same service", + application: application( + withLabel(label.Prefix+"foo."+label.BaseFrontendErrorPage+"goo."+label.SuffixErrorPageBackend, "bar1"), + withLabel(label.Prefix+"foo."+label.BaseFrontendErrorPage+"goo."+label.SuffixErrorPageStatus, "bar2"), + withLabel(label.Prefix+"foo."+label.BaseFrontendErrorPage+"goo."+label.SuffixErrorPageQuery, "bar3"), + ), + serviceName: "foofoo", + expected: nil, + }, + } + + for _, test := range testCases { + test := test + t.Run(test.desc, func(t *testing.T) { + t.Parallel() + + pages := getErrorPages(test.application, test.serviceName) + + assert.EqualValues(t, test.expected, pages) + }) + } +} + +func TestGetRateLimits(t *testing.T) { + testCases := []struct { + desc string + application marathon.Application + serviceName string + expected map[string]*types.Rate + }{ + { + desc: "with 2 rate limits", + application: application( + withLabel(label.Prefix+label.BaseFrontendRateLimit+"goo."+label.SuffixRateLimitAverage, "1"), + withLabel(label.Prefix+label.BaseFrontendRateLimit+"goo."+label.SuffixRateLimitPeriod, "2"), + withLabel(label.Prefix+label.BaseFrontendRateLimit+"goo."+label.SuffixRateLimitBurst, "3"), + withLabel(label.Prefix+label.BaseFrontendRateLimit+"hoo."+label.SuffixRateLimitAverage, "4"), + withLabel(label.Prefix+label.BaseFrontendRateLimit+"hoo."+label.SuffixRateLimitPeriod, "5"), + withLabel(label.Prefix+label.BaseFrontendRateLimit+"hoo."+label.SuffixRateLimitBurst, "6"), + ), + expected: map[string]*types.Rate{ + "goo": { + Average: 1, + Period: flaeg.Duration(2 * time.Second), + Burst: 3, + }, + "hoo": { + Average: 4, + Period: flaeg.Duration(5 * time.Second), + Burst: 6, + }, + }, + }, + { + desc: "with 2 rate limits on service", + application: application( + withLabel(label.Prefix+"foo."+label.BaseFrontendRateLimit+"goo."+label.SuffixRateLimitAverage, "1"), + withLabel(label.Prefix+"foo."+label.BaseFrontendRateLimit+"goo."+label.SuffixRateLimitPeriod, "2"), + withLabel(label.Prefix+"foo."+label.BaseFrontendRateLimit+"goo."+label.SuffixRateLimitBurst, "3"), + withLabel(label.Prefix+"foo."+label.BaseFrontendRateLimit+"hoo."+label.SuffixRateLimitAverage, "4"), + withLabel(label.Prefix+"foo."+label.BaseFrontendRateLimit+"hoo."+label.SuffixRateLimitPeriod, "5"), + withLabel(label.Prefix+"foo."+label.BaseFrontendRateLimit+"hoo."+label.SuffixRateLimitBurst, "6"), + ), + serviceName: "foo", + expected: map[string]*types.Rate{ + "goo": { + Average: 1, + Period: flaeg.Duration(2 * time.Second), + Burst: 3, + }, + "hoo": { + Average: 4, + Period: flaeg.Duration(5 * time.Second), + Burst: 6, + }, + }, + }, + { + desc: "with 1 rate limit on service but not the same service", + application: application( + withLabel(label.Prefix+"foo."+label.BaseFrontendRateLimit+"goo."+label.SuffixRateLimitAverage, "1"), + withLabel(label.Prefix+"foo."+label.BaseFrontendRateLimit+"goo."+label.SuffixRateLimitPeriod, "2"), + withLabel(label.Prefix+"foo."+label.BaseFrontendRateLimit+"goo."+label.SuffixRateLimitBurst, "3"), + ), + serviceName: "foofoo", + expected: nil, + }, + } + + for _, test := range testCases { + test := test + t.Run(test.desc, func(t *testing.T) { + t.Parallel() + + limits := getRateLimits(test.application, test.serviceName) + + assert.EqualValues(t, test.expected, limits) + }) + } +}