From f4ca8e91f2d3853e2bfc62e7c4450a07b4129326 Mon Sep 17 00:00:00 2001 From: Peter Kurfer Date: Sun, 12 Apr 2020 17:09:50 +0200 Subject: [PATCH] Add some tests to ensure proper configuration parsing --- internal/cmd/root.go | 2 +- pkg/api/protocol_handler.go | 2 +- plugins/dns_mock/main.go | 2 +- plugins/http_mock/main.go | 2 +- plugins/http_proxy/fallback.go | 6 +- plugins/http_proxy/fallback_test.go | 46 +++++++ plugins/http_proxy/main.go | 3 +- plugins/http_proxy/protocol_options_test.go | 126 ++++++++++++++++++++ plugins/tls_interceptor/main.go | 2 +- 9 files changed, 181 insertions(+), 10 deletions(-) create mode 100644 plugins/http_proxy/fallback_test.go create mode 100644 plugins/http_proxy/protocol_options_test.go diff --git a/internal/cmd/root.go b/internal/cmd/root.go index ae5f2c6..293db28 100644 --- a/internal/cmd/root.go +++ b/internal/cmd/root.go @@ -88,7 +88,7 @@ func startEndpoint(handler api.ProtocolHandler, config config.HandlerConfig, log ) } }() - handler.Run(config) + handler.Start(config) } func shutdownEndpoint(handler api.ProtocolHandler, wg *sync.WaitGroup, logger *zap.Logger) { diff --git a/pkg/api/protocol_handler.go b/pkg/api/protocol_handler.go index 98c2aa2..5b3607a 100644 --- a/pkg/api/protocol_handler.go +++ b/pkg/api/protocol_handler.go @@ -11,6 +11,6 @@ type PluginInstanceFactory func() ProtocolHandler type LoggingFactory func() (*zap.Logger, error) type ProtocolHandler interface { - Run(config config.HandlerConfig) + Start(config config.HandlerConfig) Shutdown(wg *sync.WaitGroup) } diff --git a/plugins/dns_mock/main.go b/plugins/dns_mock/main.go index 6e604e6..27f30b6 100644 --- a/plugins/dns_mock/main.go +++ b/plugins/dns_mock/main.go @@ -13,7 +13,7 @@ type dnsHandler struct { dnsServer []*dns.Server } -func (d *dnsHandler) Run(config config.HandlerConfig) { +func (d *dnsHandler) Start(config config.HandlerConfig) { options := loadFromConfig(config.Options()) addr := fmt.Sprintf("%s:%d", config.ListenAddress(), config.Port()) diff --git a/plugins/http_mock/main.go b/plugins/http_mock/main.go index 5a5c1e1..6f586a2 100644 --- a/plugins/http_mock/main.go +++ b/plugins/http_mock/main.go @@ -18,7 +18,7 @@ type httpHandler struct { server *http.Server } -func (p *httpHandler) Run(config config.HandlerConfig) { +func (p *httpHandler) Start(config config.HandlerConfig) { options := loadFromConfig(config.Options()) addr := fmt.Sprintf("%s:%d", config.ListenAddress(), config.Port()) p.server = &http.Server{Addr: addr, Handler: p.router} diff --git a/plugins/http_proxy/fallback.go b/plugins/http_proxy/fallback.go index 1a72564..6cd87f4 100644 --- a/plugins/http_proxy/fallback.go +++ b/plugins/http_proxy/fallback.go @@ -16,7 +16,7 @@ var ( func init() { fallbackStrategies = map[string]ProxyFallbackStrategy{ - passthroughStrategyName: &passthroughFallbackStrategy{}, + passthroughStrategyName: &passThroughFallbackStrategy{}, notFoundStrategyName: ¬FoundFallbackStrategy{}, } } @@ -32,10 +32,10 @@ type ProxyFallbackStrategy interface { Apply(request *http.Request) (*http.Response, error) } -type passthroughFallbackStrategy struct { +type passThroughFallbackStrategy struct { } -func (p passthroughFallbackStrategy) Apply(request *http.Request) (*http.Response, error) { +func (p passThroughFallbackStrategy) Apply(request *http.Request) (*http.Response, error) { return nil, nil } diff --git a/plugins/http_proxy/fallback_test.go b/plugins/http_proxy/fallback_test.go new file mode 100644 index 0000000..09bf015 --- /dev/null +++ b/plugins/http_proxy/fallback_test.go @@ -0,0 +1,46 @@ +package main + +import ( + "reflect" + "testing" +) + +func TestStrategyForName(t *testing.T) { + type args struct { + name string + } + tests := []struct { + name string + args args + want reflect.Type + }{ + { + name: "Test get notfound strategy", + want: reflect.TypeOf(¬FoundFallbackStrategy{}), + args: args{ + name: "notfound", + }, + }, + { + name: "Test get pass through strategy", + want: reflect.TypeOf(&passThroughFallbackStrategy{}), + args: args{ + name: "passthrough", + }, + }, + { + name: "Test get fallback strategy notfound because key is not known", + want: reflect.TypeOf(¬FoundFallbackStrategy{}), + args: args{ + name: "asdf12234", + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := StrategyForName(tt.args.name); reflect.TypeOf(got) != tt.want { + t.Errorf("StrategyForName() = %v, want %v", got, tt.want) + } + }) + } +} diff --git a/plugins/http_proxy/main.go b/plugins/http_proxy/main.go index 78bbab3..08b5496 100644 --- a/plugins/http_proxy/main.go +++ b/plugins/http_proxy/main.go @@ -19,7 +19,7 @@ type httpProxy struct { server *http.Server } -func (h *httpProxy) Run(config config.HandlerConfig) { +func (h *httpProxy) Start(config config.HandlerConfig) { options := loadFromConfig(config.Options()) addr := fmt.Sprintf("%s:%d", config.ListenAddress(), config.Port()) h.server = &http.Server{Addr: addr, Handler: h.proxy} @@ -32,7 +32,6 @@ func (h *httpProxy) Run(config config.HandlerConfig) { logger: h.logger, } h.proxy.OnRequest().Do(proxyHandler) - h.proxy.OnRequest().HandleConnect() go h.startProxy() } diff --git a/plugins/http_proxy/protocol_options_test.go b/plugins/http_proxy/protocol_options_test.go new file mode 100644 index 0000000..b706998 --- /dev/null +++ b/plugins/http_proxy/protocol_options_test.go @@ -0,0 +1,126 @@ +package main + +import ( + "bytes" + "github.com/spf13/viper" + "reflect" + "regexp" + "testing" +) + +func Test_loadFromConfig(t *testing.T) { + type args struct { + config string + } + tests := []struct { + name string + args args + wantOptions httpProxyOptions + }{ + { + name: "Parse proper configuration with notfound strategy", + args: args{ + config: ` +fallback: notfound, +rules: + - pattern: ".*" + response: ./assets/fakeFiles/default.html +`, + }, + wantOptions: httpProxyOptions{ + FallbackStrategy: StrategyForName(notFoundStrategyName), + Rules: []targetRule{ + { + response: "./assets/fakeFiles/default.html", + pattern: regexp.MustCompile(".*"), + }, + }, + }, + }, + { + name: "Parse proper configuration with pass through strategy", + args: args{ + config: ` +fallback: passthrough +rules: + - pattern: ".*" + response: ./assets/fakeFiles/default.html +`, + }, + wantOptions: httpProxyOptions{ + FallbackStrategy: StrategyForName(passthroughStrategyName), + Rules: []targetRule{ + { + response: "./assets/fakeFiles/default.html", + pattern: regexp.MustCompile(".*"), + }, + }, + }, + }, + { + name: "Parse proper configuration and preserve order of rules", + args: args{ + config: ` +fallback: notfound +rules: + - pattern: ".*\\.(?i)txt" + response: ./assets/fakeFiles/default.txt + - pattern: ".*" + response: ./assets/fakeFiles/default.html +`, + }, + wantOptions: httpProxyOptions{ + FallbackStrategy: StrategyForName(notFoundStrategyName), + Rules: []targetRule{ + { + response: "./assets/fakeFiles/default.txt", + pattern: regexp.MustCompile(".*\\.(?i)txt"), + }, + { + response: "./assets/fakeFiles/default.html", + pattern: regexp.MustCompile(".*"), + }, + }, + }, + }, + { + name: "Parse configuration with non existing fallback strategy key - falling back to 'notfound'", + args: args{ + config: ` +fallback: doesNotExist +rules: [] +`, + }, + wantOptions: httpProxyOptions{ + FallbackStrategy: StrategyForName(notFoundStrategyName), + Rules: nil, + }, + }, + { + name: "Parse configuration without any fallback key", + args: args{ + config: ` +f4llb4ck: doesNotExist +rules: [] +`, + }, + wantOptions: httpProxyOptions{ + FallbackStrategy: StrategyForName(notFoundStrategyName), + Rules: nil, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + config := viper.New() + config.SetConfigType("yaml") + if err := config.ReadConfig(bytes.NewBufferString(tt.args.config)); err != nil { + t.Errorf("failed to read config %v", err) + return + } + if gotOptions := loadFromConfig(config); !reflect.DeepEqual(gotOptions, tt.wantOptions) { + t.Errorf("loadFromConfig() = %v, want %v", gotOptions, tt.wantOptions) + } + }) + } +} diff --git a/plugins/tls_interceptor/main.go b/plugins/tls_interceptor/main.go index 3d6cf40..24af7d3 100644 --- a/plugins/tls_interceptor/main.go +++ b/plugins/tls_interceptor/main.go @@ -25,7 +25,7 @@ type tlsInterceptor struct { currentConnections []*proxyConn } -func (t *tlsInterceptor) Run(config config.HandlerConfig) { +func (t *tlsInterceptor) Start(config config.HandlerConfig) { var err error t.options = loadFromConfig(config.Options()) addr := fmt.Sprintf("%s:%d", config.ListenAddress(), config.Port())