mirror of
https://github.com/prometheus/prometheus.git
synced 2026-05-05 04:16:15 +02:00
384 lines
11 KiB
Plaintext
384 lines
11 KiB
Plaintext
# ==================== 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
|
|
|
|
# ---------- Metric names that match fill modifier keywords ----------
|
|
|
|
clear
|
|
|
|
load 5m
|
|
fill{label="a"} 1
|
|
fill{label="b"} 2
|
|
fill_left{label="a"} 10
|
|
fill_left{label="c"} 30
|
|
fill_right{label="b"} 200
|
|
fill_right{label="d"} 400
|
|
other{label="a"} 1000
|
|
other{label="e"} 5000
|
|
|
|
# Metric named "fill" on the left side.
|
|
eval instant at 0m fill + fill(0) other
|
|
{label="a"} 1001
|
|
{label="b"} 2
|
|
{label="e"} 5000
|
|
|
|
# Metric named "fill" on the right side without modifier.
|
|
eval instant at 0m other + fill
|
|
{label="a"} 1001
|
|
|
|
# Metric named "fill" on the right side with fill() modifier.
|
|
eval instant at 0m other + fill(0) fill
|
|
{label="a"} 1001
|
|
{label="b"} 2
|
|
{label="e"} 5000
|
|
|
|
# Metric named "fill_left" on the right side with fill_left() modifier.
|
|
eval instant at 0m other + fill_left(0) fill_left
|
|
{label="a"} 1010
|
|
{label="c"} 30
|
|
|
|
# Metric named "fill_right" on the right side with fill_right() modifier.
|
|
eval instant at 0m other + fill_right(0) fill_right
|
|
{label="a"} 1000
|
|
{label="e"} 5000
|