mirror of
https://github.com/open-policy-agent/opa.git
synced 2026-08-27 18:55:54 -06:00
4778996efb
This commit checks if the constant prefix of the ref is non-empty before checking if it's a prefix of a source ref. This is seen for example, when the ref represents a function call. Signed-off-by: Ashutosh Narkar <anarkar4387@gmail.com>
383 lines
6.9 KiB
Go
383 lines
6.9 KiB
Go
package refactor
|
|
|
|
import (
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/open-policy-agent/opa/ast"
|
|
)
|
|
|
|
func TestMoveRenamePackage(t *testing.T) {
|
|
module := ast.MustParseModule(`package lib.foo
|
|
|
|
default allow = false
|
|
|
|
allow {
|
|
input.message == "hello"
|
|
}`)
|
|
|
|
modules := map[string]*ast.Module{
|
|
"policy.rego": module,
|
|
}
|
|
|
|
mappings := map[string]string{
|
|
"data.lib.foo": "data.baz.bar",
|
|
}
|
|
|
|
result, err := New().Move(MoveQuery{
|
|
Modules: modules,
|
|
SrcDstMapping: mappings,
|
|
})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
actual := result.Result["policy.rego"]
|
|
|
|
expected := ast.MustParseModule(`package baz.bar
|
|
|
|
default allow = false
|
|
|
|
allow {
|
|
input.message == "hello"
|
|
}`)
|
|
|
|
if !expected.Equal(actual) {
|
|
t.Fatalf("Expected module:\n%v\n\nGot:\n%v\n", expected, actual)
|
|
}
|
|
}
|
|
|
|
func TestMoveRenamePackagePrefix(t *testing.T) {
|
|
module1 := ast.MustParseModule(`package lib.foo
|
|
|
|
default allow = false
|
|
|
|
allow {
|
|
input.message == "hello"
|
|
}`)
|
|
|
|
module2 := ast.MustParseModule(`package lib.bar
|
|
|
|
allow {
|
|
input.message == "world"
|
|
}`)
|
|
|
|
modules := map[string]*ast.Module{
|
|
"policy1.rego": module1,
|
|
"policy2.rego": module2,
|
|
}
|
|
|
|
mappings := map[string]string{
|
|
"data.lib": "data.hidden",
|
|
}
|
|
|
|
result, err := New().Move(MoveQuery{
|
|
Modules: modules,
|
|
SrcDstMapping: mappings,
|
|
})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
actual1 := result.Result["policy1.rego"]
|
|
actual2 := result.Result["policy2.rego"]
|
|
|
|
expected1 := ast.MustParseModule(`package hidden.foo
|
|
|
|
default allow = false
|
|
|
|
allow {
|
|
input.message == "hello"
|
|
}`)
|
|
|
|
expected2 := ast.MustParseModule(`package hidden.bar
|
|
|
|
allow {
|
|
input.message == "world"
|
|
}`)
|
|
|
|
if !expected1.Equal(actual1) {
|
|
t.Fatalf("Expected module:\n%v\n\nGot:\n%v\n", expected1, actual1)
|
|
}
|
|
|
|
if !expected2.Equal(actual2) {
|
|
t.Fatalf("Expected module:\n%v\n\nGot:\n%v\n", expected2, actual2)
|
|
}
|
|
}
|
|
|
|
func TestMovePrefixInjection(t *testing.T) {
|
|
module1 := ast.MustParseModule(`package a.b
|
|
|
|
p { data.x.q }`)
|
|
|
|
module2 := ast.MustParseModule(`package x
|
|
|
|
q = true`)
|
|
|
|
modules := map[string]*ast.Module{
|
|
"policy1.rego": module1,
|
|
"policy2.rego": module2,
|
|
}
|
|
|
|
mappings := map[string]string{
|
|
"data": "data.deadbeef",
|
|
}
|
|
|
|
result, err := New().Move(MoveQuery{
|
|
Modules: modules,
|
|
SrcDstMapping: mappings,
|
|
})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
actual1 := result.Result["policy1.rego"]
|
|
actual2 := result.Result["policy2.rego"]
|
|
|
|
expected1 := ast.MustParseModule(`package deadbeef.a.b
|
|
|
|
p {
|
|
data.deadbeef.x.q
|
|
}`)
|
|
|
|
expected2 := ast.MustParseModule(`package deadbeef.x
|
|
|
|
q = true`)
|
|
|
|
if !expected1.Equal(actual1) {
|
|
t.Fatalf("Expected module:\n%v\n\nGot:\n%v\n", expected1, actual1)
|
|
}
|
|
|
|
if !expected2.Equal(actual2) {
|
|
t.Fatalf("Expected module:\n%v\n\nGot:\n%v\n", expected2, actual2)
|
|
}
|
|
}
|
|
|
|
func TestMoveWithKeyword(t *testing.T) {
|
|
module1 := ast.MustParseModule(`package a.b
|
|
|
|
import data.x.q as r
|
|
|
|
p { r with data.foo as 7 }`)
|
|
|
|
module2 := ast.MustParseModule(`package x
|
|
|
|
q { data.foo == 7 }`)
|
|
|
|
modules := map[string]*ast.Module{
|
|
"policy1.rego": module1,
|
|
"policy2.rego": module2,
|
|
}
|
|
|
|
mappings := map[string]string{
|
|
"data": "data.deadbeef",
|
|
}
|
|
|
|
result, err := New().Move(MoveQuery{
|
|
Modules: modules,
|
|
SrcDstMapping: mappings,
|
|
})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
actual1 := result.Result["policy1.rego"]
|
|
actual2 := result.Result["policy2.rego"]
|
|
|
|
expected1 := ast.MustParseModule(`package deadbeef.a.b
|
|
|
|
import data.deadbeef.x.q as r
|
|
|
|
p {
|
|
r with data.deadbeef.foo as 7
|
|
}`)
|
|
|
|
expected2 := ast.MustParseModule(`package deadbeef.x
|
|
|
|
q {
|
|
data.deadbeef.foo == 7
|
|
}`)
|
|
|
|
if !expected1.Equal(actual1) {
|
|
t.Fatalf("Expected module:\n%v\n\nGot:\n%v\n", expected1, actual1)
|
|
}
|
|
|
|
if !expected2.Equal(actual2) {
|
|
t.Fatalf("Expected module:\n%v\n\nGot:\n%v\n", expected2, actual2)
|
|
}
|
|
}
|
|
|
|
func TestMovePrefixTooShort(t *testing.T) {
|
|
module1 := ast.MustParseModule(`package foo.bar
|
|
|
|
p = 7`)
|
|
|
|
module2 := ast.MustParseModule(`package a
|
|
|
|
p = data.foo`)
|
|
|
|
modules := map[string]*ast.Module{
|
|
"policy1.rego": module1,
|
|
"policy2.rego": module2,
|
|
}
|
|
|
|
mappings := map[string]string{
|
|
"data.foo.bar": "data.baz",
|
|
}
|
|
|
|
_, err := New().Move(MoveQuery{
|
|
Modules: modules,
|
|
SrcDstMapping: mappings,
|
|
})
|
|
if err == nil {
|
|
t.Fatal("Expected error but got nil")
|
|
}
|
|
|
|
errMsg := "cannot rewrite `data.foo`: constant prefix `data.foo` of `data.foo` is too short"
|
|
if !strings.Contains(err.Error(), errMsg) {
|
|
t.Fatalf("Expected error message %v but got %v", errMsg, err.Error())
|
|
}
|
|
}
|
|
|
|
func TestMovePrefixEmpty(t *testing.T) {
|
|
module1 := ast.MustParseModule(`package foo.bar.v1
|
|
|
|
helper_1 {
|
|
to_number(split(input.baz, ".")[1]) >= 1
|
|
}
|
|
|
|
helper_2 {
|
|
to_number(split(data.bar, ".")[1]) >= 1
|
|
}`)
|
|
|
|
modules := map[string]*ast.Module{
|
|
"policy1.rego": module1,
|
|
}
|
|
|
|
mappings := map[string]string{
|
|
"data.foo": "data.hidden.name[\"hello:0.1\"]",
|
|
"data.bar": "data.hello",
|
|
}
|
|
|
|
result, err := New().Move(MoveQuery{
|
|
Modules: modules,
|
|
SrcDstMapping: mappings,
|
|
})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
actual := result.Result["policy1.rego"]
|
|
|
|
expected := ast.MustParseModule(`package hidden.name["hello:0.1"].bar.v1
|
|
|
|
helper_1 {
|
|
to_number(split(input.baz, ".")[1]) >= 1
|
|
}
|
|
|
|
helper_2 {
|
|
to_number(split(data.hello, ".")[1]) >= 1
|
|
}`)
|
|
|
|
if !expected.Equal(actual) {
|
|
t.Fatalf("Expected module:\n%v\n\nGot:\n%v\n", expected, actual)
|
|
}
|
|
}
|
|
|
|
func TestMoveConflictingRulesNoValidation(t *testing.T) {
|
|
module1 := ast.MustParseModule(`package a.b
|
|
|
|
p[1]`)
|
|
|
|
module2 := ast.MustParseModule(`package b
|
|
|
|
p = 7`)
|
|
|
|
modules := map[string]*ast.Module{
|
|
"policy1.rego": module1,
|
|
"policy2.rego": module2,
|
|
}
|
|
|
|
mappings := map[string]string{
|
|
"data.a": "data",
|
|
}
|
|
|
|
_, err := New().Move(MoveQuery{
|
|
Modules: modules,
|
|
SrcDstMapping: mappings,
|
|
})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
|
|
func TestMoveConflictingRulesWithValidation(t *testing.T) {
|
|
module1 := ast.MustParseModule(`package a.b
|
|
|
|
p[1]`)
|
|
|
|
module2 := ast.MustParseModule(`package b
|
|
|
|
p = 7`)
|
|
|
|
modules := map[string]*ast.Module{
|
|
"policy1.rego": module1,
|
|
"policy2.rego": module2,
|
|
}
|
|
|
|
mappings := map[string]string{
|
|
"data.a": "data",
|
|
}
|
|
|
|
_, err := New().Move(MoveQuery{
|
|
Modules: modules,
|
|
SrcDstMapping: mappings,
|
|
}.WithValidation(true))
|
|
if err == nil {
|
|
t.Fatal("Expected error but got nil")
|
|
}
|
|
|
|
errMsg := "rego_type_error: conflicting rules named p found"
|
|
if !strings.Contains(err.Error(), errMsg) {
|
|
t.Fatalf("Expected error message %v but got %v", errMsg, err.Error())
|
|
}
|
|
}
|
|
|
|
func TestMoveBadSourceMapping(t *testing.T) {
|
|
module := ast.MustParseModule(`package lib.foo
|
|
|
|
default allow = false
|
|
|
|
allow {
|
|
input.message == "hello"
|
|
}`)
|
|
|
|
modules := map[string]*ast.Module{
|
|
"policy.rego": module,
|
|
}
|
|
|
|
mappings := map[string]string{
|
|
"data.lib.": "data.hidden",
|
|
}
|
|
|
|
_, err := New().Move(MoveQuery{
|
|
Modules: modules,
|
|
SrcDstMapping: mappings,
|
|
})
|
|
if err == nil {
|
|
t.Fatal("Expected error but got nil")
|
|
}
|
|
|
|
mappings = map[string]string{
|
|
"data.lib": "data.hidden.",
|
|
}
|
|
|
|
_, err = New().Move(MoveQuery{
|
|
Modules: modules,
|
|
SrcDstMapping: mappings,
|
|
})
|
|
if err == nil {
|
|
t.Fatal("Expected error but got nil")
|
|
}
|
|
}
|