From 328ff4afcabea63c5991ad06ffa6d3e9f7e902eb Mon Sep 17 00:00:00 2001 From: Matteo Pace Date: Tue, 28 Mar 2023 17:43:28 +0200 Subject: [PATCH] adds Overrides struct, aligns new tests structure to previous ones --- config/config_test.go | 6 ++-- config/types.go | 4 +-- runner/run.go | 2 +- runner/run_test.go | 82 +++++++++++++++++++++++++++++-------------- test/types.go | 43 ++++++++++++++++------- 5 files changed, 92 insertions(+), 45 deletions(-) diff --git a/config/config_test.go b/config/config_test.go index de570ade..5aeede68 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -54,14 +54,14 @@ func TestNewConfigConfig(t *testing.T) { assert.NoError(t, err) assert.NotNil(t, cfg) - assert.NotEmpty(t, cfg.TestOverride.Input, "Ignore list must not be empty") + assert.NotEmpty(t, cfg.TestOverride.Overrides, "Ignore list must not be empty") for id, text := range cfg.TestOverride.Ignore { assert.Contains(t, (*regexp.Regexp)(id).String(), "920400-1$", "Looks like we could not find item to ignore") assert.Equal(t, "This test must be ignored", text, "Text doesn't match") } - overrides := cfg.TestOverride.Input + overrides := cfg.TestOverride.Overrides assert.NotNil(t, overrides.DestAddr, "Looks like we are not overriding destination address") assert.Equal(t, "httpbin.org", *overrides.DestAddr, "Looks like we are not overriding destination address") } @@ -161,7 +161,7 @@ func TestNewDefaultConfigWithParams(t *testing.T) { cfg.WithLogfile("mylogfile.log") assert.Equal(t, "mylogfile.log", cfg.LogFile) overrides := FTWTestOverride{ - Input: test.Input{}, + Overrides: test.Overrides{}, Ignore: nil, ForcePass: nil, ForceFail: nil, diff --git a/config/types.go b/config/types.go index 3bdaa003..f8d1dff6 100644 --- a/config/types.go +++ b/config/types.go @@ -41,12 +41,12 @@ type FTWConfiguration struct { // FTWTestOverride holds four lists: // -// Input allows you to override input parameters in tests. An example usage is if you want to change the `dest_addr` of all tests to point to an external IP or host. +// Overrides allows you to override input parameters in tests. An example usage is if you want to change the `dest_addr` of all tests to point to an external IP or host. // Ignore is for tests you want to ignore. You should add a comment on why you ignore the test // ForcePass is for tests you want to pass unconditionally. You should add a comment on why you force to pass the test // ForceFail is for tests you want to fail unconditionally. You should add a comment on why you force to fail the test type FTWTestOverride struct { - Input test.Input `koanf:"input"` + Overrides test.Overrides `koanf:"input"` Ignore map[*FTWRegexp]string `koanf:"ignore"` ForcePass map[*FTWRegexp]string `koanf:"forcepass"` ForceFail map[*FTWRegexp]string `koanf:"forcefail"` diff --git a/runner/run.go b/runner/run.go index f267dba5..2427f5a8 100644 --- a/runner/run.go +++ b/runner/run.go @@ -379,7 +379,7 @@ func getRequestFromTest(testRequest test.Input) *ftwhttp.Request { // applyInputOverride will check if config had global overrides and write that into the test. func applyInputOverride(o config.FTWTestOverride, testRequest *test.Input) error { - overrides := o.Input + overrides := o.Overrides if overrides.Port != nil { testRequest.Port = overrides.Port } diff --git a/runner/run_test.go b/runner/run_test.go index 612327f9..015d831a 100644 --- a/runner/run_test.go +++ b/runner/run_test.go @@ -36,6 +36,34 @@ testoverride: protocol: "http" ` +var yamlConfigEmptyHostHeaderOverride = ` +--- +testoverride: + input: + dest_addr: %s + headers: + Host: %s + override_empty_host_header: true +` + +var yamlConfigHostHeaderOverride = ` +--- +testoverride: + input: + dest_addr: address.org + headers: + unique_id: %s +` + +var yamlConfigHeaderOverride = ` +--- +testoverride: + input: + dest_addr: address.org + headers: + unique_id: %s +` + var yamlConfigOverride = ` --- testoverride: @@ -419,12 +447,12 @@ func replaceDestinationInConfiguration(override *config.FTWTestOverride, dest ft replaceableAddress := "TEST_ADDR" replaceablePort := -1 - input := &override.Input - if input.DestAddr != nil && *input.DestAddr == replaceableAddress { - input.DestAddr = &dest.DestAddr + overriddenInputs := &override.Overrides + if overriddenInputs.DestAddr != nil && *overriddenInputs.DestAddr == replaceableAddress { + overriddenInputs.DestAddr = &dest.DestAddr } - if input.Port != nil && *input.Port == replaceablePort { - input.Port = &dest.Port + if overriddenInputs.Port != nil && *overriddenInputs.Port == replaceablePort { + overriddenInputs.Port = &dest.Port } } @@ -729,7 +757,7 @@ func TestApplyInputOverrideHostFromDestAddr(t *testing.T) { } cfg := &config.FTWConfiguration{ TestOverride: config.FTWTestOverride{ - Input: test.Input{ + Overrides: test.Overrides{ DestAddr: &overrideHost, }, }, @@ -754,7 +782,7 @@ func TestApplyInputOverrideEmptyHostHeaderSetHostFromDestAddr(t *testing.T) { } cfg := &config.FTWConfiguration{ TestOverride: config.FTWTestOverride{ - Input: test.Input{ + Overrides: test.Overrides{ DestAddr: &overrideHost, OverrideEmptyHostHeader: true, }, @@ -777,17 +805,8 @@ func TestApplyInputOverrideSetHostFromHostHeaderOverride(t *testing.T) { originalDestAddr := "original.com" overrideDestAddress := "wrong.org" overrideHostHeader := "override.com" - testConfig := ` ---- -testoverride: - input: - dest_addr: %s - headers: - Host: %s - override_empty_host_header: true -` - cfg, err1 := config.NewConfigFromString(fmt.Sprintf(testConfig, overrideDestAddress, overrideHostHeader)) + cfg, err1 := config.NewConfigFromString(fmt.Sprintf(yamlConfigEmptyHostHeaderOverride, overrideDestAddress, overrideHostHeader)) assert.NoError(t, err1) testInput := test.Input{ @@ -809,16 +828,27 @@ testoverride: func TestApplyInputOverrideSetHeaderOverridingExistingOne(t *testing.T) { originalHeaderValue := "original" overrideHeaderValue := "override" - testConfig := ` ---- -testoverride: - input: - dest_addr: address.org - headers: - unique_id: %s -` + cfg, err1 := config.NewConfigFromString(fmt.Sprintf(yamlConfigHostHeaderOverride, overrideHeaderValue)) + assert.NoError(t, err1) + + testInput := test.Input{ + Headers: ftwhttp.Header{"unique_id": originalHeaderValue}, + } + + assert.NotNil(t, testInput.Headers, "Header map must exist before overriding any header") + + err := applyInputOverride(cfg.TestOverride, &testInput) + assert.NoError(t, err, "Failed to apply input overrides") - cfg, err1 := config.NewConfigFromString(fmt.Sprintf(testConfig, overrideHeaderValue)) + overriddenHeader := testInput.Headers.Get("unique_id") + assert.NotEqual(t, "", overriddenHeader, "unique_id header must be set after overriding it") + assert.Equal(t, overrideHeaderValue, overriddenHeader, "Host header must be identical to overridden `Host` header.") +} + +func TestApplyInputOverrides(t *testing.T) { + originalHeaderValue := "original" + overrideHeaderValue := "override" + cfg, err1 := config.NewConfigFromString(fmt.Sprintf(yamlConfigHeaderOverride, overrideHeaderValue)) assert.NoError(t, err1) testInput := test.Input{ diff --git a/test/types.go b/test/types.go index e31fe2ef..fc515280 100644 --- a/test/types.go +++ b/test/types.go @@ -4,20 +4,37 @@ import "github.com/coreruleset/go-ftw/ftwhttp" // Input represents the input request in a stage // The fields `Version`, `Method` and `URI` we want to explicitly now when they are set to "" + type Input struct { - DestAddr *string `yaml:"dest_addr,omitempty" koanf:"dest_addr,omitempty"` - Port *int `yaml:"port,omitempty" koanf:"port,omitempty"` - Protocol *string `yaml:"protocol,omitempty" koanf:"protocol,omitempty"` - URI *string `yaml:"uri,omitempty" koanf:"uri,omitempty"` - Version *string `yaml:"version,omitempty" koanf:"version,omitempty"` - Headers ftwhttp.Header `yaml:"headers,omitempty" koanf:"headers,omitempty"` - Method *string `yaml:"method,omitempty" koanf:"method,omitempty"` - Data *string `yaml:"data,omitempty" koanf:"data,omitempty"` - SaveCookie bool `yaml:"save_cookie,omitempty" koanf:"save_cookie,omitempty"` - StopMagic bool `yaml:"stop_magic" koanf:"stop_magic,omitempty"` - EncodedRequest string `yaml:"encoded_request,omitempty" koanf:"encoded_request,omitempty"` - RAWRequest string `yaml:"raw_request,omitempty" koanf:"raw_request,omitempty"` - OverrideEmptyHostHeader bool `yaml:"override_empty_host_header,omitempty" koanf:"override_empty_host_header,omitempty"` + DestAddr *string `yaml:"dest_addr,omitempty" koanf:"dest_addr,omitempty"` + Port *int `yaml:"port,omitempty" koanf:"port,omitempty"` + Protocol *string `yaml:"protocol,omitempty" koanf:"protocol,omitempty"` + URI *string `yaml:"uri,omitempty" koanf:"uri,omitempty"` + Version *string `yaml:"version,omitempty" koanf:"version,omitempty"` + Headers ftwhttp.Header `yaml:"headers,omitempty" koanf:"headers,omitempty"` + Method *string `yaml:"method,omitempty" koanf:"method,omitempty"` + Data *string `yaml:"data,omitempty" koanf:"data,omitempty"` + SaveCookie bool `yaml:"save_cookie,omitempty" koanf:"save_cookie,omitempty"` + StopMagic bool `yaml:"stop_magic" koanf:"stop_magic,omitempty"` + EncodedRequest string `yaml:"encoded_request,omitempty" koanf:"encoded_request,omitempty"` + RAWRequest string `yaml:"raw_request,omitempty" koanf:"raw_request,omitempty"` +} + +// Overrides represents the overridden inputs that have to be applied to tests +type Overrides struct { + DestAddr *string `yaml:"dest_addr,omitempty" koanf:"dest_addr,omitempty"` + Port *int `yaml:"port,omitempty" koanf:"port,omitempty"` + Protocol *string `yaml:"protocol,omitempty" koanf:"protocol,omitempty"` + // URI *string `yaml:"uri,omitempty" koanf:"uri,omitempty"` + // Version *string `yaml:"version,omitempty" koanf:"version,omitempty"` + Headers ftwhttp.Header `yaml:"headers,omitempty" koanf:"headers,omitempty"` + // Method *string `yaml:"method,omitempty" koanf:"method,omitempty"` + // Data *string `yaml:"data,omitempty" koanf:"data,omitempty"` + // SaveCookie bool `yaml:"save_cookie,omitempty" koanf:"save_cookie,omitempty"` + // StopMagic bool `yaml:"stop_magic" koanf:"stop_magic,omitempty"` + // EncodedRequest string `yaml:"encoded_request,omitempty" koanf:"encoded_request,omitempty"` + // RAWRequest string `yaml:"raw_request,omitempty" koanf:"raw_request,omitempty"` + OverrideEmptyHostHeader bool `yaml:"override_empty_host_header,omitempty" koanf:"override_empty_host_header,omitempty"` } // Output is the response expected from the test