From 17cfda8b22cb03e845fd02a60648628930d780fe Mon Sep 17 00:00:00 2001 From: Felipe Zipitria Date: Thu, 8 Feb 2024 17:22:26 -0300 Subject: [PATCH 1/2] fix: update package structure for overrides Signed-off-by: Felipe Zipitria --- cmd/generate-doc-yaml-schema/main.go | 6 +- {types/test => internal/helpers}/helpers.go | 8 +- spec/v1.2/ftw.md | 1978 +++++++++++++++++++ types/{test => }/examples.go | 22 +- types/overrides/examples.go | 16 +- types/overrides/types.go | 8 +- types/overrides/types_test.go | 2 +- types/{test => }/types.go | 12 +- types/{test => }/types_test.go | 48 +- 9 files changed, 2041 insertions(+), 59 deletions(-) rename {types/test => internal/helpers}/helpers.go (51%) create mode 100644 spec/v1.2/ftw.md rename types/{test => }/examples.go (69%) rename types/{test => }/types.go (96%) rename types/{test => }/types_test.go (65%) diff --git a/cmd/generate-doc-yaml-schema/main.go b/cmd/generate-doc-yaml-schema/main.go index d02556f..4ade37f 100644 --- a/cmd/generate-doc-yaml-schema/main.go +++ b/cmd/generate-doc-yaml-schema/main.go @@ -6,12 +6,12 @@ package main import ( "os" - overrides "github.com/coreruleset/ftw-tests-schema/types/overrides" - test "github.com/coreruleset/ftw-tests-schema/types/test" + "github.com/coreruleset/ftw-tests-schema/types" + "github.com/coreruleset/ftw-tests-schema/types/overrides" ) func main() { - data, err := test.GetFTWTestDoc().Encode() + data, err := types.GetFTWTestDoc().Encode() if err != nil { panic(err) } diff --git a/types/test/helpers.go b/internal/helpers/helpers.go similarity index 51% rename from types/test/helpers.go rename to internal/helpers/helpers.go index 4c38d7b..2f8fb9e 100644 --- a/types/test/helpers.go +++ b/internal/helpers/helpers.go @@ -1,16 +1,16 @@ // Copyright 2023 OWASP CRS // SPDX-License-Identifier: Apache-2.0 -package types +package helpers -func intPtr(i int) *int { +func IntPtr(i int) *int { return &i } -func boolPtr(b bool) *bool { +func BoolPtr(b bool) *bool { return &b } -func strPtr(s string) *string { +func StrPtr(s string) *string { return &s } diff --git a/spec/v1.2/ftw.md b/spec/v1.2/ftw.md new file mode 100644 index 0000000..c7a7e73 --- /dev/null +++ b/spec/v1.2/ftw.md @@ -0,0 +1,1978 @@ +## FTWTest +Welcome to the FTW YAMLFormat documentation. + In this document we will explain all the possible options that can be used within the YAML format. + Generally this is the preferred format for writing tests in as they don't require any programming skills + in order to understand and change. If you find a bug in this format please open an issue. + + + FTWTest is the base type used when unmarshaling YAML tests files + + + + + + +
+ +
+ +meta FTWTestMeta + +
+
+ +Meta describes the metadata information of this yaml test file + +
+ +
+ +
+ +tests []Test + +
+
+ +Tests is a list of FTW tests + + + +Examples: + + +```yaml +tests: + - test_title: 123456-1 + rule_id: 0 + test_id: 0 + desc: Unix RCE using `time` + stages: + - description: Get cookie from server + input: + dest_addr: 192.168.0.1 + port: 8080 + protocol: http + uri: /test + version: HTTP/1.1 + method: REPORT + headers: + Accept: '*/*' + Host: localhost + User-Agent: CRS Tests + save_cookie: false + stop_magic: true + autocomplete_headers: false + encoded_request: TXkgRGF0YQo= + output: + status: 200 + log_contains: nothing + log: + expect_id: 123456 + no_expect_id: 123456 + match_regex: id[:\s"]*123456 + no_match_regex: id[:\s"]*123456 + expect_error: true +``` + + +
+ +
+ + + + + +## FTWTestMeta + +Appears in: + + +- FTWTest.meta + + + + + +
+ +
+ +author string + +
+
+ +Author is the list of authors that added content to this file + + + +Examples: + + +```yaml +# Author +author: Felipe Zipitria +``` + + +
+ +
+ +
+ +enabled bool + +
+
+ +Enabled indicates if the tests are enabled to be run by the engine or not. + + + +Examples: + + +```yaml +# Enabled +enabled: false +``` + + +
+ +
+ +
+ +name string + +
+
+ +Name is the name of the tests contained in this file. + + + +Examples: + + +```yaml +# Name +name: test01 +``` + + +
+ +
+ +
+ +description string + +
+
+ +Description is a textual description of the tests contained in this file. + + + +Examples: + + +```yaml +# Description +description: The tests here target SQL injection. +``` + + +
+ +
+ +
+ +version string + +
+
+ +Version is the version of the YAML Schema. + + + +Examples: + + +```yaml +# Version +version: v1 +``` + + +
+ +
+ + + + + +## Test + +Appears in: + + +- FTWTest.tests + + +```yaml +- test_title: 123456-1 + rule_id: 0 + test_id: 0 + desc: Unix RCE using `time` + stages: + - description: Get cookie from server + input: + dest_addr: 192.168.0.1 + port: 8080 + protocol: http + uri: /test + version: HTTP/1.1 + method: REPORT + headers: + Accept: '*/*' + Host: localhost + User-Agent: CRS Tests + save_cookie: false + stop_magic: true + autocomplete_headers: false + encoded_request: TXkgRGF0YQo= + output: + status: 200 + log_contains: nothing + log: + expect_id: 123456 + no_expect_id: 123456 + match_regex: id[:\s"]*123456 + no_match_regex: id[:\s"]*123456 + expect_error: true +``` + + + +
+ +
+ +test_title string + +
+
+ +TestTitle is the title of this particular types. It is used for inclusion/exclusion of each run by the tool. + + + +Examples: + + +```yaml +test_title: 123456-1 +``` + + +
+ +
+ +
+ +rule_id int + +
+
+ +RuleId is the ID of the rule this test targets + + + +Examples: + + +```yaml +# RuleId +rule_id: 123456 +``` + + +
+ +
+ +
+ +test_id int + +
+
+ +TestId is the ID of the test, in relation to `rule_id` + + + +Examples: + + +```yaml +# TestId +test_id: 4 +``` + + +
+ +
+ +
+ +desc string + +
+
+ +TestDescription is the description for this particular types. Should be used to describe the internals of +the specific things this test is targeting. + + + +Examples: + + +```yaml +desc: Unix RCE using `time` +``` + + +
+ +
+ +
+ +stages []Stage + +
+
+ +Stages is the list of all the stages to perform this types. + + + +Examples: + + +```yaml +stages: + - description: Get cookie from server + input: + dest_addr: 192.168.0.1 + port: 8080 + protocol: http + uri: /test + version: HTTP/1.1 + method: REPORT + headers: + Accept: '*/*' + Host: localhost + User-Agent: CRS Tests + save_cookie: false + stop_magic: true + autocomplete_headers: false + encoded_request: TXkgRGF0YQo= + output: + status: 200 + log_contains: nothing + log: + expect_id: 123456 + no_expect_id: 123456 + match_regex: id[:\s"]*123456 + no_match_regex: id[:\s"]*123456 + expect_error: true +``` + + +
+ +
+ + + + + +## Stage + +Appears in: + + +- Test.stages + + +```yaml +- description: Get cookie from server + input: + dest_addr: 192.168.0.1 + port: 8080 + protocol: http + uri: /test + version: HTTP/1.1 + method: REPORT + headers: + Accept: '*/*' + Host: localhost + User-Agent: CRS Tests + save_cookie: false + stop_magic: true + autocomplete_headers: false + encoded_request: TXkgRGF0YQo= + output: + status: 200 + log_contains: nothing + log: + expect_id: 123456 + no_expect_id: 123456 + match_regex: id[:\s"]*123456 + no_match_regex: id[:\s"]*123456 + expect_error: true +``` + + + +
+ +
+ +stage StageData + +
+
+ +StageData is an individual test stage. + +
+ +
+ +
+ +description string + +
+
+ +Describes the purpose of this stage. + + + +Examples: + + +```yaml +description: Get cookie from server +``` + + +
+ +
+ +
+ +input Input + +
+
+ +Input is the data that is passed to the test + + + +Examples: + + +```yaml +# Input +input: + dest_addr: 192.168.0.1 + port: 8080 + protocol: http + uri: /test + version: HTTP/1.1 + method: REPORT + headers: + Accept: '*/*' + Host: localhost + User-Agent: CRS Tests + save_cookie: false + stop_magic: true + autocomplete_headers: false + encoded_request: TXkgRGF0YQo= +``` + + +
+ +
+ +
+ +output Output + +
+
+ +Output is the data that is returned from the test + + + +Examples: + + +```yaml +# Output +output: + status: 200 + log_contains: nothing + log: + expect_id: 123456 + no_expect_id: 123456 + match_regex: id[:\s"]*123456 + no_match_regex: id[:\s"]*123456 + expect_error: true +``` + + +
+ +
+ + + + + +## StageData + +Appears in: + + +- Stage.stage + + + + + +
+ +
+ +input Input + +
+
+ +Input is the data that is passed to the test + + + +Examples: + + +```yaml +# Input +input: + dest_addr: 192.168.0.1 + port: 8080 + protocol: http + uri: /test + version: HTTP/1.1 + method: REPORT + headers: + Accept: '*/*' + Host: localhost + User-Agent: CRS Tests + save_cookie: false + stop_magic: true + autocomplete_headers: false + encoded_request: TXkgRGF0YQo= +``` + + +
+ +
+ +
+ +output Output + +
+
+ +Output is the data that is returned from the test + + + +Examples: + + +```yaml +# Output +output: + status: 200 + log_contains: nothing + log: + expect_id: 123456 + no_expect_id: 123456 + match_regex: id[:\s"]*123456 + no_match_regex: id[:\s"]*123456 + expect_error: true +``` + + +
+ +
+ + + + + +## Input + +Appears in: + + +- Stage.input + +- StageData.input + + +```yaml +# Input +dest_addr: 192.168.0.1 +port: 8080 +protocol: http +uri: /test +version: HTTP/1.1 +method: REPORT +headers: + Accept: '*/*' + Host: localhost + User-Agent: CRS Tests +save_cookie: false +stop_magic: true +autocomplete_headers: false +encoded_request: TXkgRGF0YQo= +``` +```yaml +# Input +dest_addr: 192.168.0.1 +port: 8080 +protocol: http +uri: /test +version: HTTP/1.1 +method: REPORT +headers: + Accept: '*/*' + Host: localhost + User-Agent: CRS Tests +save_cookie: false +stop_magic: true +autocomplete_headers: false +encoded_request: TXkgRGF0YQo= +``` + + + +
+ +
+ +dest_addr string + +
+
+ +DestAddr is the IP of the destination host that the test will send the message to. + + + +Examples: + + +```yaml +# DestAddr +dest_addr: 127.0.0.1 +``` + + +
+ +
+ +
+ +port int + +
+
+ +Port allows you to declare which port on the destination host the test should connect to. + + + +Examples: + + +```yaml +# Port +port: 80 +``` + + +
+ +
+ +
+ +protocol string + +
+
+ +Protocol allows you to declare which protocol the test should use when sending the request. + + + +Examples: + + +```yaml +# Protocol +protocol: http +``` + + +
+ +
+ +
+ +uri string + +
+
+ +URI allows you to declare the URI the test should use as part of the request line. + + + +Examples: + + +```yaml +# URI +uri: /get?hello=world +``` + + +
+ +
+ +
+ +version string + +
+
+ +Version allows you to declare the HTTP version the test should use as part of the request line. + + + +Examples: + + +```yaml +# Version +version: "1.1" +``` + + +
+ +
+ +
+ +method string + +
+
+ +Method allows you to declare the HTTP method the test should use as part of the request line. + + + +Examples: + + +```yaml +# Method +method: GET +``` + + +
+ +
+ +
+ +headers map[string]string + +
+
+ +Method allows you to declare headers that the test should send. + + + +Examples: + + +```yaml +# Headers +headers: + Accept: '*/*' + Host: localhost + User-Agent: CRS Tests +``` + + +
+ +
+ +
+ +data string + +
+
+ +Data allows you to declare the payload that the test should in the request body. + + + +Examples: + + +```yaml +# Data +data: Bibitti bopi +``` + + +
+ +
+ +
+ +save_cookie bool + +
+
+ +SaveCookie allows you to automatically provide cookies if there are multiple stages and save cookie is set + + + +Examples: + + +```yaml +# SaveCookie +save_cookie: 80 +``` + + +
+ +
+ +
+ +stop_magic bool + +
+
+ +StopMagic is deprecated. + + + +Examples: + + +```yaml +# StopMagic +stop_magic: false +``` + + +
+ +
+ +
+ +autocomplete_headers bool + +
+
+ +AutocompleteHeaders allows the test framework to automatically fill the request with Content-Type and Connection headers. +Defaults to true. + + + +Examples: + + +```yaml +# StopMagic +autocomplete_headers: false +``` + + +
+ +
+ +
+ +encoded_request string + +
+
+ +EncodedRequest will take a base64 encoded string that will be decoded and sent through as the request. +It will override all other settings + + + +Examples: + + +```yaml +# EncodedRequest +encoded_request: a +``` + + +
+ +
+ +
+ +raw_request string + +
+
+ +RAWRequest is deprecated. + + + +Examples: + + +```yaml +# RAWRequest +raw_request: TXkgRGF0YQo= +``` + + +
+ +
+ + + + + +## Output + +Appears in: + + +- Stage.output + +- StageData.output + + +```yaml +# Output +status: 200 +log_contains: nothing +log: + expect_id: 123456 + no_expect_id: 123456 + match_regex: id[:\s"]*123456 + no_match_regex: id[:\s"]*123456 +expect_error: true +``` +```yaml +# Output +status: 200 +log_contains: nothing +log: + expect_id: 123456 + no_expect_id: 123456 + match_regex: id[:\s"]*123456 + no_match_regex: id[:\s"]*123456 +expect_error: true +``` + + + +
+ +
+ +status int + +
+
+ +Status describes the HTTP status code expected in the response. + + + +Examples: + + +```yaml +# Status +status: 200 +``` + + +
+ +
+ +
+ +response_contains string + +
+
+ +ResponseContains describes the text that should be contained in the HTTP response. + + + +Examples: + + +```yaml +# ResponseContains +response_contains: Hello, World +``` + + +
+ +
+ +
+ +log_contains string + +
+
+ +LogContains describes the text that should be contained in the WAF logs. + + + +Examples: + + +```yaml +# LogContains +log_contains: id 920100 +``` + + +
+ +
+ +
+ +no_log_contains string + +
+
+ +NoLogContains describes the text that should not be contained in the WAF logs. + + + +Examples: + + +```yaml +# NoLogContains +no_log_contains: id 920100 +``` + + +
+ +
+ +
+ +log Log + +
+
+ +Log is used to configure expectations about the log contents. + + + +Examples: + + +```yaml +log: + expect_id: 123456 + no_expect_id: 123456 + match_regex: id[:\s"]*123456 + no_match_regex: id[:\s"]*123456 +``` + + +
+ +
+ +
+ +expect_error bool + +
+
+ +When `ExpectError` is true, we don't expect an answer from the WAF, just an error. + + + +Examples: + + +```yaml +# ExpectError +expect_error: false +``` + + +
+ +
+ + + + + +## Log + +Appears in: + + +- Output.log + + +```yaml +expect_id: 123456 +no_expect_id: 123456 +match_regex: id[:\s"]*123456 +no_match_regex: id[:\s"]*123456 +``` + + + +
+ +
+ +expect_id int + +
+
+ +Expect the given ID to be contained in the log output. + + + +Examples: + + +```yaml +expect_id: 123456 +``` + + +
+ +
+ +
+ +no_expect_id int + +
+
+ +Expect the given ID _not_ to be contained in the log output. + + + +Examples: + + +```yaml +no_expect_id: 123456 +``` + + +
+ +
+ +
+ +match_regex string + +
+
+ +Expect the regular expression to match log content for the current types. + + + +Examples: + + +```yaml +match_regex: id[:\s"]*123456 +``` + + +
+ +
+ +
+ +no_match_regex string + +
+
+ +Expect the regular expression to _not_ match log content for the current types. + + + +Examples: + + +```yaml +no_match_regex: id[:\s"]*123456 +``` + + +
+ +
+ + + + + + + + +## FTWOverrides +FTWOverrides describes platform specific overrides for tests + + + + + + +
+ +
+ +version string + +
+
+ +The version field designates the version of the schema that validates this file + + + +Examples: + + +```yaml +version: v0.1.0 +``` + + +
+ +
+ +
+ +meta FTWOverridesMeta + +
+
+ +Meta describes the metadata information + + + +Examples: + + +```yaml +meta: + engine: libmodsecurity3 + platform: nginx + annotations: + os: Debian Bullseye + purpose: L7ASR test suite +``` + + +
+ +
+ +
+ +test_overrides []TestOverride + +
+
+ +List of test override specifications + + + +Examples: + + +```yaml +test_overrides: + - rule_id: 920100 + test_ids: [4, 6] + reason: |- + nginx returns 400 when `Content-Length` header is sent in a + `Transfer-Encoding: chunked` request. + expect_failure: true + output: + status: 200 + log_contains: nothing + log: + expect_id: 123456 + no_expect_id: 123456 + match_regex: id[:\s"]*123456 + no_match_regex: id[:\s"]*123456 + expect_error: true +``` + + +
+ +
+ + + + + +## FTWOverridesMeta + +Appears in: + + +- FTWOverrides.meta + + +```yaml +engine: libmodsecurity3 +platform: nginx +annotations: + os: Debian Bullseye + purpose: L7ASR test suite +``` + + + +
+ +
+ +engine string + +
+
+ +The name of the WAF engine the tests are expected to run against + + + +Examples: + + +```yaml +engine: coraza +``` + + +
+ +
+ +
+ +platform string + +
+
+ +The name of the platform (e.g., web server) the tests are expected to run against + + + +Examples: + + +```yaml +platform: nginx +``` + + +
+ +
+ +
+ +annotations map[string]string + +
+
+ +Custom annotations; can be used to add additional meta information + + + +Examples: + + +```yaml +annotations: + os: Debian Bullseye + purpose: L7ASR test suite +``` + + +
+ +
+ + + + + +## TestOverride + +Appears in: + + +- FTWOverrides.test_overrides + + +```yaml +- rule_id: 920100 + test_ids: [4, 6] + reason: |- + nginx returns 400 when `Content-Length` header is sent in a + `Transfer-Encoding: chunked` request. + expect_failure: true + output: + status: 200 + log_contains: nothing + log: + expect_id: 123456 + no_expect_id: 123456 + match_regex: id[:\s"]*123456 + no_match_regex: id[:\s"]*123456 + expect_error: true +``` + + + +
+ +
+ +rule_id int + +
+
+ +ID of the rule this test targets. + + + +Examples: + + +```yaml +rule_id: 920100 +``` + + +
+ +
+ +
+ +test_ids []int + +
+
+ +IDs of the tests for rule_id that overrides should be applied to. +If this field is not set, the overrides will be applied to all tests of rule_id. + + + +Examples: + + +```yaml +test_ids: + - 4 + - 6 +``` + + +
+ +
+ +
+ +reason string + +
+
+ +Describes why this override is necessary. + + + +Examples: + + +```yaml +reason: |- + nginx returns 400 when `Content-Length` header is sent in a + `Transfer-Encoding: chunked` request. +``` + + +
+ +
+ +
+ +expect_failure bool + +
+
+ +Whether this test is expected to fail for this particular configuration. +Default: false + + + +Examples: + + +```yaml +expect_failure: true +``` + + +
+ +
+ +
+ +retry_once bool + +
+
+ +Whether a stage should be retried once in case of failure. +This option is primarily a workaround for a race condition in phase 5, +where the log entry of a rule may be flushed after the test end marker. + + + +Examples: + + +```yaml +retry_once: true +``` + + +
+ +
+ +
+ +output types.Output + +
+
+ +Specifies overrides on the test output + + + +Examples: + + +```yaml +output: 400 +``` + + +
+ +
+ + + + + +## types.Output +Output is the response expected from the test + +Appears in: + + +- TestOverride.output + + +```yaml +400 +``` + + + +
+ +
+ +status int + +
+
+ +Status describes the HTTP status code expected in the response. + + + +Examples: + + +```yaml +# Status +status: 200 +``` + + +
+ +
+ +
+ +response_contains string + +
+
+ +ResponseContains describes the text that should be contained in the HTTP response. + + + +Examples: + + +```yaml +# ResponseContains +response_contains: Hello, World +``` + + +
+ +
+ +
+ +log_contains string + +
+
+ +LogContains describes the text that should be contained in the WAF logs. + + + +Examples: + + +```yaml +# LogContains +log_contains: id 920100 +``` + + +
+ +
+ +
+ +no_log_contains string + +
+
+ +NoLogContains describes the text that should not be contained in the WAF logs. + + + +Examples: + + +```yaml +# NoLogContains +no_log_contains: id 920100 +``` + + +
+ +
+ +
+ +log Log + +
+
+ +Log is used to configure expectations about the log contents. + + + +Examples: + + +```yaml +log: + expect_id: 123456 + no_expect_id: 123456 + match_regex: id[:\s"]*123456 + no_match_regex: id[:\s"]*123456 +``` + + +
+ +
+ +
+ +expect_error types.bool + +
+
+ +When `ExpectError` is true, we don't expect an answer from the WAF, just an error. + + + +Examples: + + +```yaml +# ExpectError +expect_error: false +``` + + +
+ +
+ + + + + +## types.Log + + + + + + +
+ +
+ +expect_id int + +
+
+ +Expect the given ID to be contained in the log output. + + + +Examples: + + +```yaml +expect_id: 123456 +``` + + +
+ +
+ +
+ +no_expect_id int + +
+
+ +Expect the given ID _not_ to be contained in the log output. + + + +Examples: + + +```yaml +no_expect_id: 123456 +``` + + +
+ +
+ +
+ +match_regex string + +
+
+ +Expect the regular expression to match log content for the current types. + + + +Examples: + + +```yaml +match_regex: id[:\s"]*123456 +``` + + +
+ +
+ +
+ +no_match_regex string + +
+
+ +Expect the regular expression to _not_ match log content for the current types. + + + +Examples: + + +```yaml +no_match_regex: id[:\s"]*123456 +``` + + +
+ +
+ + + + diff --git a/types/test/examples.go b/types/examples.go similarity index 69% rename from types/test/examples.go rename to types/examples.go index a53818c..1f4a330 100644 --- a/types/test/examples.go +++ b/types/examples.go @@ -3,6 +3,8 @@ package types +import "github.com/coreruleset/ftw-tests-schema/internal/helpers" + var ( ExampleTests = []Test{ ExampleTest, @@ -26,18 +28,18 @@ var ( "Accept": "*/*", } ExampleInput = Input{ - DestAddr: strPtr("192.168.0.1"), - Port: intPtr(8080), - Protocol: strPtr("http"), - URI: strPtr("/test"), - Version: strPtr("HTTP/1.1"), + DestAddr: helpers.StrPtr("192.168.0.1"), + Port: helpers.IntPtr(8080), + Protocol: helpers.StrPtr("http"), + URI: helpers.StrPtr("/test"), + Version: helpers.StrPtr("HTTP/1.1"), Headers: ExampleHeaders, - Method: strPtr("REPORT"), + Method: helpers.StrPtr("REPORT"), Data: nil, EncodedRequest: "TXkgRGF0YQo=", - SaveCookie: boolPtr(false), - StopMagic: boolPtr(true), - AutocompleteHeaders: boolPtr(false), + SaveCookie: helpers.BoolPtr(false), + StopMagic: helpers.BoolPtr(true), + AutocompleteHeaders: helpers.BoolPtr(false), } ExampleOutput = Output{ Status: 200, @@ -45,7 +47,7 @@ var ( LogContains: "nothing", NoLogContains: "", Log: ExampleLog, - ExpectError: boolPtr(true), + ExpectError: helpers.BoolPtr(true), } ExampleLog = Log{ ExpectId: 123456, diff --git a/types/overrides/examples.go b/types/overrides/examples.go index e41cdd5..2a6eb27 100644 --- a/types/overrides/examples.go +++ b/types/overrides/examples.go @@ -1,28 +1,28 @@ // Copyright 2023 OWASP CRS // SPDX-License-Identifier: Apache-2.0 -package types +package overrides -import test "github.com/coreruleset/ftw-tests-schema/types/test" +import "github.com/coreruleset/ftw-tests-schema/types" var ( // imported - AnnotationsExample = test.AnnotationsExample - ReasonExample = test.ReasonExample - ExampleLog = test.ExampleLog + AnnotationsExample = types.AnnotationsExample + ReasonExample = types.ReasonExample + ExampleLog = types.ExampleLog MetaExample = FTWOverridesMeta{ Engine: "libmodsecurity3", Platform: "nginx", - Annotations: test.AnnotationsExample, + Annotations: types.AnnotationsExample, } TestOverridesExample = []TestOverride{ { RuleId: 920100, TestIds: []int{4, 6}, - Reason: test.ReasonExample, + Reason: types.ReasonExample, ExpectFailure: func() *bool { b := true; return &b }(), - Output: test.ExampleOutput, + Output: types.ExampleOutput, }, } ) diff --git a/types/overrides/types.go b/types/overrides/types.go index a3cc363..c5c7df7 100644 --- a/types/overrides/types.go +++ b/types/overrides/types.go @@ -1,11 +1,11 @@ // Copyright 2023 OWASP CRS // SPDX-License-Identifier: Apache-2.0 -//go:generate dstdocgen -package types -path . -structure FTWOverrides -output ./overrides_doc.go +//go:generate dstdocgen -package overrides -path . -structure FTWOverrides -output ./overrides_doc.go -package types +package overrides -import test "github.com/coreruleset/ftw-tests-schema/types/test" +import "github.com/coreruleset/ftw-tests-schema/types" // FTWOverrides describes platform specific overrides for tests type FTWOverrides struct { @@ -89,5 +89,5 @@ type TestOverride struct { // Specifies overrides on the test output // examples: // - value: 400 - Output test.Output `yaml:"output"` + Output types.Output `yaml:"output"` } diff --git a/types/overrides/types_test.go b/types/overrides/types_test.go index 929ea16..324ea86 100644 --- a/types/overrides/types_test.go +++ b/types/overrides/types_test.go @@ -1,7 +1,7 @@ // Copyright 2023 OWASP CRS // SPDX-License-Identifier: Apache-2.0 -package types +package overrides import ( "testing" diff --git a/types/test/types.go b/types/types.go similarity index 96% rename from types/test/types.go rename to types/types.go index 1db55df..8de2617 100644 --- a/types/test/types.go +++ b/types/types.go @@ -70,10 +70,10 @@ type FTWTestMeta struct { Version string `yaml:"version,omitempty"` } -// Test is an individual test. One test can have multiple stages. +// Test is an individual types. One test can have multiple stages. type Test struct { // description: | - // TestTitle is the title of this particular test. It is used for inclusion/exclusion of each run by the tool. + // TestTitle is the title of this particular types. It is used for inclusion/exclusion of each run by the tool. // examples: // - value: ExampleTest.TestTitle // @@ -95,14 +95,14 @@ type Test struct { TestId int `yaml:"test_id"` // description: | - // TestDescription is the description for this particular test. Should be used to describe the internals of + // TestDescription is the description for this particular types. Should be used to describe the internals of // the specific things this test is targeting. // examples: // - value: ExampleTest.TestDescription TestDescription string `yaml:"desc,omitempty"` // description: | - // Stages is the list of all the stages to perform this test. + // Stages is the list of all the stages to perform this types. // examples: // - value: ExampleStages Stages []Stage `yaml:"stages"` @@ -319,13 +319,13 @@ type Log struct { NoExpectId int `yaml:"no_expect_id,omitempty"` // description: | - // Expect the regular expression to match log content for the current test. + // Expect the regular expression to match log content for the current types. // examples: // - value: ExampleLog.MatchRegex MatchRegex string `yaml:"match_regex,omitempty"` // description: | - // Expect the regular expression to _not_ match log content for the current test. + // Expect the regular expression to _not_ match log content for the current types. // examples: // - value: ExampleLog.NoMatchRegex NoMatchRegex string `yaml:"no_match_regex,omitempty"` diff --git a/types/test/types_test.go b/types/types_test.go similarity index 65% rename from types/test/types_test.go rename to types/types_test.go index 47a8a8b..34a9d05 100644 --- a/types/test/types_test.go +++ b/types/types_test.go @@ -8,6 +8,8 @@ import ( "github.com/goccy/go-yaml" "github.com/stretchr/testify/assert" + + "github.com/coreruleset/ftw-tests-schema/internal/helpers" ) var testYaml = `--- @@ -59,7 +61,7 @@ var ftwTest = &FTWTest{ FileName: "testYaml.yaml", Meta: FTWTestMeta{ Author: "ftw-tests-schema", - Enabled: boolPtr(true), + Enabled: helpers.BoolPtr(true), Name: "testYaml", Description: "Simple YAML to test that the schema is working.", }, @@ -82,9 +84,9 @@ var ftwTest = &FTWTest{ Stages: []Stage{ { Input: Input{ - DestAddr: strPtr("127.0.0.1"), - Port: intPtr(80), - Method: strPtr("OPTIONS"), + DestAddr: helpers.StrPtr("127.0.0.1"), + Port: helpers.IntPtr(80), + Method: helpers.StrPtr("OPTIONS"), Headers: map[string]string{ "User-Agent": "FTW Schema Tests", "Host": "localhost", @@ -101,39 +103,39 @@ var ftwTest = &FTWTest{ func TestUnmarshalFTWTest(t *testing.T) { var ftw FTWTest - assert := assert.New(t) + assertions := assert.New(t) err := yaml.Unmarshal([]byte(testYaml), &ftw) - assert.NoError(err) + assertions.NoError(err) - assert.Equal(ftwTest.FileName, ftw.FileName) - assert.Equal(ftwTest.Meta.Author, ftw.Meta.Author) - assert.Equal(ftwTest.Meta.Enabled, ftw.Meta.Enabled) - assert.Equal(ftwTest.Meta.Name, ftw.Meta.Name) - assert.Equal(ftwTest.Meta.Description, ftw.Meta.Description) - assert.Len(ftwTest.Tests, len(ftw.Tests)) + assertions.Equal(ftwTest.FileName, ftw.FileName) + assertions.Equal(ftwTest.Meta.Author, ftw.Meta.Author) + assertions.Equal(ftwTest.Meta.Enabled, ftw.Meta.Enabled) + assertions.Equal(ftwTest.Meta.Name, ftw.Meta.Name) + assertions.Equal(ftwTest.Meta.Description, ftw.Meta.Description) + assertions.Len(ftwTest.Tests, len(ftw.Tests)) for i, test := range ftw.Tests { expectedTest := ftwTest.Tests[i] - assert.Equal(expectedTest.TestTitle, test.TestTitle) - assert.Equal(expectedTest.RuleId, test.RuleId) - assert.Equal(expectedTest.TestId, test.TestId) - assert.Len(test.Stages, len(expectedTest.Stages)) + assertions.Equal(expectedTest.TestTitle, test.TestTitle) + assertions.Equal(expectedTest.RuleId, test.RuleId) + assertions.Equal(expectedTest.TestId, test.TestId) + assertions.Len(test.Stages, len(expectedTest.Stages)) for j, stage := range test.Stages { expectedStage := expectedTest.Stages[j] - assert.Equal(expectedStage.Input.DestAddr, stage.Input.DestAddr) - assert.Equal(expectedStage.Input.Port, stage.Input.Port) - assert.Equal(expectedStage.Input.Method, stage.Input.Method) - assert.Len(stage.Input.Headers, len(expectedStage.Input.Headers)) + assertions.Equal(expectedStage.Input.DestAddr, stage.Input.DestAddr) + assertions.Equal(expectedStage.Input.Port, stage.Input.Port) + assertions.Equal(expectedStage.Input.Method, stage.Input.Method) + assertions.Len(stage.Input.Headers, len(expectedStage.Input.Headers)) for k, header := range stage.Input.Headers { expectedHeader := expectedStage.Input.Headers[k] - assert.Equal(expectedHeader, header) + assertions.Equal(expectedHeader, header) } - assert.Equal(expectedStage.Output.NoLogContains, stage.Output.NoLogContains) - assert.Equal(expectedStage.Output.Status, stage.Output.Status) + assertions.Equal(expectedStage.Output.NoLogContains, stage.Output.NoLogContains) + assertions.Equal(expectedStage.Output.Status, stage.Output.Status) } } } From 0230d109519a5c7db9b8e37d04b389f9fae121a1 Mon Sep 17 00:00:00 2001 From: Max Leske Date: Sat, 10 Feb 2024 09:27:08 +0100 Subject: [PATCH 2/2] feat: clean up markup generator binary --- .gitignore | 3 +++ magefile.go | 9 +++++++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 3b9eaa7..e80be65 100644 --- a/.gitignore +++ b/.gitignore @@ -16,3 +16,6 @@ # Generated files **/*_doc.go + +# Markdown generator binary +generate-doc-yaml-schema diff --git a/magefile.go b/magefile.go index acc8ede..d2366d8 100644 --- a/magefile.go +++ b/magefile.go @@ -10,6 +10,7 @@ import ( "errors" "fmt" "io" + "os" "github.com/magefile/mage/mg" "github.com/magefile/mage/sh" @@ -93,11 +94,15 @@ func Test() error { // Generate Markdown output (printed to terminal) func Markdown() error { mg.SerialDeps(Generate) + generatorBinary := "generate-doc-yaml-schema" - if err := sh.RunV("go", "build", "./cmd/generate-doc-yaml-schema"); err != nil { + if err := sh.RunV("go", "build", "./cmd/"+generatorBinary); err != nil { return err } - markdown, err := sh.Output("./generate-doc-yaml-schema") + + defer os.Remove(generatorBinary) + + markdown, err := sh.Output("./" + generatorBinary) if err != nil { return err }