Files
releases/internal/bundle/inspect/inspect_test.go
T
Johan Fylling 7bb6dbe36b Preparing for v1 API
Moving (most) source to v1 root package to prepare for v0/v1 API separation.

Signed-off-by: Johan Fylling <johan.dev@fylling.se>
2024-12-12 15:09:03 +01:00

270 lines
8.3 KiB
Go

// Copyright 2021 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 inspect
import (
"encoding/json"
"fmt"
"os"
"path"
"path/filepath"
"reflect"
"strings"
"testing"
"github.com/open-policy-agent/opa/internal/file/archive"
"github.com/open-policy-agent/opa/v1/ast"
"github.com/open-policy-agent/opa/v1/bundle"
"github.com/open-policy-agent/opa/v1/util/test"
)
func TestGenerateBundleInfoWithFileDir(t *testing.T) {
files := map[string]string{
"/fuz/data.json": "[1,2,3]",
"/fuz/fuz.rego": "package fuz\np = 1",
"/data.json": `{"a": {"b": {"c": [123]}}}`,
"/foo/policy.rego": "package foo\np = 1",
"/baz/authz.rego": "package foo\nx = 1",
"base.rego": "package bar\nx = 1 { input > 7 }",
"/.manifest": `{"roots": ["foo", "bar", "fuz", "baz", "a"], "revision": "rev"}`,
}
test.WithTempFS(files, func(rootDir string) {
info, err := File(rootDir, false)
if err != nil {
t.Fatalf("Unexpected error: %v", err)
}
expectedManifest := bundle.Manifest{
Revision: "rev",
Roots: &[]string{"foo", "bar", "fuz", "baz", "a"},
WasmResolvers: nil,
Metadata: nil,
}
if !info.Manifest.Equal(expectedManifest) {
t.Fatalf("expected manifest %v, but got: %v", expectedManifest, info.Manifest)
}
expectedNamespaces := map[string][]string{
"data": {filepath.Join(rootDir, "data.json")},
"data.bar": {filepath.Join(rootDir, "base.rego")},
"data.foo": {filepath.Join(rootDir, "baz/authz.rego"), filepath.Join(rootDir, "foo/policy.rego")},
"data.fuz": {filepath.Join(rootDir, "fuz/fuz.rego"), filepath.Join(rootDir, "fuz/data.json")},
}
if !reflect.DeepEqual(info.Namespaces, expectedNamespaces) {
t.Fatalf("expected namespaces %v, but got %v", expectedNamespaces, info.Namespaces)
}
var builtinNames []string
for _, bi := range info.Required.Builtins {
builtinNames = append(builtinNames, bi.Name)
}
expBuiltinNames := []string{"eq", "gt"}
if !reflect.DeepEqual(expBuiltinNames, builtinNames) {
t.Fatalf("expected builtin names to be %v but got %v", expBuiltinNames, builtinNames)
}
})
}
func TestBundleInfoHasAnnotationLocationDataSet(t *testing.T) {
files := map[string]string{
"/fuz/fuz.rego": `# METADATA
# title: My package
package fuz
p = 1`,
}
test.WithTempFS(files, func(rootDir string) {
info, err := File(rootDir, true)
if err != nil {
t.Fatalf("Unexpected error: %v", err)
}
if got, exp := len(info.Annotations), 1; got != exp {
t.Fatalf("expected %d annotation, but got: %d", exp, got)
}
bs, err := json.Marshal(info.Annotations[0])
if err != nil {
t.Fatalf("Unexpected error: %v", err)
}
exp := fmt.Sprintf(`"location":{"file":"%s/fuz/fuz.rego","row":3,"col":1}`, rootDir)
if got := string(bs); !strings.Contains(got, exp) {
t.Fatalf("expected to find %q in %q", exp, got)
}
})
}
func TestGenerateBundleInfoWithFile(t *testing.T) {
files := map[string]string{
"bundle.tar.gz": "",
}
mod := "package b.c\np=1"
test.WithTempFS(files, func(rootDir string) {
bundleFile := filepath.Join(rootDir, "bundle.tar.gz")
f, err := os.Create(bundleFile)
if err != nil {
t.Fatalf("Unexpected error: %s", err)
}
b := &bundle.Bundle{
Manifest: bundle.Manifest{
Roots: &[]string{"a", "b/c"},
Revision: "123",
},
Data: map[string]interface{}{
"a": map[string]interface{}{
"b": []int{4, 5, 6},
},
},
Modules: []bundle.ModuleFile{
{
URL: path.Join(bundleFile, "policy.rego"),
Path: "/policy.rego",
Raw: []byte(mod),
Parsed: ast.MustParseModule(mod),
},
},
}
err = bundle.Write(f, *b)
if err != nil {
t.Fatalf("Unexpected error: %s", err)
}
err = f.Close()
if err != nil {
t.Fatalf("Unexpected error: %s", err)
}
info, err := File(bundleFile, false)
if err != nil {
t.Fatalf("Unexpected error: %v", err)
}
if !info.Manifest.Equal(b.Manifest) {
t.Fatalf("expected manifest %v, but got: %v", b.Manifest, info.Manifest)
}
expectedNamespaces := map[string][]string{
"data": {"/data.json"},
"data.b.c": {"/policy.rego"},
}
if !reflect.DeepEqual(info.Namespaces, expectedNamespaces) {
t.Fatalf("expected namespaces %v, but got %v", expectedNamespaces, info.Namespaces)
}
})
}
func TestGenerateBundleInfoWithBundleTarGz(t *testing.T) {
signedTokenHS256 := `eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6ImZvbyJ9.eyJmaWxlcyI6W3sibmFtZSI6Ii5tYW5pZmVzdCIsImhhc2giOiI1MDdhMmMzOGExNDQxZGI1OGQyY2I4Nzk4MmM0MmFhOTFhNDM0MmVmNDIyYTZiNTQyZWRkZWJlZWY2ZjA0MTJmIiwiYWxnb3JpdGhtIjoiU0hBLTI1NiJ9LHsibmFtZSI6ImEvYi9jL2RhdGEuanNvbiIsImhhc2giOiI0MmNmZTY3NjhiNTdiYjVmNzUwM2MxNjVjMjhkZDA3YWM1YjgxMzU1NGViYzg1MGYyY2MzNTg0M2U3MTM3YjFkIiwiYWxnb3JpdGhtIjoiU0hBLTI1NiJ9LHsibmFtZSI6Imh0dHAvcG9saWN5L3BvbGljeS5yZWdvIiwiaGFzaCI6ImE2MTVlZWFlZTIxZGU1MTc5ZGUwODBkZThjMzA1MmM4ZGE5MDExMzg0MDZiYTcxYzM4YzAzMjg0NWY3ZDU0ZjQiLCJhbGdvcml0aG0iOiJTSEEtMjU2In1dLCJpYXQiOjE1OTIyNDgwMjcsImlzcyI6IkpXVFNlcnZpY2UiLCJrZXlpZCI6ImZvbyIsInNjb3BlIjoid3JpdGUifQ.grzWHYvyVS6LfWy0oiFTEJThKooOAwic8sexYaflzOM`
files := [][2]string{
{"/.signatures.json", fmt.Sprintf(`{"signatures": ["%v"]}`, signedTokenHS256)},
{"/.manifest", `{"revision": "quickbrownfaux", "metadata": {"foo": "bar"}, "wasm": [{"entrypoint": "http/example/authz/allow", "module": "/policy.wasm"}, {"entrypoint": "http/example/foo/allow", "module": "/example/policy.wasm"}]}`},
{"/a/b/c/data.json", "[1,2,3]"},
{"/a/b/d/data.json", "true"},
{"/a/b/y/data.yaml", `foo: 1`},
{"/a/b/y/foo.rego", `package a.b.y`},
{"/example/example.rego", `package example`},
{"/example/policy.wasm", `modules-compiled-as-wasm-binary`},
{"/policy.wasm", `modules-compiled-as-wasm-binary`},
{"/data.json", `{"x": {"y": true}, "a": {"b": {"z": true}}}`},
}
buf := archive.MustWriteTarGz(files)
test.WithTempFS(nil, func(rootDir string) {
bundleFile := filepath.Join(rootDir, "bundle.tar.gz")
out, err := os.Create(bundleFile)
if err != nil {
t.Fatalf("Unexpected error: %v", err)
}
_, err = out.Write(buf.Bytes())
if err != nil {
t.Fatalf("Unexpected error: %v", err)
}
info, err := File(bundleFile, false)
if err != nil {
t.Fatalf("Unexpected error: %v", err)
}
metadata := map[string]interface{}{"foo": "bar"}
wasmResolvers := []bundle.WasmResolver{{
Entrypoint: "http/example/authz/allow",
Module: "/policy.wasm",
}, {
Entrypoint: "http/example/foo/allow",
Module: "/example/policy.wasm"},
}
expectedManifest := bundle.Manifest{
Revision: "quickbrownfaux",
WasmResolvers: wasmResolvers,
Metadata: metadata,
}
if !info.Manifest.Equal(expectedManifest) {
t.Fatalf("expected manifest %v, but got: %v", expectedManifest, info.Manifest)
}
expectedNamespaces := map[string][]string{
"data.example": {"/example/example.rego"},
"data": {"/data.json"},
"data.a.b.c": {"/a/b/c/data.json"},
"data.a.b.d": {"/a/b/d/data.json"},
"data.a.b.y": {"/a/b/y/foo.rego", "/a/b/y/data.yaml"},
"data.http.example.authz.allow": {"/policy.wasm"},
"data.http.example.foo.allow": {"/example/policy.wasm"},
}
if !reflect.DeepEqual(info.Namespaces, expectedNamespaces) {
t.Fatalf("expected namespaces %v, but got %v", expectedNamespaces, info.Namespaces)
}
expectedWasmModules := []map[string]interface{}{}
expectedWasmModule1 := map[string]interface{}{
"path": "/example/policy.wasm",
"url": filepath.Join(bundleFile, "/example/policy.wasm"),
"entrypoints": []string{"data.http.example.foo.allow"},
}
expectedWasmModule2 := map[string]interface{}{
"path": "/policy.wasm",
"url": filepath.Join(bundleFile, "policy.wasm"),
"entrypoints": []string{"data.http.example.authz.allow"},
}
expectedWasmModules = append(expectedWasmModules, expectedWasmModule1, expectedWasmModule2)
if !reflect.DeepEqual(info.WasmModules, expectedWasmModules) {
t.Fatalf("expected wasm modules %v, but got %v", expectedWasmModules, info.WasmModules)
}
expectedSign := bundle.SignaturesConfig{
Signatures: []string{signedTokenHS256},
}
if !reflect.DeepEqual(info.Signatures, expectedSign) {
t.Fatalf("expected signature config %v, but got %v", expectedSign, info.Signatures)
}
})
}