mirror of
https://github.com/open-policy-agent/opa.git
synced 2026-08-12 19:32:48 -06:00
7bb6dbe36b
Moving (most) source to v1 root package to prepare for v0/v1 API separation. Signed-off-by: Johan Fylling <johan.dev@fylling.se>
246 lines
6.0 KiB
Go
246 lines
6.0 KiB
Go
package exec
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/open-policy-agent/opa/v1/logging"
|
|
"github.com/open-policy-agent/opa/v1/sdk"
|
|
|
|
"github.com/open-policy-agent/opa/v1/util/test"
|
|
)
|
|
|
|
/*
|
|
Most of cmd/internal/exec/exec.go is tested indirectly in cmd/exec_test.go.
|
|
This file tests internal functions that are not as easily accessed, particularly
|
|
their edge and error cases.
|
|
*/
|
|
|
|
func TestParse(t *testing.T) {
|
|
files := map[string]string{
|
|
"valid.json": `{"this": "that"}`,
|
|
"invalid.json": `{[a",!`,
|
|
}
|
|
|
|
test.WithTempFS(files, func(rootDir string) {
|
|
if val, err := parse(filepath.Join(rootDir, "no parser")); val != nil || err != nil {
|
|
t.Fatalf("return values should have been nil passing a file path with no matching extension, got val: %v; err: %s", val, err.Error())
|
|
}
|
|
if _, err := parse(filepath.Join(rootDir, "nonexistent.json")); err == nil {
|
|
t.Fatalf("should have received an error for passing a file path that does not exist")
|
|
}
|
|
if _, err := parse(filepath.Join(rootDir, "invalid.json")); err == nil {
|
|
t.Fatalf("should have received an error for passing a file with invalid json")
|
|
}
|
|
if val, err := parse(filepath.Join(rootDir, "valid.json")); err != nil {
|
|
t.Fatalf("unexpected error when passing file wiith valid json: %q", err.Error())
|
|
} else {
|
|
v := *val
|
|
that, ok := v.(map[string]interface{})["this"]
|
|
if !ok {
|
|
t.Fatalf("expected parsed data to have key %q with value %q, found none", "this", "that")
|
|
}
|
|
if that.(string) != "that" {
|
|
t.Fatalf("expected parsed data to have key %q with value %q, instead got value %v", "this", "that", that)
|
|
}
|
|
}
|
|
})
|
|
}
|
|
|
|
func TestListAllPaths(t *testing.T) {
|
|
files := map[string]string{
|
|
"file.json": `{"this": "that"}`,
|
|
}
|
|
|
|
test.WithTempFS(files, func(rootDir string) {
|
|
notFound := "./test/error"
|
|
ch := listAllPaths([]string{rootDir, notFound})
|
|
for item := range ch {
|
|
if strings.Contains(item.Path, rootDir) {
|
|
if item.Error != nil {
|
|
t.Errorf("unexpected error for mock file: %q", item.Error)
|
|
}
|
|
} else if strings.Contains(item.Path, notFound) {
|
|
if item.Error == nil {
|
|
t.Errorf("expected error for tempDir, found none")
|
|
}
|
|
}
|
|
}
|
|
})
|
|
}
|
|
|
|
func TestExec(t *testing.T) {
|
|
tests := []struct {
|
|
description string
|
|
files map[string]string
|
|
stdIn bool
|
|
input string
|
|
assertion func(t *testing.T, buf string, err error)
|
|
}{
|
|
{
|
|
description: "should read from valid JSON file and not raise an error",
|
|
files: map[string]string{
|
|
"files/test.json": `{"foo": 7}`,
|
|
"bundle/x.rego": `package system
|
|
|
|
test_fun := x {
|
|
x = false
|
|
x
|
|
}
|
|
|
|
undefined_test {
|
|
test_fun
|
|
}`,
|
|
},
|
|
assertion: func(t *testing.T, _ string, err error) {
|
|
if err != nil {
|
|
t.Fatalf("unexpected error raised: %q", err.Error())
|
|
}
|
|
},
|
|
},
|
|
{
|
|
description: "should raise error count if invalid json is found",
|
|
files: map[string]string{
|
|
"files/test.json": `{[foo":`,
|
|
"bundle/x.rego": `package system
|
|
|
|
test_fun := x {
|
|
x = false
|
|
x
|
|
}
|
|
|
|
undefined_test {
|
|
test_fun
|
|
}`,
|
|
},
|
|
assertion: func(t *testing.T, _ string, err error) {
|
|
if err == nil {
|
|
t.Fatalf("expected error, found none")
|
|
}
|
|
if r.errorCount != 1 {
|
|
t.Fatalf("expected r.errorCount to be 1, got %d", r.errorCount)
|
|
}
|
|
},
|
|
},
|
|
{
|
|
description: "should read from stdin-input if flag is set",
|
|
files: map[string]string{
|
|
"bundle/x.rego": `package system
|
|
|
|
test_fun := x {
|
|
x = false
|
|
x
|
|
}
|
|
|
|
undefined_test {
|
|
test_fun
|
|
}`,
|
|
},
|
|
stdIn: true,
|
|
input: `{"foo": 7}`,
|
|
assertion: func(t *testing.T, _ string, err error) {
|
|
if err != nil {
|
|
t.Fatalf("unexpected error raised: %q", err.Error())
|
|
}
|
|
},
|
|
},
|
|
{
|
|
description: "should read from files and stdin-input if flag is set",
|
|
files: map[string]string{
|
|
"files/test.json": `{"foo": 8}`,
|
|
"bundle/x.rego": `package system
|
|
|
|
test_fun := x {
|
|
x = false
|
|
x
|
|
}
|
|
|
|
undefined_test {
|
|
test_fun
|
|
}`,
|
|
},
|
|
stdIn: true,
|
|
input: `{"foo": 7}`,
|
|
assertion: func(t *testing.T, output string, err error) {
|
|
if err != nil {
|
|
t.Fatalf("unexpected error raised: %q", err.Error())
|
|
}
|
|
|
|
exp := `{
|
|
"result": [
|
|
{
|
|
"path": "--stdin-input",
|
|
"error": {
|
|
"code": "opa_undefined_error",
|
|
"message": "/system/main decision was undefined"
|
|
}
|
|
},
|
|
{
|
|
"path": "%ROOT%/files/test.json",
|
|
"error": {
|
|
"code": "opa_undefined_error",
|
|
"message": "/system/main decision was undefined"
|
|
}
|
|
}
|
|
]
|
|
}
|
|
`
|
|
if output != exp {
|
|
t.Fatalf("expected output to be:\n\n%s\n\ngot:\n\n%s", exp, output)
|
|
}
|
|
},
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.description, func(t *testing.T) {
|
|
test.WithTempFS(tt.files, func(dir string) {
|
|
var buf bytes.Buffer
|
|
params := NewParams(&buf)
|
|
_ = params.OutputFormat.Set("json")
|
|
params.BundlePaths = []string{dir + "/bundle/"}
|
|
params.FailNonEmpty = true
|
|
if tt.stdIn {
|
|
params.StdIn = true
|
|
tempFile, err := os.CreateTemp("", "test")
|
|
if err != nil {
|
|
t.Fatalf("unexpected error creating temp file: %q", err.Error())
|
|
}
|
|
if _, err := tempFile.WriteString(tt.input); err != nil {
|
|
t.Fatalf("unexpeced error when writing to temp file: %q", err.Error())
|
|
}
|
|
if _, err := tempFile.Seek(0, 0); err != nil {
|
|
t.Fatalf("unexpected error when rewinding temp file: %q", err.Error())
|
|
}
|
|
oldStdin := os.Stdin
|
|
defer func() {
|
|
os.Stdin = oldStdin
|
|
os.Remove(tempFile.Name())
|
|
}()
|
|
os.Stdin = tempFile
|
|
}
|
|
|
|
if _, ok := tt.files["files/test.json"]; ok {
|
|
params.Paths = append(params.Paths, dir+"/files/")
|
|
}
|
|
|
|
ctx := context.Background()
|
|
opa, _ := sdk.New(ctx, sdk.Options{
|
|
Config: bytes.NewReader([]byte{}),
|
|
Logger: logging.NewNoOpLogger(),
|
|
ConsoleLogger: logging.NewNoOpLogger(),
|
|
Ready: make(chan struct{}),
|
|
V1Compatible: params.V1Compatible,
|
|
})
|
|
|
|
err := Exec(ctx, opa, params)
|
|
output := strings.Replace(buf.String(), dir, "%ROOT%", -1)
|
|
tt.assertion(t, output, err)
|
|
})
|
|
})
|
|
}
|
|
}
|