Example #1
0
func setupBenchmark(nodes int, pods int) *topdown.QueryParams {

	// policy compilation
	c := ast.NewCompiler()
	modules := map[string]*ast.Module{
		"test": ast.MustParseModule(policy),
	}

	if c.Compile(modules); c.Failed() {
		panic(c.Errors)
	}

	// storage setup
	store := storage.New(storage.InMemoryConfig())

	// parameter setup
	ctx := context.Background()
	request := ast.ObjectTerm(ast.Item(ast.StringTerm("pod"), ast.MustParseTerm(requestedPod)))
	path := ast.MustParseRef("data.opa.test.scheduler.fit")
	txn := storage.NewTransactionOrDie(ctx, store)
	params := topdown.NewQueryParams(ctx, c, store, txn, request.Value, path)

	// data setup
	setupNodes(ctx, store, txn, nodes)
	setupRCs(ctx, store, txn, 1)
	setupPods(ctx, store, txn, pods, nodes)

	return params
}
Example #2
0
func setup(t *testing.T, filename string) *topdown.QueryParams {

	// policy compilation
	c := ast.NewCompiler()
	modules := map[string]*ast.Module{
		"test": ast.MustParseModule(policy),
	}

	if c.Compile(modules); c.Failed() {
		t.Fatal("unexpected error:", c.Errors)
	}

	// storage setup
	store := storage.New(storage.Config{
		Builtin: loadDataStore(filename),
	})

	// parameter setup
	ctx := context.Background()
	request := ast.ObjectTerm(ast.Item(ast.StringTerm("pod"), ast.MustParseTerm(requestedPod)))
	path := ast.MustParseRef("data.opa.test.scheduler.fit")
	txn := storage.NewTransactionOrDie(ctx, store)
	params := topdown.NewQueryParams(ctx, c, store, txn, request.Value, path)

	return params
}
Example #3
0
func executeQuery(data string, compiler *ast.Compiler, tracer topdown.Tracer) {
	topdown.ResetQueryIDs()

	d := map[string]interface{}{}

	if len(data) > 0 {
		if err := util.UnmarshalJSON([]byte(data), &d); err != nil {
			panic(err)
		}
	}

	ctx := context.Background()
	store := storage.New(storage.InMemoryWithJSONConfig(d))
	txn := storage.NewTransactionOrDie(ctx, store)
	defer store.Close(ctx, txn)
	params := topdown.NewQueryParams(ctx, compiler, store, txn, nil, ast.MustParseRef("data.test.p"))
	params.Tracer = tracer

	_, err := topdown.Query(params)
	if err != nil {
		panic(err)
	}
}
Example #4
0
func TestInit(t *testing.T) {
	ctx := context.Background()

	tmp1, err := ioutil.TempFile("", "docFile")
	if err != nil {
		panic(err)
	}
	defer os.Remove(tmp1.Name())

	doc1 := `{"foo": "bar", "x": {"y": {"z": [1]}}}`
	if _, err := tmp1.Write([]byte(doc1)); err != nil {
		panic(err)
	}
	if err := tmp1.Close(); err != nil {
		panic(err)
	}

	tmp2, err := ioutil.TempFile("", "policyFile")
	if err != nil {
		panic(err)
	}
	defer os.Remove(tmp2.Name())
	mod1 := `
	package a.b.c
	import data.foo
	p = true :- foo = "bar"
	p = true :- 1 = 2
	`
	if _, err := tmp2.Write([]byte(mod1)); err != nil {
		panic(err)
	}
	if err := tmp2.Close(); err != nil {
		panic(err)
	}

	tmp3, err := ioutil.TempDir("", "policyDir")
	if err != nil {
		panic(err)
	}

	defer os.RemoveAll(tmp3)

	tmp4 := filepath.Join(tmp3, "existingPolicy")

	err = ioutil.WriteFile(tmp4, []byte(`
	package a.b.c
	q = true :- false
	`), 0644)
	if err != nil {
		panic(err)
	}

	rt := Runtime{}

	err = rt.init(ctx, &Params{
		Paths:     []string{tmp1.Name(), tmp2.Name()},
		PolicyDir: tmp3,
	})

	if err != nil {
		t.Errorf("Unexpected error: %v", err)
		return
	}

	txn := storage.NewTransactionOrDie(ctx, rt.Store)

	node, err := rt.Store.Read(ctx, txn, storage.MustParsePath("/foo"))
	if util.Compare(node, "bar") != 0 || err != nil {
		t.Errorf("Expected %v but got %v (err: %v)", "bar", node, err)
		return
	}

	modules := rt.Store.ListPolicies(txn)
	expected := ast.MustParseModule(mod1)

	if !expected.Equal(modules[tmp2.Name()]) {
		t.Fatalf("Expected %v but got: %v", expected, modules[tmp2.Name()])
	}

}
Example #5
0
func TestPrettyTrace(t *testing.T) {
	module := `
	package test
	p :- q[x], plus(x, 1, n)
	q[x] :- x = data.a[_]
	`

	ctx := context.Background()
	compiler := compileModules([]string{module})
	data := loadSmallTestData()
	store := storage.New(storage.InMemoryWithJSONConfig(data))
	txn := storage.NewTransactionOrDie(ctx, store)
	defer store.Close(ctx, txn)

	params := NewQueryParams(ctx, compiler, store, txn, nil, ast.MustParseRef("data.test.p"))
	tracer := NewBufferTracer()
	params.Tracer = tracer

	_, err := Query(params)
	if err != nil {
		panic(err)
	}

	expected := `Enter eq(data.test.p, _)
| Eval eq(data.test.p, _)
| Enter p = true :- data.test.q[x], plus(x, 1, n)
| | Eval data.test.q[x]
| | Enter q[x] :- eq(x, data.a[_])
| | | Eval eq(x, data.a[_])
| | | Exit q[x] :- eq(x, data.a[_])
| | Eval plus(x, 1, n)
| | Exit p = true :- data.test.q[x], plus(x, 1, n)
| Redo p = true :- data.test.q[x], plus(x, 1, n)
| | Redo data.test.q[x]
| | Redo q[x] :- eq(x, data.a[_])
| | | Redo eq(x, data.a[_])
| | | Exit q[x] :- eq(x, data.a[_])
| | Eval plus(x, 1, n)
| | Exit p = true :- data.test.q[x], plus(x, 1, n)
| Redo p = true :- data.test.q[x], plus(x, 1, n)
| | Redo data.test.q[x]
| | Redo q[x] :- eq(x, data.a[_])
| | | Redo eq(x, data.a[_])
| | | Exit q[x] :- eq(x, data.a[_])
| | Eval plus(x, 1, n)
| | Exit p = true :- data.test.q[x], plus(x, 1, n)
| Redo p = true :- data.test.q[x], plus(x, 1, n)
| | Redo data.test.q[x]
| | Redo q[x] :- eq(x, data.a[_])
| | | Redo eq(x, data.a[_])
| | | Exit q[x] :- eq(x, data.a[_])
| | Eval plus(x, 1, n)
| | Exit p = true :- data.test.q[x], plus(x, 1, n)
| Exit eq(data.test.p, _)
`

	a := strings.Split(expected, "\n")
	var buf bytes.Buffer
	PrettyTrace(&buf, *tracer)
	b := strings.Split(buf.String(), "\n")

	min := len(a)
	if min > len(b) {
		min = len(b)
	}

	for i := 0; i < min; i++ {
		if a[i] != b[i] {
			t.Errorf("Line %v in trace is incorrect. Expected %v but got: %v", i+1, a[i], b[i])
		}
	}

	if len(a) < len(b) {
		t.Fatalf("Extra lines in trace:\n%v", strings.Join(b[min:], "\n"))
	} else if len(b) < len(a) {
		t.Fatalf("Missing lines in trace:\n%v", strings.Join(a[min:], "\n"))
	}
}