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 }
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 }
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) } }
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()]) } }
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")) } }