Skip to content

Commit

Permalink
wip: use *bool to detect missing values
Browse files Browse the repository at this point in the history
- use *bool instead of bool for all value of Input and Overrides
- centralise post loading / override application
- add / adapt tests
  • Loading branch information
theseion committed Jun 24, 2023
1 parent 5c6ca66 commit 2b2e288
Show file tree
Hide file tree
Showing 13 changed files with 520 additions and 369 deletions.
2 changes: 1 addition & 1 deletion check/base.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ func (c *FTWCheck) SetExpectResponse(response string) {

// SetExpectError sets the boolean if we are expecting an error from the server
func (c *FTWCheck) SetExpectError(expect bool) {
c.expected.ExpectError = expect
c.expected.ExpectError = &expect
}

// SetLogContains sets the string to look for in logs
Expand Down
4 changes: 2 additions & 2 deletions check/base_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,11 +62,11 @@ func (s *checkBaseTestSuite) TestNewCheck() {
ResponseContains: "",
LogContains: "nothing",
NoLogContains: "",
ExpectError: true,
ExpectError: func() *bool { b := true; return &b }(),
}
c.SetExpectTestOutput(&to)

s.True(c.expected.ExpectError, "Problem setting expected output")
s.True(*c.expected.ExpectError, "Problem setting expected output")

c.SetNoLogContains("nologcontains")

Expand Down
6 changes: 3 additions & 3 deletions check/error.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ import "github.com/rs/zerolog/log"
// AssertExpectError helper to check if this error was expected or not
func (c *FTWCheck) AssertExpectError(err error) bool {
if err != nil {
log.Debug().Msgf("ftw/check: expected error? -> %t, and error is %s", c.expected.ExpectError, err.Error())
log.Debug().Msgf("ftw/check: expected error? -> %t, and error is %s", *c.expected.ExpectError, err.Error())
} else {
log.Debug().Msgf("ftw/check: expected error? -> %t, and error is nil", c.expected.ExpectError)
log.Debug().Msgf("ftw/check: expected error? -> %t, and error is nil", *c.expected.ExpectError)
}
if c.expected.ExpectError && err != nil {
if *c.expected.ExpectError && err != nil {
return true
}
return false
Expand Down
1 change: 1 addition & 0 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,4 +68,5 @@ func initConfig() {
if cloud {
cfg.RunMode = config.CloudRunMode
}

}
132 changes: 29 additions & 103 deletions runner/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import (
"github.com/coreruleset/go-ftw/waflog"
)

var errBadTestRequest = errors.New("ftw/run: bad test: choose between data, encoded_request, or raw_request")
var errBadTestInput = errors.New("ftw/run: bad test input: choose between data, encoded_request, or raw_request")

// Run runs your tests with the specified Config.
func Run(cfg *config.FTWConfiguration, tests []test.FTWTest, c RunnerConfig, out *output.Output) (*TestRunContext, error) {
Expand Down Expand Up @@ -75,9 +75,9 @@ func RunTest(runContext *TestRunContext, ftwTest test.FTWTest) error {

for _, testCase := range ftwTest.Tests {
// if we received a particular testid, skip until we find it
if needToSkipTest(runContext.Include, runContext.Exclude, testCase.TestTitle, ftwTest.Meta.Enabled) {
if needToSkipTest(runContext.Include, runContext.Exclude, testCase.TestTitle, *ftwTest.Meta.Enabled) {
runContext.Stats.addResultToStats(Skipped, testCase.TestTitle, 0)
if !ftwTest.Meta.Enabled && !runContext.ShowOnlyFailed {
if !*ftwTest.Meta.Enabled && !runContext.ShowOnlyFailed {
runContext.Output.Println("\tskipping %s - (enabled: false) in file.", testCase.TestTitle)
}
continue
Expand Down Expand Up @@ -115,16 +115,13 @@ func RunStage(runContext *TestRunContext, ftwCheck *check.FTWCheck, testCase tes
stageStartTime := time.Now()
stageID := uuid.NewString()
// Apply global overrides initially
testRequest := stage.Input
err := applyInputOverride(runContext.Config.TestOverride, &testRequest)
if err != nil {
log.Debug().Msgf("ftw/run: problem overriding input: %s", err.Error())
}
testInput := stage.Input
test.ApplyInputOverrides(&runContext.Config.TestOverride.Overrides, &testInput)
expectedOutput := stage.Output

// Check sanity first
if checkTestSanity(testRequest) {
return errBadTestRequest
if checkTestSanity(testInput) {
return errBadTestInput
}

// Do not even run test if result is overridden. Just use the override and display the overridden result.
Expand All @@ -138,38 +135,38 @@ func RunStage(runContext *TestRunContext, ftwCheck *check.FTWCheck, testCase tes

// Destination is needed for a request
dest := &ftwhttp.Destination{
DestAddr: testRequest.GetDestAddr(),
Port: testRequest.GetPort(),
Protocol: testRequest.GetProtocol(),
DestAddr: testInput.GetDestAddr(),
Port: testInput.GetPort(),
Protocol: testInput.GetProtocol(),
}

if notRunningInCloudMode(ftwCheck) {
startMarker, err := markAndFlush(runContext, dest, stageID)
if err != nil && !expectedOutput.ExpectError {
if err != nil && !*expectedOutput.ExpectError {
return fmt.Errorf("failed to find start marker: %w", err)
}
ftwCheck.SetStartMarker(startMarker)
}

req = getRequestFromTest(testRequest)
req = getRequestFromTest(testInput)

err = runContext.Client.NewConnection(*dest)
err := runContext.Client.NewConnection(*dest)

if err != nil && !expectedOutput.ExpectError {
if err != nil && !*expectedOutput.ExpectError {
return fmt.Errorf("can't connect to destination %+v: %w", dest, err)
}
runContext.Client.StartTrackingTime()

response, responseErr := runContext.Client.Do(*req)

runContext.Client.StopTrackingTime()
if responseErr != nil && !expectedOutput.ExpectError {
if responseErr != nil && !*expectedOutput.ExpectError {
return fmt.Errorf("failed sending request to destination %+v: %w", dest, responseErr)
}

if notRunningInCloudMode(ftwCheck) {
endMarker, err := markAndFlush(runContext, dest, stageID)
if err != nil && !expectedOutput.ExpectError {
if err != nil && !*expectedOutput.ExpectError {
return fmt.Errorf("failed to find end marker: %w", err)

}
Expand Down Expand Up @@ -270,10 +267,10 @@ func needToSkipTest(include *regexp.Regexp, exclude *regexp.Regexp, title string
return result
}

func checkTestSanity(testRequest test.Input) bool {
return (utils.IsNotEmpty(testRequest.Data) && testRequest.EncodedRequest != "") ||
(utils.IsNotEmpty(testRequest.Data) && testRequest.RAWRequest != "") ||
(testRequest.EncodedRequest != "" && testRequest.RAWRequest != "")
func checkTestSanity(testInput test.Input) bool {
return (utils.IsNotEmpty(testInput.Data) && testInput.EncodedRequest != "") ||
(utils.IsNotEmpty(testInput.Data) && testInput.RAWRequest != "") ||
(testInput.EncodedRequest != "" && testInput.RAWRequest != "")
}

func displayResult(rc *TestRunContext, result TestResult, roundTripTime time.Duration, stageTime time.Duration) {
Expand Down Expand Up @@ -353,104 +350,33 @@ func checkResult(c *check.FTWCheck, response *ftwhttp.Response, responseError er
return Success
}

func getRequestFromTest(testRequest test.Input) *ftwhttp.Request {
func getRequestFromTest(testInput test.Input) *ftwhttp.Request {
var req *ftwhttp.Request
// get raw request, if anything
raw, err := testRequest.GetRawRequest()
raw, err := testInput.GetRawRequest()
if err != nil {
log.Error().Msgf("ftw/run: error getting raw data: %s\n", err.Error())
}

// If we use raw or encoded request, then we don't use other fields
if raw != nil {
req = ftwhttp.NewRawRequest(raw, !testRequest.NoAutocompleteHeaders)
req = ftwhttp.NewRawRequest(raw, !*testInput.NoAutocompleteHeaders)
} else {
rline := &ftwhttp.RequestLine{
Method: testRequest.GetMethod(),
URI: testRequest.GetURI(),
Version: testRequest.GetVersion(),
Method: testInput.GetMethod(),
URI: testInput.GetURI(),
Version: testInput.GetVersion(),
}

data := testRequest.ParseData()
data := testInput.ParseData()
// create a new request
req = ftwhttp.NewRequest(rline, testRequest.Headers,
data, !testRequest.NoAutocompleteHeaders)
req = ftwhttp.NewRequest(rline, testInput.Headers,
data, !*testInput.NoAutocompleteHeaders)

}
return req
}

// 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.Overrides

if overrides.DestAddr != nil {
testRequest.DestAddr = overrides.DestAddr
if testRequest.Headers == nil {
testRequest.Headers = ftwhttp.Header{}
}
if overrides.OverrideEmptyHostHeader && testRequest.Headers.Get("Host") == "" {
testRequest.Headers.Set("Host", *overrides.DestAddr)
}
}

if overrides.Port != nil {
testRequest.Port = overrides.Port
}

if overrides.Protocol != nil {
testRequest.Protocol = overrides.Protocol
}

if overrides.URI != nil {
testRequest.URI = overrides.URI
}

if overrides.Version != nil {
testRequest.Version = overrides.Version
}

if overrides.Headers != nil {
if testRequest.Headers == nil {
testRequest.Headers = ftwhttp.Header{}
}
for k, v := range overrides.Headers {
testRequest.Headers.Set(k, v)
}
}

if overrides.Method != nil {
testRequest.Method = overrides.Method
}

if overrides.Data != nil {
testRequest.Data = overrides.Data
}

// TODO: postprocess
if overrides.SaveCookie != nil {
testRequest.SaveCookie = overrides.SaveCookie
}

if overrides.StopMagic != nil {
testRequest.StopMagic = overrides.StopMagic
}

if overrides.NoAutocompleteHeaders != nil {
testRequest.NoAutocompleteHeaders = overrides.NoAutocompleteHeaders
}

if overrides.EncodedRequest != nil {
testRequest.EncodedRequest = *overrides.EncodedRequest
}

if overrides.RAWRequest != nil {
testRequest.RAWRequest = *overrides.RAWRequest
}

return nil
}

func notRunningInCloudMode(c *check.FTWCheck) bool {
return !c.CloudMode()
}
Expand Down
Loading

0 comments on commit 2b2e288

Please sign in to comment.