Skip to content

Commit

Permalink
[WIP] Add a command to run tests on queries based on a jsonnet test file
Browse files Browse the repository at this point in the history
  • Loading branch information
HappyTetrahedron committed Feb 20, 2024
1 parent 3c90f3e commit 38a5155
Show file tree
Hide file tree
Showing 5 changed files with 447 additions and 0 deletions.
33 changes: 33 additions & 0 deletions common.libsonnet
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
local formatLabels = function(labels)
local lf = std.join(', ', std.map(function(l) '%s="%s"' % [l, labels[l]], std.objectFields(labels)));
'{%s}' % [lf];

// returns a series object with correctly formatted labels.
// labels can be modified post creation using `_labels`.
local series = function(name, labels, values) {
_name:: name,
_labels:: labels,
series: self._name + formatLabels(self._labels),
values: values,
};

// returns a test object with the given series and samples. Sample interval is 30s
// the evaluation time is set one hour in the future since all our queries operate on a 1h window
local test = function(name, series, query, samples, interval='30s', eval_time='1h') {
name: name,
interval: interval,
input_series: if std.isArray(series) then series else std.objectValues(series),
promql_expr_test: [
{
expr: query,
eval_time: eval_time,
exp_samples: if std.isArray(samples) then samples else [samples],
},
],
};

{
series: series,
formatLabels: formatLabels,
test: test,
}
1 change: 1 addition & 0 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ func newApp() (context.Context, context.CancelFunc, *cli.App) {
},
Commands: []*cli.Command{
newReportCommand(),
newQueryTestCommand(),
},
ExitErrHandler: func(context *cli.Context, err error) {
if err == nil {
Expand Down
45 changes: 45 additions & 0 deletions pkg/querycheck/querycheck.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package querycheck

import (
"fmt"
"os"
"os/exec"
"path"
"strings"

"github.com/google/go-jsonnet"

"github.com/appuio/appuio-reporting/pkg/testsuite"
)

func RunTestQueries(filepath string) error {
tmp, err := renderJsonnet(filepath)
if err != nil {
return err
}
return runPromtool(tmp)
}

func runPromtool(tmp string) error {
cmd := exec.Command(testsuite.PromtoolBin, "test", "rules", tmp)
var stderr, stdout strings.Builder
cmd.Stderr = &stderr
cmd.Stdout = &stdout
err := cmd.Run()
// Not using t.Log to keep formatting sane
fmt.Println("STDOUT")
fmt.Println(stdout.String())
fmt.Println("STDERR")
fmt.Println(stderr.String())
return err
}

func renderJsonnet(tFile string) (string, error) {
ev, err := jsonnet.MakeVM().EvaluateFile(tFile)
if err != nil {
return "", err
}
tmp := path.Join("/tmp", "test.json")
err = os.WriteFile(tmp, []byte(ev), 0644)
return tmp, err
}
46 changes: 46 additions & 0 deletions query_test_command.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package main

import (
"fmt"

"github.com/appuio/appuio-reporting/pkg/querycheck"
"github.com/urfave/cli/v2"
)

type queryTestCommand struct {
testFilePath string
}

var queryTestCommandName = "test"

func newQueryTestCommand() *cli.Command {
command := &queryTestCommand{}
return &cli.Command{
Name: queryTestCommandName,
Usage: "Run Prometheus tests on a set of query test cases",
Before: command.before,
Action: command.execute,
Flags: []cli.Flag{
&cli.StringFlag{Name: "test-file", Usage: "Path of the jsonnet test file from which to test queries",
EnvVars: envVars("TEST_FILE"), Destination: &command.testFilePath, Value: "./test.jsonnet"},
},
}
}

func (cmd *queryTestCommand) before(context *cli.Context) error {
fmt.Println("begin!")
return nil
}

func (cmd *queryTestCommand) execute(cliCtx *cli.Context) error {
ctx := cliCtx.Context
log := AppLogger(ctx).WithName(queryTestCommandName)

err := querycheck.RunTestQueries(cmd.testFilePath)

if err != nil {
log.Error(err, "Query test failed")
}
log.Info("Done")
return err
}
Loading

0 comments on commit 38a5155

Please sign in to comment.