fix(promtool): use the final database path for --sandbox-dir-root instead of the default value as it may be overridden
add a regression test for that. Signed-off-by: machine424 <ayoubmrini424@gmail.com>
This commit is contained in:
parent
be3597c272
commit
cc40b65ab4
|
@ -236,14 +236,14 @@ func main() {
|
||||||
|
|
||||||
tsdbDumpCmd := tsdbCmd.Command("dump", "Dump samples from a TSDB.")
|
tsdbDumpCmd := tsdbCmd.Command("dump", "Dump samples from a TSDB.")
|
||||||
dumpPath := tsdbDumpCmd.Arg("db path", "Database path (default is "+defaultDBPath+").").Default(defaultDBPath).String()
|
dumpPath := tsdbDumpCmd.Arg("db path", "Database path (default is "+defaultDBPath+").").Default(defaultDBPath).String()
|
||||||
dumpSandboxDirRoot := tsdbDumpCmd.Flag("sandbox-dir-root", "Root directory where a sandbox directory would be created in case WAL replay generates chunks. The sandbox directory is cleaned up at the end.").Default(defaultDBPath).String()
|
dumpSandboxDirRoot := tsdbDumpCmd.Flag("sandbox-dir-root", "Root directory where a sandbox directory will be created, this sandbox is used in case WAL replay generates chunks (default is the database path). The sandbox is cleaned up at the end.").String()
|
||||||
dumpMinTime := tsdbDumpCmd.Flag("min-time", "Minimum timestamp to dump.").Default(strconv.FormatInt(math.MinInt64, 10)).Int64()
|
dumpMinTime := tsdbDumpCmd.Flag("min-time", "Minimum timestamp to dump.").Default(strconv.FormatInt(math.MinInt64, 10)).Int64()
|
||||||
dumpMaxTime := tsdbDumpCmd.Flag("max-time", "Maximum timestamp to dump.").Default(strconv.FormatInt(math.MaxInt64, 10)).Int64()
|
dumpMaxTime := tsdbDumpCmd.Flag("max-time", "Maximum timestamp to dump.").Default(strconv.FormatInt(math.MaxInt64, 10)).Int64()
|
||||||
dumpMatch := tsdbDumpCmd.Flag("match", "Series selector. Can be specified multiple times.").Default("{__name__=~'(?s:.*)'}").Strings()
|
dumpMatch := tsdbDumpCmd.Flag("match", "Series selector. Can be specified multiple times.").Default("{__name__=~'(?s:.*)'}").Strings()
|
||||||
|
|
||||||
tsdbDumpOpenMetricsCmd := tsdbCmd.Command("dump-openmetrics", "[Experimental] Dump samples from a TSDB into OpenMetrics text format, excluding native histograms and staleness markers, which are not representable in OpenMetrics.")
|
tsdbDumpOpenMetricsCmd := tsdbCmd.Command("dump-openmetrics", "[Experimental] Dump samples from a TSDB into OpenMetrics text format, excluding native histograms and staleness markers, which are not representable in OpenMetrics.")
|
||||||
dumpOpenMetricsPath := tsdbDumpOpenMetricsCmd.Arg("db path", "Database path (default is "+defaultDBPath+").").Default(defaultDBPath).String()
|
dumpOpenMetricsPath := tsdbDumpOpenMetricsCmd.Arg("db path", "Database path (default is "+defaultDBPath+").").Default(defaultDBPath).String()
|
||||||
dumpOpenMetricsSandboxDirRoot := tsdbDumpOpenMetricsCmd.Flag("sandbox-dir-root", "Root directory where a sandbox directory would be created in case WAL replay generates chunks. The sandbox directory is cleaned up at the end.").Default(defaultDBPath).String()
|
dumpOpenMetricsSandboxDirRoot := tsdbDumpOpenMetricsCmd.Flag("sandbox-dir-root", "Root directory where a sandbox directory will be created, this sandbox is used in case WAL replay generates chunks (default is the database path). The sandbox is cleaned up at the end.").String()
|
||||||
dumpOpenMetricsMinTime := tsdbDumpOpenMetricsCmd.Flag("min-time", "Minimum timestamp to dump.").Default(strconv.FormatInt(math.MinInt64, 10)).Int64()
|
dumpOpenMetricsMinTime := tsdbDumpOpenMetricsCmd.Flag("min-time", "Minimum timestamp to dump.").Default(strconv.FormatInt(math.MinInt64, 10)).Int64()
|
||||||
dumpOpenMetricsMaxTime := tsdbDumpOpenMetricsCmd.Flag("max-time", "Maximum timestamp to dump.").Default(strconv.FormatInt(math.MaxInt64, 10)).Int64()
|
dumpOpenMetricsMaxTime := tsdbDumpOpenMetricsCmd.Flag("max-time", "Maximum timestamp to dump.").Default(strconv.FormatInt(math.MaxInt64, 10)).Int64()
|
||||||
dumpOpenMetricsMatch := tsdbDumpOpenMetricsCmd.Flag("match", "Series selector. Can be specified multiple times.").Default("{__name__=~'(?s:.*)'}").Strings()
|
dumpOpenMetricsMatch := tsdbDumpOpenMetricsCmd.Flag("match", "Series selector. Can be specified multiple times.").Default("{__name__=~'(?s:.*)'}").Strings()
|
||||||
|
|
|
@ -35,6 +35,7 @@ import (
|
||||||
|
|
||||||
"github.com/prometheus/prometheus/model/labels"
|
"github.com/prometheus/prometheus/model/labels"
|
||||||
"github.com/prometheus/prometheus/model/rulefmt"
|
"github.com/prometheus/prometheus/model/rulefmt"
|
||||||
|
"github.com/prometheus/prometheus/promql/promqltest"
|
||||||
)
|
)
|
||||||
|
|
||||||
var promtoolPath = os.Args[0]
|
var promtoolPath = os.Args[0]
|
||||||
|
@ -549,3 +550,46 @@ func TestCheckRulesWithRuleFiles(t *testing.T) {
|
||||||
require.Equal(t, lintErrExitCode, exitCode, "")
|
require.Equal(t, lintErrExitCode, exitCode, "")
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestTSDBDumpCommand(t *testing.T) {
|
||||||
|
if testing.Short() {
|
||||||
|
t.Skip("skipping test in short mode.")
|
||||||
|
}
|
||||||
|
|
||||||
|
storage := promqltest.LoadedStorage(t, `
|
||||||
|
load 1m
|
||||||
|
metric{foo="bar"} 1 2 3
|
||||||
|
`)
|
||||||
|
t.Cleanup(func() { storage.Close() })
|
||||||
|
|
||||||
|
for _, c := range []struct {
|
||||||
|
name string
|
||||||
|
subCmd string
|
||||||
|
sandboxDirRoot string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "dump",
|
||||||
|
subCmd: "dump",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "dump with sandbox dir root",
|
||||||
|
subCmd: "dump",
|
||||||
|
sandboxDirRoot: t.TempDir(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "dump-openmetrics",
|
||||||
|
subCmd: "dump-openmetrics",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "dump-openmetrics with sandbox dir root",
|
||||||
|
subCmd: "dump-openmetrics",
|
||||||
|
sandboxDirRoot: t.TempDir(),
|
||||||
|
},
|
||||||
|
} {
|
||||||
|
t.Run(c.name, func(t *testing.T) {
|
||||||
|
args := []string{"-test.main", "tsdb", c.subCmd, storage.Dir()}
|
||||||
|
cmd := exec.Command(promtoolPath, args...)
|
||||||
|
require.NoError(t, cmd.Run())
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -55,7 +55,7 @@ func TestGenerateBucket(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// getDumpedSamples dumps samples and returns them.
|
// getDumpedSamples dumps samples and returns them.
|
||||||
func getDumpedSamples(t *testing.T, path string, mint, maxt int64, match []string, formatter SeriesSetFormatter) string {
|
func getDumpedSamples(t *testing.T, databasePath, sandboxDirRoot string, mint, maxt int64, match []string, formatter SeriesSetFormatter) string {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
|
|
||||||
oldStdout := os.Stdout
|
oldStdout := os.Stdout
|
||||||
|
@ -64,8 +64,8 @@ func getDumpedSamples(t *testing.T, path string, mint, maxt int64, match []strin
|
||||||
|
|
||||||
err := dumpSamples(
|
err := dumpSamples(
|
||||||
context.Background(),
|
context.Background(),
|
||||||
path,
|
databasePath,
|
||||||
t.TempDir(),
|
sandboxDirRoot,
|
||||||
mint,
|
mint,
|
||||||
maxt,
|
maxt,
|
||||||
match,
|
match,
|
||||||
|
@ -96,13 +96,15 @@ func TestTSDBDump(t *testing.T) {
|
||||||
heavy_metric{foo="bar"} 5 4 3 2 1
|
heavy_metric{foo="bar"} 5 4 3 2 1
|
||||||
heavy_metric{foo="foo"} 5 4 3 2 1
|
heavy_metric{foo="foo"} 5 4 3 2 1
|
||||||
`)
|
`)
|
||||||
|
t.Cleanup(func() { storage.Close() })
|
||||||
|
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
mint int64
|
mint int64
|
||||||
maxt int64
|
maxt int64
|
||||||
match []string
|
sandboxDirRoot string
|
||||||
expectedDump string
|
match []string
|
||||||
|
expectedDump string
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "default match",
|
name: "default match",
|
||||||
|
@ -111,6 +113,14 @@ func TestTSDBDump(t *testing.T) {
|
||||||
match: []string{"{__name__=~'(?s:.*)'}"},
|
match: []string{"{__name__=~'(?s:.*)'}"},
|
||||||
expectedDump: "testdata/dump-test-1.prom",
|
expectedDump: "testdata/dump-test-1.prom",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "default match with sandbox dir root set",
|
||||||
|
mint: math.MinInt64,
|
||||||
|
maxt: math.MaxInt64,
|
||||||
|
sandboxDirRoot: t.TempDir(),
|
||||||
|
match: []string{"{__name__=~'(?s:.*)'}"},
|
||||||
|
expectedDump: "testdata/dump-test-1.prom",
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "same matcher twice",
|
name: "same matcher twice",
|
||||||
mint: math.MinInt64,
|
mint: math.MinInt64,
|
||||||
|
@ -149,7 +159,7 @@ func TestTSDBDump(t *testing.T) {
|
||||||
}
|
}
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
dumpedMetrics := getDumpedSamples(t, storage.Dir(), tt.mint, tt.maxt, tt.match, formatSeriesSet)
|
dumpedMetrics := getDumpedSamples(t, storage.Dir(), tt.sandboxDirRoot, tt.mint, tt.maxt, tt.match, formatSeriesSet)
|
||||||
expectedMetrics, err := os.ReadFile(tt.expectedDump)
|
expectedMetrics, err := os.ReadFile(tt.expectedDump)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
expectedMetrics = normalizeNewLine(expectedMetrics)
|
expectedMetrics = normalizeNewLine(expectedMetrics)
|
||||||
|
@ -171,12 +181,29 @@ func TestTSDBDumpOpenMetrics(t *testing.T) {
|
||||||
my_counter{foo="bar", baz="abc"} 1 2 3 4 5
|
my_counter{foo="bar", baz="abc"} 1 2 3 4 5
|
||||||
my_gauge{bar="foo", abc="baz"} 9 8 0 4 7
|
my_gauge{bar="foo", abc="baz"} 9 8 0 4 7
|
||||||
`)
|
`)
|
||||||
|
t.Cleanup(func() { storage.Close() })
|
||||||
|
|
||||||
expectedMetrics, err := os.ReadFile("testdata/dump-openmetrics-test.prom")
|
tests := []struct {
|
||||||
require.NoError(t, err)
|
name string
|
||||||
expectedMetrics = normalizeNewLine(expectedMetrics)
|
sandboxDirRoot string
|
||||||
dumpedMetrics := getDumpedSamples(t, storage.Dir(), math.MinInt64, math.MaxInt64, []string{"{__name__=~'(?s:.*)'}"}, formatSeriesSetOpenMetrics)
|
}{
|
||||||
require.Equal(t, sortLines(string(expectedMetrics)), sortLines(dumpedMetrics))
|
{
|
||||||
|
name: "default match",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "default match with sandbox dir root set",
|
||||||
|
sandboxDirRoot: t.TempDir(),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
expectedMetrics, err := os.ReadFile("testdata/dump-openmetrics-test.prom")
|
||||||
|
require.NoError(t, err)
|
||||||
|
expectedMetrics = normalizeNewLine(expectedMetrics)
|
||||||
|
dumpedMetrics := getDumpedSamples(t, storage.Dir(), tt.sandboxDirRoot, math.MinInt64, math.MaxInt64, []string{"{__name__=~'(?s:.*)'}"}, formatSeriesSetOpenMetrics)
|
||||||
|
require.Equal(t, sortLines(string(expectedMetrics)), sortLines(dumpedMetrics))
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestTSDBDumpOpenMetricsRoundTrip(t *testing.T) {
|
func TestTSDBDumpOpenMetricsRoundTrip(t *testing.T) {
|
||||||
|
@ -195,7 +222,7 @@ func TestTSDBDumpOpenMetricsRoundTrip(t *testing.T) {
|
||||||
})
|
})
|
||||||
|
|
||||||
// Dump the blocks into OM format
|
// Dump the blocks into OM format
|
||||||
dumpedMetrics := getDumpedSamples(t, dbDir, math.MinInt64, math.MaxInt64, []string{"{__name__=~'(?s:.*)'}"}, formatSeriesSetOpenMetrics)
|
dumpedMetrics := getDumpedSamples(t, dbDir, "", math.MinInt64, math.MaxInt64, []string{"{__name__=~'(?s:.*)'}"}, formatSeriesSetOpenMetrics)
|
||||||
|
|
||||||
// Should get back the initial metrics.
|
// Should get back the initial metrics.
|
||||||
require.Equal(t, string(initialMetrics), dumpedMetrics)
|
require.Equal(t, string(initialMetrics), dumpedMetrics)
|
||||||
|
|
|
@ -575,7 +575,7 @@ Dump samples from a TSDB.
|
||||||
|
|
||||||
| Flag | Description | Default |
|
| Flag | Description | Default |
|
||||||
| --- | --- | --- |
|
| --- | --- | --- |
|
||||||
| <code class="text-nowrap">--sandbox-dir-root</code> | Root directory where a sandbox directory would be created in case WAL replay generates chunks. The sandbox directory is cleaned up at the end. | `data/` |
|
| <code class="text-nowrap">--sandbox-dir-root</code> | Root directory where a sandbox directory will be created, this sandbox is used in case WAL replay generates chunks (default is the database path). The sandbox is cleaned up at the end. | |
|
||||||
| <code class="text-nowrap">--min-time</code> | Minimum timestamp to dump. | `-9223372036854775808` |
|
| <code class="text-nowrap">--min-time</code> | Minimum timestamp to dump. | `-9223372036854775808` |
|
||||||
| <code class="text-nowrap">--max-time</code> | Maximum timestamp to dump. | `9223372036854775807` |
|
| <code class="text-nowrap">--max-time</code> | Maximum timestamp to dump. | `9223372036854775807` |
|
||||||
| <code class="text-nowrap">--match</code> <code class="text-nowrap">...<code class="text-nowrap"> | Series selector. Can be specified multiple times. | `{__name__=~'(?s:.*)'}` |
|
| <code class="text-nowrap">--match</code> <code class="text-nowrap">...<code class="text-nowrap"> | Series selector. Can be specified multiple times. | `{__name__=~'(?s:.*)'}` |
|
||||||
|
@ -602,7 +602,7 @@ Dump samples from a TSDB.
|
||||||
|
|
||||||
| Flag | Description | Default |
|
| Flag | Description | Default |
|
||||||
| --- | --- | --- |
|
| --- | --- | --- |
|
||||||
| <code class="text-nowrap">--sandbox-dir-root</code> | Root directory where a sandbox directory would be created in case WAL replay generates chunks. The sandbox directory is cleaned up at the end. | `data/` |
|
| <code class="text-nowrap">--sandbox-dir-root</code> | Root directory where a sandbox directory will be created, this sandbox is used in case WAL replay generates chunks (default is the database path). The sandbox is cleaned up at the end. | |
|
||||||
| <code class="text-nowrap">--min-time</code> | Minimum timestamp to dump. | `-9223372036854775808` |
|
| <code class="text-nowrap">--min-time</code> | Minimum timestamp to dump. | `-9223372036854775808` |
|
||||||
| <code class="text-nowrap">--max-time</code> | Maximum timestamp to dump. | `9223372036854775807` |
|
| <code class="text-nowrap">--max-time</code> | Maximum timestamp to dump. | `9223372036854775807` |
|
||||||
| <code class="text-nowrap">--match</code> <code class="text-nowrap">...<code class="text-nowrap"> | Series selector. Can be specified multiple times. | `{__name__=~'(?s:.*)'}` |
|
| <code class="text-nowrap">--match</code> <code class="text-nowrap">...<code class="text-nowrap"> | Series selector. Can be specified multiple times. | `{__name__=~'(?s:.*)'}` |
|
||||||
|
|
Loading…
Reference in New Issue