Skip to content

Commit

Permalink
Adding tests
Browse files Browse the repository at this point in the history
for:

* compiler
* parser
* bundle compiler
* rego SDK
* OPA SDK

Signed-off-by: Johan Fylling <[email protected]>
  • Loading branch information
johanfylling committed Nov 24, 2024
1 parent c22d553 commit 31b5f17
Show file tree
Hide file tree
Showing 14 changed files with 1,627 additions and 30 deletions.
99 changes: 99 additions & 0 deletions ast/compile_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
// Copyright 2024 The OPA Authors. All rights reserved.
// Use of this source code is governed by an Apache2
// license that can be found in the LICENSE file.

package ast

import (
"strings"
"testing"
)

func TestCompile_DefaultRegoVersion(t *testing.T) {
tests := []struct {
note string
modules map[string]*Module
expErrs []string
}{
{
note: "no module rego-version, no v1 violations",
modules: map[string]*Module{
"test": {
Package: MustParsePackage(`package test`),
Imports: MustParseImports(`import data.foo
import data.bar`),
},
},
},
{
note: "no module rego-version, v1 violations", // default is v0, no errors expected
modules: map[string]*Module{
"test": {
Package: MustParsePackage(`package test`),
Imports: MustParseImports(`import data.foo
import data.bar as foo`),
},
},
},
{
note: "v0 module, v1 violations",
modules: map[string]*Module{
"test": MustParseModuleWithOpts(`package test
import data.foo
import data.bar as foo`,
ParserOptions{RegoVersion: RegoV0}),
},
},
{
note: "v1 module, v1 violations",
modules: map[string]*Module{
"test": MustParseModuleWithOpts(`package test
import data.foo
import data.bar as foo`,
ParserOptions{RegoVersion: RegoV1}),
},
expErrs: []string{
"3:7: rego_compile_error: import must not shadow import data.foo",
},
},
}

for _, tc := range tests {
t.Run(tc.note, func(t *testing.T) {
compiler := NewCompiler()

compiler.Compile(tc.modules)

if len(tc.expErrs) > 0 {
assertErrors(t, compiler.Errors, tc.expErrs)
} else {
if len(compiler.Errors) > 0 {
t.Fatalf("Unexpected errors: %v", compiler.Errors)
}
}
})
}
}

func assertErrors(t *testing.T, actual Errors, expected []string) {
t.Helper()
if len(expected) != len(actual) {
t.Fatalf("Expected %d errors, got %d:\n\n%s\n", len(expected), len(actual), actual.Error())
}
incorrectErrs := false
for _, e := range expected {
found := false
for _, actual := range actual {
if strings.Contains(actual.Error(), e) {
found = true
break
}
}
if !found {
incorrectErrs = true
}
}
if incorrectErrs {
t.Fatalf("Expected errors:\n\n%s\n\nGot:\n\n%s\n", expected, actual.Error())
}
}
14 changes: 7 additions & 7 deletions ast/parser_ext.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,6 @@ import (
v1 "github.com/open-policy-agent/opa/v1/ast"
)

func setDefaultRegoVersion(opts ParserOptions) ParserOptions {
if opts.RegoVersion == RegoUndefined {
opts.RegoVersion = DefaultRegoVersion
}
return opts
}

// MustParseBody returns a parsed body.
// If an error occurs during parsing, panic.
func MustParseBody(input string) Body {
Expand Down Expand Up @@ -308,3 +301,10 @@ func ParseStatementsWithOpts(filename, input string, popts ParserOptions) ([]Sta

// ParserErrorDetail holds additional details for parser errors.
type ParserErrorDetail = v1.ParserErrorDetail

func setDefaultRegoVersion(opts ParserOptions) ParserOptions {
if opts.RegoVersion == RegoUndefined {
opts.RegoVersion = DefaultRegoVersion
}
return opts
}
127 changes: 127 additions & 0 deletions ast/parser_ext_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
// Copyright 2024 The OPA Authors. All rights reserved.
// Use of this source code is governed by an Apache2
// license that can be found in the LICENSE file.

package ast_test

import (
"strings"
"testing"

"github.com/open-policy-agent/opa/ast"
"github.com/open-policy-agent/opa/format"
)

func TestParseModule_DefaultRegoVersion(t *testing.T) {
tests := []struct {
note string
mod string
expRules []string
expErrs []string
}{
{
note: "v0", // default rego-version
mod: `package test
p[x] {
x = "a"
}`,
expRules: []string{"p"},
},
{
note: "import rego.v1",
mod: `package test
import rego.v1
p contains x if {
x = "a"
}`,
expRules: []string{"p"},
},
{
note: "v1", // NOT default rego-version
mod: `package test
p contains x if {
x = "a"
}`,
expErrs: []string{
"test.rego:2: rego_parse_error: var cannot be used for rule name",
},
},
}

for _, tc := range tests {
t.Run(tc.note, func(t *testing.T) {
m, err := ast.ParseModule("test.rego", tc.mod)

if len(tc.expErrs) > 0 {
for i, expErr := range tc.expErrs {
if !strings.Contains(err.Error(), expErr) {
t.Fatalf("Expected error %d to contain %q, got %q", i, expErr, err.Error())
}
}
} else {
if err != nil {
t.Fatalf("Unexpected error: %s", err)
}

if len(m.Rules) != len(tc.expRules) {
t.Fatalf("Expected %d rules, got %d", len(tc.expRules), len(m.Rules))
}
for i, r := range m.Rules {
if r.Head.Name.String() != tc.expRules[i] {
t.Fatalf("Expected rule %q, got %q", tc.expRules[i], r.Head.Name.String())
}
}
}
})
}
}

func TestParseBody_DefaultRegoVersion(t *testing.T) {
tests := []struct {
note string
body string
expStmts int
assertSame bool
}{
{
note: "v0", // default rego-version
body: `x := ["a", "b", "c"][i]
`,
expStmts: 1,
assertSame: true,
},
{
note: "v1", // NOT default rego-version
body: `some x, i in ["a", "b", "c"]
`,
expStmts: 3,
assertSame: false,
},
}

for _, tc := range tests {
t.Run(tc.note, func(t *testing.T) {
body, err := ast.ParseBody(tc.body)

if err != nil {
t.Fatalf("Unexpected error: %s", err)
}

if len(body) != tc.expStmts {
t.Fatalf("Expected %d statements, got %d:%q\n\n", tc.expStmts, len(body), body)
}

if tc.assertSame {
formatted, err := format.AstWithOpts(body, format.Opts{RegoVersion: ast.RegoV1}) // every body is v1-compatible
if err != nil {
t.Fatalf("Unexpected error: %s", err)
}

if strings.Compare(string(formatted), tc.body) != 0 {
t.Fatalf("Expected body to be %q, got %q", tc.body, string(formatted))
}
}
})
}
}
2 changes: 1 addition & 1 deletion compile/compile.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,5 +33,5 @@ type Compiler = v1.Compiler

// New returns a new compiler instance that can be invoked.
func New() *Compiler {
return v1.New().WithRegoVersion(ast.RegoV1)
return v1.New().WithRegoVersion(ast.DefaultRegoVersion)
}
Loading

0 comments on commit 31b5f17

Please sign in to comment.