mirror of
https://github.com/prometheus/prometheus.git
synced 2026-02-03 20:39:32 -05:00
Add fill modifier PromQL tests
Signed-off-by: Julius Volz <julius.volz@gmail.com>
This commit is contained in:
parent
af3277f832
commit
57dd1f18b4
1 changed files with 343 additions and 0 deletions
343
promql/promqltest/testdata/fill-modifier.test
vendored
Normal file
343
promql/promqltest/testdata/fill-modifier.test
vendored
Normal file
|
|
@ -0,0 +1,343 @@
|
|||
# ==================== fill / fill_left / fill_right modifier tests ====================
|
||||
|
||||
# Test data for fill modifier tests: vectors with partial overlap.
|
||||
load 5m
|
||||
left_vector{label="a"} 10
|
||||
left_vector{label="b"} 20
|
||||
left_vector{label="c"} 30
|
||||
right_vector{label="a"} 100
|
||||
right_vector{label="b"} 200
|
||||
right_vector{label="d"} 400
|
||||
|
||||
# ---------- Arithmetic operators with fill modifiers ----------
|
||||
|
||||
# fill(0): Fill both sides with 0 for addition.
|
||||
eval instant at 0m left_vector + fill(0) right_vector
|
||||
{label="a"} 110
|
||||
{label="b"} 220
|
||||
{label="c"} 30
|
||||
{label="d"} 400
|
||||
|
||||
# fill_left(0): Only fill left side with 0.
|
||||
eval instant at 0m left_vector + fill_left(0) right_vector
|
||||
{label="a"} 110
|
||||
{label="b"} 220
|
||||
{label="d"} 400
|
||||
|
||||
# fill_right(0): Only fill right side with 0.
|
||||
eval instant at 0m left_vector + fill_right(0) right_vector
|
||||
{label="a"} 110
|
||||
{label="b"} 220
|
||||
{label="c"} 30
|
||||
|
||||
# fill_left and fill_right with different values.
|
||||
eval instant at 0m left_vector + fill_left(5) fill_right(7) right_vector
|
||||
{label="a"} 110
|
||||
{label="b"} 220
|
||||
{label="c"} 37
|
||||
{label="d"} 405
|
||||
|
||||
# fill with NaN.
|
||||
eval instant at 0m left_vector + fill(NaN) right_vector
|
||||
{label="a"} 110
|
||||
{label="b"} 220
|
||||
{label="c"} NaN
|
||||
{label="d"} NaN
|
||||
|
||||
# fill with Inf.
|
||||
eval instant at 0m left_vector + fill(Inf) right_vector
|
||||
{label="a"} 110
|
||||
{label="b"} 220
|
||||
{label="c"} +Inf
|
||||
{label="d"} +Inf
|
||||
|
||||
# fill with -Inf.
|
||||
eval instant at 0m left_vector + fill(-Inf) right_vector
|
||||
{label="a"} 110
|
||||
{label="b"} 220
|
||||
{label="c"} -Inf
|
||||
{label="d"} -Inf
|
||||
|
||||
# ---------- Comparison operators with fill modifiers ----------
|
||||
|
||||
# fill with equality comparison.
|
||||
eval instant at 0m left_vector == fill(30) right_vector
|
||||
left_vector{label="c"} 30
|
||||
|
||||
# fill with inequality comparison.
|
||||
eval instant at 0m left_vector != fill(30) right_vector
|
||||
left_vector{label="a"} 10
|
||||
left_vector{label="b"} 20
|
||||
{label="d"} 30
|
||||
|
||||
# fill with greater than.
|
||||
eval instant at 0m left_vector > fill(25) right_vector
|
||||
left_vector{label="c"} 30
|
||||
|
||||
# ---------- Comparison operators with bool modifier and fill ----------
|
||||
|
||||
# fill with equality comparison and bool.
|
||||
eval instant at 0m left_vector == bool fill(30) right_vector
|
||||
{label="a"} 0
|
||||
{label="b"} 0
|
||||
{label="c"} 1
|
||||
{label="d"} 0
|
||||
|
||||
# fill with inequality comparison and bool.
|
||||
eval instant at 0m left_vector != bool fill(30) right_vector
|
||||
{label="a"} 1
|
||||
{label="b"} 1
|
||||
{label="c"} 0
|
||||
{label="d"} 1
|
||||
|
||||
# fill with greater than and bool.
|
||||
eval instant at 0m left_vector > bool fill(25) right_vector
|
||||
{label="a"} 0
|
||||
{label="b"} 0
|
||||
{label="c"} 1
|
||||
{label="d"} 0
|
||||
|
||||
# ---------- fill with on() and ignoring() modifiers ----------
|
||||
|
||||
clear
|
||||
|
||||
load 5m
|
||||
left_vector{job="foo", instance="a"} 10
|
||||
left_vector{job="foo", instance="b"} 20
|
||||
left_vector{job="bar", instance="a"} 30
|
||||
right_vector{job="foo", instance="a"} 100
|
||||
right_vector{job="foo", instance="c"} 300
|
||||
|
||||
# fill with on().
|
||||
eval instant at 0m left_vector + on(job, instance) fill(0) right_vector
|
||||
{job="foo", instance="a"} 110
|
||||
{job="foo", instance="b"} 20
|
||||
{job="bar", instance="a"} 30
|
||||
{job="foo", instance="c"} 300
|
||||
|
||||
# fill_right with on().
|
||||
eval instant at 0m left_vector + on(job, instance) fill_right(0) right_vector
|
||||
{job="foo", instance="a"} 110
|
||||
{job="foo", instance="b"} 20
|
||||
{job="bar", instance="a"} 30
|
||||
|
||||
# fill_left with on().
|
||||
eval instant at 0m left_vector + on(job, instance) fill_left(0) right_vector
|
||||
{job="foo", instance="a"} 110
|
||||
{job="foo", instance="c"} 300
|
||||
|
||||
# fill with ignoring() - requires group_left since ignoring(job) creates many-to-one matching
|
||||
# when two left_vector series have same instance but different jobs.
|
||||
eval instant at 0m left_vector + ignoring(job) group_left fill(0) right_vector
|
||||
{instance="a", job="foo"} 110
|
||||
{instance="a", job="bar"} 130
|
||||
{instance="b", job="foo"} 20
|
||||
{instance="c"} 300
|
||||
|
||||
# ---------- fill with group_left / group_right (many-to-one / one-to-many) ----------
|
||||
|
||||
clear
|
||||
|
||||
load 5m
|
||||
requests{method="GET", status="200"} 100
|
||||
requests{method="POST", status="200"} 200
|
||||
requests{method="GET", status="500"} 10
|
||||
requests{method="POST", status="500"} 20
|
||||
limits{status="200"} 1000
|
||||
limits{status="404"} 500
|
||||
limits{status="500"} 50
|
||||
|
||||
# group_left with fill_right: fill missing "one" side series.
|
||||
eval instant at 0m requests / on(status) group_left fill_right(1) limits
|
||||
{method="GET", status="200"} 0.1
|
||||
{method="POST", status="200"} 0.2
|
||||
{method="GET", status="500"} 0.2
|
||||
{method="POST", status="500"} 0.4
|
||||
|
||||
# group_left with fill_left: fill missing "many" side series.
|
||||
# For status="404", there's no matching requests, so a single series with the match group's labels is filled
|
||||
eval instant at 0m requests + on(status) group_left fill_left(0) limits
|
||||
{method="GET", status="200"} 1100
|
||||
{method="POST", status="200"} 1200
|
||||
{method="GET", status="500"} 60
|
||||
{method="POST", status="500"} 70
|
||||
{status="404"} 500
|
||||
|
||||
# group_left with fill on both sides.
|
||||
eval instant at 0m requests + on(status) group_left fill(0) limits
|
||||
{method="GET", status="200"} 1100
|
||||
{method="POST", status="200"} 1200
|
||||
{method="GET", status="500"} 60
|
||||
{method="POST", status="500"} 70
|
||||
{status="404"} 500
|
||||
|
||||
# group_right with fill_left: fill missing "one" side series.
|
||||
clear
|
||||
|
||||
load 5m
|
||||
cpu_info{instance="a", cpu="0"} 1
|
||||
cpu_info{instance="a", cpu="1"} 1
|
||||
cpu_info{instance="b", cpu="0"} 1
|
||||
node_meta{instance="a"} 100
|
||||
node_meta{instance="c"} 300
|
||||
|
||||
# fill_left fills the "one" side (node_meta) when missing for a "many" side series.
|
||||
eval instant at 0m node_meta * on(instance) group_right fill_left(1) cpu_info
|
||||
{instance="a", cpu="0"} 100
|
||||
{instance="a", cpu="1"} 100
|
||||
{instance="c"} 300
|
||||
|
||||
# group_right with fill_right: fill missing "many" side series.
|
||||
eval instant at 0m node_meta * on(instance) group_right fill_right(0) cpu_info
|
||||
{instance="a", cpu="0"} 100
|
||||
{instance="a", cpu="1"} 100
|
||||
{instance="b", cpu="0"} 0
|
||||
|
||||
# group_right with fill on both sides.
|
||||
eval instant at 0m node_meta * on(instance) group_right fill(1) cpu_info
|
||||
{instance="a", cpu="0"} 100
|
||||
{instance="a", cpu="1"} 100
|
||||
{instance="b", cpu="0"} 1
|
||||
{instance="c"} 300
|
||||
|
||||
# ---------- fill with group_left/group_right and extra labels ----------
|
||||
|
||||
clear
|
||||
|
||||
load 5m
|
||||
requests{method="GET", status="200"} 100
|
||||
requests{method="POST", status="200"} 200
|
||||
limits{status="200", owner="team-a"} 1000
|
||||
limits{status="500", owner="team-b"} 50
|
||||
|
||||
# group_left with extra label and fill_right.
|
||||
# Note: when filling the "one" side, the joined label cannot be filled.
|
||||
eval instant at 0m requests + on(status) group_left(owner) fill_right(0) limits
|
||||
{method="GET", status="200", owner="team-a"} 1100
|
||||
{method="POST", status="200", owner="team-a"} 1200
|
||||
|
||||
# ---------- Edge cases ----------
|
||||
|
||||
clear
|
||||
|
||||
load 5m
|
||||
only_left{label="a"} 10
|
||||
only_left{label="b"} 20
|
||||
only_right{label="c"} 30
|
||||
only_right{label="d"} 40
|
||||
|
||||
# No overlap at all - fill creates all results.
|
||||
eval instant at 0m only_left + fill(0) only_right
|
||||
{label="a"} 10
|
||||
{label="b"} 20
|
||||
{label="c"} 30
|
||||
{label="d"} 40
|
||||
|
||||
# No overlap - fill_left only creates right side results.
|
||||
eval instant at 0m only_left + fill_left(0) only_right
|
||||
{label="c"} 30
|
||||
{label="d"} 40
|
||||
|
||||
# No overlap - fill_right only creates left side results.
|
||||
eval instant at 0m only_left + fill_right(0) only_right
|
||||
{label="a"} 10
|
||||
{label="b"} 20
|
||||
|
||||
# Complete overlap - fill has no effect.
|
||||
clear
|
||||
|
||||
load 5m
|
||||
complete_left{label="a"} 10
|
||||
complete_left{label="b"} 20
|
||||
complete_right{label="a"} 100
|
||||
complete_right{label="b"} 200
|
||||
|
||||
eval instant at 0m complete_left + fill(99) complete_right
|
||||
{label="a"} 110
|
||||
{label="b"} 220
|
||||
|
||||
# ---------- fill with range queries ----------
|
||||
|
||||
clear
|
||||
|
||||
load 5m
|
||||
range_left{label="a"} 1 2 3 4 5
|
||||
range_left{label="b"} 10 20 30 40 50
|
||||
range_right{label="a"} 100 200 300 400 500
|
||||
range_right{label="c"} 1000 2000 3000 4000 5000
|
||||
|
||||
eval range from 0 to 20m step 5m range_left + fill(0) range_right
|
||||
{label="a"} 101 202 303 404 505
|
||||
{label="b"} 10 20 30 40 50
|
||||
{label="c"} 1000 2000 3000 4000 5000
|
||||
|
||||
eval range from 0 to 20m step 5m range_left + fill_right(0) range_right
|
||||
{label="a"} 101 202 303 404 505
|
||||
{label="b"} 10 20 30 40 50
|
||||
|
||||
eval range from 0 to 20m step 5m range_left + fill_left(0) range_right
|
||||
{label="a"} 101 202 303 404 505
|
||||
{label="c"} 1000 2000 3000 4000 5000
|
||||
|
||||
# Range queries with intermittently present series.
|
||||
clear
|
||||
|
||||
load 5m
|
||||
intermittent_left{label="a"} 1 _ 3 _ 5
|
||||
intermittent_left{label="b"} _ 20 _ 40 _
|
||||
intermittent_right{label="a"} _ 200 _ 400 _
|
||||
intermittent_right{label="b"} 100 _ 300 _ 500
|
||||
intermittent_right{label="c"} 1000 _ _ 4000 5000
|
||||
|
||||
# When both sides have the same label but are present at different times,
|
||||
# fill creates results at all timestamps where at least one side is present.
|
||||
eval range from 0 to 20m step 5m intermittent_left + fill(0) intermittent_right
|
||||
{label="a"} 1 200 3 400 5
|
||||
{label="b"} 100 20 300 40 500
|
||||
{label="c"} 1000 _ _ 4000 5000
|
||||
|
||||
# fill_right only fills the right side when it's missing.
|
||||
# Output only exists when left side is present (right side filled with 0 if missing).
|
||||
eval range from 0 to 20m step 5m intermittent_left + fill_right(0) intermittent_right
|
||||
{label="a"} 1 _ 3 _ 5
|
||||
{label="b"} _ 20 _ 40 _
|
||||
|
||||
# fill_left only fills the left side when it's missing.
|
||||
# Output only exists when right side is present (left side filled with 0 if missing).
|
||||
eval range from 0 to 20m step 5m intermittent_left + fill_left(0) intermittent_right
|
||||
{label="a"} _ 200 _ 400 _
|
||||
{label="b"} 100 _ 300 _ 500
|
||||
{label="c"} 1000 _ _ 4000 5000
|
||||
|
||||
# ---------- fill with vectors where one side is empty ----------
|
||||
|
||||
clear
|
||||
|
||||
load 5m
|
||||
non_empty{label="a"} 10
|
||||
non_empty{label="b"} 20
|
||||
|
||||
# Empty right side - fill_right has no effect (nothing to add).
|
||||
eval instant at 0m non_empty + fill_right(0) nonexistent
|
||||
{label="a"} 10
|
||||
{label="b"} 20
|
||||
|
||||
# Empty right side - fill_left creates nothing (no right side labels to use).
|
||||
eval instant at 0m non_empty + fill_left(0) nonexistent
|
||||
|
||||
# Empty left side - fill_left has no effect.
|
||||
eval instant at 0m nonexistent + fill_left(0) non_empty
|
||||
{label="a"} 10
|
||||
{label="b"} 20
|
||||
|
||||
# Empty left side - fill_right creates nothing.
|
||||
eval instant at 0m nonexistent + fill_right(0) non_empty
|
||||
|
||||
# fill both sides with one side empty.
|
||||
eval instant at 0m non_empty + fill(0) nonexistent
|
||||
{label="a"} 10
|
||||
{label="b"} 20
|
||||
|
||||
eval instant at 0m nonexistent + fill(0) non_empty
|
||||
{label="a"} 10
|
||||
{label="b"} 20
|
||||
Loading…
Reference in a new issue