Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .github/workflows/forest.yml
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,9 @@ jobs:
- uses: actions/setup-go@v6
with:
go-version-file: "go.work"
- name: Go tests
run: |
go test -v ./tools/prometheus_metrics_validator
- name: Cargo Install
env:
# To minimize compile times: https://nnethercote.github.io/perf-book/build-configuration.html#minimizing-compile-times
Expand Down Expand Up @@ -155,6 +158,9 @@ jobs:
- name: Set permissions
run: |
chmod +x ~/.cargo/bin/forest*
- uses: actions/setup-go@v6
with:
go-version-file: "go.work"
- name: Other commands check
run: ./scripts/tests/calibnet_other_check.sh
timeout-minutes: ${{ fromJSON(env.SCRIPT_TIMEOUT_MINUTES) }}
Expand Down
1 change: 1 addition & 0 deletions go.work
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ go 1.25.2
use (
./f3-sidecar
./interop-tests/src/tests/go_app
./tools/prometheus_metrics_validator
)
4 changes: 4 additions & 0 deletions scripts/tests/calibnet_other_check.sh
Original file line number Diff line number Diff line change
Expand Up @@ -79,3 +79,7 @@ if ! [[ "$head_epoch" =~ ^[0-9]+$ ]]; then
fi
start_epoch=$(( head_epoch > 900 ? head_epoch - 900 : 0 ))
$FOREST_CLI_PATH state compute --epoch "$start_epoch" -n 10 -v

echo "Validating metrics"
wget -O metrics.log http://localhost:6116/metrics
go run ./tools/prometheus_metrics_validator metrics.log
10 changes: 10 additions & 0 deletions tools/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
### Unit tests

- run `go test -v .`

### Validate Forest metrics

```bash
wget http://localhost:6116/metrics -O metrics.txt
go run . metrics.txt
```
2 changes: 2 additions & 0 deletions tools/prometheus_metrics_validator/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
metrics
metrics.txt
24 changes: 24 additions & 0 deletions tools/prometheus_metrics_validator/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
module prometheus_metrics_validator/v2

go 1.25.2

require (
github.com/prometheus/prometheus v0.306.0
github.com/stretchr/testify v1.11.1
github.com/urfave/cli/v3 v3.4.1
)

require (
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/grafana/regexp v0.0.0-20250905093917-f7b3be9d1853 // indirect
github.com/kr/pretty v0.3.1 // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/prometheus/client_model v0.6.2 // indirect
github.com/prometheus/common v0.67.1 // indirect
go.yaml.in/yaml/v2 v2.4.3 // indirect
golang.org/x/text v0.30.0 // indirect
google.golang.org/protobuf v1.36.10 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
188 changes: 188 additions & 0 deletions tools/prometheus_metrics_validator/go.sum

Large diffs are not rendered by default.

60 changes: 60 additions & 0 deletions tools/prometheus_metrics_validator/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package main

import (
"context"
"errors"
"fmt"
"io"
"os"

"github.com/prometheus/prometheus/model/labels"
"github.com/prometheus/prometheus/model/textparse"
"github.com/urfave/cli/v3"
)

func main() {
cmd := &cli.Command{
Name: "prometheus-metrics-validator",
Usage: "A tool for validating the compatibility of Prometheus metrics text files with Grafana scrapers.",
Arguments: []cli.Argument{
&cli.StringArg{
Name: "file",
UsageText: "Path to the Prometheus metrics text file",
},
},
Action: func(ctx context.Context, c *cli.Command) error {
path := c.StringArg("file")
metrics, err := os.ReadFile(path)
if err != nil {
return err
}
if err = Validate(metrics); err != nil {
fmt.Printf("Validation failed: %v\n", err)
os.Exit(1)
} else {
fmt.Println("Validation passed!")
}
return nil
},
}
if err := cmd.Run(context.Background(), os.Args); err != nil {
panic(err)
}
}

func Validate(metrics []byte) error {
p, err := textparse.New(metrics, "text/plain", "", false, false, true, labels.NewSymbolTable())
if err != nil {
return err
}
for {
if _, err := p.Next(); err != nil {
if errors.Is(err, io.EOF) {
break
} else {
return err
}
}
}
return nil
}
45 changes: 45 additions & 0 deletions tools/prometheus_metrics_validator/main_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package main

import (
"testing"

"github.com/stretchr/testify/require"
)

func TestValidateWithoutEOF(t *testing.T) {
metric := []byte(`
cache_zstd_frame_0_size_bytes 268422051
zstd_frame_0_len 18022
zstd_frame_0_cap -1
`)
e := Validate(metric)
require.NoError(t, e)
}

func TestValidateWithEOF(t *testing.T) {
metric := []byte(`
# HELP cache_zstd_frame_0_size_bytes Size of LruCache zstd_frame_0 in bytes
# TYPE cache_zstd_frame_0_size_bytes gauge
# UNIT cache_zstd_frame_0_size_bytes bytes
cache_zstd_frame_0_size_bytes 268422051
# HELP zstd_frame_0_len Length of LruCache zstd_frame_0
# TYPE zstd_frame_0_len gauge
zstd_frame_0_len 18022
# HELP zstd_frame_0_cap Capacity of LruCache zstd_frame_0
# TYPE zstd_frame_0_cap gauge
zstd_frame_0_cap -1
# EOF
`)
e := Validate(metric)
require.NoError(t, e)
}

func TestValidateWithInvalidCharacters(t *testing.T) {
metric := []byte(`
cache_zstd_frame_0_size_bytes 268422051
zstd_frame_0_len 18022
zstd_frame_0_<cap> -1
`)
e := Validate(metric)
require.ErrorContains(t, e, "unsupported character")
}
Loading