Skip to content

Commit

Permalink
Parse gatekeeper-test flags (#1379)
Browse files Browse the repository at this point in the history
This PR sets up several function and type stubs to be worked on in the
future. The intent here is to make it easy for development to be able to
happen in parallel PRs. The comments on these stubs is to clarify what
they _should_ do when complete rather than what they currently do.

These are the code paths which can be worked on in parallel:

1) Listing the set of files to test
2) Creating the Filter to select suites and tests to run
3) Running test suites and printing test output

Fixes: #1369

Signed-off-by: Will Beason <willbeason@google.com>
  • Loading branch information
Will Beason committed Jun 22, 2021
1 parent c94ef09 commit b888cc0
Show file tree
Hide file tree
Showing 5 changed files with 140 additions and 0 deletions.
51 changes: 51 additions & 0 deletions cmd/gatekeeper-test-alpha/gatekeeper-test-alpha.go
Original file line number Diff line number Diff line change
@@ -1,16 +1,67 @@
package main

import (
"errors"
"fmt"
"os"

"github.com/open-policy-agent/gatekeeper/pkg/gktest"
"github.com/spf13/cobra"
)

var run string

func init() {
rootCmd.Flags().StringVarP(&run, "run", "r", "",
`regular expression which filters tests to run by name`)
}

var rootCmd = &cobra.Command{
Use: "gatekeeper-test-alpha path [--run=name]",
Short: "Gatekeeper Test Alpha is a unit test CLI for Gatekeeper Constraints",
Example: ` # Run all tests in label-tests.yaml
gatekeeper-test-alpha label-tests.yaml
# Run all suites whose names contain "forbid-labels".
gatekeeper-test-alpha tests/... --run forbid-labels//
# Run all tests whose names contain "nginx-deployment".
gatekeeper-test-alpha tests/... --run //nginx-deployment
# Run all tests whose names exactly match "nginx-deployment".
gatekeeper-test-alpha tests/... --run '//^nginx-deployment$'
# Run all tests that are either named "forbid-labels" or are
# in suites named "forbid-labels".
gatekeeper-test-alpha tests/... --run '^forbid-labels$'`,
Version: "alpha",
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
path := args[0]

testFiles, err := gktest.ToTestFiles(path)
if err != nil {
return fmt.Errorf("listing test files: %w", err)
}
filter, err := gktest.NewFilter(run)
if err != nil {
return fmt.Errorf("compiling filter: %w", err)
}

isFailure := false
for _, f := range testFiles {
result := gktest.Run(f, filter)
// If Result contains an error status, it is safe to execute tests in other
// files so we can continue execution.
isFailure = isFailure || result.IsFailure()
fmt.Println(result.String())
}
if isFailure {
// At least one test failed or there was a problem executing tests in at
// least one file.
return errors.New("FAIL")
}

return nil
},
}
Expand Down
11 changes: 11 additions & 0 deletions pkg/gktest/files.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package gktest

// ToTestFiles returns the set of test files selected by path.
//
// 1) If path is a path to a YAML, runs the suites in that file.
// 2) If the path is a directory, runs suites in that directory (not recursively).
// 3) If the path is a directory followed by "...", recursively runs suites
// in that directory and its subdirectories.
func ToTestFiles(path string) ([]string, error) {
return nil, nil
}
58 changes: 58 additions & 0 deletions pkg/gktest/filter.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package gktest

// Filter filters suites and tests to run.
type Filter struct{}

// NewFilter parses run into a Filter for selecting suites and individual tests
// to run.
//
// Empty string results in a Filter which matches all tests.
//
// Examples:
// 1) NewFiler("require-foo-label//missing-label")
// Matches tests in suites containing the string "require-foo-label" and tests
// containing the string "missing-label". So this would match all of the
// following:
// - Suite: "require-foo-label", Test: "missing-label"
// - Suite: "not-require-foo-label, Test: "not-missing-label"
// - Suite: "require-foo-label-and-bar-annotation", Test: "missing-label-and-annotation"
//
// 2) NewFilter("missing-label")
// Matches tests which either have a name containing "missing-label" or which
// are in a suite containing "missing-label". Matches the following:
// - Suite: "forbid-missing-label", Test: "with-foo-label"
// - Suite: "required-labels", Test: "missing-label"
//
// 3) NewFilter("^require-foo-label$//")
// Matches tests in suites which exactly match "require-foo-label". Matches the
// following:
// - Suite: "require-foo-label", Test: "with-foo-label"
// - Suite: "require-foo-label", Test: "no-labels"
//
// 4) NewFilter("//empty-object")
// Matches tests whose names contain the string "empty-object". Matches the
// following:
// - Suite: "forbid-foo-label", Test: "empty-object"
// - Suite: "forbid-foo-label", Test: "another-empty-object"
// - Suite: "require-bar-annotation", Test: "empty-object"
func NewFilter(run string) (Filter, error) {
return Filter{}, nil
}

// Suite filters the set of test suites to run by suite name and the tests
// contained in the suite. Returns true if the suite should be run.
//
// If a suite regex was specified, returns true if the suite regex matches
// `suite`.
// If a suite regex was not specified but a test regex was, returns true if at
// least one test in `tests` matches the test regex.
func (f Filter) Suite(suite string, tests []string) bool {
return true
}

// Test filters the set of tests to run by name.
//
// Returns true if the test regex matches test.
func (f Filter) Test(test string) bool {
return true
}
14 changes: 14 additions & 0 deletions pkg/gktest/result.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package gktest

// Result is the structured form of the results of running a test.
type Result struct{}

func (r Result) String() string {
return ""
}

// IsFailure returns true if either a test failed or there was a problem
// executing tests.
func (r Result) IsFailure() bool {
return false
}
6 changes: 6 additions & 0 deletions pkg/gktest/run.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package gktest

// Run executes all suites and tests in file which match filter.
func Run(file string, filter Filter) Result {
return Result{}
}

0 comments on commit b888cc0

Please sign in to comment.