# Testdata for resets() and changes(). load 5m http_requests{path="/foo"} 1 2 3 0 1 0 0 1 2 0 http_requests{path="/bar"} 1 2 3 4 5 1 2 3 4 5 http_requests{path="/biz"} 0 0 0 0 0 1 1 1 1 1 # Tests for resets(). eval instant at 50m resets(http_requests[5m]) {path="/foo"} 0 {path="/bar"} 0 {path="/biz"} 0 eval instant at 50m resets(http_requests[300]) {path="/foo"} 0 {path="/bar"} 0 {path="/biz"} 0 eval instant at 50m resets(http_requests[20m]) {path="/foo"} 1 {path="/bar"} 0 {path="/biz"} 0 eval instant at 50m resets(http_requests[30m]) {path="/foo"} 2 {path="/bar"} 1 {path="/biz"} 0 eval instant at 50m resets(http_requests[50m]) {path="/foo"} 3 {path="/bar"} 1 {path="/biz"} 0 eval instant at 50m resets(nonexistent_metric[50m]) # Tests for changes(). eval instant at 50m changes(http_requests[5m]) {path="/foo"} 0 {path="/bar"} 0 {path="/biz"} 0 eval instant at 50m changes(http_requests[20m]) {path="/foo"} 3 {path="/bar"} 3 {path="/biz"} 0 eval instant at 50m changes(http_requests[30m]) {path="/foo"} 4 {path="/bar"} 5 {path="/biz"} 1 eval instant at 50m changes(http_requests[50m]) {path="/foo"} 8 {path="/bar"} 9 {path="/biz"} 1 eval instant at 50m changes((http_requests[50m])) {path="/foo"} 8 {path="/bar"} 9 {path="/biz"} 1 eval instant at 50m changes(nonexistent_metric[50m]) clear load 5m x{a="b"} NaN NaN NaN x{a="c"} 0 NaN 0 eval instant at 15m changes(x[15m]) {a="b"} 0 {a="c"} 2 clear # Tests for increase(). load 5m http_requests{path="/foo"} 0+10x10 http_requests{path="/bar"} 0+10x5 0+10x5 http_requests{path="/dings"} 10+10x10 http_requests{path="/bumms"} 1+10x10 # Tests for increase(). eval instant at 50m increase(http_requests[50m]) {path="/foo"} 100 {path="/bar"} 90 {path="/dings"} 100 {path="/bumms"} 100 # "foo" and "bar" are already at value 0 at t=0, so no extrapolation # happens. "dings" has value 10 at t=0 and would reach 0 at t=-5m. The # normal extrapolation by half a sample interval only goes to # t=-2m30s, so that's not yet reaching a negative value and therefore # chosen. However, "bumms" has value 1 at t=0 and would reach 0 at # t=-30s. Here the extrapolation to t=-2m30s would reach a negative # value, and therefore the extrapolation happens only by 30s. eval instant at 50m increase(http_requests[100m]) {path="/foo"} 100 {path="/bar"} 90 {path="/dings"} 105 {path="/bumms"} 101 clear # Test for increase() with counter reset. # When the counter is reset, it always starts at 0. # So the sequence 3 2 (decreasing counter = reset) is interpreted the same as 3 0 1 2. # Prometheus assumes it missed the intermediate values 0 and 1. load 5m http_requests{path="/foo"} 0 1 2 3 2 3 4 eval instant at 30m increase(http_requests[30m]) {path="/foo"} 7 clear # Tests for rate(). load 5m testcounter_reset_middle 0+10x4 0+10x5 testcounter_reset_end 0+10x9 0 10 # Counter resets at in the middle of range are handled correctly by rate(). eval instant at 50m rate(testcounter_reset_middle[50m]) {} 0.03 # Counter resets at end of range are ignored by rate(). eval instant at 50m rate(testcounter_reset_end[5m]) {} 0 clear load 5m calculate_rate_offset{x="a"} 0+10x10 calculate_rate_offset{x="b"} 0+20x10 calculate_rate_window 0+80x10 # Rates should calculate per-second rates. eval instant at 50m rate(calculate_rate_window[50m]) {} 0.26666666666666666 eval instant at 50m rate(calculate_rate_offset[10m] offset 5m) {x="a"} 0.03333333333333333 {x="b"} 0.06666666666666667 clear load 4m testcounter_zero_cutoff{start="0m"} 0+240x10 testcounter_zero_cutoff{start="1m"} 60+240x10 testcounter_zero_cutoff{start="2m"} 120+240x10 testcounter_zero_cutoff{start="3m"} 180+240x10 testcounter_zero_cutoff{start="4m"} 240+240x10 testcounter_zero_cutoff{start="5m"} 300+240x10 # Zero cutoff for left-side extrapolation happens until we # reach half a sampling interval (2m). Beyond that, we only # extrapolate by half a sampling interval. eval instant at 10m rate(testcounter_zero_cutoff[20m]) {start="0m"} 0.5 {start="1m"} 0.55 {start="2m"} 0.6 {start="3m"} 0.6 {start="4m"} 0.6 {start="5m"} 0.6 # Normal half-interval cutoff for left-side extrapolation. eval instant at 50m rate(testcounter_zero_cutoff[20m]) {start="0m"} 0.6 {start="1m"} 0.6 {start="2m"} 0.6 {start="3m"} 0.6 {start="4m"} 0.6 {start="5m"} 0.6 clear # Tests for irate(). load 5m http_requests{path="/foo"} 0+10x10 http_requests{path="/bar"} 0+10x5 0+10x5 eval instant at 50m irate(http_requests[50m]) {path="/foo"} .03333333333333333333 {path="/bar"} .03333333333333333333 # Counter reset. eval instant at 30m irate(http_requests[50m]) {path="/foo"} .03333333333333333333 {path="/bar"} 0 clear # Tests for delta(). load 5m http_requests{path="/foo"} 0 50 100 150 200 http_requests{path="/bar"} 200 150 100 50 0 eval instant at 20m delta(http_requests[20m]) {path="/foo"} 200 {path="/bar"} -200 clear # Tests for idelta(). load 5m http_requests{path="/foo"} 0 50 100 150 http_requests{path="/bar"} 0 50 100 50 eval instant at 20m idelta(http_requests[20m]) {path="/foo"} 50 {path="/bar"} -50 clear # Tests for deriv() and predict_linear(). load 5m testcounter_reset_middle 0+10x4 0+10x5 http_requests{job="app-server", instance="1", group="canary"} 0+80x10 # deriv should return the same as rate in simple cases. eval instant at 50m rate(http_requests{group="canary", instance="1", job="app-server"}[50m]) {group="canary", instance="1", job="app-server"} 0.26666666666666666 eval instant at 50m deriv(http_requests{group="canary", instance="1", job="app-server"}[50m]) {group="canary", instance="1", job="app-server"} 0.26666666666666666 # deriv should return correct result. eval instant at 50m deriv(testcounter_reset_middle[100m]) {} 0.010606060606060607 # predict_linear should return correct result. # X/s = [ 0, 300, 600, 900,1200,1500,1800,2100,2400,2700,3000] # Y = [ 0, 10, 20, 30, 40, 0, 10, 20, 30, 40, 50] # sumX = 16500 # sumY = 250 # sumXY = 480000 # sumX2 = 34650000 # n = 11 # covXY = 105000 # varX = 9900000 # slope = 0.010606060606060607 # intercept at t=0: 6.818181818181818 # intercept at t=3000: 38.63636363636364 # intercept at t=3000+3600: 76.81818181818181 eval instant at 50m predict_linear(testcounter_reset_middle[50m], 3600) {} 76.81818181818181 eval instant at 50m predict_linear(testcounter_reset_middle[50m], 1h) {} 76.81818181818181 # intercept at t = 3000+3600 = 6600 eval instant at 50m predict_linear(testcounter_reset_middle[50m] @ 3000, 3600) {} 76.81818181818181 eval instant at 50m predict_linear(testcounter_reset_middle[50m] @ 3000, 1h) {} 76.81818181818181 # intercept at t = 600+3600 = 4200 eval instant at 10m predict_linear(testcounter_reset_middle[50m] @ 3000, 3600) {} 51.36363636363637 # intercept at t = 4200+3600 = 7800 eval instant at 70m predict_linear(testcounter_reset_middle[50m] @ 3000, 3600) {} 89.54545454545455 # With http_requests, there is a sample value exactly at the end of # the range, and it has exactly the predicted value, so predict_linear # can be emulated with deriv. eval instant at 50m predict_linear(http_requests[50m], 3600) - (http_requests + deriv(http_requests[50m]) * 3600) {group="canary", instance="1", job="app-server"} 0 clear # Tests for label_replace. load 5m testmetric{src="source-value-10",dst="original-destination-value"} 0 testmetric{src="source-value-20",dst="original-destination-value"} 1 # label_replace does a full-string match and replace. eval instant at 0m label_replace(testmetric, "dst", "destination-value-$1", "src", "source-value-(.*)") testmetric{src="source-value-10",dst="destination-value-10"} 0 testmetric{src="source-value-20",dst="destination-value-20"} 1 # label_replace does not do a sub-string match. eval instant at 0m label_replace(testmetric, "dst", "destination-value-$1", "src", "value-(.*)") testmetric{src="source-value-10",dst="original-destination-value"} 0 testmetric{src="source-value-20",dst="original-destination-value"} 1 # label_replace works with multiple capture groups. eval instant at 0m label_replace(testmetric, "dst", "$1-value-$2", "src", "(.*)-value-(.*)") testmetric{src="source-value-10",dst="source-value-10"} 0 testmetric{src="source-value-20",dst="source-value-20"} 1 # label_replace does not overwrite the destination label if the source label # does not exist. eval instant at 0m label_replace(testmetric, "dst", "value-$1", "nonexistent-src", "source-value-(.*)") testmetric{src="source-value-10",dst="original-destination-value"} 0 testmetric{src="source-value-20",dst="original-destination-value"} 1 # label_replace overwrites the destination label if the source label is empty, # but matched. eval instant at 0m label_replace(testmetric, "dst", "value-$1", "nonexistent-src", "(.*)") testmetric{src="source-value-10",dst="value-"} 0 testmetric{src="source-value-20",dst="value-"} 1 # label_replace does not overwrite the destination label if the source label # is not matched. eval instant at 0m label_replace(testmetric, "dst", "value-$1", "src", "non-matching-regex") testmetric{src="source-value-10",dst="original-destination-value"} 0 testmetric{src="source-value-20",dst="original-destination-value"} 1 eval instant at 0m label_replace((((testmetric))), (("dst")), (("value-$1")), (("src")), (("non-matching-regex"))) testmetric{src="source-value-10",dst="original-destination-value"} 0 testmetric{src="source-value-20",dst="original-destination-value"} 1 # label_replace drops labels that are set to empty values. eval instant at 0m label_replace(testmetric, "dst", "", "dst", ".*") testmetric{src="source-value-10"} 0 testmetric{src="source-value-20"} 1 # label_replace fails when the regex is invalid. eval_fail instant at 0m label_replace(testmetric, "dst", "value-$1", "src", "(.*") # label_replace fails when the destination label name is not a valid Prometheus label name. eval_fail instant at 0m label_replace(testmetric, "invalid-label-name", "", "src", "(.*)") # label_replace fails when there would be duplicated identical output label sets. eval_fail instant at 0m label_replace(testmetric, "src", "", "", "") clear # Tests for vector, time and timestamp. load 10s metric 1 1 eval instant at 0s timestamp(metric) {} 0 eval instant at 5s timestamp(metric) {} 0 eval instant at 5s timestamp(((metric))) {} 0 eval instant at 10s timestamp(metric) {} 10 eval instant at 10s timestamp(((metric))) {} 10 # Tests for label_join. load 5m testmetric{src="a",src1="b",src2="c",dst="original-destination-value"} 0 testmetric{src="d",src1="e",src2="f",dst="original-destination-value"} 1 # label_join joins all src values in order. eval instant at 0m label_join(testmetric, "dst", "-", "src", "src1", "src2") testmetric{src="a",src1="b",src2="c",dst="a-b-c"} 0 testmetric{src="d",src1="e",src2="f",dst="d-e-f"} 1 # label_join treats non existent src labels as empty strings. eval instant at 0m label_join(testmetric, "dst", "-", "src", "src3", "src1") testmetric{src="a",src1="b",src2="c",dst="a--b"} 0 testmetric{src="d",src1="e",src2="f",dst="d--e"} 1 # label_join overwrites the destination label even if the resulting dst label is empty string eval instant at 0m label_join(testmetric, "dst", "", "emptysrc", "emptysrc1", "emptysrc2") testmetric{src="a",src1="b",src2="c"} 0 testmetric{src="d",src1="e",src2="f"} 1 # test without src label for label_join eval instant at 0m label_join(testmetric, "dst", ", ") testmetric{src="a",src1="b",src2="c"} 0 testmetric{src="d",src1="e",src2="f"} 1 # test without dst label for label_join load 5m testmetric1{src="foo",src1="bar",src2="foobar"} 0 testmetric1{src="fizz",src1="buzz",src2="fizzbuzz"} 1 # label_join creates dst label if not present. eval instant at 0m label_join(testmetric1, "dst", ", ", "src", "src1", "src2") testmetric1{src="foo",src1="bar",src2="foobar",dst="foo, bar, foobar"} 0 testmetric1{src="fizz",src1="buzz",src2="fizzbuzz",dst="fizz, buzz, fizzbuzz"} 1 clear # Tests for vector. eval instant at 0m vector(1) {} 1 eval instant at 0s vector(time()) {} 0 eval instant at 5s vector(time()) {} 5 eval instant at 60m vector(time()) {} 3600 # Tests for clamp_max, clamp_min(), and clamp(). load 5m test_clamp{src="clamp-a"} -50 test_clamp{src="clamp-b"} 0 test_clamp{src="clamp-c"} 100 eval instant at 0m clamp_max(test_clamp, 75) {src="clamp-a"} -50 {src="clamp-b"} 0 {src="clamp-c"} 75 eval instant at 0m clamp_min(test_clamp, -25) {src="clamp-a"} -25 {src="clamp-b"} 0 {src="clamp-c"} 100 eval instant at 0m clamp(test_clamp, -25, 75) {src="clamp-a"} -25 {src="clamp-b"} 0 {src="clamp-c"} 75 eval instant at 0m clamp_max(clamp_min(test_clamp, -20), 70) {src="clamp-a"} -20 {src="clamp-b"} 0 {src="clamp-c"} 70 eval instant at 0m clamp_max((clamp_min(test_clamp, (-20))), (70)) {src="clamp-a"} -20 {src="clamp-b"} 0 {src="clamp-c"} 70 eval instant at 0m clamp(test_clamp, 0, NaN) {src="clamp-a"} NaN {src="clamp-b"} NaN {src="clamp-c"} NaN eval instant at 0m clamp(test_clamp, NaN, 0) {src="clamp-a"} NaN {src="clamp-b"} NaN {src="clamp-c"} NaN eval instant at 0m clamp(test_clamp, 5, -5) # Test cases for sgn. clear load 5m test_sgn{src="sgn-a"} -Inf test_sgn{src="sgn-b"} Inf test_sgn{src="sgn-c"} NaN test_sgn{src="sgn-d"} -50 test_sgn{src="sgn-e"} 0 test_sgn{src="sgn-f"} 100 eval instant at 0m sgn(test_sgn) {src="sgn-a"} -1 {src="sgn-b"} 1 {src="sgn-c"} NaN {src="sgn-d"} -1 {src="sgn-e"} 0 {src="sgn-f"} 1 # Tests for sort/sort_desc. clear load 5m http_requests{job="api-server", instance="0", group="production"} 0+10x10 http_requests{job="api-server", instance="1", group="production"} 0+20x10 http_requests{job="api-server", instance="0", group="canary"} 0+30x10 http_requests{job="api-server", instance="1", group="canary"} 0+40x10 http_requests{job="api-server", instance="2", group="canary"} NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN http_requests{job="app-server", instance="0", group="production"} 0+50x10 http_requests{job="app-server", instance="1", group="production"} 0+60x10 http_requests{job="app-server", instance="0", group="canary"} 0+70x10 http_requests{job="app-server", instance="1", group="canary"} 0+80x10 eval_ordered instant at 50m sort(http_requests) http_requests{group="production", instance="0", job="api-server"} 100 http_requests{group="production", instance="1", job="api-server"} 200 http_requests{group="canary", instance="0", job="api-server"} 300 http_requests{group="canary", instance="1", job="api-server"} 400 http_requests{group="production", instance="0", job="app-server"} 500 http_requests{group="production", instance="1", job="app-server"} 600 http_requests{group="canary", instance="0", job="app-server"} 700 http_requests{group="canary", instance="1", job="app-server"} 800 http_requests{group="canary", instance="2", job="api-server"} NaN eval_ordered instant at 50m sort_desc(http_requests) http_requests{group="canary", instance="1", job="app-server"} 800 http_requests{group="canary", instance="0", job="app-server"} 700 http_requests{group="production", instance="1", job="app-server"} 600 http_requests{group="production", instance="0", job="app-server"} 500 http_requests{group="canary", instance="1", job="api-server"} 400 http_requests{group="canary", instance="0", job="api-server"} 300 http_requests{group="production", instance="1", job="api-server"} 200 http_requests{group="production", instance="0", job="api-server"} 100 http_requests{group="canary", instance="2", job="api-server"} NaN # Tests for sort_by_label/sort_by_label_desc. clear load 5m http_requests{job="api-server", instance="0", group="production"} 0+10x10 http_requests{job="api-server", instance="1", group="production"} 0+20x10 http_requests{job="api-server", instance="0", group="canary"} 0+30x10 http_requests{job="api-server", instance="1", group="canary"} 0+40x10 http_requests{job="api-server", instance="2", group="canary"} NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN http_requests{job="app-server", instance="0", group="production"} 0+50x10 http_requests{job="app-server", instance="1", group="production"} 0+60x10 http_requests{job="app-server", instance="0", group="canary"} 0+70x10 http_requests{job="app-server", instance="1", group="canary"} 0+80x10 http_requests{job="api-server", instance="2", group="production"} 0+10x10 cpu_time_total{job="cpu", cpu="0"} 0+10x10 cpu_time_total{job="cpu", cpu="1"} 0+10x10 cpu_time_total{job="cpu", cpu="2"} 0+10x10 cpu_time_total{job="cpu", cpu="3"} 0+10x10 cpu_time_total{job="cpu", cpu="10"} 0+10x10 cpu_time_total{job="cpu", cpu="11"} 0+10x10 cpu_time_total{job="cpu", cpu="12"} 0+10x10 cpu_time_total{job="cpu", cpu="20"} 0+10x10 cpu_time_total{job="cpu", cpu="21"} 0+10x10 cpu_time_total{job="cpu", cpu="100"} 0+10x10 node_uname_info{job="node_exporter", instance="4m600", release="1.2.3"} 0+10x10 node_uname_info{job="node_exporter", instance="4m5", release="1.11.3"} 0+10x10 node_uname_info{job="node_exporter", instance="4m1000", release="1.111.3"} 0+10x10 eval_ordered instant at 50m sort_by_label(http_requests, "instance") http_requests{group="production", instance="0", job="api-server"} 100 http_requests{group="canary", instance="0", job="api-server"} 300 http_requests{group="production", instance="0", job="app-server"} 500 http_requests{group="canary", instance="0", job="app-server"} 700 http_requests{group="production", instance="1", job="api-server"} 200 http_requests{group="canary", instance="1", job="api-server"} 400 http_requests{group="production", instance="1", job="app-server"} 600 http_requests{group="canary", instance="1", job="app-server"} 800 http_requests{group="production", instance="2", job="api-server"} 100 http_requests{group="canary", instance="2", job="api-server"} NaN eval_ordered instant at 50m sort_by_label(http_requests, "instance", "group") http_requests{group="canary", instance="0", job="api-server"} 300 http_requests{group="canary", instance="0", job="app-server"} 700 http_requests{group="production", instance="0", job="api-server"} 100 http_requests{group="production", instance="0", job="app-server"} 500 http_requests{group="canary", instance="1", job="api-server"} 400 http_requests{group="canary", instance="1", job="app-server"} 800 http_requests{group="production", instance="1", job="api-server"} 200 http_requests{group="production", instance="1", job="app-server"} 600 http_requests{group="canary", instance="2", job="api-server"} NaN http_requests{group="production", instance="2", job="api-server"} 100 eval_ordered instant at 50m sort_by_label(http_requests, "instance", "group") http_requests{group="canary", instance="0", job="api-server"} 300 http_requests{group="canary", instance="0", job="app-server"} 700 http_requests{group="production", instance="0", job="api-server"} 100 http_requests{group="production", instance="0", job="app-server"} 500 http_requests{group="canary", instance="1", job="api-server"} 400 http_requests{group="canary", instance="1", job="app-server"} 800 http_requests{group="production", instance="1", job="api-server"} 200 http_requests{group="production", instance="1", job="app-server"} 600 http_requests{group="canary", instance="2", job="api-server"} NaN http_requests{group="production", instance="2", job="api-server"} 100 eval_ordered instant at 50m sort_by_label(http_requests, "group", "instance", "job") http_requests{group="canary", instance="0", job="api-server"} 300 http_requests{group="canary", instance="0", job="app-server"} 700 http_requests{group="canary", instance="1", job="api-server"} 400 http_requests{group="canary", instance="1", job="app-server"} 800 http_requests{group="canary", instance="2", job="api-server"} NaN http_requests{group="production", instance="0", job="api-server"} 100 http_requests{group="production", instance="0", job="app-server"} 500 http_requests{group="production", instance="1", job="api-server"} 200 http_requests{group="production", instance="1", job="app-server"} 600 http_requests{group="production", instance="2", job="api-server"} 100 eval_ordered instant at 50m sort_by_label(http_requests, "job", "instance", "group") http_requests{group="canary", instance="0", job="api-server"} 300 http_requests{group="production", instance="0", job="api-server"} 100 http_requests{group="canary", instance="1", job="api-server"} 400 http_requests{group="production", instance="1", job="api-server"} 200 http_requests{group="canary", instance="2", job="api-server"} NaN http_requests{group="production", instance="2", job="api-server"} 100 http_requests{group="canary", instance="0", job="app-server"} 700 http_requests{group="production", instance="0", job="app-server"} 500 http_requests{group="canary", instance="1", job="app-server"} 800 http_requests{group="production", instance="1", job="app-server"} 600 eval_ordered instant at 50m sort_by_label_desc(http_requests, "instance") http_requests{group="production", instance="2", job="api-server"} 100 http_requests{group="canary", instance="2", job="api-server"} NaN http_requests{group="canary", instance="1", job="app-server"} 800 http_requests{group="production", instance="1", job="app-server"} 600 http_requests{group="canary", instance="1", job="api-server"} 400 http_requests{group="production", instance="1", job="api-server"} 200 http_requests{group="canary", instance="0", job="app-server"} 700 http_requests{group="production", instance="0", job="app-server"} 500 http_requests{group="canary", instance="0", job="api-server"} 300 http_requests{group="production", instance="0", job="api-server"} 100 eval_ordered instant at 50m sort_by_label_desc(http_requests, "instance", "group") http_requests{group="production", instance="2", job="api-server"} 100 http_requests{group="canary", instance="2", job="api-server"} NaN http_requests{group="production", instance="1", job="app-server"} 600 http_requests{group="production", instance="1", job="api-server"} 200 http_requests{group="canary", instance="1", job="app-server"} 800 http_requests{group="canary", instance="1", job="api-server"} 400 http_requests{group="production", instance="0", job="app-server"} 500 http_requests{group="production", instance="0", job="api-server"} 100 http_requests{group="canary", instance="0", job="app-server"} 700 http_requests{group="canary", instance="0", job="api-server"} 300 eval_ordered instant at 50m sort_by_label_desc(http_requests, "instance", "group", "job") http_requests{group="production", instance="2", job="api-server"} 100 http_requests{group="canary", instance="2", job="api-server"} NaN http_requests{group="production", instance="1", job="app-server"} 600 http_requests{group="production", instance="1", job="api-server"} 200 http_requests{group="canary", instance="1", job="app-server"} 800 http_requests{group="canary", instance="1", job="api-server"} 400 http_requests{group="production", instance="0", job="app-server"} 500 http_requests{group="production", instance="0", job="api-server"} 100 http_requests{group="canary", instance="0", job="app-server"} 700 http_requests{group="canary", instance="0", job="api-server"} 300 eval_ordered instant at 50m sort_by_label(cpu_time_total, "cpu") cpu_time_total{job="cpu", cpu="0"} 100 cpu_time_total{job="cpu", cpu="1"} 100 cpu_time_total{job="cpu", cpu="2"} 100 cpu_time_total{job="cpu", cpu="3"} 100 cpu_time_total{job="cpu", cpu="10"} 100 cpu_time_total{job="cpu", cpu="11"} 100 cpu_time_total{job="cpu", cpu="12"} 100 cpu_time_total{job="cpu", cpu="20"} 100 cpu_time_total{job="cpu", cpu="21"} 100 cpu_time_total{job="cpu", cpu="100"} 100 eval_ordered instant at 50m sort_by_label(node_uname_info, "instance") node_uname_info{job="node_exporter", instance="4m5", release="1.11.3"} 100 node_uname_info{job="node_exporter", instance="4m600", release="1.2.3"} 100 node_uname_info{job="node_exporter", instance="4m1000", release="1.111.3"} 100 eval_ordered instant at 50m sort_by_label(node_uname_info, "release") node_uname_info{job="node_exporter", instance="4m600", release="1.2.3"} 100 node_uname_info{job="node_exporter", instance="4m5", release="1.11.3"} 100 node_uname_info{job="node_exporter", instance="4m1000", release="1.111.3"} 100 # Tests for holt_winters clear # positive trends load 10s http_requests{job="api-server", instance="0", group="production"} 0+10x1000 100+30x1000 http_requests{job="api-server", instance="1", group="production"} 0+20x1000 200+30x1000 http_requests{job="api-server", instance="0", group="canary"} 0+30x1000 300+80x1000 http_requests{job="api-server", instance="1", group="canary"} 0+40x2000 eval instant at 8000s holt_winters(http_requests[1m], 0.01, 0.1) {job="api-server", instance="0", group="production"} 8000 {job="api-server", instance="1", group="production"} 16000 {job="api-server", instance="0", group="canary"} 24000 {job="api-server", instance="1", group="canary"} 32000 # negative trends clear load 10s http_requests{job="api-server", instance="0", group="production"} 8000-10x1000 http_requests{job="api-server", instance="1", group="production"} 0-20x1000 http_requests{job="api-server", instance="0", group="canary"} 0+30x1000 300-80x1000 http_requests{job="api-server", instance="1", group="canary"} 0-40x1000 0+40x1000 eval instant at 8000s holt_winters(http_requests[1m], 0.01, 0.1) {job="api-server", instance="0", group="production"} 0 {job="api-server", instance="1", group="production"} -16000 {job="api-server", instance="0", group="canary"} 24000 {job="api-server", instance="1", group="canary"} -32000 # Tests for avg_over_time clear load 10s metric 1 2 3 4 5 metric2 1 2 3 4 Inf metric3 1 2 3 4 -Inf metric4 1 2 3 Inf -Inf metric5 Inf 0 Inf metric5b Inf 0 Inf metric5c Inf Inf Inf -Inf metric6 1 2 3 -Inf -Inf metric6b -Inf 0 -Inf metric6c -Inf -Inf -Inf Inf metric7 1 2 -Inf -Inf Inf metric8 9.988465674311579e+307 9.988465674311579e+307 metric9 -9.988465674311579e+307 -9.988465674311579e+307 -9.988465674311579e+307 metric10 -9.988465674311579e+307 9.988465674311579e+307 eval instant at 1m avg_over_time(metric[1m]) {} 3 eval instant at 1m sum_over_time(metric[1m])/count_over_time(metric[1m]) {} 3 eval instant at 1m avg_over_time(metric2[1m]) {} Inf eval instant at 1m sum_over_time(metric2[1m])/count_over_time(metric2[1m]) {} Inf eval instant at 1m avg_over_time(metric3[1m]) {} -Inf eval instant at 1m sum_over_time(metric3[1m])/count_over_time(metric3[1m]) {} -Inf eval instant at 1m avg_over_time(metric4[1m]) {} NaN eval instant at 1m sum_over_time(metric4[1m])/count_over_time(metric4[1m]) {} NaN eval instant at 1m avg_over_time(metric5[1m]) {} Inf eval instant at 1m sum_over_time(metric5[1m])/count_over_time(metric5[1m]) {} Inf eval instant at 1m avg_over_time(metric5b[1m]) {} Inf eval instant at 1m sum_over_time(metric5b[1m])/count_over_time(metric5b[1m]) {} Inf eval instant at 1m avg_over_time(metric5c[1m]) {} NaN eval instant at 1m sum_over_time(metric5c[1m])/count_over_time(metric5c[1m]) {} NaN eval instant at 1m avg_over_time(metric6[1m]) {} -Inf eval instant at 1m sum_over_time(metric6[1m])/count_over_time(metric6[1m]) {} -Inf eval instant at 1m avg_over_time(metric6b[1m]) {} -Inf eval instant at 1m sum_over_time(metric6b[1m])/count_over_time(metric6b[1m]) {} -Inf eval instant at 1m avg_over_time(metric6c[1m]) {} NaN eval instant at 1m sum_over_time(metric6c[1m])/count_over_time(metric6c[1m]) {} NaN eval instant at 1m avg_over_time(metric7[1m]) {} NaN eval instant at 1m sum_over_time(metric7[1m])/count_over_time(metric7[1m]) {} NaN eval instant at 1m avg_over_time(metric8[1m]) {} 9.988465674311579e+307 # This overflows float64. eval instant at 1m sum_over_time(metric8[1m])/count_over_time(metric8[1m]) {} Inf eval instant at 1m avg_over_time(metric9[1m]) {} -9.988465674311579e+307 # This overflows float64. eval instant at 1m sum_over_time(metric9[1m])/count_over_time(metric9[1m]) {} -Inf eval instant at 1m avg_over_time(metric10[1m]) {} 0 eval instant at 1m sum_over_time(metric10[1m])/count_over_time(metric10[1m]) {} 0 # Test if very big intermediate values cause loss of detail. clear load 10s metric 1 1e100 1 -1e100 eval instant at 1m sum_over_time(metric[1m]) {} 2 eval instant at 1m avg_over_time(metric[1m]) {} 0.5 # Tests for stddev_over_time and stdvar_over_time. clear load 10s metric 0 8 8 2 3 eval instant at 1m stdvar_over_time(metric[1m]) {} 10.56 eval instant at 1m stddev_over_time(metric[1m]) {} 3.249615 eval instant at 1m stddev_over_time((metric[1m])) {} 3.249615 # Tests for stddev_over_time and stdvar_over_time #4927. clear load 10s metric 1.5990505637277868 1.5990505637277868 1.5990505637277868 eval instant at 1m stdvar_over_time(metric[1m]) {} 0 eval instant at 1m stddev_over_time(metric[1m]) {} 0 # Tests for mad_over_time. clear load 10s metric 4 6 2 1 999 1 2 eval instant at 70s mad_over_time(metric[70s]) {} 1 # Tests for quantile_over_time clear load 10s data{test="two samples"} 0 1 data{test="three samples"} 0 1 2 data{test="uneven samples"} 0 1 4 eval instant at 1m quantile_over_time(0, data[1m]) {test="two samples"} 0 {test="three samples"} 0 {test="uneven samples"} 0 eval instant at 1m quantile_over_time(0.5, data[1m]) {test="two samples"} 0.5 {test="three samples"} 1 {test="uneven samples"} 1 eval instant at 1m quantile_over_time(0.75, data[1m]) {test="two samples"} 0.75 {test="three samples"} 1.5 {test="uneven samples"} 2.5 eval instant at 1m quantile_over_time(0.8, data[1m]) {test="two samples"} 0.8 {test="three samples"} 1.6 {test="uneven samples"} 2.8 eval instant at 1m quantile_over_time(1, data[1m]) {test="two samples"} 1 {test="three samples"} 2 {test="uneven samples"} 4 eval_warn instant at 1m quantile_over_time(-1, data[1m]) {test="two samples"} -Inf {test="three samples"} -Inf {test="uneven samples"} -Inf eval_warn instant at 1m quantile_over_time(2, data[1m]) {test="two samples"} +Inf {test="three samples"} +Inf {test="uneven samples"} +Inf eval_warn instant at 1m (quantile_over_time(2, (data[1m]))) {test="two samples"} +Inf {test="three samples"} +Inf {test="uneven samples"} +Inf clear # Test time-related functions. eval instant at 0m year() {} 1970 eval instant at 1ms time() 0.001 eval instant at 50m time() 3000 eval instant at 0m year(vector(1136239445)) {} 2006 eval instant at 0m month() {} 1 eval instant at 0m month(vector(1136239445)) {} 1 eval instant at 0m day_of_month() {} 1 eval instant at 0m day_of_month(vector(1136239445)) {} 2 eval instant at 0m day_of_year() {} 1 eval instant at 0m day_of_year(vector(1136239445)) {} 2 # Thursday. eval instant at 0m day_of_week() {} 4 eval instant at 0m day_of_week(vector(1136239445)) {} 1 eval instant at 0m hour() {} 0 eval instant at 0m hour(vector(1136239445)) {} 22 eval instant at 0m minute() {} 0 eval instant at 0m minute(vector(1136239445)) {} 4 # 2008-12-31 23:59:59 just before leap second. eval instant at 0m year(vector(1230767999)) {} 2008 # 2009-01-01 00:00:00 just after leap second. eval instant at 0m year(vector(1230768000)) {} 2009 # 2016-02-29 23:59:59 February 29th in leap year. eval instant at 0m month(vector(1456790399)) + day_of_month(vector(1456790399)) / 100 {} 2.29 # 2016-03-01 00:00:00 March 1st in leap year. eval instant at 0m month(vector(1456790400)) + day_of_month(vector(1456790400)) / 100 {} 3.01 # 2016-12-31 13:37:00 366th day in leap year. eval instant at 0m day_of_year(vector(1483191420)) {} 366 # 2022-12-31 13:37:00 365th day in non-leap year. eval instant at 0m day_of_year(vector(1672493820)) {} 365 # February 1st 2016 in leap year. eval instant at 0m days_in_month(vector(1454284800)) {} 29 # February 1st 2017 not in leap year. eval instant at 0m days_in_month(vector(1485907200)) {} 28 clear # Test duplicate labelset in promql output. load 5m testmetric1{src="a",dst="b"} 0 testmetric2{src="a",dst="b"} 1 eval_fail instant at 0m changes({__name__=~'testmetric1|testmetric2'}[5m]) # Tests for *_over_time clear load 10s data{type="numbers"} 2 0 3 data{type="some_nan"} 2 0 NaN data{type="some_nan2"} 2 NaN 1 data{type="some_nan3"} NaN 0 1 data{type="only_nan"} NaN NaN NaN eval instant at 1m min_over_time(data[1m]) {type="numbers"} 0 {type="some_nan"} 0 {type="some_nan2"} 1 {type="some_nan3"} 0 {type="only_nan"} NaN eval instant at 1m max_over_time(data[1m]) {type="numbers"} 3 {type="some_nan"} 2 {type="some_nan2"} 2 {type="some_nan3"} 1 {type="only_nan"} NaN eval instant at 1m last_over_time(data[1m]) data{type="numbers"} 3 data{type="some_nan"} NaN data{type="some_nan2"} 1 data{type="some_nan3"} 1 data{type="only_nan"} NaN clear # Test for absent() eval instant at 50m absent(nonexistent) {} 1 eval instant at 50m absent(nonexistent{job="testjob", instance="testinstance", method=~".x"}) {instance="testinstance", job="testjob"} 1 eval instant at 50m absent(nonexistent{job="testjob",job="testjob2",foo="bar"}) {foo="bar"} 1 eval instant at 50m absent(nonexistent{job="testjob",job="testjob2",job="three",foo="bar"}) {foo="bar"} 1 eval instant at 50m absent(nonexistent{job="testjob",job=~"testjob2",foo="bar"}) {foo="bar"} 1 clear # Don't return anything when there's something there. load 5m http_requests{job="api-server", instance="0", group="production"} 0+10x10 eval instant at 50m absent(http_requests) eval instant at 50m absent(sum(http_requests)) clear eval instant at 50m absent(sum(nonexistent{job="testjob", instance="testinstance"})) {} 1 eval instant at 50m absent(max(nonexistant)) {} 1 eval instant at 50m absent(nonexistant > 1) {} 1 eval instant at 50m absent(a + b) {} 1 eval instant at 50m absent(a and b) {} 1 eval instant at 50m absent(rate(nonexistant[5m])) {} 1 clear # Testdata for absent_over_time() eval instant at 1m absent_over_time(http_requests[5m]) {} 1 eval instant at 1m absent_over_time(http_requests{handler="/foo"}[5m]) {handler="/foo"} 1 eval instant at 1m absent_over_time(http_requests{handler!="/foo"}[5m]) {} 1 eval instant at 1m absent_over_time(http_requests{handler="/foo", handler="/bar", handler="/foobar"}[5m]) {} 1 eval instant at 1m absent_over_time(rate(nonexistant[5m])[5m:]) {} 1 eval instant at 1m absent_over_time(http_requests{handler="/foo", handler="/bar", instance="127.0.0.1"}[5m]) {instance="127.0.0.1"} 1 load 1m http_requests{path="/foo",instance="127.0.0.1",job="httpd"} 1+1x10 http_requests{path="/bar",instance="127.0.0.1",job="httpd"} 1+1x10 httpd_handshake_failures_total{instance="127.0.0.1",job="node"} 1+1x15 httpd_log_lines_total{instance="127.0.0.1",job="node"} 1 ssl_certificate_expiry_seconds{job="ingress"} NaN NaN NaN NaN NaN eval instant at 5m absent_over_time(http_requests[5m]) eval instant at 5m absent_over_time(rate(http_requests[5m])[5m:1m]) eval instant at 0m absent_over_time(httpd_log_lines_total[30s]) eval instant at 1m absent_over_time(httpd_log_lines_total[30s]) {} 1 eval instant at 15m absent_over_time(http_requests[5m]) eval instant at 16m absent_over_time(http_requests[5m]) {} 1 eval instant at 16m absent_over_time(http_requests[6m]) eval instant at 16m absent_over_time(httpd_handshake_failures_total[1m]) eval instant at 16m absent_over_time({instance="127.0.0.1"}[5m]) eval instant at 21m absent_over_time({instance="127.0.0.1"}[5m]) {instance="127.0.0.1"} 1 eval instant at 21m absent_over_time({instance="127.0.0.1"}[20m]) eval instant at 21m absent_over_time({job="grok"}[20m]) {job="grok"} 1 eval instant at 30m absent_over_time({instance="127.0.0.1"}[5m:5s]) {} 1 eval instant at 5m absent_over_time({job="ingress"}[4m]) eval instant at 10m absent_over_time({job="ingress"}[4m]) {job="ingress"} 1 clear # Testdata for present_over_time() eval instant at 1m present_over_time(http_requests[5m]) eval instant at 1m present_over_time(http_requests{handler="/foo"}[5m]) eval instant at 1m present_over_time(http_requests{handler!="/foo"}[5m]) eval instant at 1m present_over_time(http_requests{handler="/foo", handler="/bar", handler="/foobar"}[5m]) eval instant at 1m present_over_time(rate(nonexistant[5m])[5m:]) eval instant at 1m present_over_time(http_requests{handler="/foo", handler="/bar", instance="127.0.0.1"}[5m]) load 1m http_requests{path="/foo",instance="127.0.0.1",job="httpd"} 1+1x10 http_requests{path="/bar",instance="127.0.0.1",job="httpd"} 1+1x10 httpd_handshake_failures_total{instance="127.0.0.1",job="node"} 1+1x15 httpd_log_lines_total{instance="127.0.0.1",job="node"} 1 ssl_certificate_expiry_seconds{job="ingress"} NaN NaN NaN NaN NaN eval instant at 5m present_over_time(http_requests[5m]) {instance="127.0.0.1", job="httpd", path="/bar"} 1 {instance="127.0.0.1", job="httpd", path="/foo"} 1 eval instant at 5m present_over_time(rate(http_requests[5m])[5m:1m]) {instance="127.0.0.1", job="httpd", path="/bar"} 1 {instance="127.0.0.1", job="httpd", path="/foo"} 1 eval instant at 0m present_over_time(httpd_log_lines_total[30s]) {instance="127.0.0.1",job="node"} 1 eval instant at 1m present_over_time(httpd_log_lines_total[30s]) eval instant at 15m present_over_time(http_requests[5m]) {instance="127.0.0.1", job="httpd", path="/bar"} 1 {instance="127.0.0.1", job="httpd", path="/foo"} 1 eval instant at 16m present_over_time(http_requests[5m]) eval instant at 16m present_over_time(http_requests[6m]) {instance="127.0.0.1", job="httpd", path="/bar"} 1 {instance="127.0.0.1", job="httpd", path="/foo"} 1 eval instant at 16m present_over_time(httpd_handshake_failures_total[1m]) {instance="127.0.0.1", job="node"} 1 eval instant at 16m present_over_time({instance="127.0.0.1"}[5m]) {instance="127.0.0.1",job="node"} 1 eval instant at 21m present_over_time({job="grok"}[20m]) eval instant at 30m present_over_time({instance="127.0.0.1"}[5m:5s]) eval instant at 5m present_over_time({job="ingress"}[4m]) {job="ingress"} 1 eval instant at 10m present_over_time({job="ingress"}[4m]) clear # Testing exp() sqrt() log2() log10() ln() load 5m exp_root_log{l="x"} 10 exp_root_log{l="y"} 20 eval instant at 5m exp(exp_root_log) {l="x"} 22026.465794806718 {l="y"} 485165195.4097903 eval instant at 5m exp(exp_root_log - 10) {l="y"} 22026.465794806718 {l="x"} 1 eval instant at 5m exp(exp_root_log - 20) {l="x"} 4.5399929762484854e-05 {l="y"} 1 eval instant at 5m ln(exp_root_log) {l="x"} 2.302585092994046 {l="y"} 2.995732273553991 eval instant at 5m ln(exp_root_log - 10) {l="y"} 2.302585092994046 {l="x"} -Inf eval instant at 5m ln(exp_root_log - 20) {l="y"} -Inf {l="x"} NaN eval instant at 5m exp(ln(exp_root_log)) {l="y"} 20 {l="x"} 10 eval instant at 5m sqrt(exp_root_log) {l="x"} 3.1622776601683795 {l="y"} 4.47213595499958 eval instant at 5m log2(exp_root_log) {l="x"} 3.3219280948873626 {l="y"} 4.321928094887363 eval instant at 5m log2(exp_root_log - 10) {l="y"} 3.3219280948873626 {l="x"} -Inf eval instant at 5m log2(exp_root_log - 20) {l="x"} NaN {l="y"} -Inf eval instant at 5m log10(exp_root_log) {l="x"} 1 {l="y"} 1.301029995663981 eval instant at 5m log10(exp_root_log - 10) {l="y"} 1 {l="x"} -Inf eval instant at 5m log10(exp_root_log - 20) {l="x"} NaN {l="y"} -Inf clear # Test that timestamp() handles the scenario where there are more steps than samples. load 1m metric 0+1x1000 # We expect the value to be 0 for t=0s to t=59s (inclusive), then 60 for t=60s and t=61s. eval range from 0 to 61s step 1s timestamp(metric) {} 0x59 60 60