From 6452df7c7fc051c34fc875eb5af38582b3cc907b Mon Sep 17 00:00:00 2001 From: Liz Rice Date: Thu, 24 Dec 2020 14:38:22 +0000 Subject: [PATCH] Expected result pattern not always shows (#784) * Add expectedResultPattern to invalid test when testing and try convert to numeric we didn't set expectedResultPattern value. * check for auditconfig before using it The current state is that when ever audit output is not what we search for we check for auditConfig output which is sometime empty and therefore create empty expected result as described in #694 * Fix issue about expectedResultPattern expectedResultPattern not always shown and wasn't accurate enough Issue #705 * Add tests for ExpectedResult and fixes Add tests for ExpectedResult with the new output and the verify that the fix is working * Add missing flags In some cases not having audit or audit_config flag would fail the test. So added just a simple commands like echo something to solve this issue Also add bitmask checks * Add example IAM policy * Pass RotateKubeletServerCertificate related checks if it's not found (#767) * Allow for environment variables to be checked in tests (#755) * Initial commit for checking environment variables for etcd * Revert config changes * Remove redundant struct data * Fix issues with failing tests * Initial changes based on code review * Add option to disable envTesting + Update docs * Initial tests * Finished testing * Fix broken tests * Add a total summary and always show all tests. (#759) Whether the total summary is shown can be specified with an option. Fixes #528 Signed-off-by: Christian Zunker * Update Readme.md file with link to Contribution guide (#754) * Update License with the year and the owner name Please add this to make your license agreement strong * Updated Readme.md file with license and proper documentation links I have added a proper license agreement to the documentation. Also shortened the links to the issues so that it does not break in any on the forks. * Update LICENSE * Update README.md * Update README.md * Remove erroneous license info Co-authored-by: Liz Rice * Support auto-detect platform when running on EKS or GKE (#683) * Support auto-detect platform when running on EKS or GKE * Change to get platform name from `kubectl version` * fix regexp and add test * Update Server Version match for EKS * try to get version info from api sever at first * Change expected expectedResultPattern Now expectedResultPattern is more verbose * Update ops tests * Fix unit tests * Fix bitmask output syntax * Changes to be committed: modified: check/check.go modified: check/test.go modified: check/test_test.go fix unit testing and test.go to resolve conflicts. * Change found to flagFound * add missing } * change found to flag found Co-authored-by: yoavrotems --- check/check.go | 14 +- check/data | 69 +++- check/test.go | 38 +- check/test_test.go | 989 ++++++++++++++++++++++++++++----------------- 4 files changed, 707 insertions(+), 403 deletions(-) diff --git a/check/check.go b/check/check.go index eb24bff..da621d7 100644 --- a/check/check.go +++ b/check/check.go @@ -84,7 +84,7 @@ type Check struct { AuditOutput string `json:"-"` AuditEnvOutput string `json:"-"` AuditConfigOutput string `json:"-"` - DisableEnvTesting bool `json:"-"` + DisableEnvTesting bool `json:"-"` } // Runner wraps the basic Run method. @@ -220,14 +220,22 @@ func (c *Check) execute() (finalOutput *testOutput, err error) { // Try with the auditOutput first, and if that's not found, try the auditConfigOutput t.auditUsed = AuditCommand result := *(t.execute(c.AuditOutput)) - if !result.found { + + // Check for AuditConfigOutput only if AuditConfig is set + if !result.flagFound && c.AuditConfig != "" { + //t.isConfigSetting = true t.auditUsed = AuditConfig result = *(t.execute(c.AuditConfigOutput)) - if !result.found && t.Env != "" { + if !result.flagFound && t.Env != "" { t.auditUsed = AuditEnv result = *(t.execute(c.AuditEnvOutput)) } } + + if !result.flagFound && t.Env != "" { + t.auditUsed = AuditEnv + result = *(t.execute(c.AuditEnvOutput)) + } res[i] = result expectedResultArr[i] = res[i].ExpectedResult } diff --git a/check/data b/check/data index 4e0b214..fa3c2fe 100644 --- a/check/data +++ b/check/data @@ -1,14 +1,15 @@ --- controls: id: 1 -text: "Master Checks" +text: "Test Checks" type: "master" groups: - id: 1.1 - text: "Kube-apiserver" + text: "First Group" checks: - id: 0 text: "flag is set" + audit: "echo \"Non empty command\"" tests: test_items: - flag: "--allow-privileged" @@ -16,6 +17,7 @@ groups: - id: 1 text: "flag is not set" + audit: "echo \"Non empty command\"" tests: test_items: - flag: "--basic-auth" @@ -23,6 +25,7 @@ groups: - id: 2 text: "flag value is set to some value" + audit: "echo \"Non empty command\"" tests: test_items: - flag: "--insecure-port" @@ -33,6 +36,7 @@ groups: - id: 3 text: "flag value is greater than or equal some number" + audit: "echo \"Non empty command\"" tests: test_items: - flag: "--audit-log-maxage" @@ -43,6 +47,7 @@ groups: - id: 4 text: "flag value is less than some number" + audit: "echo \"Non empty command\"" tests: test_items: - flag: "--max-backlog" @@ -53,6 +58,7 @@ groups: - id: 5 text: "flag value does not have some value" + audit: "echo \"Non empty command\"" tests: test_items: - flag: "--admission-control" @@ -63,6 +69,7 @@ groups: - id: 6 text: "test AND binary operation" + audit: "echo \"Non empty command\"" tests: bin_op: and test_items: @@ -73,6 +80,7 @@ groups: - id: 7 text: "test OR binary operation" + audit: "echo \"Non empty command\"" tests: bin_op: or test_items: @@ -87,38 +95,29 @@ groups: - id: 8 text: "test flag with arbitrary text" + audit: "echo \"Non empty command\"" tests: test_items: - - flag: "644" + - flag: "permissions" compare: op: eq - value: "644" + value: "SomeValue" set: true - id: 9 text: "test permissions" - audit: "/bin/sh -c 'if test -e $config; then stat -c %a $config; fi'" + audit: "/bin/sh -c 'if test -e $config; then stat -c permissions=%a $config; fi'" tests: - bin_op: or test_items: - - flag: "644" + - flag: "permissions" compare: - op: eq + op: bitmask value: "644" set: true - - flag: "640" - compare: - op: eq - value: "640" - set: true - - flag: "600" - compare: - op: eq - value: "600" - set: true - id: 10 text: "flag value includes some value in a comma-separated list, value is last in list" + audit: "echo \"Non empty command\"" tests: test_items: - flag: "--admission-control" @@ -129,6 +128,7 @@ groups: - id: 11 text: "flag value includes some value in a comma-separated list, value is first in list" + audit: "echo \"Non empty command\"" tests: test_items: - flag: "--admission-control" @@ -139,6 +139,7 @@ groups: - id: 12 text: "flag value includes some value in a comma-separated list, value middle of list" + audit: "echo \"Non empty command\"" tests: test_items: - flag: "--admission-control" @@ -149,6 +150,7 @@ groups: - id: 13 text: "flag value includes some value in a comma-separated list, value only one in list" + audit: "echo \"Non empty command\"" tests: test_items: - flag: "--admission-control" @@ -159,6 +161,7 @@ groups: - id: 14 text: "check that flag some-arg is set to some-val with ':' separator" + audit: "echo \"Non empty command\"" tests: test_items: - flag: "some-arg" @@ -169,7 +172,10 @@ groups: - id: 15 text: "jsonpath correct value on field" + audit: "echo \"Non empty command\"" + audit_config: "echo \"Non empty command\"" tests: + bin_op: or test_items: - path: "{.readOnlyPort}" compare: @@ -189,6 +195,8 @@ groups: - id: 16 text: "jsonpath correct case-sensitive value on string field" + audit: "echo \"Non empty command\"" + audit_config: "echo \"Non empty command\"" tests: test_items: - path: "{.stringValue}" @@ -209,6 +217,8 @@ groups: - id: 17 text: "jsonpath correct value on boolean field" + audit: "echo \"Non empty command\"" + audit_config: "echo \"Non empty command\"" tests: test_items: - path: "{.trueValue}" @@ -229,6 +239,8 @@ groups: - id: 18 text: "jsonpath field absent" + audit: "echo \"Non empty command\"" + audit_config: "echo \"Non empty command\"" tests: test_items: - path: "{.notARealField}" @@ -236,6 +248,8 @@ groups: - id: 19 text: "jsonpath correct value on nested field" + audit: "echo \"Non empty command\"" + audit_config: "echo \"Non empty command\"" tests: test_items: - path: "{.authentication.anonymous.enabled}" @@ -246,6 +260,8 @@ groups: - id: 20 text: "yamlpath correct value on field" + audit: "echo \"Non empty command\"" + audit_config: "echo \"Non empty command\"" tests: test_items: - path: "{.readOnlyPort}" @@ -256,6 +272,8 @@ groups: - id: 21 text: "yamlpath field absent" + audit: "echo \"Non empty command\"" + audit_config: "echo \"Non empty command\"" tests: test_items: - path: "{.fieldThatIsUnset}" @@ -263,6 +281,8 @@ groups: - id: 22 text: "yamlpath correct value on nested field" + audit: "echo \"Non empty command\"" + audit_config: "echo \"Non empty command\"" tests: test_items: - path: "{.authentication.anonymous.enabled}" @@ -273,6 +293,8 @@ groups: - id: 23 text: "path on invalid json" + audit: "echo \"Non empty command\"" + audit_config: "echo \"Non empty command\"" tests: test_items: - path: "{.authentication.anonymous.enabled}" @@ -283,13 +305,16 @@ groups: - id: 24 text: "path with broken expression" + audit: "echo \"Non empty command\"" + audit_config: "echo \"Non empty command\"" tests: test_items: - - path: "{.missingClosingBrace" + - path: "{.missingClosingBrace}" set: true - id: 25 text: "yamlpath on invalid yaml" + audit: "echo \"Non empty command\"" tests: test_items: - path: "{.authentication.anonymous.enabled}" @@ -300,6 +325,8 @@ groups: - id: 26 text: "check regex op matches" + audit: "echo \"Non empty command\"" + audit_config: "echo \"Non empty command\"" tests: test_items: - path: "{.currentMasterVersion}" @@ -310,6 +337,7 @@ groups: - id: 27 text: "check boolean flag with no value" + audit: "echo \"Non empty command\"" tests: test_items: - flag: "--peer-client-cert-auth" @@ -320,6 +348,7 @@ groups: - id: 28 text: "check boolean flag with false value" + audit: "echo \"Non empty command\"" tests: test_items: - flag: "--peer-client-cert-auth" @@ -587,7 +616,7 @@ groups: path: '{.readOnlyPort}' set: false scored: true - - id: 15 + - id: 16 text: "parameter and config file don't have same default - parameter has bad value and config is not present - failing" audit: "echo '--read-only-port=1'" audit_config: "echo ''" diff --git a/check/test.go b/check/test.go index 7664cd0..b5abd30 100644 --- a/check/test.go +++ b/check/test.go @@ -52,8 +52,8 @@ type AuditUsed string const ( AuditCommand AuditUsed = "auditCommand" - AuditConfig AuditUsed = "auditConfig" - AuditEnv AuditUsed = "auditEnv" + AuditConfig AuditUsed = "auditConfig" + AuditEnv AuditUsed = "auditEnv" ) type testItem struct { @@ -65,7 +65,7 @@ type testItem struct { Set bool Compare compare isMultipleOutput bool - auditUsed AuditUsed + auditUsed AuditUsed } type envTestItem testItem @@ -79,7 +79,7 @@ type compare struct { type testOutput struct { testResult bool - found bool + flagFound bool actualResult string ExpectedResult string } @@ -178,7 +178,7 @@ func (t envTestItem) findValue(s string) (match bool, value string, err error) { if len(out) > 0 { match = true value = out - }else{ + } else { match = false value = "" } @@ -221,7 +221,7 @@ func (t testItem) evaluate(s string) *testOutput { if t.Set { if match && t.Compare.Op != "" { - result.ExpectedResult, result.testResult = compareOp(t.Compare.Op, value, t.Compare.Value) + result.ExpectedResult, result.testResult = compareOp(t.Compare.Op, value, t.Compare.Value, t.value()) } else { result.ExpectedResult = fmt.Sprintf("'%s' is present", t.value()) result.testResult = match @@ -231,13 +231,14 @@ func (t testItem) evaluate(s string) *testOutput { result.testResult = !match } - result.found = match - glog.V(3).Info(fmt.Sprintf("found %v", result.found)) + result.flagFound = match + glog.V(3).Info(fmt.Sprintf("found %v", result.flagFound)) + return result } -func compareOp(tCompareOp string, flagVal string, tCompareValue string) (string, bool) { +func compareOp(tCompareOp string, flagVal string, tCompareValue string, flagName string) (string, bool) { expectedResultPattern := "" testResult := false @@ -266,24 +267,25 @@ func compareOp(tCompareOp string, flagVal string, tCompareValue string) (string, case "gt", "gte", "lt", "lte": a, b, err := toNumeric(flagVal, tCompareValue) if err != nil { + expectedResultPattern = "Invalid Number(s) used for comparison: '%s' '%s'" glog.V(1).Infof(fmt.Sprintf("Not numeric value - flag: %q - compareValue: %q %v\n", flagVal, tCompareValue, err)) - return "Invalid Number(s) used for comparison", false + return fmt.Sprintf(expectedResultPattern, flagVal, tCompareValue), false } switch tCompareOp { case "gt": - expectedResultPattern = "%s is greater than %s" + expectedResultPattern = "'%s' is greater than %s" testResult = a > b case "gte": - expectedResultPattern = "%s is greater or equal to %s" + expectedResultPattern = "'%s' is greater or equal to %s" testResult = a >= b case "lt": - expectedResultPattern = "%s is lower than %s" + expectedResultPattern = "'%s' is lower than %s" testResult = a < b case "lte": - expectedResultPattern = "%s is lower or equal to %s" + expectedResultPattern = "'%s' is lower or equal to %s" testResult = a <= b } @@ -292,11 +294,11 @@ func compareOp(tCompareOp string, flagVal string, tCompareValue string) (string, testResult = strings.Contains(flagVal, tCompareValue) case "nothave": - expectedResultPattern = " '%s' not have '%s'" + expectedResultPattern = "'%s' does not have '%s'" testResult = !strings.Contains(flagVal, tCompareValue) case "regex": - expectedResultPattern = " '%s' matched by '%s'" + expectedResultPattern = "'%s' matched by regex expression '%s'" opRe := regexp.MustCompile(tCompareValue) testResult = opRe.MatchString(flagVal) @@ -307,7 +309,7 @@ func compareOp(tCompareOp string, flagVal string, tCompareValue string) (string, testResult = allElementsValid(s, target) case "bitmask": - expectedResultPattern = "bitmask '%s' AND '%s'" + expectedResultPattern = "%s has permissions " + flagVal + ", expected %s or more restrictive" requested, err := strconv.ParseInt(flagVal, 8, 64) if err != nil { glog.V(1).Infof(fmt.Sprintf("Not numeric value - flag: %q - compareValue: %q %v\n", flagVal, tCompareValue, err)) @@ -324,7 +326,7 @@ func compareOp(tCompareOp string, flagVal string, tCompareValue string) (string, return expectedResultPattern, testResult } - return fmt.Sprintf(expectedResultPattern, flagVal, tCompareValue), testResult + return fmt.Sprintf(expectedResultPattern, flagName, tCompareValue), testResult } func unmarshal(s string, jsonInterface *interface{}) error { diff --git a/check/test_test.go b/check/test_test.go index cafc7a2..12879b4 100644 --- a/check/test_test.go +++ b/check/test_test.go @@ -48,248 +48,257 @@ func init() { func TestTestExecute(t *testing.T) { cases := []struct { - *Check - str string - strConfig string - strEnv string + check *Check + str string + strConfig string + expectedTestResult string + strEnv string }{ { - controls.Groups[0].Checks[0], - "2:45 ../kubernetes/kube-apiserver --allow-privileged=false --option1=20,30,40", - "", - "", + check: controls.Groups[0].Checks[0], + str: "2:45 ../kubernetes/kube-apiserver --allow-privileged=false --option1=20,30,40", + strConfig: "", + expectedTestResult: "'--allow-privileged' is present", }, { - controls.Groups[0].Checks[1], - "2:45 ../kubernetes/kube-apiserver --allow-privileged=false", - "", - "", + check: controls.Groups[0].Checks[1], + str: "2:45 ../kubernetes/kube-apiserver --allow-privileged=false", + strConfig: "", + expectedTestResult: "'--basic-auth' is not present", }, { - controls.Groups[0].Checks[2], - "niinai 13617 2635 99 19:26 pts/20 00:03:08 ./kube-apiserver --insecure-port=0 --anonymous-auth", - "", - "", + check: controls.Groups[0].Checks[2], + str: "niinai 13617 2635 99 19:26 pts/20 00:03:08 ./kube-apiserver --insecure-port=0 --anonymous-auth", + strConfig: "", + expectedTestResult: "'--insecure-port' is equal to '0'", }, { - controls.Groups[0].Checks[3], - "2:45 ../kubernetes/kube-apiserver --secure-port=0 --audit-log-maxage=40 --option", - "", - "", + check: controls.Groups[0].Checks[3], + str: "2:45 ../kubernetes/kube-apiserver --secure-port=0 --audit-log-maxage=40 --option", + strConfig: "", + expectedTestResult: "'--audit-log-maxage' is greater or equal to 30", }, { - controls.Groups[0].Checks[4], - "2:45 ../kubernetes/kube-apiserver --max-backlog=20 --secure-port=0 --audit-log-maxage=40 --option", - "", - "", + check: controls.Groups[0].Checks[4], + str: "2:45 ../kubernetes/kube-apiserver --max-backlog=20 --secure-port=0 --audit-log-maxage=40 --option", + strConfig: "", + expectedTestResult: "'--max-backlog' is lower than 30", }, { - controls.Groups[0].Checks[5], - "2:45 ../kubernetes/kube-apiserver --option --admission-control=WebHook,RBAC ---audit-log-maxage=40", - "", - "", + check: controls.Groups[0].Checks[5], + str: "2:45 ../kubernetes/kube-apiserver --option --admission-control=WebHook,RBAC ---audit-log-maxage=40", + strConfig: "", + expectedTestResult: "'--admission-control' does not have 'AlwaysAdmit'", }, { - controls.Groups[0].Checks[6], - "2:45 .. --kubelet-clientkey=foo --kubelet-client-certificate=bar --admission-control=Webhook,RBAC", - "", - "", + check: controls.Groups[0].Checks[6], + str: "2:45 .. --kubelet-clientkey=foo --kubelet-client-certificate=bar --admission-control=Webhook,RBAC", + strConfig: "", + expectedTestResult: "'--kubelet-client-certificate' is present AND '--kubelet-clientkey' is present", }, { - controls.Groups[0].Checks[7], - "2:45 .. --secure-port=0 --kubelet-client-certificate=bar --admission-control=Webhook,RBAC", - "", - "", + check: controls.Groups[0].Checks[7], + str: "2:45 .. --secure-port=0 --kubelet-client-certificate=bar --admission-control=Webhook,RBAC", + strConfig: "", + expectedTestResult: "'--secure-port' is equal to '0' OR '--secure-port' is not present", }, { - controls.Groups[0].Checks[8], - "644", - "", - "", + check: controls.Groups[0].Checks[8], + str: "permissions=SomeValue", + strConfig: "", + expectedTestResult: "'permissions' is equal to 'SomeValue'", }, { - controls.Groups[0].Checks[9], - "640", - "", - "", + check: controls.Groups[0].Checks[9], + str: "permissions=640", + strConfig: "", + expectedTestResult: "permissions has permissions 640, expected 644 or more restrictive", }, { - controls.Groups[0].Checks[9], - "600", - "", - "", + check: controls.Groups[0].Checks[9], + str: "permissions=600", + strConfig: "", + expectedTestResult: "permissions has permissions 600, expected 644 or more restrictive", }, { - controls.Groups[0].Checks[10], - "2:45 ../kubernetes/kube-apiserver --option --admission-control=WebHook,RBAC ---audit-log-maxage=40", - "", - "", + check: controls.Groups[0].Checks[10], + str: "2:45 ../kubernetes/kube-apiserver --option --admission-control=WebHook,RBAC ---audit-log-maxage=40", + strConfig: "", + expectedTestResult: "'--admission-control' has 'RBAC'", }, { - controls.Groups[0].Checks[11], - "2:45 ../kubernetes/kube-apiserver --option --admission-control=WebHook,RBAC ---audit-log-maxage=40", - "", - "", + check: controls.Groups[0].Checks[11], + str: "2:45 ../kubernetes/kube-apiserver --option --admission-control=WebHook,RBAC ---audit-log-maxage=40", + strConfig: "", + expectedTestResult: "'--admission-control' has 'WebHook'", }, { - controls.Groups[0].Checks[12], - "2:45 ../kubernetes/kube-apiserver --option --admission-control=WebHook,Something,RBAC ---audit-log-maxage=40", - "", - "", + check: controls.Groups[0].Checks[12], + str: "2:45 ../kubernetes/kube-apiserver --option --admission-control=WebHook,Something,RBAC ---audit-log-maxage=40", + strConfig: "", + expectedTestResult: "'--admission-control' has 'Something'", }, { - controls.Groups[0].Checks[13], - "2:45 ../kubernetes/kube-apiserver --option --admission-control=Something ---audit-log-maxage=40", - "", - "", + check: controls.Groups[0].Checks[13], + str: "2:45 ../kubernetes/kube-apiserver --option --admission-control=Something ---audit-log-maxage=40", + strConfig: "", + expectedTestResult: "'--admission-control' has 'Something'", }, { // check for ':' as argument-value separator, with space between arg and val - controls.Groups[0].Checks[14], - "2:45 kube-apiserver some-arg: some-val --admission-control=Something ---audit-log-maxage=40", - "", - "", + check: controls.Groups[0].Checks[14], + str: "2:45 kube-apiserver some-arg: some-val --admission-control=Something ---audit-log-maxage=40", + strConfig: "", + expectedTestResult: "'some-arg' is equal to 'some-val'", }, { // check for ':' as argument-value separator, with no space between arg and val - controls.Groups[0].Checks[14], - "2:45 kube-apiserver some-arg:some-val --admission-control=Something ---audit-log-maxage=40", - "", - "", + check: controls.Groups[0].Checks[14], + str: "2:45 kube-apiserver some-arg:some-val --admission-control=Something ---audit-log-maxage=40", + strConfig: "", + expectedTestResult: "'some-arg' is equal to 'some-val'", }, { - controls.Groups[0].Checks[15], - "", - "{\"readOnlyPort\": 15000}", - "", + check: controls.Groups[0].Checks[15], + str: "", + strConfig: "{\"readOnlyPort\": 15000}", + expectedTestResult: "'{.readOnlyPort}' is equal to '15000' OR '{.readOnlyPort}' is greater or equal to 15000 OR '{.readOnlyPort}' is lower or equal to 15000", }, { - controls.Groups[0].Checks[16], - "", - "{\"stringValue\": \"WebHook,Something,RBAC\"}", - "", + check: controls.Groups[0].Checks[16], + str: "", + strConfig: "{\"stringValue\": \"WebHook,Something,RBAC\"}", + expectedTestResult: "'{.stringValue}' is not equal to 'None' AND '{.stringValue}' is not equal to 'webhook,Something,RBAC' AND '{.stringValue}' is equal to 'WebHook,Something,RBAC'", }, { - controls.Groups[0].Checks[17], - "", - "{\"trueValue\": true}", - "", + check: controls.Groups[0].Checks[17], + str: "", + strConfig: "{\"trueValue\": true}", + expectedTestResult: "'{.trueValue}' is not equal to 'somethingElse' AND '{.trueValue}' is not equal to 'false' AND '{.trueValue}' is equal to 'true'", }, { - controls.Groups[0].Checks[18], - "", - "{\"readOnlyPort\": 15000}", - "", + check: controls.Groups[0].Checks[18], + str: "", + strConfig: "{\"readOnlyPort\": 15000}", + expectedTestResult: "'{.notARealField}' is not present", }, { - controls.Groups[0].Checks[19], - "", - "{\"authentication\": { \"anonymous\": {\"enabled\": false}}}", - "", + check: controls.Groups[0].Checks[19], + str: "", + strConfig: "{\"authentication\": { \"anonymous\": {\"enabled\": false}}}", + expectedTestResult: "'{.authentication.anonymous.enabled}' is equal to 'false'", }, { - controls.Groups[0].Checks[20], - "", - "readOnlyPort: 15000", - "", + check: controls.Groups[0].Checks[20], + str: "", + strConfig: "readOnlyPort: 15000", + expectedTestResult: "'{.readOnlyPort}' is greater than 14999", }, { - controls.Groups[0].Checks[21], - "", - "readOnlyPort: 15000", - "", + check: controls.Groups[0].Checks[21], + str: "", + strConfig: "readOnlyPort: 15000", + expectedTestResult: "'{.fieldThatIsUnset}' is not present", }, { - controls.Groups[0].Checks[22], - "", - "authentication:\n anonymous:\n enabled: false", - "", + check: controls.Groups[0].Checks[22], + str: "", + strConfig: "authentication:\n anonymous:\n enabled: false", + expectedTestResult: "'{.authentication.anonymous.enabled}' is equal to 'false'", }, { - controls.Groups[0].Checks[26], - "", - "currentMasterVersion: 1.12.7", - "", + check: controls.Groups[0].Checks[26], + str: "", + strConfig: "currentMasterVersion: 1.12.7", + expectedTestResult: "'{.currentMasterVersion}' matched by regex expression '^1\\.12.*$'", }, { - controls.Groups[0].Checks[27], - "--peer-client-cert-auth", - "", - "", + check: controls.Groups[0].Checks[27], + str: "--peer-client-cert-auth", + strConfig: "", + expectedTestResult: "'--peer-client-cert-auth' is equal to 'true'", }, { - controls.Groups[0].Checks[27], - "--abc=true --peer-client-cert-auth --efg=false", - "", - "", + check: controls.Groups[0].Checks[27], + str: "--abc=true --peer-client-cert-auth --efg=false", + strConfig: "", + expectedTestResult: "'--peer-client-cert-auth' is equal to 'true'", }, { - controls.Groups[0].Checks[27], - "--abc --peer-client-cert-auth --efg", - "", - "", + check: controls.Groups[0].Checks[27], + str: "--abc --peer-client-cert-auth --efg", + strConfig: "", + expectedTestResult: "'--peer-client-cert-auth' is equal to 'true'", }, { - controls.Groups[0].Checks[27], - "--peer-client-cert-auth=true", - "", - "", + check: controls.Groups[0].Checks[27], + str: "--peer-client-cert-auth=true", + strConfig: "", + expectedTestResult: "'--peer-client-cert-auth' is equal to 'true'", }, { - controls.Groups[0].Checks[27], - "--abc --peer-client-cert-auth=true --efg", - "", - "", + check: controls.Groups[0].Checks[27], + str: "--abc --peer-client-cert-auth=true --efg", + strConfig: "", + expectedTestResult: "'--peer-client-cert-auth' is equal to 'true'", }, { - controls.Groups[0].Checks[28], - "--abc --peer-client-cert-auth=false --efg", - "", - "", + check: controls.Groups[0].Checks[28], + str: "--abc --peer-client-cert-auth=false --efg", + strConfig: "", + expectedTestResult: "'--peer-client-cert-auth' is equal to 'false'", }, { - controls.Groups[0].Checks[29], - "2:45 ../kubernetes/kube-apiserver --option1=20,30,40", - "", - "SOME_OTHER_ENV=true\nALLOW_PRIVILEGED=false", + check: controls.Groups[0].Checks[29], + str: "2:45 ../kubernetes/kube-apiserver --option1=20,30,40", + strConfig: "", + expectedTestResult: "'ALLOW_PRIVILEGED' is present", + strEnv: "SOME_OTHER_ENV=true\nALLOW_PRIVILEGED=false", }, { - controls.Groups[0].Checks[30], - "2:45 ../kubernetes/kube-apiserver --option1=20,30,40", - "", - "", + check: controls.Groups[0].Checks[30], + str: "2:45 ../kubernetes/kube-apiserver --option1=20,30,40", + strConfig: "", + expectedTestResult: "'BASIC_AUTH' is not present", + strEnv: "", }, { - controls.Groups[0].Checks[31], - "2:45 ../kubernetes/kube-apiserver --option1=20,30,40", - "", - "INSECURE_PORT=0", + check: controls.Groups[0].Checks[31], + str: "2:45 ../kubernetes/kube-apiserver --option1=20,30,40", + strConfig: "", + expectedTestResult: "'INSECURE_PORT' is equal to '0'", + strEnv: "INSECURE_PORT=0", }, { - controls.Groups[0].Checks[32], - "2:45 ../kubernetes/kube-apiserver --option1=20,30,40", - "", - "AUDIT_LOG_MAXAGE=40", + check: controls.Groups[0].Checks[32], + str: "2:45 ../kubernetes/kube-apiserver --option1=20,30,40", + strConfig: "", + expectedTestResult: "'AUDIT_LOG_MAXAGE' is greater or equal to 30", + strEnv: "AUDIT_LOG_MAXAGE=40", }, { - controls.Groups[0].Checks[33], - "2:45 ../kubernetes/kube-apiserver --option1=20,30,40", - "", - "MAX_BACKLOG=20", + check: controls.Groups[0].Checks[33], + str: "2:45 ../kubernetes/kube-apiserver --option1=20,30,40", + strConfig: "", + expectedTestResult: "'MAX_BACKLOG' is lower than 30", + strEnv: "MAX_BACKLOG=20", }, } for _, c := range cases { - t.Run(c.Text, func(t *testing.T) { - c.Check.AuditOutput = c.str - c.Check.AuditConfigOutput = c.strConfig - c.Check.AuditEnvOutput = c.strEnv - res, err := c.Check.execute() + t.Run(c.check.Text, func(t *testing.T) { + c.check.AuditOutput = c.str + c.check.AuditConfigOutput = c.strConfig + c.check.AuditEnvOutput = c.strEnv + res, err := c.check.execute() if err != nil { t.Errorf(err.Error()) } if !res.testResult { - t.Errorf("expected:%v, got:%v", true, res) + t.Errorf("Test ID %v - expected:%v, got:%v", c.check.ID, true, res) + } + if res.ExpectedResult != c.expectedTestResult { + t.Errorf("Test ID %v - \nexpected:%v, \ngot: %v", c.check.ID, c.expectedTestResult, res.ExpectedResult) } }) } @@ -572,256 +581,512 @@ func TestCompareOp(t *testing.T) { cases := []struct { label string op string - flagVal string - compareValue string + flagVal string // Test output. + compareValue string // Flag value to compare with. expectedResultPattern string + flagName string // Compared flag name. testResult bool }{ // Test Op not matching - {label: "empty - op", op: "", flagVal: "", compareValue: "", expectedResultPattern: "", testResult: false}, - {label: "op=blah", op: "blah", flagVal: "foo", compareValue: "bar", expectedResultPattern: "", testResult: false}, + {label: "empty - op", op: "", flagVal: "", compareValue: "", expectedResultPattern: "", testResult: false, flagName: ""}, + {label: "op=blah", op: "blah", flagVal: "foo", compareValue: "bar", expectedResultPattern: "", testResult: false, flagName: ""}, // Test Op "eq" - {label: "op=eq, both empty", op: "eq", flagVal: "", compareValue: "", expectedResultPattern: "'' is equal to ''", testResult: true}, + {label: "op=eq, both empty", op: "eq", flagVal: "", compareValue: "", expectedResultPattern: "'' is equal to ''", testResult: true, flagName: ""}, {label: "op=eq, true==true", op: "eq", flagVal: "true", compareValue: "true", - expectedResultPattern: "'true' is equal to 'true'", - testResult: true}, + expectedResultPattern: "'parameterTrue' is equal to 'true'", + testResult: true, + flagName: "parameterTrue"}, {label: "op=eq, false==false", op: "eq", flagVal: "false", compareValue: "false", - expectedResultPattern: "'false' is equal to 'false'", - testResult: true}, + expectedResultPattern: "'parameterFalse' is equal to 'false'", + testResult: true, + flagName: "parameterFalse"}, {label: "op=eq, false==true", op: "eq", flagVal: "false", compareValue: "true", - expectedResultPattern: "'false' is equal to 'true'", - testResult: false}, + expectedResultPattern: "'parameterFalse' is equal to 'true'", + testResult: false, + flagName: "parameterFalse"}, {label: "op=eq, strings match", op: "eq", flagVal: "KubeletConfiguration", compareValue: "KubeletConfiguration", - expectedResultPattern: "'KubeletConfiguration' is equal to 'KubeletConfiguration'", - testResult: true}, + expectedResultPattern: "'--FlagNameKubeletConf' is equal to 'KubeletConfiguration'", + testResult: true, + flagName: "--FlagNameKubeletConf"}, {label: "op=eq, flagVal=empty", op: "eq", flagVal: "", compareValue: "KubeletConfiguration", - expectedResultPattern: "'' is equal to 'KubeletConfiguration'", - testResult: false}, + expectedResultPattern: "'--FlagNameKubeletConf' is equal to 'KubeletConfiguration'", + testResult: false, + flagName: "--FlagNameKubeletConf"}, - {label: "op=eq, compareValue=empty", op: "eq", flagVal: "KubeletConfiguration", + {label: "op=eq, compareValue=empty", + op: "eq", + flagVal: "KubeletConfiguration", compareValue: "", - expectedResultPattern: "'KubeletConfiguration' is equal to ''", - testResult: false}, + expectedResultPattern: "'--FlagNameKubeletConf' is equal to ''", + testResult: false, + flagName: "--FlagNameKubeletConf"}, // Test Op "noteq" - {label: "op=noteq, both empty", op: "noteq", flagVal: "", - compareValue: "", expectedResultPattern: "'' is not equal to ''", - testResult: false}, - - {label: "op=noteq, true!=true", op: "noteq", flagVal: "true", - compareValue: "true", - expectedResultPattern: "'true' is not equal to 'true'", - testResult: false}, - - {label: "op=noteq, false!=false", op: "noteq", flagVal: "false", - compareValue: "false", - expectedResultPattern: "'false' is not equal to 'false'", - testResult: false}, - - {label: "op=noteq, false!=true", op: "noteq", flagVal: "false", - compareValue: "true", - expectedResultPattern: "'false' is not equal to 'true'", - testResult: true}, - - {label: "op=noteq, strings match", op: "noteq", flagVal: "KubeletConfiguration", - compareValue: "KubeletConfiguration", - expectedResultPattern: "'KubeletConfiguration' is not equal to 'KubeletConfiguration'", - testResult: false}, - - {label: "op=noteq, flagVal=empty", op: "noteq", flagVal: "", - compareValue: "KubeletConfiguration", - expectedResultPattern: "'' is not equal to 'KubeletConfiguration'", - testResult: true}, - - {label: "op=noteq, compareValue=empty", op: "noteq", flagVal: "KubeletConfiguration", + {label: "op=noteq, both empty", + op: "noteq", + flagVal: "", compareValue: "", - expectedResultPattern: "'KubeletConfiguration' is not equal to ''", - testResult: true}, + expectedResultPattern: "'parameter' is not equal to ''", + testResult: false, + flagName: "parameter"}, + + {label: "op=noteq, true!=true", + op: "noteq", + flagVal: "true", + compareValue: "true", + expectedResultPattern: "'parameterTrue' is not equal to 'true'", + testResult: false, + flagName: "parameterTrue"}, + + {label: "op=noteq, false!=false", + op: "noteq", + flagVal: "false", + compareValue: "false", + expectedResultPattern: "'parameterFalse' is not equal to 'false'", + testResult: false, + flagName: "parameterFalse"}, + + {label: "op=noteq, false!=true", + op: "noteq", + flagVal: "false", + compareValue: "true", + expectedResultPattern: "'parameterFalse' is not equal to 'true'", + testResult: true, + flagName: "parameterFalse"}, + + {label: "op=noteq, strings match", + op: "noteq", + flagVal: "KubeletConfiguration", + compareValue: "KubeletConfiguration", + expectedResultPattern: "'--FlagNameKubeletConf' is not equal to 'KubeletConfiguration'", + testResult: false, + flagName: "--FlagNameKubeletConf"}, + + {label: "op=noteq, flagVal=empty", + op: "noteq", + flagVal: "", + compareValue: "KubeletConfiguration", + expectedResultPattern: "'--FlagNameKubeletConf' is not equal to 'KubeletConfiguration'", + testResult: true, + flagName: "--FlagNameKubeletConf"}, + + {label: "op=noteq, compareValue=empty", + op: "noteq", + flagVal: "KubeletConfiguration", + compareValue: "", + expectedResultPattern: "'--FlagNameKubeletConf' is not equal to ''", + testResult: true, + flagName: "--FlagNameKubeletConf"}, // Test Op "gt" - {label: "op=gt, both empty", op: "gt", flagVal: "", - compareValue: "", expectedResultPattern: "Invalid Number(s) used for comparison", - testResult: false}, - {label: "op=gt, 0 > 0", op: "gt", flagVal: "0", - compareValue: "0", expectedResultPattern: "0 is greater than 0", - testResult: false}, - {label: "op=gt, 4 > 5", op: "gt", flagVal: "4", - compareValue: "5", expectedResultPattern: "4 is greater than 5", - testResult: false}, - {label: "op=gt, 5 > 4", op: "gt", flagVal: "5", - compareValue: "4", expectedResultPattern: "5 is greater than 4", - testResult: true}, - {label: "op=gt, 5 > 5", op: "gt", flagVal: "5", - compareValue: "5", expectedResultPattern: "5 is greater than 5", - testResult: false}, - {label: "op=gt, Pikachu > 5", op: "gt", flagVal: "Pikachu", - compareValue: "5", expectedResultPattern: "Invalid Number(s) used for comparison", - testResult: false}, - {label: "op=gt, 5 > Bulbasaur", op: "gt", flagVal: "5", - compareValue: "Bulbasaur", expectedResultPattern: "Invalid Number(s) used for comparison", - testResult: false}, + {label: "op=gt, both empty", + op: "gt", + flagVal: "", + compareValue: "", + expectedResultPattern: "Invalid Number(s) used for comparison: '' ''", + testResult: false, + flagName: "flagName"}, + {label: "op=gt, 0 > 0", + op: "gt", + flagVal: "0", + compareValue: "0", expectedResultPattern: "'flagName' is greater than 0", + testResult: false, + flagName: "flagName"}, + {label: "op=gt, 4 > 5", + op: "gt", + flagVal: "4", + compareValue: "5", + expectedResultPattern: "'flagName' is greater than 5", + testResult: false, + flagName: "flagName"}, + {label: "op=gt, 5 > 4", + op: "gt", + flagVal: "5", + compareValue: "4", + expectedResultPattern: "'flagName' is greater than 4", + testResult: true, + flagName: "flagName"}, + {label: "op=gt, 5 > 5", + op: "gt", + flagVal: "5", + compareValue: "5", + expectedResultPattern: "'flagName' is greater than 5", + testResult: false, + flagName: "flagName"}, + {label: "op=gt, Pikachu > 5", + op: "gt", + flagVal: "Pikachu", + compareValue: "5", + expectedResultPattern: "Invalid Number(s) used for comparison: 'Pikachu' '5'", + testResult: false, + flagName: "flagName"}, + {label: "op=gt, 5 > Bulbasaur", + op: "gt", + flagVal: "5", + compareValue: "Bulbasaur", + expectedResultPattern: "Invalid Number(s) used for comparison: '5' 'Bulbasaur'", + testResult: false, + flagName: "flagName"}, // Test Op "lt" - {label: "op=lt, both empty", op: "lt", flagVal: "", - compareValue: "", expectedResultPattern: "Invalid Number(s) used for comparison", - testResult: false}, - {label: "op=lt, 0 < 0", op: "lt", flagVal: "0", - compareValue: "0", expectedResultPattern: "0 is lower than 0", - testResult: false}, - {label: "op=lt, 4 < 5", op: "lt", flagVal: "4", - compareValue: "5", expectedResultPattern: "4 is lower than 5", - testResult: true}, - {label: "op=lt, 5 < 4", op: "lt", flagVal: "5", - compareValue: "4", expectedResultPattern: "5 is lower than 4", - testResult: false}, - {label: "op=lt, 5 < 5", op: "lt", flagVal: "5", - compareValue: "5", expectedResultPattern: "5 is lower than 5", - testResult: false}, - {label: "op=lt, Charmander < 5", op: "lt", flagVal: "Charmander", - compareValue: "5", expectedResultPattern: "Invalid Number(s) used for comparison", - testResult: false}, - {label: "op=lt, 5 < Charmeleon", op: "lt", flagVal: "5", - compareValue: "Charmeleon", expectedResultPattern: "Invalid Number(s) used for comparison", - testResult: false}, + {label: "op=lt, both empty", + op: "lt", + flagVal: "", + compareValue: "", + expectedResultPattern: "Invalid Number(s) used for comparison: '' ''", + testResult: false, + flagName: "flagName"}, + {label: "op=lt, 0 < 0", + op: "lt", + flagVal: "0", + compareValue: "0", + expectedResultPattern: "'flagName' is lower than 0", + testResult: false, + flagName: "flagName"}, + {label: "op=lt, 4 < 5", + op: "lt", + flagVal: "4", + compareValue: "5", + expectedResultPattern: "'flagName' is lower than 5", + testResult: true, + flagName: "flagName"}, + {label: "op=lt, 5 < 4", + op: "lt", + flagVal: "5", + compareValue: "4", + expectedResultPattern: "'flagName' is lower than 4", + testResult: false, + flagName: "flagName"}, + {label: "op=lt, 5 < 5", + op: "lt", + flagVal: "5", + compareValue: "5", + expectedResultPattern: "'flagName' is lower than 5", + testResult: false, + flagName: "flagName"}, + {label: "op=lt, Charmander < 5", + op: "lt", + flagVal: "Charmander", + compareValue: "5", + expectedResultPattern: "Invalid Number(s) used for comparison: 'Charmander' '5'", + testResult: false, + flagName: "flagName"}, + {label: "op=lt, 5 < Charmeleon", + op: "lt", + flagVal: "5", + compareValue: "Charmeleon", + expectedResultPattern: "Invalid Number(s) used for comparison: '5' 'Charmeleon'", + testResult: false, + flagName: "flagName"}, // Test Op "gte" - {label: "op=gte, both empty", op: "gte", flagVal: "", - compareValue: "", expectedResultPattern: "Invalid Number(s) used for comparison", - testResult: false}, - {label: "op=gte, 0 >= 0", op: "gte", flagVal: "0", - compareValue: "0", expectedResultPattern: "0 is greater or equal to 0", - testResult: true}, - {label: "op=gte, 4 >= 5", op: "gte", flagVal: "4", - compareValue: "5", expectedResultPattern: "4 is greater or equal to 5", - testResult: false}, - {label: "op=gte, 5 >= 4", op: "gte", flagVal: "5", - compareValue: "4", expectedResultPattern: "5 is greater or equal to 4", - testResult: true}, - {label: "op=gte, 5 >= 5", op: "gte", flagVal: "5", - compareValue: "5", expectedResultPattern: "5 is greater or equal to 5", - testResult: true}, - {label: "op=gte, Ekans >= 5", op: "gte", flagVal: "Ekans", - compareValue: "5", expectedResultPattern: "Invalid Number(s) used for comparison", - testResult: false}, - {label: "op=gte, 4 >= Zubat", op: "gte", flagVal: "4", - compareValue: "Zubat", expectedResultPattern: "Invalid Number(s) used for comparison", - testResult: false}, + {label: "op=gte, both empty", + op: "gte", + flagVal: "", + compareValue: "", + expectedResultPattern: "Invalid Number(s) used for comparison: '' ''", + testResult: false, + flagName: "flagName"}, + {label: "op=gte, 0 >= 0", + op: "gte", + flagVal: "0", + compareValue: "0", + expectedResultPattern: "'flagName' is greater or equal to 0", + testResult: true, + flagName: "flagName"}, + {label: "op=gte, 4 >= 5", + op: "gte", + flagVal: "4", + compareValue: "5", + expectedResultPattern: "'flagName' is greater or equal to 5", + testResult: false, + flagName: "flagName"}, + {label: "op=gte, 5 >= 4", + op: "gte", + flagVal: "5", + compareValue: "4", + expectedResultPattern: "'flagName' is greater or equal to 4", + testResult: true, + flagName: "flagName"}, + {label: "op=gte, 5 >= 5", + op: "gte", + flagVal: "5", + compareValue: "5", + expectedResultPattern: "'flagName' is greater or equal to 5", + testResult: true, + flagName: "flagName"}, + {label: "op=gte, Ekans >= 5", + op: "gte", + flagVal: "Ekans", + compareValue: "5", + expectedResultPattern: "Invalid Number(s) used for comparison: 'Ekans' '5'", + testResult: false, + flagName: "flagName"}, + {label: "op=gte, 4 >= Zubat", + op: "gte", + flagVal: "4", + compareValue: "Zubat", + expectedResultPattern: "Invalid Number(s) used for comparison: '4' 'Zubat'", + testResult: false, + flagName: "flagName"}, // Test Op "lte" - {label: "op=lte, both empty", op: "lte", flagVal: "", - compareValue: "", expectedResultPattern: "Invalid Number(s) used for comparison", - testResult: false}, - {label: "op=lte, 0 <= 0", op: "lte", flagVal: "0", - compareValue: "0", expectedResultPattern: "0 is lower or equal to 0", - testResult: true}, - {label: "op=lte, 4 <= 5", op: "lte", flagVal: "4", - compareValue: "5", expectedResultPattern: "4 is lower or equal to 5", - testResult: true}, - {label: "op=lte, 5 <= 4", op: "lte", flagVal: "5", - compareValue: "4", expectedResultPattern: "5 is lower or equal to 4", - testResult: false}, - {label: "op=lte, 5 <= 5", op: "lte", flagVal: "5", - compareValue: "5", expectedResultPattern: "5 is lower or equal to 5", - testResult: true}, - {label: "op=lte, Venomoth <= 4", op: "lte", flagVal: "Venomoth", - compareValue: "4", expectedResultPattern: "Invalid Number(s) used for comparison", - testResult: false}, - {label: "op=lte, 5 <= Meowth", op: "lte", flagVal: "5", - compareValue: "Meowth", expectedResultPattern: "Invalid Number(s) used for comparison", - testResult: false}, + {label: "op=lte, both empty", + op: "lte", + flagVal: "", + compareValue: "", + expectedResultPattern: "Invalid Number(s) used for comparison: '' ''", + testResult: false, + flagName: "flagName"}, + {label: "op=lte, 0 <= 0", + op: "lte", + flagVal: "0", + compareValue: "0", + expectedResultPattern: "'flagName' is lower or equal to 0", + testResult: true, + flagName: "flagName"}, + {label: "op=lte, 4 <= 5", + op: "lte", + flagVal: "4", + compareValue: "5", + expectedResultPattern: "'flagName' is lower or equal to 5", + testResult: true, + flagName: "flagName"}, + {label: "op=lte, 5 <= 4", + op: "lte", + flagVal: "5", + compareValue: "4", + expectedResultPattern: "'flagName' is lower or equal to 4", + testResult: false, + flagName: "flagName"}, + {label: "op=lte, 5 <= 5", + op: "lte", + flagVal: "5", + compareValue: "5", + expectedResultPattern: "'flagName' is lower or equal to 5", + testResult: true, + flagName: "flagName"}, + {label: "op=lte, Venomoth <= 4", + op: "lte", + flagVal: "Venomoth", + compareValue: "4", + expectedResultPattern: "Invalid Number(s) used for comparison: 'Venomoth' '4'", + testResult: false, + flagName: "flagName"}, + {label: "op=lte, 5 <= Meowth", + op: "lte", + flagVal: "5", + compareValue: "Meowth", + expectedResultPattern: "Invalid Number(s) used for comparison: '5' 'Meowth'", + testResult: false, + flagName: "flagName"}, // Test Op "has" - {label: "op=has, both empty", op: "has", flagVal: "", - compareValue: "", expectedResultPattern: "'' has ''", - testResult: true}, - {label: "op=has, flagVal=empty", op: "has", flagVal: "", - compareValue: "blah", expectedResultPattern: "'' has 'blah'", - testResult: false}, - {label: "op=has, compareValue=empty", op: "has", flagVal: "blah", - compareValue: "", expectedResultPattern: "'blah' has ''", - testResult: true}, - {label: "op=has, 'blah' has 'la'", op: "has", flagVal: "blah", - compareValue: "la", expectedResultPattern: "'blah' has 'la'", - testResult: true}, - {label: "op=has, 'blah' has 'LA'", op: "has", flagVal: "blah", - compareValue: "LA", expectedResultPattern: "'blah' has 'LA'", - testResult: false}, - {label: "op=has, 'blah' has 'lo'", op: "has", flagVal: "blah", - compareValue: "lo", expectedResultPattern: "'blah' has 'lo'", - testResult: false}, + {label: "op=has, both empty", + op: "has", + flagVal: "", + compareValue: "", + expectedResultPattern: "'flagName' has ''", + testResult: true, + flagName: "flagName"}, + {label: "op=has, flagVal=empty", + op: "has", + flagVal: "", + compareValue: "blah", + expectedResultPattern: "'flagName' has 'blah'", + testResult: false, + flagName: "flagName"}, + {label: "op=has, compareValue=empty", + op: "has", + flagVal: "blah", + compareValue: "", + expectedResultPattern: "'flagName-blah' has ''", + testResult: true, + flagName: "flagName-blah"}, + {label: "op=has, 'blah' has 'la'", + op: "has", + flagVal: "blah", + compareValue: "la", + expectedResultPattern: "'flagName-blah' has 'la'", + testResult: true, + flagName: "flagName-blah"}, + {label: "op=has, 'blah' has 'LA'", + op: "has", + flagVal: "blah", + compareValue: "LA", + expectedResultPattern: "'flagName-blah' has 'LA'", + testResult: false, + flagName: "flagName-blah"}, + {label: "op=has, 'blah' has 'lo'", + op: "has", + flagVal: "blah", + compareValue: "lo", + expectedResultPattern: "'flagName-blah' has 'lo'", + testResult: false, + flagName: "flagName-blah"}, // Test Op "nothave" - {label: "op=nothave, both empty", op: "nothave", flagVal: "", - compareValue: "", expectedResultPattern: " '' not have ''", - testResult: false}, - {label: "op=nothave, flagVal=empty", op: "nothave", flagVal: "", - compareValue: "blah", expectedResultPattern: " '' not have 'blah'", - testResult: true}, - {label: "op=nothave, compareValue=empty", op: "nothave", flagVal: "blah", - compareValue: "", expectedResultPattern: " 'blah' not have ''", - testResult: false}, - {label: "op=nothave, 'blah' not have 'la'", op: "nothave", flagVal: "blah", - compareValue: "la", expectedResultPattern: " 'blah' not have 'la'", - testResult: false}, - {label: "op=nothave, 'blah' not have 'LA'", op: "nothave", flagVal: "blah", - compareValue: "LA", expectedResultPattern: " 'blah' not have 'LA'", - testResult: true}, - {label: "op=nothave, 'blah' not have 'lo'", op: "nothave", flagVal: "blah", - compareValue: "lo", expectedResultPattern: " 'blah' not have 'lo'", - testResult: true}, + {label: "op=nothave, both empty", + op: "nothave", + flagVal: "", + compareValue: "", + expectedResultPattern: "'flagName' does not have ''", + testResult: false, + flagName: "flagName"}, + {label: "op=nothave, flagVal=empty", + op: "nothave", + flagVal: "", + compareValue: "blah", + expectedResultPattern: "'flagName' does not have 'blah'", + testResult: true, + flagName: "flagName"}, + {label: "op=nothave, compareValue=empty", + op: "nothave", + flagVal: "blah", + compareValue: "", + expectedResultPattern: "'flagName-blah' does not have ''", + testResult: false, + flagName: "flagName-blah"}, + {label: "op=nothave, 'blah' not have 'la'", + op: "nothave", + flagVal: "blah", + compareValue: "la", + expectedResultPattern: "'flagName-blah' does not have 'la'", + testResult: false, + flagName: "flagName-blah"}, + {label: "op=nothave, 'blah' not have 'LA'", + op: "nothave", + flagVal: "blah", + compareValue: "LA", + expectedResultPattern: "'flagName-blah' does not have 'LA'", + testResult: true, + flagName: "flagName-blah"}, + {label: "op=nothave, 'blah' not have 'lo'", + op: "nothave", + flagVal: "blah", + compareValue: "lo", + expectedResultPattern: "'flagName-blah' does not have 'lo'", + testResult: true, + flagName: "flagName-blah"}, // Test Op "regex" - {label: "op=regex, both empty", op: "regex", flagVal: "", - compareValue: "", expectedResultPattern: " '' matched by ''", - testResult: true}, - {label: "op=regex, flagVal=empty", op: "regex", flagVal: "", - compareValue: "blah", expectedResultPattern: " '' matched by 'blah'", - testResult: false}, + {label: "op=regex, both empty", + op: "regex", + flagVal: "", + compareValue: "", + expectedResultPattern: "'flagName' matched by regex expression ''", + testResult: true, + flagName: "flagName"}, + {label: "op=regex, flagVal=empty", + op: "regex", + flagVal: "", + compareValue: "blah", + expectedResultPattern: "'flagName' matched by regex expression 'blah'", + testResult: false, + flagName: "flagName"}, // Test Op "valid_elements" - {label: "op=valid_elements, valid_elements both empty", op: "valid_elements", flagVal: "", - compareValue: "", expectedResultPattern: "'' contains valid elements from ''", - testResult: true}, + {label: "op=valid_elements, valid_elements both empty", + op: "valid_elements", + flagVal: "", + compareValue: "", + expectedResultPattern: "'flagWithMultipleElements' contains valid elements from ''", + testResult: true, + flagName: "flagWithMultipleElements"}, - {label: "op=valid_elements, valid_elements flagVal empty", op: "valid_elements", flagVal: "", - compareValue: "a,b", expectedResultPattern: "'' contains valid elements from 'a,b'", - testResult: false}, + {label: "op=valid_elements, valid_elements flagVal empty", + op: "valid_elements", + flagVal: "", + compareValue: "a,b", + expectedResultPattern: "'flagWithMultipleElements' contains valid elements from 'a,b'", + testResult: false, + flagName: "flagWithMultipleElements"}, + + {label: "op=valid_elements, valid_elements compareValue empty", + op: "valid_elements", + flagVal: "a,b", + compareValue: "", + expectedResultPattern: "'flagWithMultipleElements' contains valid elements from ''", + testResult: false, + flagName: "flagWithMultipleElements"}, + {label: "op=valid_elements, valid_elements two list equals", + op: "valid_elements", + flagVal: "a,b,c", + compareValue: "a,b,c", + expectedResultPattern: "'flagWithMultipleElements' contains valid elements from 'a,b,c'", + testResult: true, + flagName: "flagWithMultipleElements"}, + {label: "op=valid_elements, valid_elements partial flagVal valid", + op: "valid_elements", + flagVal: "a,c", + compareValue: "a,b,c", + expectedResultPattern: "'flagWithMultipleElements' contains valid elements from 'a,b,c'", + testResult: true, + flagName: "flagWithMultipleElements"}, + {label: "op=valid_elements, valid_elements partial compareValue valid", + op: "valid_elements", + flagVal: "a,b,c", + compareValue: "a,c", + expectedResultPattern: "'flagWithMultipleElements' contains valid elements from 'a,c'", + testResult: false, + flagName: "flagWithMultipleElements"}, - {label: "op=valid_elements, valid_elements expectedResultPattern empty", op: "valid_elements", flagVal: "a,b", - compareValue: "", expectedResultPattern: "'a,b' contains valid elements from ''", - testResult: false}, // Test Op "bitmask" - {label: "op=bitmask, 644 AND 640", op: "bitmask", flagVal: "640", - compareValue: "644", expectedResultPattern: "bitmask '640' AND '644'", - testResult: true}, - {label: "op=bitmask, 644 AND 777", op: "bitmask", flagVal: "777", - compareValue: "644", expectedResultPattern: "bitmask '777' AND '644'", - testResult: false}, - {label: "op=bitmask, 644 AND 444", op: "bitmask", flagVal: "444", - compareValue: "644", expectedResultPattern: "bitmask '444' AND '644'", - testResult: true}, - {label: "op=bitmask, 644 AND 211", op: "bitmask", flagVal: "211", - compareValue: "644", expectedResultPattern: "bitmask '211' AND '644'", - testResult: false}, - {label: "op=bitmask, Harry AND 211", op: "bitmask", flagVal: "Harry", - compareValue: "644", expectedResultPattern: "Not numeric value - flag: Harry", - testResult: false}, - {label: "op=bitmask, 644 AND Potter", op: "bitmask", flagVal: "211", - compareValue: "Potter", expectedResultPattern: "Not numeric value - flag: Potter", - testResult: false}, + {label: "op=bitmask, 644 AND 640", + op: "bitmask", + flagVal: "640", + compareValue: "644", + expectedResultPattern: "etc/fileExamplePermission640 has permissions 640, expected 644 or more restrictive", + testResult: true, + flagName: "etc/fileExamplePermission640"}, + {label: "op=bitmask, 644 AND 777", + op: "bitmask", + flagVal: "777", + compareValue: "644", + expectedResultPattern: "etc/fileExamplePermission777 has permissions 777, expected 644 or more restrictive", + testResult: false, + flagName: "etc/fileExamplePermission777"}, + {label: "op=bitmask, 644 AND 444", + op: "bitmask", + flagVal: "444", + compareValue: "644", + expectedResultPattern: "etc/fileExamplePermission444 has permissions 444, expected 644 or more restrictive", + testResult: true, + flagName: "etc/fileExamplePermission444"}, + {label: "op=bitmask, 644 AND 211", + op: "bitmask", + flagVal: "211", + compareValue: "644", + expectedResultPattern: "etc/fileExamplePermission211 has permissions 211, expected 644 or more restrictive", + testResult: false, + flagName: "etc/fileExamplePermission211"}, + {label: "op=bitmask, Harry AND 211", + op: "bitmask", + flagVal: "Harry", + compareValue: "644", + expectedResultPattern: "Not numeric value - flag: Harry", + testResult: false, + flagName: "etc/fileExample"}, + {label: "op=bitmask, 644 AND Potter", + op: "bitmask", + flagVal: "211", + compareValue: "Potter", + expectedResultPattern: "Not numeric value - flag: Potter", + testResult: false, + flagName: "etc/fileExample"}, } for _, c := range cases { t.Run(c.label, func(t *testing.T) { - expectedResultPattern, testResult := compareOp(c.op, c.flagVal, c.compareValue) + expectedResultPattern, testResult := compareOp(c.op, c.flagVal, c.compareValue, c.flagName) if expectedResultPattern != c.expectedResultPattern { t.Errorf("'expectedResultPattern' did not match - op: %q expected:%q got:%q", c.op, c.expectedResultPattern, expectedResultPattern) }