Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
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 premetheus_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