diff --git a/cmd/promtool/main.go b/cmd/promtool/main.go index 5fa4de44ed..0304fa2d57 100644 --- a/cmd/promtool/main.go +++ b/cmd/promtool/main.go @@ -61,6 +61,8 @@ import ( "github.com/prometheus/prometheus/util/documentcli" ) +var promqlEnableDelayedNameRemoval = false + func init() { // This can be removed when the legacy global mode is fully deprecated. //nolint:staticcheck @@ -304,7 +306,7 @@ func main() { promQLLabelsDeleteQuery := promQLLabelsDeleteCmd.Arg("query", "PromQL query.").Required().String() promQLLabelsDeleteName := promQLLabelsDeleteCmd.Arg("name", "Name of the label to delete.").Required().String() - featureList := app.Flag("enable-feature", "Comma separated feature names to enable. Currently unused.").Default("").Strings() + featureList := app.Flag("enable-feature", "Comma separated feature names to enable. Valid options: promql-experimental-functions, promql-delayed-name-removal. See https://prometheus.io/docs/prometheus/latest/feature_flags/ for more details").Default("").Strings() documentationCmd := app.Command("write-documentation", "Generate command line documentation. Internal use.").Hidden() @@ -338,10 +340,14 @@ func main() { opts := strings.Split(f, ",") for _, o := range opts { switch o { + case "promql-experimental-functions": + parser.EnableExperimentalFunctions = true + case "promql-delayed-name-removal": + promqlEnableDelayedNameRemoval = true case "": continue default: - fmt.Printf(" WARNING: --enable-feature is currently a no-op") + fmt.Printf(" WARNING: Unknown feature passed to --enable-feature: %s", o) } } } @@ -399,8 +405,9 @@ func main() { } os.Exit(RulesUnitTestResult(results, promqltest.LazyLoaderOpts{ - EnableAtModifier: true, - EnableNegativeOffset: true, + EnableAtModifier: true, + EnableNegativeOffset: true, + EnableDelayedNameRemoval: promqlEnableDelayedNameRemoval, }, *testRulesRun, *testRulesDiff, diff --git a/cmd/promtool/main_test.go b/cmd/promtool/main_test.go index d3804da5e2..d1390f0d67 100644 --- a/cmd/promtool/main_test.go +++ b/cmd/promtool/main_test.go @@ -558,6 +558,16 @@ func TestCheckRules(t *testing.T) { }) } +func TestCheckRulesWithFeatureFlag(t *testing.T) { + // As opposed to TestCheckRules calling CheckRules directly we run promtool + // so the feature flag parsing can be tested. + + args := []string{"-test.main", "--enable-feature=promql-experimental-functions", "check", "rules", "testdata/features.yml"} + tool := exec.Command(promtoolPath, args...) + err := tool.Run() + require.NoError(t, err) +} + func TestCheckRulesWithRuleFiles(t *testing.T) { t.Run("rules-good", func(t *testing.T) { t.Parallel() diff --git a/cmd/promtool/testdata/features.yml b/cmd/promtool/testdata/features.yml new file mode 100644 index 0000000000..769f8362bf --- /dev/null +++ b/cmd/promtool/testdata/features.yml @@ -0,0 +1,6 @@ +groups: + - name: features + rules: + - record: x + # We don't expect anything from this, just want to check the function parses. + expr: sort_by_label(up, "instance") diff --git a/docs/command-line/promtool.md b/docs/command-line/promtool.md index ab675e6345..1c4c0a18f9 100644 --- a/docs/command-line/promtool.md +++ b/docs/command-line/promtool.md @@ -15,7 +15,7 @@ Tooling for the Prometheus monitoring system. | -h, --help | Show context-sensitive help (also try --help-long and --help-man). | | --version | Show application version. | | --experimental | Enable experimental commands. | -| --enable-feature ... | Comma separated feature names to enable. Currently unused. | +| --enable-feature ... | Comma separated feature names to enable. Valid options: promql-experimental-functions, promql-delayed-name-removal. See https://prometheus.io/docs/prometheus/latest/feature_flags/ for more details | diff --git a/promql/promqltest/test.go b/promql/promqltest/test.go index 84ca16e8ab..cbdf14fcd9 100644 --- a/promql/promqltest/test.go +++ b/promql/promqltest/test.go @@ -1501,6 +1501,9 @@ type LazyLoaderOpts struct { // Prometheus v2.33). They can still be disabled here for legacy and // other uses. EnableAtModifier, EnableNegativeOffset bool + // Currently defaults to false, matches the "promql-delayed-name-removal" + // feature flag. + EnableDelayedNameRemoval bool } // NewLazyLoader returns an initialized empty LazyLoader. @@ -1563,7 +1566,7 @@ func (ll *LazyLoader) clear() error { NoStepSubqueryIntervalFn: func(int64) int64 { return durationMilliseconds(ll.SubqueryInterval) }, EnableAtModifier: ll.opts.EnableAtModifier, EnableNegativeOffset: ll.opts.EnableNegativeOffset, - EnableDelayedNameRemoval: true, + EnableDelayedNameRemoval: ll.opts.EnableDelayedNameRemoval, } ll.queryEngine = promql.NewEngine(opts)