mirror of
https://github.com/open-policy-agent/opa.git
synced 2026-08-12 19:32:48 -06:00
826578dba5
Signed-off-by: Torin Sandall <torin@styra.com>
271 lines
6.0 KiB
Go
271 lines
6.0 KiB
Go
package cmd
|
|
|
|
import (
|
|
"bytes"
|
|
"maps"
|
|
"os"
|
|
"path/filepath"
|
|
"testing"
|
|
|
|
"github.com/open-policy-agent/opa/v1/ast"
|
|
"github.com/open-policy-agent/opa/v1/format"
|
|
"github.com/open-policy-agent/opa/v1/util/test"
|
|
)
|
|
|
|
func TestDoMoveRenamePackage(t *testing.T) {
|
|
cases := []struct {
|
|
note string
|
|
v0Compatible bool
|
|
module string
|
|
expected *ast.Module
|
|
}{
|
|
{
|
|
note: "v0",
|
|
v0Compatible: true,
|
|
module: `package lib.foo
|
|
|
|
# this is a comment
|
|
default allow = false
|
|
|
|
allow {
|
|
input.message == "hello" # this is a comment too
|
|
}`,
|
|
expected: ast.MustParseModuleWithOpts(`package baz.bar
|
|
|
|
# this is a comment
|
|
default allow = false
|
|
|
|
allow {
|
|
input.message == "hello" # this is a comment too
|
|
}`, ast.ParserOptions{RegoVersion: ast.RegoV0}),
|
|
},
|
|
{
|
|
note: "v1",
|
|
module: `package lib.foo
|
|
|
|
# this is a comment
|
|
default allow = false
|
|
|
|
allow if {
|
|
input.message == "hello" # this is a comment too
|
|
}`,
|
|
expected: ast.MustParseModuleWithOpts(`package baz.bar
|
|
|
|
# this is a comment
|
|
default allow = false
|
|
|
|
allow if {
|
|
input.message == "hello" # this is a comment too
|
|
}`, ast.ParserOptions{RegoVersion: ast.RegoV1}),
|
|
},
|
|
}
|
|
|
|
for _, tc := range cases {
|
|
t.Run(tc.note, func(t *testing.T) {
|
|
files := map[string]string{
|
|
"policy.rego": tc.module,
|
|
}
|
|
|
|
test.WithTempFS(files, func(path string) {
|
|
|
|
mappings := []string{"data.lib.foo:data.baz.bar"}
|
|
|
|
params := moveCommandParams{
|
|
mapping: newrepeatedStringFlag(mappings),
|
|
v0Compatible: tc.v0Compatible,
|
|
}
|
|
|
|
var buf bytes.Buffer
|
|
|
|
err := doMove(params, []string{path}, &buf)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
var formatted []byte
|
|
if tc.v0Compatible {
|
|
formatted = format.MustAstWithOpts(tc.expected, format.Opts{RegoVersion: ast.RegoV0})
|
|
} else {
|
|
formatted = format.MustAstWithOpts(tc.expected, format.Opts{RegoVersion: ast.RegoV1})
|
|
}
|
|
|
|
if !bytes.Equal(formatted, buf.Bytes()) {
|
|
t.Fatalf("Expected module:\n%v\n\nGot:\n%v\n", string(formatted), buf.String())
|
|
}
|
|
})
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestDoMoveOverwriteFile(t *testing.T) {
|
|
cases := []struct {
|
|
note string
|
|
v0Compatible bool
|
|
module string
|
|
expected *ast.Module
|
|
}{
|
|
{
|
|
note: "v0",
|
|
v0Compatible: true,
|
|
module: `package lib.foo
|
|
|
|
import data.x.q
|
|
|
|
default allow := false
|
|
|
|
allow {
|
|
input.message == "hello"
|
|
}
|
|
`,
|
|
expected: ast.MustParseModuleWithOpts(`package baz.bar
|
|
|
|
import data.hidden.q
|
|
|
|
default allow := false
|
|
|
|
allow {
|
|
input.message == "hello"
|
|
}`, ast.ParserOptions{RegoVersion: ast.RegoV0}),
|
|
},
|
|
{
|
|
note: "v1",
|
|
module: `package lib.foo
|
|
|
|
import data.x.q
|
|
|
|
default allow := false
|
|
|
|
allow if {
|
|
input.message == "hello"
|
|
}
|
|
`,
|
|
expected: ast.MustParseModuleWithOpts(`package baz.bar
|
|
|
|
import data.hidden.q
|
|
|
|
default allow := false
|
|
|
|
allow if {
|
|
input.message == "hello"
|
|
}`, ast.ParserOptions{RegoVersion: ast.RegoV1}),
|
|
},
|
|
}
|
|
|
|
for _, tc := range cases {
|
|
t.Run(tc.note, func(t *testing.T) {
|
|
files := map[string]string{
|
|
"policy.rego": tc.module,
|
|
}
|
|
|
|
test.WithTempFS(files, func(path string) {
|
|
|
|
mappings := []string{"data.lib.foo:data.baz.bar", "data.x: data.hidden"}
|
|
|
|
params := moveCommandParams{
|
|
mapping: newrepeatedStringFlag(mappings),
|
|
overwrite: true,
|
|
v0Compatible: tc.v0Compatible,
|
|
}
|
|
|
|
var buf bytes.Buffer
|
|
|
|
err := doMove(params, []string{path}, &buf)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
data, err := os.ReadFile(filepath.Join(path, "policy.rego"))
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
var actual *ast.Module
|
|
if tc.v0Compatible {
|
|
actual = ast.MustParseModuleWithOpts(string(data), ast.ParserOptions{RegoVersion: ast.RegoV0})
|
|
} else {
|
|
actual = ast.MustParseModuleWithOpts(string(data), ast.ParserOptions{RegoVersion: ast.RegoV1})
|
|
}
|
|
|
|
if !tc.expected.Equal(actual) {
|
|
t.Fatalf("Expected module:\n%v\n\nGot:\n%v\n", tc.expected, actual)
|
|
}
|
|
})
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestParseSrcDstMap(t *testing.T) {
|
|
actual, err := parseSrcDstMap([]string{"data.lib.foo:data.baz.bar", "data:data.acme"})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
expected := map[string]string{"data.lib.foo": "data.baz.bar", "data": "data.acme"}
|
|
|
|
if !maps.Equal(actual, expected) {
|
|
t.Fatalf("Expected mapping %v but got %v", expected, actual)
|
|
}
|
|
|
|
actual, err = parseSrcDstMap([]string{`data.foo:data.bar["baz:qux"]`})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
expected = map[string]string{"data.foo": `data.bar["baz:qux"]`}
|
|
if !maps.Equal(actual, expected) {
|
|
t.Fatalf("Expected mapping %v but got %v", expected, actual)
|
|
}
|
|
|
|
_, err = parseSrcDstMap([]string{"data.lib.foo:data.baz.bar", "data::data.acme"})
|
|
if err == nil {
|
|
t.Fatal("Expected error but got nil")
|
|
}
|
|
|
|
_, err = parseSrcDstMap([]string{"data.lib.foo:data.baz.bar", "data%data.acme:foo:bar"})
|
|
if err == nil {
|
|
t.Fatal("Expected error but got nil")
|
|
}
|
|
|
|
_, err = parseSrcDstMap([]string{"[1]"}) // invalid term type
|
|
if err == nil {
|
|
t.Fatal("Expected error but got nil")
|
|
}
|
|
_, err = parseSrcDstMap([]string{"[1,"}) // parse error
|
|
if err == nil {
|
|
t.Fatal("Expected error but got nil")
|
|
}
|
|
_, err = parseSrcDstMap([]string{`{"data.a:data.b, data.c:data.d}`}) // multiple mappings
|
|
if err == nil {
|
|
t.Fatal("Expected error but got nil")
|
|
}
|
|
}
|
|
|
|
func TestDoMoveNoMapping(t *testing.T) {
|
|
err := doMove(moveCommandParams{}, []string{}, os.Stdout)
|
|
if err == nil {
|
|
t.Fatal("Expected error but got nil")
|
|
}
|
|
|
|
msg := "specify at least one mapping of the form <from>:<to>"
|
|
if err.Error() != msg {
|
|
t.Fatalf("Expected error %v but got %v", msg, err.Error())
|
|
}
|
|
}
|
|
|
|
func TestValidateMoveArgs(t *testing.T) {
|
|
err := validateMoveArgs([]string{})
|
|
if err == nil {
|
|
t.Fatal("Expected error but got nil")
|
|
}
|
|
|
|
msg := "specify at least one path containing policy files"
|
|
if err.Error() != msg {
|
|
t.Fatalf("Expected error %v but got %v", msg, err.Error())
|
|
}
|
|
|
|
err = validateMoveArgs([]string{"foo"})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|