mirror of
https://github.com/hanzoai/datastore.git
synced 2026-09-26 13:55:07 +00:00
3705 lines
167 KiB
Python
3705 lines
167 KiB
Python
import pytest
|
|
|
|
from helpers.cluster import ClickHouseCluster
|
|
from helpers.test_tools import tsv_close_to
|
|
import requests
|
|
|
|
from .prometheus_test_utils import (
|
|
convert_time_series_to_protobuf,
|
|
execute_query_via_http_api,
|
|
execute_range_query_via_http_api,
|
|
http_api_response_close_to,
|
|
send_protobuf_to_remote_write,
|
|
)
|
|
|
|
|
|
cluster = ClickHouseCluster(__file__)
|
|
|
|
node = cluster.add_instance(
|
|
"node",
|
|
main_configs=["configs/prometheus.xml"],
|
|
user_configs=["configs/allow_experimental_time_series_table.xml"],
|
|
handle_prometheus_remote_read=(9093, "/read"),
|
|
handle_prometheus_remote_write=(9093, "/write"),
|
|
with_prometheus_reader=True,
|
|
with_prometheus_receiver=True,
|
|
)
|
|
|
|
|
|
# Sends data [ ({'label_name1': 'label_value1], ...}, {timestamp1: value1, ...} ), ... ]
|
|
# to the "protobuf_receiver" service and also to ClickHouse via the RemoteWrite protocol.
|
|
def send_data(time_series):
|
|
protobuf = convert_time_series_to_protobuf(time_series)
|
|
send_protobuf_to_remote_write(
|
|
cluster.prometheus_ip["receiver"],
|
|
cluster.prometheus_port["receiver"],
|
|
"api/v1/write",
|
|
protobuf,
|
|
)
|
|
send_protobuf_to_remote_write(node.ip_address, 9093, "/write", protobuf)
|
|
|
|
|
|
# Executes a query in the "prometheus_reader" service. This service uses the RemoteRead protocol to get data from ClickHouse.
|
|
def execute_query_in_prometheus_reader(query, timestamp=None, expect_error=False):
|
|
return execute_query_via_http_api(
|
|
cluster.prometheus_ip["reader"],
|
|
cluster.prometheus_port["reader"],
|
|
"/api/v1/query",
|
|
query,
|
|
timestamp=timestamp,
|
|
expect_error=expect_error,
|
|
)
|
|
|
|
|
|
# Executes a query in the "prometheus_receiver" service. We sent data to this service earlier via the RemoteWrite protocol.
|
|
def execute_query_in_prometheus_receiver(query, timestamp, expect_error=False):
|
|
return execute_query_via_http_api(
|
|
cluster.prometheus_ip["receiver"],
|
|
cluster.prometheus_port["receiver"],
|
|
"/api/v1/query",
|
|
query,
|
|
timestamp=timestamp,
|
|
expect_error=expect_error,
|
|
)
|
|
|
|
|
|
# Executes a query in both prometheus services - results should be the same.
|
|
def execute_query_in_prometheus(query, timestamp, expect_error=False):
|
|
r1 = execute_query_in_prometheus_reader(query, timestamp, expect_error=expect_error)
|
|
r2 = execute_query_in_prometheus_receiver(
|
|
query, timestamp, expect_error=expect_error
|
|
)
|
|
assert r1 == r2
|
|
return r1
|
|
|
|
|
|
# Executes a prometheus query in ClickHouse via HTTP API
|
|
def execute_query_in_clickhouse_http_api(query, timestamp, expect_error=False):
|
|
return execute_query_via_http_api(
|
|
node.ip_address,
|
|
9093,
|
|
"/api/v1/query",
|
|
query,
|
|
timestamp=timestamp,
|
|
expect_error=expect_error,
|
|
)
|
|
|
|
|
|
# Executes a prometheus query in ClickHouse via SQL query
|
|
def execute_query_in_clickhouse_sql(query, timestamp, expect_error=False):
|
|
quoted_query = "'" + query.replace("'", "''") + "'"
|
|
sql_query = (
|
|
f"SELECT * FROM prometheusQuery(prometheus, {quoted_query}, {timestamp})"
|
|
)
|
|
if expect_error:
|
|
return node.query_and_get_error(sql_query)
|
|
return node.query(sql_query)
|
|
|
|
|
|
# Executes a range query in both prometheus services.
|
|
def execute_range_query_in_prometheus(query, start_time, end_time, step):
|
|
r1 = execute_range_query_via_http_api(
|
|
cluster.prometheus_ip["reader"],
|
|
cluster.prometheus_port["reader"],
|
|
"/api/v1/query_range",
|
|
query,
|
|
start_time,
|
|
end_time,
|
|
step,
|
|
)
|
|
r2 = execute_range_query_via_http_api(
|
|
cluster.prometheus_ip["receiver"],
|
|
cluster.prometheus_port["receiver"],
|
|
"/api/v1/query_range",
|
|
query,
|
|
start_time,
|
|
end_time,
|
|
step,
|
|
)
|
|
assert r1 == r2
|
|
return r1
|
|
|
|
|
|
# Executes a range query in ClickHouse via HTTP API
|
|
def execute_range_query_in_clickhouse_http_api(query, start_time, end_time, step):
|
|
return execute_range_query_via_http_api(
|
|
node.ip_address,
|
|
9093,
|
|
"/api/v1/query_range",
|
|
query,
|
|
start_time,
|
|
end_time,
|
|
step,
|
|
)
|
|
|
|
|
|
# Executes a range query in ClickHouse via SQL query
|
|
def execute_range_query_in_clickhouse_sql(query, start_time, end_time, step):
|
|
return node.query(
|
|
f"SELECT * FROM prometheusQueryRange(prometheus, '{query}', {start_time}, {end_time}, {step})"
|
|
)
|
|
|
|
|
|
# Sends all test data to the "protobuf_receiver" service and also to ClickHouse via the RemoteWrite protocol.
|
|
def send_test_data():
|
|
send_data([({"__name__": "up", "job": "prometheus"}, {1753176654.832: 1})])
|
|
|
|
send_data(
|
|
[
|
|
(
|
|
{"__name__": "test"},
|
|
{
|
|
110: 1,
|
|
120: 1,
|
|
130: 3,
|
|
140: 4,
|
|
190: 5,
|
|
200: 5,
|
|
210: 8,
|
|
220: 12,
|
|
230: 13,
|
|
},
|
|
)
|
|
]
|
|
)
|
|
|
|
send_data(
|
|
[
|
|
(
|
|
{"__name__": "timestamps", "job": "test"},
|
|
{
|
|
110: 1764498605,
|
|
120: 1765035045,
|
|
},
|
|
),
|
|
]
|
|
)
|
|
|
|
send_data(
|
|
[
|
|
(
|
|
{"__name__": "deltas", "job": "test"},
|
|
{
|
|
100: -2,
|
|
200: -1,
|
|
300: -0.5,
|
|
400: 0,
|
|
500: 0.5,
|
|
600: 1,
|
|
700: 2,
|
|
},
|
|
),
|
|
]
|
|
)
|
|
|
|
# A counter that resets (decreases) at 140 (8 -> 2) and 200 (10 -> 3).
|
|
send_data(
|
|
[
|
|
(
|
|
{"__name__": "resets", "job": "test"},
|
|
{
|
|
110: 1,
|
|
120: 5,
|
|
130: 8,
|
|
140: 2,
|
|
150: 6,
|
|
190: 10,
|
|
200: 3,
|
|
210: 9,
|
|
},
|
|
)
|
|
]
|
|
)
|
|
|
|
send_data(
|
|
[
|
|
(
|
|
{"__name__": "http_errors", "http_code": "401"},
|
|
{
|
|
150: 0,
|
|
200: 4,
|
|
},
|
|
),
|
|
(
|
|
{"__name__": "http_errors", "http_code": "404"},
|
|
{
|
|
110: 1,
|
|
120: 5,
|
|
},
|
|
),
|
|
(
|
|
{"__name__": "download_failures", "http_code": "404"},
|
|
{
|
|
130: 0,
|
|
150: 1,
|
|
},
|
|
),
|
|
]
|
|
)
|
|
|
|
send_data(
|
|
[
|
|
(
|
|
{"__name__": "foo", "shape": "square", "size": "s"},
|
|
{110: 4, 130: 40},
|
|
),
|
|
(
|
|
{"__name__": "foo", "shape": "triangle", "size": "m"},
|
|
{110: 8, 120: 80},
|
|
),
|
|
(
|
|
{"__name__": "foo", "shape": "circle", "size": "l"},
|
|
{110: 16, 130: 16, 150: 16},
|
|
),
|
|
|
|
(
|
|
{"__name__": "bar", "shape": "circle", "size": "l"},
|
|
{110: 10, 120: 16, 130: 50, 150: 1000},
|
|
),
|
|
(
|
|
{"__name__": "bar", "shape": "square", "size": "s"},
|
|
{110: 3, 120: 40, 140: 700},
|
|
),
|
|
(
|
|
{"__name__": "bar", "shape": "triangle", "size": "xl"},
|
|
{110: 8, 150: 30},
|
|
),
|
|
(
|
|
{"__name__": "bar", "shape": "rectangle", "size": "l"},
|
|
{110: 9, 130: 90},
|
|
),
|
|
]
|
|
)
|
|
|
|
# Classic Prometheus histogram buckets for `histogram_quantile` testing.
|
|
# At t=300 the cumulative counts are: le=0.1 -> 10, le=0.5 -> 30, le=1.0 -> 50, le=+Inf -> 60.
|
|
# That describes 10 observations <= 0.1s, 20 in (0.1, 0.5], 20 in (0.5, 1.0], and 10 in (1.0, +Inf).
|
|
send_data(
|
|
[
|
|
(
|
|
{"__name__": "http_request_duration_seconds_bucket", "job": "api", "le": "0.1"},
|
|
{300: 10},
|
|
),
|
|
(
|
|
{"__name__": "http_request_duration_seconds_bucket", "job": "api", "le": "0.5"},
|
|
{300: 30},
|
|
),
|
|
(
|
|
{"__name__": "http_request_duration_seconds_bucket", "job": "api", "le": "1.0"},
|
|
{300: 50},
|
|
),
|
|
(
|
|
{"__name__": "http_request_duration_seconds_bucket", "job": "api", "le": "+Inf"},
|
|
{300: 60},
|
|
),
|
|
]
|
|
)
|
|
|
|
# A second histogram metric with two `job` groupings, used to verify that
|
|
# `histogram_quantile` correctly groups by all labels except `le` and `__name__`.
|
|
# For each job, total = 10, so phi=0.5 targets rank 5.
|
|
# job=reader cumulative [2, 8, 10]: rank 5 is in (1, 4], interpolates to 1 + 3*(5-2)/(8-2) = 2.5.
|
|
# job=writer cumulative [4, 8, 10]: rank 5 is in (1, 4], interpolates to 1 + 3*(5-4)/(8-4) = 1.75.
|
|
send_data(
|
|
[
|
|
(
|
|
{"__name__": "cache_lookup_duration_seconds_bucket", "job": "reader", "le": "1"},
|
|
{300: 2},
|
|
),
|
|
(
|
|
{"__name__": "cache_lookup_duration_seconds_bucket", "job": "reader", "le": "4"},
|
|
{300: 8},
|
|
),
|
|
(
|
|
{"__name__": "cache_lookup_duration_seconds_bucket", "job": "reader", "le": "+Inf"},
|
|
{300: 10},
|
|
),
|
|
(
|
|
{"__name__": "cache_lookup_duration_seconds_bucket", "job": "writer", "le": "1"},
|
|
{300: 4},
|
|
),
|
|
(
|
|
{"__name__": "cache_lookup_duration_seconds_bucket", "job": "writer", "le": "4"},
|
|
{300: 8},
|
|
),
|
|
(
|
|
{"__name__": "cache_lookup_duration_seconds_bucket", "job": "writer", "le": "+Inf"},
|
|
{300: 10},
|
|
),
|
|
]
|
|
)
|
|
|
|
# Histograms for `histogram_quantile` edge-case coverage. `rate_bucket` carries two
|
|
# sample points per bucket so `rate(rate_bucket[60s])` is defined; the rest have a
|
|
# single sample at t=300.
|
|
send_data(
|
|
[
|
|
(
|
|
{"__name__": "only_inf_bucket", "le": "+Inf"},
|
|
{300: 10},
|
|
),
|
|
(
|
|
{"__name__": "no_inf_bucket", "le": "0.1"},
|
|
{300: 5},
|
|
),
|
|
(
|
|
{"__name__": "no_inf_bucket", "le": "0.5"},
|
|
{300: 8},
|
|
),
|
|
(
|
|
{"__name__": "no_inf_bucket", "le": "1.0"},
|
|
{300: 10},
|
|
),
|
|
(
|
|
{"__name__": "zero_count_bucket", "le": "0.1"},
|
|
{300: 0},
|
|
),
|
|
(
|
|
{"__name__": "zero_count_bucket", "le": "0.5"},
|
|
{300: 0},
|
|
),
|
|
(
|
|
{"__name__": "zero_count_bucket", "le": "+Inf"},
|
|
{300: 0},
|
|
),
|
|
(
|
|
{"__name__": "negative_le_bucket", "le": "-1.0"},
|
|
{300: 5},
|
|
),
|
|
(
|
|
{"__name__": "negative_le_bucket", "le": "0"},
|
|
{300: 10},
|
|
),
|
|
(
|
|
{"__name__": "negative_le_bucket", "le": "+Inf"},
|
|
{300: 15},
|
|
),
|
|
# Two distinct histograms (different `__name__`) selected together by a
|
|
# name regex. They share `env` but differ in another label, so after
|
|
# `histogram_quantile` drops `__name__` from the output the two series
|
|
# remain distinguishable. Used to verify that the quantile is computed
|
|
# per histogram (i.e. `__name__` participates in the GROUP BY) — merging
|
|
# buckets across histograms would yield a single, incorrect result.
|
|
(
|
|
{"__name__": "two_hist_a_bucket", "env": "prod", "kind": "a", "le": "0.1"},
|
|
{300: 10},
|
|
),
|
|
(
|
|
{"__name__": "two_hist_a_bucket", "env": "prod", "kind": "a", "le": "1.0"},
|
|
{300: 50},
|
|
),
|
|
(
|
|
{"__name__": "two_hist_a_bucket", "env": "prod", "kind": "a", "le": "+Inf"},
|
|
{300: 60},
|
|
),
|
|
(
|
|
{"__name__": "two_hist_b_bucket", "env": "prod", "kind": "b", "le": "0.1"},
|
|
{300: 5},
|
|
),
|
|
(
|
|
{"__name__": "two_hist_b_bucket", "env": "prod", "kind": "b", "le": "1.0"},
|
|
{300: 8},
|
|
),
|
|
(
|
|
{"__name__": "two_hist_b_bucket", "env": "prod", "kind": "b", "le": "+Inf"},
|
|
{300: 10},
|
|
),
|
|
# Histogram with a bucket whose `le` label is not parseable as a float.
|
|
# Prometheus drops the malformed bucket from the calculation rather than
|
|
# failing the query, so the result must be the quantile over the remaining
|
|
# well-formed buckets.
|
|
(
|
|
{"__name__": "bad_le_bucket", "le": "0.1"},
|
|
{300: 10},
|
|
),
|
|
(
|
|
{"__name__": "bad_le_bucket", "le": "abc"},
|
|
{300: 25},
|
|
),
|
|
(
|
|
{"__name__": "bad_le_bucket", "le": "1.0"},
|
|
{300: 50},
|
|
),
|
|
(
|
|
{"__name__": "bad_le_bucket", "le": "+Inf"},
|
|
{300: 60},
|
|
),
|
|
(
|
|
{"__name__": "rate_bucket", "le": "0.1"},
|
|
{300: 10, 330: 15, 360: 20},
|
|
),
|
|
(
|
|
{"__name__": "rate_bucket", "le": "0.5"},
|
|
{300: 30, 330: 45, 360: 60},
|
|
),
|
|
(
|
|
{"__name__": "rate_bucket", "le": "1.0"},
|
|
{300: 50, 330: 75, 360: 100},
|
|
),
|
|
(
|
|
{"__name__": "rate_bucket", "le": "+Inf"},
|
|
{300: 60, 330: 90, 360: 120},
|
|
),
|
|
]
|
|
)
|
|
|
|
|
|
@pytest.fixture(scope="module", autouse=True)
|
|
def start_cluster():
|
|
try:
|
|
cluster.start()
|
|
node.query("CREATE TABLE prometheus ENGINE=TimeSeries")
|
|
send_test_data()
|
|
yield cluster
|
|
finally:
|
|
cluster.shutdown()
|
|
|
|
|
|
# Evaluates the same query in Prometheus and in ClickHouse and compare the results.
|
|
def do_query_test(
|
|
query,
|
|
timestamp,
|
|
result,
|
|
chresult,
|
|
clickhouse_http_api_result_is_same_as_prometheus=True,
|
|
eps=0,
|
|
):
|
|
assert execute_query_in_prometheus(query, timestamp) == result
|
|
|
|
actual_chresult = execute_query_in_clickhouse_sql(query, timestamp)
|
|
assert tsv_close_to(
|
|
actual_chresult, chresult, eps=eps
|
|
), f"actual result: {actual_chresult}, expected: {chresult}"
|
|
|
|
actual_result_from_http_api = execute_query_in_clickhouse_http_api(query, timestamp)
|
|
assert (
|
|
http_api_response_close_to(actual_result_from_http_api, result, eps=eps)
|
|
== clickhouse_http_api_result_is_same_as_prometheus
|
|
), f"actual_result_from_http_api: {actual_result_from_http_api}, expected: {result}"
|
|
|
|
|
|
def do_query_test_expect_error(
|
|
query,
|
|
timestamp,
|
|
expected_error,
|
|
expected_cherror,
|
|
):
|
|
assert expected_error in execute_query_in_prometheus_reader(
|
|
query, timestamp, expect_error=True
|
|
)
|
|
assert expected_error in execute_query_in_prometheus_receiver(
|
|
query, timestamp, expect_error=True
|
|
)
|
|
assert expected_cherror in execute_query_in_clickhouse_sql(
|
|
query, timestamp, expect_error=True
|
|
)
|
|
assert expected_cherror in execute_query_in_clickhouse_http_api(
|
|
query, timestamp, expect_error=True
|
|
)
|
|
|
|
|
|
# Evaluates the same range query in Prometheus and in ClickHouse and compare the results.
|
|
def do_range_query_test(
|
|
query,
|
|
start_time,
|
|
end_time,
|
|
step,
|
|
result,
|
|
chresult,
|
|
clickhouse_http_api_result_is_same_as_prometheus=True,
|
|
eps=0,
|
|
):
|
|
assert (
|
|
execute_range_query_in_prometheus(query, start_time, end_time, step) == result
|
|
)
|
|
|
|
actual_chresult = execute_range_query_in_clickhouse_sql(
|
|
query, start_time, end_time, step
|
|
)
|
|
assert tsv_close_to(
|
|
actual_chresult, chresult, eps=eps
|
|
), f"actual result: {actual_chresult}, expected: {chresult}"
|
|
|
|
actual_result_from_http_api = execute_range_query_in_clickhouse_http_api(
|
|
query, start_time, end_time, step
|
|
)
|
|
assert (
|
|
http_api_response_close_to(actual_result_from_http_api, result, eps=eps)
|
|
== clickhouse_http_api_result_is_same_as_prometheus
|
|
), f"actual_result_from_http_api: {actual_result_from_http_api}, expected: {result}"
|
|
|
|
|
|
# Evaluates a query in ClickHouse only (no comparison with Prometheus) and checks the result.
|
|
# Used to verify deterministic behavior of our implementation in cases where Prometheus is expected
|
|
# to provide a different result.
|
|
def do_clickhouse_only_query_test(
|
|
query,
|
|
timestamp,
|
|
result,
|
|
chresult,
|
|
eps=0,
|
|
):
|
|
actual_chresult = execute_query_in_clickhouse_sql(query, timestamp)
|
|
assert tsv_close_to(
|
|
actual_chresult, chresult, eps=eps
|
|
), f"actual result: {actual_chresult}, expected: {chresult}"
|
|
|
|
actual_result_from_http_api = execute_query_in_clickhouse_http_api(query, timestamp)
|
|
assert http_api_response_close_to(
|
|
actual_result_from_http_api, result, eps=eps
|
|
), f"actual_result_from_http_api: {actual_result_from_http_api}, expected: {result}"
|
|
|
|
|
|
def test_up():
|
|
do_query_test(
|
|
"up",
|
|
1753176757.89,
|
|
'{"resultType": "vector", "result": [{"metric": {"__name__": "up", "job": "prometheus"}, "value": [1753176757.89, "1"]}]}',
|
|
[["[('__name__','up'),('job','prometheus')]", "2025-07-22 09:32:37.890", "1"]],
|
|
)
|
|
|
|
|
|
def test_range_selectors():
|
|
do_query_test(
|
|
"test[30s]",
|
|
129,
|
|
'{"resultType": "matrix", "result": [{"metric": {"__name__": "test"}, "values": [[110, "1"], [120, "1"]]}]}',
|
|
[
|
|
[
|
|
"[('__name__','test')]",
|
|
"[('1970-01-01 00:01:50.000',1),('1970-01-01 00:02:00.000',1)]",
|
|
]
|
|
],
|
|
)
|
|
|
|
do_query_test(
|
|
"test[30s]",
|
|
130,
|
|
'{"resultType": "matrix", "result": [{"metric": {"__name__": "test"}, "values": [[110, "1"], [120, "1"], [130, "3"]]}]}',
|
|
[
|
|
[
|
|
"[('__name__','test')]",
|
|
"[('1970-01-01 00:01:50.000',1),('1970-01-01 00:02:00.000',1),('1970-01-01 00:02:10.000',3)]",
|
|
]
|
|
],
|
|
)
|
|
|
|
do_query_test(
|
|
"test[30s]",
|
|
131,
|
|
'{"resultType": "matrix", "result": [{"metric": {"__name__": "test"}, "values": [[110, "1"], [120, "1"], [130, "3"]]}]}',
|
|
[
|
|
[
|
|
"[('__name__','test')]",
|
|
"[('1970-01-01 00:01:50.000',1),('1970-01-01 00:02:00.000',1),('1970-01-01 00:02:10.000',3)]",
|
|
]
|
|
],
|
|
)
|
|
|
|
do_query_test(
|
|
"test[11s]",
|
|
140,
|
|
'{"resultType": "matrix", "result": [{"metric": {"__name__": "test"}, "values": [[130, "3"], [140, "4"]]}]}',
|
|
[
|
|
[
|
|
"[('__name__','test')]",
|
|
"[('1970-01-01 00:02:10.000',3),('1970-01-01 00:02:20.000',4)]",
|
|
]
|
|
],
|
|
)
|
|
|
|
do_query_test(
|
|
"test[10s]",
|
|
140,
|
|
'{"resultType": "matrix", "result": [{"metric": {"__name__": "test"}, "values": [[140, "4"]]}]}',
|
|
[
|
|
[
|
|
"[('__name__','test')]",
|
|
"[('1970-01-01 00:02:20.000',4)]",
|
|
]
|
|
],
|
|
)
|
|
|
|
do_query_test(
|
|
"test[9s]",
|
|
140,
|
|
'{"resultType": "matrix", "result": [{"metric": {"__name__": "test"}, "values": [[140, "4"]]}]}',
|
|
[
|
|
[
|
|
"[('__name__','test')]",
|
|
"[('1970-01-01 00:02:20.000',4)]",
|
|
]
|
|
],
|
|
)
|
|
|
|
|
|
def test_instant_selectors():
|
|
do_query_test(
|
|
"test",
|
|
129,
|
|
'{"resultType": "vector", "result": [{"metric": {"__name__": "test"}, "value": [129, "1"]}]}',
|
|
[
|
|
[
|
|
"[('__name__','test')]",
|
|
"1970-01-01 00:02:09.000",
|
|
"1",
|
|
]
|
|
],
|
|
)
|
|
|
|
do_query_test(
|
|
"test",
|
|
130,
|
|
'{"resultType": "vector", "result": [{"metric": {"__name__": "test"}, "value": [130, "3"]}]}',
|
|
[
|
|
[
|
|
"[('__name__','test')]",
|
|
"1970-01-01 00:02:10.000",
|
|
"3",
|
|
]
|
|
],
|
|
)
|
|
|
|
do_query_test(
|
|
"test",
|
|
131,
|
|
'{"resultType": "vector", "result": [{"metric": {"__name__": "test"}, "value": [131, "3"]}]}',
|
|
[
|
|
[
|
|
"[('__name__','test')]",
|
|
"1970-01-01 00:02:11.000",
|
|
"3",
|
|
]
|
|
],
|
|
)
|
|
|
|
|
|
def test_function_over_time():
|
|
# last_over_time
|
|
do_query_test(
|
|
"last_over_time(test[45s])[120s:15s]",
|
|
210,
|
|
'{"resultType": "matrix", "result": [{"metric": {"__name__": "test"}, "values": [[120, "1"], [135, "3"], [150, "4"], [165, "4"], [180, "4"], [195, "5"], [210, "8"]]}]}',
|
|
[
|
|
[
|
|
"[('__name__','test')]",
|
|
"[('1970-01-01 00:02:00.000',1),('1970-01-01 00:02:15.000',3),('1970-01-01 00:02:30.000',4),('1970-01-01 00:02:45.000',4),('1970-01-01 00:03:00.000',4),('1970-01-01 00:03:15.000',5),('1970-01-01 00:03:30.000',8)]",
|
|
]
|
|
],
|
|
)
|
|
|
|
# step (15s) > window (10s): the sample at 140 is outside grid point 150's window (140, 150], so 150 must be empty.
|
|
do_query_test(
|
|
"last_over_time(test[10s])[120s:15s]",
|
|
210,
|
|
'{"resultType": "matrix", "result": [{"metric": {"__name__": "test"}, "values": [[120, "1"], [135, "3"], [195, "5"], [210, "8"]]}]}',
|
|
[
|
|
[
|
|
"[('__name__','test')]",
|
|
"[('1970-01-01 00:02:00.000',1),('1970-01-01 00:02:15.000',3),('1970-01-01 00:03:15.000',5),('1970-01-01 00:03:30.000',8)]",
|
|
]
|
|
],
|
|
)
|
|
|
|
do_query_test(
|
|
"test[120s:15s]",
|
|
210,
|
|
'{"resultType": "matrix", "result": [{"metric": {"__name__": "test"}, "values": [[120, "1"], [135, "3"], [150, "4"], [165, "4"], [180, "4"], [195, "5"], [210, "8"]]}]}',
|
|
[
|
|
[
|
|
"[('__name__','test')]",
|
|
"[('1970-01-01 00:02:00.000',1),('1970-01-01 00:02:15.000',3),('1970-01-01 00:02:30.000',4),('1970-01-01 00:02:45.000',4),('1970-01-01 00:03:00.000',4),('1970-01-01 00:03:15.000',5),('1970-01-01 00:03:30.000',8)]",
|
|
]
|
|
],
|
|
)
|
|
|
|
# idelta
|
|
do_query_test(
|
|
"idelta(test[45s])[120s:15s]",
|
|
210,
|
|
'{"resultType": "matrix", "result": [{"metric": {}, "values": [[120, "0"], [135, "2"], [150, "1"], [165, "1"], [210, "3"]]}]}',
|
|
[
|
|
[
|
|
"[]",
|
|
"[('1970-01-01 00:02:00.000',0),('1970-01-01 00:02:15.000',2),('1970-01-01 00:02:30.000',1),('1970-01-01 00:02:45.000',1),('1970-01-01 00:03:30.000',3)]",
|
|
]
|
|
],
|
|
)
|
|
|
|
do_query_test(
|
|
"idelta(test[35s])[120s:15s]",
|
|
210,
|
|
'{"resultType": "matrix", "result": [{"metric": {}, "values": [[120, "0"], [135, "2"], [150, "1"], [210, "3"]]}]}',
|
|
[
|
|
[
|
|
"[]",
|
|
"[('1970-01-01 00:02:00.000',0),('1970-01-01 00:02:15.000',2),('1970-01-01 00:02:30.000',1),('1970-01-01 00:03:30.000',3)]",
|
|
]
|
|
],
|
|
)
|
|
|
|
# irate
|
|
do_query_test(
|
|
"irate(test[45s])[120s:15s]",
|
|
210,
|
|
'{"resultType": "matrix", "result": [{"metric": {}, "values": [[120, "0"], [135, "0.2"], [150, "0.1"], [165, "0.1"], [210, "0.3"]]}]}',
|
|
[
|
|
[
|
|
"[]",
|
|
"[('1970-01-01 00:02:00.000',0),('1970-01-01 00:02:15.000',0.2),('1970-01-01 00:02:30.000',0.1),('1970-01-01 00:02:45.000',0.1),('1970-01-01 00:03:30.000',0.3)]",
|
|
]
|
|
],
|
|
)
|
|
|
|
# rate
|
|
do_query_test(
|
|
"rate(test[45s])[120s:15s]",
|
|
210,
|
|
'{"resultType": "matrix", "result": [{"metric": {}, "values": [[120, "0"], [135, "0.06666666666666667"], [150, "0.1"], [165, "0.05555555555555555"], [210, "0.08333333333333333"]]}]}',
|
|
[
|
|
[
|
|
"[]",
|
|
"[('1970-01-01 00:02:00.000',0),('1970-01-01 00:02:15.000',0.06666666666666667),('1970-01-01 00:02:30.000',0.1),('1970-01-01 00:02:45.000',0.05555555555555555),('1970-01-01 00:03:30.000',0.08333333333333333)]",
|
|
]
|
|
],
|
|
)
|
|
|
|
# delta
|
|
do_query_test(
|
|
"delta(test[45s])[120s:15s]",
|
|
210,
|
|
'{"resultType": "matrix", "result": [{"metric": {}, "values": [[120, "0"], [135, "3"], [150, "4.5"], [165, "2.5"], [210, "3.75"]]}]}',
|
|
[
|
|
[
|
|
"[]",
|
|
"[('1970-01-01 00:02:00.000',0),('1970-01-01 00:02:15.000',3),('1970-01-01 00:02:30.000',4.5),('1970-01-01 00:02:45.000',2.5),('1970-01-01 00:03:30.000',3.75)]",
|
|
]
|
|
],
|
|
)
|
|
|
|
do_query_test(
|
|
"delta(resets[45s])[120s:15s]",
|
|
210,
|
|
'{"resultType": "matrix", "result": [{"metric": {"job": "test"}, "values": [[120, "6"], [135, "10.5"], [150, "5.625"], [165, "-3.5"], [180, "8"], [210, "-1.25"]]}]}',
|
|
[
|
|
[
|
|
"[('job','test')]",
|
|
"[('1970-01-01 00:02:00.000',6),('1970-01-01 00:02:15.000',10.5),('1970-01-01 00:02:30.000',5.625),('1970-01-01 00:02:45.000',-3.5),('1970-01-01 00:03:00.000',8),('1970-01-01 00:03:30.000',-1.25)]",
|
|
]
|
|
],
|
|
eps=1e-9,
|
|
)
|
|
|
|
# increase: `test` has no resets, so increase() equals delta() on it.
|
|
do_query_test(
|
|
"increase(test[45s])[120s:15s]",
|
|
210,
|
|
'{"resultType": "matrix", "result": [{"metric": {}, "values": [[120, "0"], [135, "3"], [150, "4.5"], [165, "2.5"], [210, "3.75"]]}]}',
|
|
[
|
|
[
|
|
"[]",
|
|
"[('1970-01-01 00:02:00.000',0),('1970-01-01 00:02:15.000',3),('1970-01-01 00:02:30.000',4.5),('1970-01-01 00:02:45.000',2.5),('1970-01-01 00:03:30.000',3.75)]",
|
|
]
|
|
],
|
|
)
|
|
|
|
do_query_test(
|
|
"increase(resets[45s])[120s:15s]",
|
|
210,
|
|
'{"resultType": "matrix", "result": [{"metric": {"job": "test"}, "values": [[120, "5"], [135, "9.75"], [150, "14.000000000000002"], [165, "10.5"], [180, "8"], [210, "11.25"]]}]}',
|
|
[
|
|
[
|
|
"[('job','test')]",
|
|
"[('1970-01-01 00:02:00.000',5),('1970-01-01 00:02:15.000',9.75),('1970-01-01 00:02:30.000',14),('1970-01-01 00:02:45.000',10.5),('1970-01-01 00:03:00.000',8),('1970-01-01 00:03:30.000',11.25)]",
|
|
]
|
|
],
|
|
eps=1e-9,
|
|
)
|
|
|
|
|
|
def test_literals():
|
|
timestamp = 250
|
|
do_query_test(
|
|
"23",
|
|
timestamp,
|
|
'{"resultType": "scalar", "result": [250, "23"]}',
|
|
[["1970-01-01 00:04:10.000", 23]],
|
|
)
|
|
|
|
do_query_test(
|
|
"-2.43",
|
|
timestamp,
|
|
'{"resultType": "scalar", "result": [250, "-2.43"]}',
|
|
[["1970-01-01 00:04:10.000", -2.43]],
|
|
)
|
|
|
|
do_query_test(
|
|
"3.4e-5",
|
|
timestamp,
|
|
'{"resultType": "scalar", "result": [250, "0.000034"]}',
|
|
[["1970-01-01 00:04:10.000", "0.000034"]],
|
|
)
|
|
|
|
do_query_test(
|
|
"0x8f",
|
|
timestamp,
|
|
'{"resultType": "scalar", "result": [250, "143"]}',
|
|
[["1970-01-01 00:04:10.000", 143]],
|
|
)
|
|
|
|
do_query_test(
|
|
"-Inf",
|
|
timestamp,
|
|
'{"resultType": "scalar", "result": [250, "-Inf"]}',
|
|
[["1970-01-01 00:04:10.000", "-inf"]],
|
|
)
|
|
|
|
do_query_test(
|
|
"NaN",
|
|
timestamp,
|
|
'{"resultType": "scalar", "result": [250, "NaN"]}',
|
|
[["1970-01-01 00:04:10.000", "nan"]],
|
|
)
|
|
|
|
do_query_test(
|
|
"1_000_000",
|
|
timestamp,
|
|
'{"resultType": "scalar", "result": [250, "1000000"]}',
|
|
[["1970-01-01 00:04:10.000", "1000000"]],
|
|
)
|
|
|
|
do_query_test(
|
|
".123_456_789",
|
|
timestamp,
|
|
'{"resultType": "scalar", "result": [250, "0.123456789"]}',
|
|
[["1970-01-01 00:04:10.000", "0.123456789"]],
|
|
)
|
|
|
|
do_query_test(
|
|
"0x_53_AB_F3_82",
|
|
timestamp,
|
|
'{"resultType": "scalar", "result": [250, "1403777922"]}',
|
|
[["1970-01-01 00:04:10.000", 1403777922]],
|
|
)
|
|
|
|
do_query_test(
|
|
"1h30m",
|
|
timestamp,
|
|
'{"resultType": "scalar", "result": [250, "5400"]}',
|
|
[["1970-01-01 00:04:10.000", 5400]],
|
|
)
|
|
|
|
do_query_test(
|
|
"12h34m56s",
|
|
timestamp,
|
|
'{"resultType": "scalar", "result": [250, "45296"]}',
|
|
[["1970-01-01 00:04:10.000", 45296]],
|
|
)
|
|
|
|
do_query_test(
|
|
"54s321ms",
|
|
timestamp,
|
|
'{"resultType": "scalar", "result": [250, "54.321"]}',
|
|
[["1970-01-01 00:04:10.000", "54.321"]],
|
|
)
|
|
|
|
do_query_test(
|
|
"1y2w3d",
|
|
timestamp,
|
|
'{"resultType": "scalar", "result": [250, "33004800"]}',
|
|
[["1970-01-01 00:04:10.000", "33004800"]],
|
|
)
|
|
|
|
do_query_test(
|
|
'"this is a string"',
|
|
timestamp,
|
|
'{"resultType": "string", "result": [250, "this is a string"]}',
|
|
[["1970-01-01 00:04:10.000", "this is a string"]],
|
|
)
|
|
|
|
|
|
def test_unary_operators():
|
|
do_query_test(
|
|
"+test",
|
|
180,
|
|
'{"resultType": "vector", "result": [{"metric": {"__name__": "test"}, "value": [180, "4"]}]}',
|
|
[["[('__name__','test')]", "1970-01-01 00:03:00.000", 4]],
|
|
)
|
|
|
|
do_query_test(
|
|
"+test",
|
|
180,
|
|
'{"resultType": "vector", "result": [{"metric": {"__name__": "test"}, "value": [180, "4"]}]}',
|
|
[["[('__name__','test')]", "1970-01-01 00:03:00.000", 4]],
|
|
)
|
|
|
|
do_query_test(
|
|
"-test",
|
|
180,
|
|
'{"resultType": "vector", "result": [{"metric": {}, "value": [180, "-4"]}]}',
|
|
[["[]", "1970-01-01 00:03:00.000", -4]],
|
|
)
|
|
|
|
do_query_test(
|
|
"(-test)[120s:15s]",
|
|
180,
|
|
'{"resultType": "matrix", "result": [{"metric": {}, "values": [[120, "-1"], [135, "-3"], [150, "-4"], [165, "-4"], [180, "-4"]]}]}',
|
|
[
|
|
[
|
|
"[]",
|
|
"[('1970-01-01 00:02:00.000',-1),('1970-01-01 00:02:15.000',-3),('1970-01-01 00:02:30.000',-4),('1970-01-01 00:02:45.000',-4),('1970-01-01 00:03:00.000',-4)]",
|
|
]
|
|
],
|
|
)
|
|
|
|
|
|
def test_conversion_functions():
|
|
do_query_test(
|
|
"vector(1)",
|
|
180,
|
|
'{"resultType": "vector", "result": [{"metric": {}, "value": [180, "1"]}]}',
|
|
[["[]", "1970-01-01 00:03:00.000", 1]],
|
|
)
|
|
|
|
do_query_test(
|
|
"vector(-1)",
|
|
180,
|
|
'{"resultType": "vector", "result": [{"metric": {}, "value": [180, "-1"]}]}',
|
|
[["[]", "1970-01-01 00:03:00.000", -1]],
|
|
)
|
|
|
|
do_query_test(
|
|
"-vector(1)",
|
|
180,
|
|
'{"resultType": "vector", "result": [{"metric": {}, "value": [180, "-1"]}]}',
|
|
[["[]", "1970-01-01 00:03:00.000", -1]],
|
|
)
|
|
|
|
do_query_test(
|
|
"vector(time())",
|
|
180,
|
|
'{"resultType": "vector", "result": [{"metric": {}, "value": [180, "180"]}]}',
|
|
[["[]", "1970-01-01 00:03:00.000", 180]],
|
|
)
|
|
|
|
do_query_test(
|
|
"vector(1)[40:10]",
|
|
180,
|
|
'{"resultType": "matrix", "result": [{"metric": {}, "values": [[150, "1"], [160, "1"], [170, "1"], [180, "1"]]}]}',
|
|
[
|
|
[
|
|
"[]",
|
|
"[('1970-01-01 00:02:30.000',1),('1970-01-01 00:02:40.000',1),('1970-01-01 00:02:50.000',1),('1970-01-01 00:03:00.000',1)]",
|
|
]
|
|
],
|
|
)
|
|
|
|
do_query_test(
|
|
"vector(time())[40:10]",
|
|
180,
|
|
'{"resultType": "matrix", "result": [{"metric": {}, "values": [[150, "150"], [160, "160"], [170, "170"], [180, "180"]]}]}',
|
|
[
|
|
[
|
|
"[]",
|
|
"[('1970-01-01 00:02:30.000',150),('1970-01-01 00:02:40.000',160),('1970-01-01 00:02:50.000',170),('1970-01-01 00:03:00.000',180)]",
|
|
]
|
|
],
|
|
)
|
|
|
|
do_query_test(
|
|
"scalar(vector(1))",
|
|
180,
|
|
'{"resultType": "scalar", "result": [180, "1"]}',
|
|
[["1970-01-01 00:03:00.000", 1]],
|
|
)
|
|
|
|
do_query_test(
|
|
"vector(scalar(vector(time())))[40:10]",
|
|
180,
|
|
'{"resultType": "matrix", "result": [{"metric": {}, "values": [[150, "150"], [160, "160"], [170, "170"], [180, "180"]]}]}',
|
|
[
|
|
[
|
|
"[]",
|
|
"[('1970-01-01 00:02:30.000',150),('1970-01-01 00:02:40.000',160),('1970-01-01 00:02:50.000',170),('1970-01-01 00:03:00.000',180)]",
|
|
]
|
|
],
|
|
)
|
|
|
|
do_query_test(
|
|
"vector(scalar({http_code='404'}))[80:10]",
|
|
180,
|
|
'{"resultType": "matrix", "result": [{"metric": {}, "values": [[110, "1"], [120, "5"], [130, "NaN"], [140, "NaN"], [150, "NaN"], [160, "NaN"], [170, "NaN"], [180, "NaN"]]}]}',
|
|
[
|
|
[
|
|
"[]",
|
|
"[('1970-01-01 00:01:50.000',1),('1970-01-01 00:02:00.000',5),('1970-01-01 00:02:10.000',nan),('1970-01-01 00:02:20.000',nan),('1970-01-01 00:02:30.000',nan),('1970-01-01 00:02:40.000',nan),('1970-01-01 00:02:50.000',nan),('1970-01-01 00:03:00.000',nan)]",
|
|
]
|
|
],
|
|
)
|
|
|
|
do_query_test(
|
|
"vector(scalar(last_over_time({http_code='404'}[10])))[80:10]",
|
|
180,
|
|
'{"resultType": "matrix", "result": [{"metric": {}, "values": [[110, "1"], [120, "5"], [130, "0"], [140, "NaN"], [150, "1"], [160, "NaN"], [170, "NaN"], [180, "NaN"]]}]}',
|
|
[
|
|
[
|
|
"[]",
|
|
"[('1970-01-01 00:01:50.000',1),('1970-01-01 00:02:00.000',5),('1970-01-01 00:02:10.000',0),('1970-01-01 00:02:20.000',nan),('1970-01-01 00:02:30.000',1),('1970-01-01 00:02:40.000',nan),('1970-01-01 00:02:50.000',nan),('1970-01-01 00:03:00.000',nan)]",
|
|
]
|
|
],
|
|
)
|
|
|
|
|
|
def test_date_time_functions():
|
|
do_query_test(
|
|
"day_of_week(vector(time()))",
|
|
1770582640,
|
|
'{"resultType": "vector", "result": [{"metric": {}, "value": [1770582640, "0"]}]}',
|
|
[["[]", "2026-02-08 20:30:40.000", 0]],
|
|
)
|
|
|
|
do_query_test(
|
|
"day_of_week(timestamps)[20:10]",
|
|
120,
|
|
'{"resultType": "matrix", "result": [{"metric": {"job": "test"}, "values": [[110, "0"], [120, "6"]]}]}',
|
|
[
|
|
[
|
|
"[('job','test')]",
|
|
"[('1970-01-01 00:01:50.000',0),('1970-01-01 00:02:00.000',6)]",
|
|
]
|
|
],
|
|
)
|
|
|
|
do_query_test(
|
|
"day_of_month(vector(time()))",
|
|
1770582640,
|
|
'{"resultType": "vector", "result": [{"metric": {}, "value": [1770582640, "8"]}]}',
|
|
[["[]", "2026-02-08 20:30:40.000", 8]],
|
|
)
|
|
|
|
do_query_test(
|
|
"day_of_month(timestamps)[20:10]",
|
|
120,
|
|
'{"resultType": "matrix", "result": [{"metric": {"job": "test"}, "values": [[110, "30"], [120, "6"]]}]}',
|
|
[
|
|
[
|
|
"[('job','test')]",
|
|
"[('1970-01-01 00:01:50.000',30),('1970-01-01 00:02:00.000',6)]",
|
|
]
|
|
],
|
|
)
|
|
|
|
do_query_test(
|
|
"days_in_month(vector(time()))",
|
|
1770582640,
|
|
'{"resultType": "vector", "result": [{"metric": {}, "value": [1770582640, "28"]}]}',
|
|
[["[]", "2026-02-08 20:30:40.000", 28]],
|
|
)
|
|
|
|
do_query_test(
|
|
"days_in_month(timestamps)[20:10]",
|
|
120,
|
|
'{"resultType": "matrix", "result": [{"metric": {"job": "test"}, "values": [[110, "30"], [120, "31"]]}]}',
|
|
[
|
|
[
|
|
"[('job','test')]",
|
|
"[('1970-01-01 00:01:50.000',30),('1970-01-01 00:02:00.000',31)]",
|
|
]
|
|
],
|
|
)
|
|
|
|
do_query_test(
|
|
"day_of_year(vector(time()))",
|
|
1770582640,
|
|
'{"resultType": "vector", "result": [{"metric": {}, "value": [1770582640, "39"]}]}',
|
|
[["[]", "2026-02-08 20:30:40.000", 39]],
|
|
)
|
|
|
|
do_query_test(
|
|
"day_of_year(timestamps)[20:10]",
|
|
120,
|
|
'{"resultType": "matrix", "result": [{"metric": {"job": "test"}, "values": [[110, "334"], [120, "340"]]}]}',
|
|
[
|
|
[
|
|
"[('job','test')]",
|
|
"[('1970-01-01 00:01:50.000',334),('1970-01-01 00:02:00.000',340)]",
|
|
]
|
|
],
|
|
)
|
|
|
|
do_query_test(
|
|
"minute(vector(time()))",
|
|
1770582640,
|
|
'{"resultType": "vector", "result": [{"metric": {}, "value": [1770582640, "30"]}]}',
|
|
[["[]", "2026-02-08 20:30:40.000", 30]],
|
|
)
|
|
|
|
do_query_test(
|
|
"minute(timestamps)[20:10]",
|
|
120,
|
|
'{"resultType": "matrix", "result": [{"metric": {"job": "test"}, "values": [[110, "30"], [120, "30"]]}]}',
|
|
[
|
|
[
|
|
"[('job','test')]",
|
|
"[('1970-01-01 00:01:50.000',30),('1970-01-01 00:02:00.000',30)]",
|
|
]
|
|
],
|
|
)
|
|
|
|
do_query_test(
|
|
"hour(vector(time()))",
|
|
1770582640,
|
|
'{"resultType": "vector", "result": [{"metric": {}, "value": [1770582640, "20"]}]}',
|
|
[["[]", "2026-02-08 20:30:40.000", 20]],
|
|
)
|
|
|
|
do_query_test(
|
|
"hour(timestamps)[20:10]",
|
|
120,
|
|
'{"resultType": "matrix", "result": [{"metric": {"job": "test"}, "values": [[110, "10"], [120, "15"]]}]}',
|
|
[
|
|
[
|
|
"[('job','test')]",
|
|
"[('1970-01-01 00:01:50.000',10),('1970-01-01 00:02:00.000',15)]",
|
|
]
|
|
],
|
|
)
|
|
|
|
do_query_test(
|
|
"month(vector(time()))",
|
|
1770582640,
|
|
'{"resultType": "vector", "result": [{"metric": {}, "value": [1770582640, "2"]}]}',
|
|
[["[]", "2026-02-08 20:30:40.000", 2]],
|
|
)
|
|
|
|
do_query_test(
|
|
"month(timestamps)[20:10]",
|
|
120,
|
|
'{"resultType": "matrix", "result": [{"metric": {"job": "test"}, "values": [[110, "11"], [120, "12"]]}]}',
|
|
[
|
|
[
|
|
"[('job','test')]",
|
|
"[('1970-01-01 00:01:50.000',11),('1970-01-01 00:02:00.000',12)]",
|
|
]
|
|
],
|
|
)
|
|
|
|
do_query_test(
|
|
"year(vector(time()))",
|
|
1770582640,
|
|
'{"resultType": "vector", "result": [{"metric": {}, "value": [1770582640, "2026"]}]}',
|
|
[["[]", "2026-02-08 20:30:40.000", 2026]],
|
|
)
|
|
|
|
do_query_test(
|
|
"year(timestamps)[20:10]",
|
|
120,
|
|
'{"resultType": "matrix", "result": [{"metric": {"job": "test"}, "values": [[110, "2025"], [120, "2025"]]}]}',
|
|
[
|
|
[
|
|
"[('job','test')]",
|
|
"[('1970-01-01 00:01:50.000',2025),('1970-01-01 00:02:00.000',2025)]",
|
|
]
|
|
],
|
|
)
|
|
|
|
|
|
def test_math_functions():
|
|
do_query_test(
|
|
"abs(vector(-3))",
|
|
500,
|
|
'{"resultType": "vector", "result": [{"metric": {}, "value": [500, "3"]}]}',
|
|
[["[]", "1970-01-01 00:08:20.000", 3]],
|
|
)
|
|
|
|
do_query_test(
|
|
"abs(deltas)[700:100]",
|
|
700,
|
|
'{"resultType": "matrix", "result": [{"metric": {"job": "test"}, "values": [[100, "2"], [200, "1"], [300, "0.5"], [400, "0"], [500, "0.5"], [600, "1"], [700, "2"]]}]}',
|
|
[
|
|
[
|
|
"[('job','test')]",
|
|
"[('1970-01-01 00:01:40.000',2),('1970-01-01 00:03:20.000',1),('1970-01-01 00:05:00.000',0.5),('1970-01-01 00:06:40.000',0),('1970-01-01 00:08:20.000',0.5),('1970-01-01 00:10:00.000',1),('1970-01-01 00:11:40.000',2)]",
|
|
]
|
|
],
|
|
)
|
|
|
|
do_query_test(
|
|
"abs(vector(scalar(deltas)))[700:100]",
|
|
700,
|
|
'{"resultType": "matrix", "result": [{"metric": {}, "values": [[100, "2"], [200, "1"], [300, "0.5"], [400, "0"], [500, "0.5"], [600, "1"], [700, "2"]]}]}',
|
|
[
|
|
[
|
|
"[]",
|
|
"[('1970-01-01 00:01:40.000',2),('1970-01-01 00:03:20.000',1),('1970-01-01 00:05:00.000',0.5),('1970-01-01 00:06:40.000',0),('1970-01-01 00:08:20.000',0.5),('1970-01-01 00:10:00.000',1),('1970-01-01 00:11:40.000',2)]",
|
|
]
|
|
],
|
|
)
|
|
|
|
do_query_test(
|
|
"sgn(vector(-3))",
|
|
500,
|
|
'{"resultType": "vector", "result": [{"metric": {}, "value": [500, "-1"]}]}',
|
|
[["[]", "1970-01-01 00:08:20.000", -1]],
|
|
)
|
|
|
|
do_query_test(
|
|
"sgn(deltas)[700:100]",
|
|
700,
|
|
'{"resultType": "matrix", "result": [{"metric": {"job": "test"}, "values": [[100, "-1"], [200, "-1"], [300, "-1"], [400, "0"], [500, "1"], [600, "1"], [700, "1"]]}]}',
|
|
[
|
|
[
|
|
"[('job','test')]",
|
|
"[('1970-01-01 00:01:40.000',-1),('1970-01-01 00:03:20.000',-1),('1970-01-01 00:05:00.000',-1),('1970-01-01 00:06:40.000',0),('1970-01-01 00:08:20.000',1),('1970-01-01 00:10:00.000',1),('1970-01-01 00:11:40.000',1)]",
|
|
]
|
|
],
|
|
)
|
|
|
|
do_query_test(
|
|
"floor(vector(5.6))",
|
|
500,
|
|
'{"resultType": "vector", "result": [{"metric": {}, "value": [500, "5"]}]}',
|
|
[["[]", "1970-01-01 00:08:20.000", 5]],
|
|
)
|
|
|
|
do_query_test(
|
|
"floor(deltas)[700:100]",
|
|
700,
|
|
'{"resultType": "matrix", "result": [{"metric": {"job": "test"}, "values": [[100, "-2"], [200, "-1"], [300, "-1"], [400, "0"], [500, "0"], [600, "1"], [700, "2"]]}]}',
|
|
[
|
|
[
|
|
"[('job','test')]",
|
|
"[('1970-01-01 00:01:40.000',-2),('1970-01-01 00:03:20.000',-1),('1970-01-01 00:05:00.000',-1),('1970-01-01 00:06:40.000',0),('1970-01-01 00:08:20.000',0),('1970-01-01 00:10:00.000',1),('1970-01-01 00:11:40.000',2)]",
|
|
]
|
|
],
|
|
)
|
|
|
|
do_query_test(
|
|
"ceil(vector(5.6))",
|
|
500,
|
|
'{"resultType": "vector", "result": [{"metric": {}, "value": [500, "6"]}]}',
|
|
[["[]", "1970-01-01 00:08:20.000", 6]],
|
|
)
|
|
|
|
do_query_test(
|
|
"ceil(deltas)[700:100]",
|
|
700,
|
|
'{"resultType": "matrix", "result": [{"metric": {"job": "test"}, "values": [[100, "-2"], [200, "-1"], [300, "-0"], [400, "0"], [500, "1"], [600, "1"], [700, "2"]]}]}',
|
|
[
|
|
[
|
|
"[('job','test')]",
|
|
"[('1970-01-01 00:01:40.000',-2),('1970-01-01 00:03:20.000',-1),('1970-01-01 00:05:00.000',-0),('1970-01-01 00:06:40.000',0),('1970-01-01 00:08:20.000',1),('1970-01-01 00:10:00.000',1),('1970-01-01 00:11:40.000',2)]",
|
|
]
|
|
],
|
|
)
|
|
|
|
do_query_test(
|
|
"sqrt(vector(1.44))",
|
|
500,
|
|
'{"resultType": "vector", "result": [{"metric": {}, "value": [500, "1.2"]}]}',
|
|
[["[]", "1970-01-01 00:08:20.000", 1.2]],
|
|
)
|
|
|
|
do_query_test(
|
|
"sqrt(deltas)[700:100]",
|
|
700,
|
|
'{"resultType": "matrix", "result": [{"metric": {"job": "test"}, "values": [[100, "NaN"], [200, "NaN"], [300, "NaN"], [400, "0"], [500, "0.7071067811865476"], [600, "1"], [700, "1.4142135623730951"]]}]}',
|
|
[
|
|
[
|
|
"[('job','test')]",
|
|
"[('1970-01-01 00:01:40.000',nan),('1970-01-01 00:03:20.000',nan),('1970-01-01 00:05:00.000',nan),('1970-01-01 00:06:40.000',0),('1970-01-01 00:08:20.000',0.7071067811865476),('1970-01-01 00:10:00.000',1),('1970-01-01 00:11:40.000',1.4142135623730951)]",
|
|
]
|
|
],
|
|
)
|
|
|
|
do_query_test(
|
|
"exp(vector(2))",
|
|
500,
|
|
'{"resultType": "vector", "result": [{"metric": {}, "value": [500, "7.38905609893065"]}]}',
|
|
[["[]", "1970-01-01 00:08:20.000", 7.389056098924109]],
|
|
eps=1e-11, # See https://github.com/ClickHouse/ClickHouse/issues/30340
|
|
)
|
|
|
|
do_query_test(
|
|
"exp(deltas)[700:100]",
|
|
700,
|
|
'{"resultType": "matrix", "result": [{"metric": {"job": "test"}, "values": [[100, "0.1353352832366127"], [200, "0.36787944117144233"], [300, "0.6065306597126334"], [400, "1"], [500, "1.6487212707001282"], [600, "2.718281828459045"], [700, "7.38905609893065"]]}]}',
|
|
[
|
|
[
|
|
"[('job','test')]",
|
|
"[('1970-01-01 00:01:40.000',0.13533528323672805),('1970-01-01 00:03:20.000',0.3678794411711252),('1970-01-01 00:05:00.000',0.6065306597123097),('1970-01-01 00:06:40.000',1),('1970-01-01 00:08:20.000',1.6487212707014907),('1970-01-01 00:10:00.000',2.7182818284606256),('1970-01-01 00:11:40.000',7.389056098924109)]",
|
|
]
|
|
],
|
|
eps=1e-11, # See https://github.com/ClickHouse/ClickHouse/issues/30340
|
|
)
|
|
|
|
do_query_test(
|
|
"ln(vector(2))",
|
|
500,
|
|
'{"resultType": "vector", "result": [{"metric": {}, "value": [500, "0.6931471805599453"]}]}',
|
|
[["[]", "1970-01-01 00:08:20.000", 0.6931471805599453]],
|
|
)
|
|
|
|
do_query_test(
|
|
"ln(deltas)[700:100]",
|
|
700,
|
|
'{"resultType": "matrix", "result": [{"metric": {"job": "test"}, "values": [[100, "NaN"], [200, "NaN"], [300, "NaN"], [400, "-Inf"], [500, "-0.6931471805599453"], [600, "0"], [700, "0.6931471805599453"]]}]}',
|
|
[
|
|
[
|
|
"[('job','test')]",
|
|
"[('1970-01-01 00:01:40.000',nan),('1970-01-01 00:03:20.000',nan),('1970-01-01 00:05:00.000',nan),('1970-01-01 00:06:40.000',-inf),('1970-01-01 00:08:20.000',-0.6931471805599453),('1970-01-01 00:10:00.000',0),('1970-01-01 00:11:40.000',0.6931471805599453)]",
|
|
]
|
|
],
|
|
)
|
|
|
|
do_query_test(
|
|
"log2(vector(256))",
|
|
500,
|
|
'{"resultType": "vector", "result": [{"metric": {}, "value": [500, "8"]}]}',
|
|
[["[]", "1970-01-01 00:08:20.000", 8]],
|
|
)
|
|
|
|
do_query_test(
|
|
"log2(deltas)[700:100]",
|
|
700,
|
|
'{"resultType": "matrix", "result": [{"metric": {"job": "test"}, "values": [[100, "NaN"], [200, "NaN"], [300, "NaN"], [400, "-Inf"], [500, "-1"], [600, "0"], [700, "1"]]}]}',
|
|
[
|
|
[
|
|
"[('job','test')]",
|
|
"[('1970-01-01 00:01:40.000',nan),('1970-01-01 00:03:20.000',nan),('1970-01-01 00:05:00.000',nan),('1970-01-01 00:06:40.000',-inf),('1970-01-01 00:08:20.000',-1),('1970-01-01 00:10:00.000',0),('1970-01-01 00:11:40.000',1)]",
|
|
]
|
|
],
|
|
)
|
|
|
|
do_query_test(
|
|
"log10(vector(1000000))",
|
|
500,
|
|
'{"resultType": "vector", "result": [{"metric": {}, "value": [500, "6"]}]}',
|
|
[["[]", "1970-01-01 00:08:20.000", 6]],
|
|
)
|
|
|
|
do_query_test(
|
|
"log10(deltas)[700:100]",
|
|
700,
|
|
'{"resultType": "matrix", "result": [{"metric": {"job": "test"}, "values": [[100, "NaN"], [200, "NaN"], [300, "NaN"], [400, "-Inf"], [500, "-0.3010299956639812"], [600, "0"], [700, "0.3010299956639812"]]}]}',
|
|
[
|
|
[
|
|
"[('job','test')]",
|
|
"[('1970-01-01 00:01:40.000',nan),('1970-01-01 00:03:20.000',nan),('1970-01-01 00:05:00.000',nan),('1970-01-01 00:06:40.000',-inf),('1970-01-01 00:08:20.000',-0.3010299956639812),('1970-01-01 00:10:00.000',0),('1970-01-01 00:11:40.000',0.3010299956639812)]",
|
|
]
|
|
],
|
|
)
|
|
|
|
do_query_test(
|
|
"rad(vector(30))",
|
|
500,
|
|
'{"resultType": "vector", "result": [{"metric": {}, "value": [500, "0.5235987755982988"]}]}',
|
|
[["[]", "1970-01-01 00:08:20.000", 0.5235987755982988]],
|
|
)
|
|
|
|
do_query_test(
|
|
"rad(deltas)[700:100]",
|
|
700,
|
|
'{"resultType": "matrix", "result": [{"metric": {"job": "test"}, "values": [[100, "-0.03490658503988659"], [200, "-0.017453292519943295"], [300, "-0.008726646259971648"], [400, "0"], [500, "0.008726646259971648"], [600, "0.017453292519943295"], [700, "0.03490658503988659"]]}]}',
|
|
[
|
|
[
|
|
"[('job','test')]",
|
|
"[('1970-01-01 00:01:40.000',-0.03490658503988659),('1970-01-01 00:03:20.000',-0.017453292519943295),('1970-01-01 00:05:00.000',-0.008726646259971648),('1970-01-01 00:06:40.000',0),('1970-01-01 00:08:20.000',0.008726646259971648),('1970-01-01 00:10:00.000',0.017453292519943295),('1970-01-01 00:11:40.000',0.03490658503988659)]",
|
|
]
|
|
],
|
|
)
|
|
|
|
do_query_test(
|
|
"deg(vector(pi()))",
|
|
500,
|
|
'{"resultType": "vector", "result": [{"metric": {}, "value": [500, "180"]}]}',
|
|
[["[]", "1970-01-01 00:08:20.000", 180]],
|
|
)
|
|
|
|
do_query_test(
|
|
"deg(deltas)[700:100]",
|
|
700,
|
|
'{"resultType": "matrix", "result": [{"metric": {"job": "test"}, "values": [[100, "-114.59155902616465"], [200, "-57.29577951308232"], [300, "-28.64788975654116"], [400, "0"], [500, "28.64788975654116"], [600, "57.29577951308232"], [700, "114.59155902616465"]]}]}',
|
|
[
|
|
[
|
|
"[('job','test')]",
|
|
"[('1970-01-01 00:01:40.000',-114.59155902616465),('1970-01-01 00:03:20.000',-57.29577951308232),('1970-01-01 00:05:00.000',-28.64788975654116),('1970-01-01 00:06:40.000',0),('1970-01-01 00:08:20.000',28.64788975654116),('1970-01-01 00:10:00.000',57.29577951308232),('1970-01-01 00:11:40.000',114.59155902616465)]",
|
|
]
|
|
],
|
|
)
|
|
|
|
do_query_test(
|
|
"sin(vector(1))",
|
|
500,
|
|
'{"resultType": "vector", "result": [{"metric": {}, "value": [500, "0.8414709848078965"]}]}',
|
|
[["[]", "1970-01-01 00:08:20.000", 0.8414709848078965]],
|
|
)
|
|
|
|
do_query_test(
|
|
"sin(deltas)[700:100]",
|
|
700,
|
|
'{"resultType": "matrix", "result": [{"metric": {"job": "test"}, "values": [[100, "-0.9092974268256816"], [200, "-0.8414709848078965"], [300, "-0.479425538604203"], [400, "0"], [500, "0.479425538604203"], [600, "0.8414709848078965"], [700, "0.9092974268256816"]]}]}',
|
|
[
|
|
[
|
|
"[('job','test')]",
|
|
"[('1970-01-01 00:01:40.000',-0.9092974268256817),('1970-01-01 00:03:20.000',-0.8414709848078965),('1970-01-01 00:05:00.000',-0.479425538604203),('1970-01-01 00:06:40.000',0),('1970-01-01 00:08:20.000',0.479425538604203),('1970-01-01 00:10:00.000',0.8414709848078965),('1970-01-01 00:11:40.000',0.9092974268256817)]",
|
|
]
|
|
],
|
|
eps=1e-15,
|
|
)
|
|
|
|
do_query_test(
|
|
"cos(vector(1))",
|
|
500,
|
|
'{"resultType": "vector", "result": [{"metric": {}, "value": [500, "0.5403023058681398"]}]}',
|
|
[["[]", "1970-01-01 00:08:20.000", 0.5403023058681398]],
|
|
)
|
|
|
|
do_query_test(
|
|
"cos(deltas)[700:100]",
|
|
700,
|
|
'{"resultType": "matrix", "result": [{"metric": {"job": "test"}, "values": [[100, "-0.4161468365471424"], [200, "0.5403023058681398"], [300, "0.8775825618903728"], [400, "1"], [500, "0.8775825618903728"], [600, "0.5403023058681398"], [700, "-0.4161468365471424"]]}]}',
|
|
[
|
|
[
|
|
"[('job','test')]",
|
|
"[('1970-01-01 00:01:40.000',-0.4161468365471424),('1970-01-01 00:03:20.000',0.5403023058681398),('1970-01-01 00:05:00.000',0.8775825618903728),('1970-01-01 00:06:40.000',1),('1970-01-01 00:08:20.000',0.8775825618903728),('1970-01-01 00:10:00.000',0.5403023058681398),('1970-01-01 00:11:40.000',-0.4161468365471424)]",
|
|
]
|
|
],
|
|
)
|
|
|
|
do_query_test(
|
|
"tan(vector(1))",
|
|
500,
|
|
'{"resultType": "vector", "result": [{"metric": {}, "value": [500, "1.557407724654902"]}]}',
|
|
[["[]", "1970-01-01 00:08:20.000", 1.5574077246549023]],
|
|
eps=1e-15,
|
|
)
|
|
|
|
do_query_test(
|
|
"tan(deltas)[700:100]",
|
|
700,
|
|
'{"resultType": "matrix", "result": [{"metric": {"job": "test"}, "values": [[100, "2.185039863261519"], [200, "-1.557407724654902"], [300, "-0.5463024898437905"], [400, "0"], [500, "0.5463024898437905"], [600, "1.557407724654902"], [700, "-2.185039863261519"]]}]}',
|
|
[
|
|
[
|
|
"[('job','test')]",
|
|
"[('1970-01-01 00:01:40.000',2.185039863261519),('1970-01-01 00:03:20.000',-1.5574077246549023),('1970-01-01 00:05:00.000',-0.5463024898437905),('1970-01-01 00:06:40.000',0),('1970-01-01 00:08:20.000',0.5463024898437905),('1970-01-01 00:10:00.000',1.5574077246549023),('1970-01-01 00:11:40.000',-2.185039863261519)]",
|
|
]
|
|
],
|
|
eps=1e-15,
|
|
)
|
|
|
|
do_query_test(
|
|
"asin(vector(1))",
|
|
500,
|
|
'{"resultType": "vector", "result": [{"metric": {}, "value": [500, "1.5707963267948966"]}]}',
|
|
[["[]", "1970-01-01 00:08:20.000", 1.5707963267948966]],
|
|
)
|
|
|
|
do_query_test(
|
|
"asin(deltas)[700:100]",
|
|
700,
|
|
'{"resultType": "matrix", "result": [{"metric": {"job": "test"}, "values": [[100, "NaN"], [200, "-1.5707963267948966"], [300, "-0.5235987755982989"], [400, "0"], [500, "0.5235987755982989"], [600, "1.5707963267948966"], [700, "NaN"]]}]}',
|
|
[
|
|
[
|
|
"[('job','test')]",
|
|
"[('1970-01-01 00:01:40.000',nan),('1970-01-01 00:03:20.000',-1.5707963267948966),('1970-01-01 00:05:00.000',-0.5235987755982991),('1970-01-01 00:06:40.000',0),('1970-01-01 00:08:20.000',0.5235987755982991),('1970-01-01 00:10:00.000',1.5707963267948966),('1970-01-01 00:11:40.000',nan)]",
|
|
]
|
|
],
|
|
eps=1e-15,
|
|
)
|
|
|
|
do_query_test(
|
|
"acos(vector(1))",
|
|
500,
|
|
'{"resultType": "vector", "result": [{"metric": {}, "value": [500, "0"]}]}',
|
|
[["[]", "1970-01-01 00:08:20.000", 0]],
|
|
)
|
|
|
|
do_query_test(
|
|
"acos(deltas)[700:100]",
|
|
700,
|
|
'{"resultType": "matrix", "result": [{"metric": {"job": "test"}, "values": [[100, "NaN"], [200, "3.141592653589793"], [300, "2.0943951023931957"], [400, "1.5707963267948966"], [500, "1.0471975511965976"], [600, "0"], [700, "NaN"]]}]}',
|
|
[
|
|
[
|
|
"[('job','test')]",
|
|
"[('1970-01-01 00:01:40.000',nan),('1970-01-01 00:03:20.000',3.141592653589793),('1970-01-01 00:05:00.000',2.0943951023931957),('1970-01-01 00:06:40.000',1.5707963267948966),('1970-01-01 00:08:20.000',1.0471975511965974),('1970-01-01 00:10:00.000',0),('1970-01-01 00:11:40.000',nan)]",
|
|
]
|
|
],
|
|
eps=1e-15,
|
|
)
|
|
|
|
do_query_test(
|
|
"atan(vector(1))",
|
|
500,
|
|
'{"resultType": "vector", "result": [{"metric": {}, "value": [500, "0.7853981633974483"]}]}',
|
|
[["[]", "1970-01-01 00:08:20.000", 0.7853981633974483]],
|
|
)
|
|
|
|
do_query_test(
|
|
"atan(deltas)[700:100]",
|
|
700,
|
|
'{"resultType": "matrix", "result": [{"metric": {"job": "test"}, "values": [[100, "-1.1071487177940904"], [200, "-0.7853981633974483"], [300, "-0.4636476090008061"], [400, "0"], [500, "0.4636476090008061"], [600, "0.7853981633974483"], [700, "1.1071487177940904"]]}]}',
|
|
[
|
|
[
|
|
"[('job','test')]",
|
|
"[('1970-01-01 00:01:40.000',-1.1071487177940904),('1970-01-01 00:03:20.000',-0.7853981633974483),('1970-01-01 00:05:00.000',-0.4636476090008061),('1970-01-01 00:06:40.000',0),('1970-01-01 00:08:20.000',0.4636476090008061),('1970-01-01 00:10:00.000',0.7853981633974483),('1970-01-01 00:11:40.000',1.1071487177940904)]",
|
|
]
|
|
],
|
|
)
|
|
|
|
do_query_test(
|
|
"sinh(vector(1))",
|
|
500,
|
|
'{"resultType": "vector", "result": [{"metric": {}, "value": [500, "1.1752011936438014"]}]}',
|
|
[["[]", "1970-01-01 00:08:20.000", 1.1752011936438014]],
|
|
)
|
|
|
|
do_query_test(
|
|
"sinh(deltas)[700:100]",
|
|
700,
|
|
'{"resultType": "matrix", "result": [{"metric": {"job": "test"}, "values": [[100, "-3.626860407847019"], [200, "-1.1752011936438014"], [300, "-0.5210953054937474"], [400, "0"], [500, "0.5210953054937474"], [600, "1.1752011936438014"], [700, "3.626860407847019"]]}]}',
|
|
[
|
|
[
|
|
"[('job','test')]",
|
|
"[('1970-01-01 00:01:40.000',-3.626860407847019),('1970-01-01 00:03:20.000',-1.1752011936438014),('1970-01-01 00:05:00.000',-0.5210953054937474),('1970-01-01 00:06:40.000',0),('1970-01-01 00:08:20.000',0.5210953054937474),('1970-01-01 00:10:00.000',1.1752011936438014),('1970-01-01 00:11:40.000',3.626860407847019)]",
|
|
]
|
|
],
|
|
)
|
|
|
|
do_query_test(
|
|
"cosh(vector(1))",
|
|
500,
|
|
'{"resultType": "vector", "result": [{"metric": {}, "value": [500, "1.5430806348152437"]}]}',
|
|
[["[]", "1970-01-01 00:08:20.000", 1.5430806348152437]],
|
|
)
|
|
|
|
do_query_test(
|
|
"cosh(deltas)[700:100]",
|
|
700,
|
|
'{"resultType": "matrix", "result": [{"metric": {"job": "test"}, "values": [[100, "3.7621956910836314"], [200, "1.5430806348152437"], [300, "1.1276259652063807"], [400, "1"], [500, "1.1276259652063807"], [600, "1.5430806348152437"], [700, "3.7621956910836314"]]}]}',
|
|
[
|
|
[
|
|
"[('job','test')]",
|
|
"[('1970-01-01 00:01:40.000',3.7621956910836314),('1970-01-01 00:03:20.000',1.5430806348152437),('1970-01-01 00:05:00.000',1.1276259652063807),('1970-01-01 00:06:40.000',1),('1970-01-01 00:08:20.000',1.1276259652063807),('1970-01-01 00:10:00.000',1.5430806348152437),('1970-01-01 00:11:40.000',3.7621956910836314)]",
|
|
]
|
|
],
|
|
)
|
|
|
|
do_query_test(
|
|
"tanh(vector(1))",
|
|
500,
|
|
'{"resultType": "vector", "result": [{"metric": {}, "value": [500, "0.7615941559557649"]}]}',
|
|
[["[]", "1970-01-01 00:08:20.000", 0.7615946626193841]],
|
|
eps=1e-6, # See https://github.com/ClickHouse/ClickHouse/issues/62390
|
|
)
|
|
|
|
do_query_test(
|
|
"tanh(deltas)[700:100]",
|
|
700,
|
|
'{"resultType": "matrix", "result": [{"metric": {"job": "test"}, "values": [[100, "-0.9640275800758169"], [200, "-0.7615941559557649"], [300, "-0.46211715726000974"], [400, "0"], [500, "0.46211715726000974"], [600, "0.7615941559557649"], [700, "0.9640275800758169"]]}]}',
|
|
[
|
|
[
|
|
"[('job','test')]",
|
|
"[('1970-01-01 00:01:40.000',-0.964027555388663),('1970-01-01 00:03:20.000',-0.7615947917469623),('1970-01-01 00:05:00.000',-0.46211751165947257),('1970-01-01 00:06:40.000',0),('1970-01-01 00:08:20.000',0.46211811616870957),('1970-01-01 00:10:00.000',0.7615946626193841),('1970-01-01 00:11:40.000',0.9640275074014772)]",
|
|
]
|
|
],
|
|
eps=1e-6, # See https://github.com/ClickHouse/ClickHouse/issues/62390
|
|
)
|
|
|
|
do_query_test(
|
|
"asinh(vector(1))",
|
|
500,
|
|
'{"resultType": "vector", "result": [{"metric": {}, "value": [500, "0.881373587019543"]}]}',
|
|
[["[]", "1970-01-01 00:08:20.000", 0.881373587019543]],
|
|
)
|
|
|
|
do_query_test(
|
|
"asinh(deltas)[700:100]",
|
|
700,
|
|
'{"resultType": "matrix", "result": [{"metric": {"job": "test"}, "values": [[100, "-1.4436354751788103"], [200, "-0.881373587019543"], [300, "-0.48121182505960347"], [400, "0"], [500, "0.48121182505960347"], [600, "0.881373587019543"], [700, "1.4436354751788103"]]}]}',
|
|
[
|
|
[
|
|
"[('job','test')]",
|
|
"[('1970-01-01 00:01:40.000',-1.4436354751788103),('1970-01-01 00:03:20.000',-0.881373587019543),('1970-01-01 00:05:00.000',-0.48121182505960347),('1970-01-01 00:06:40.000',0),('1970-01-01 00:08:20.000',0.48121182505960347),('1970-01-01 00:10:00.000',0.881373587019543),('1970-01-01 00:11:40.000',1.4436354751788103)]",
|
|
]
|
|
],
|
|
)
|
|
|
|
do_query_test(
|
|
"acosh(vector(1))",
|
|
500,
|
|
'{"resultType": "vector", "result": [{"metric": {}, "value": [500, "0"]}]}',
|
|
[["[]", "1970-01-01 00:08:20.000", 0]],
|
|
)
|
|
|
|
do_query_test(
|
|
"acosh(deltas)[700:100]",
|
|
700,
|
|
'{"resultType": "matrix", "result": [{"metric": {"job": "test"}, "values": [[100, "NaN"], [200, "NaN"], [300, "NaN"], [400, "NaN"], [500, "NaN"], [600, "0"], [700, "1.3169578969248166"]]}]}',
|
|
[
|
|
[
|
|
"[('job','test')]",
|
|
"[('1970-01-01 00:01:40.000',nan),('1970-01-01 00:03:20.000',nan),('1970-01-01 00:05:00.000',nan),('1970-01-01 00:06:40.000',nan),('1970-01-01 00:08:20.000',nan),('1970-01-01 00:10:00.000',0),('1970-01-01 00:11:40.000',1.3169578969248166)]",
|
|
]
|
|
],
|
|
)
|
|
|
|
do_query_test(
|
|
"atanh(vector(1))",
|
|
500,
|
|
'{"resultType": "vector", "result": [{"metric": {}, "value": [500, "+Inf"]}]}',
|
|
[["[]", "1970-01-01 00:08:20.000", "inf"]],
|
|
)
|
|
|
|
do_query_test(
|
|
"atanh(deltas)[700:100]",
|
|
700,
|
|
'{"resultType": "matrix", "result": [{"metric": {"job": "test"}, "values": [[100, "NaN"], [200, "-Inf"], [300, "-0.5493061443340548"], [400, "0"], [500, "0.5493061443340548"], [600, "+Inf"], [700, "NaN"]]}]}',
|
|
[
|
|
[
|
|
"[('job','test')]",
|
|
"[('1970-01-01 00:01:40.000',nan),('1970-01-01 00:03:20.000',-inf),('1970-01-01 00:05:00.000',-0.5493061443340548),('1970-01-01 00:06:40.000',0),('1970-01-01 00:08:20.000',0.5493061443340548),('1970-01-01 00:10:00.000',inf),('1970-01-01 00:11:40.000',nan)]",
|
|
]
|
|
],
|
|
)
|
|
|
|
|
|
def test_range_query():
|
|
do_range_query_test(
|
|
"test",
|
|
120,
|
|
220,
|
|
15,
|
|
'{"resultType": "matrix", "result": [{"metric": {"__name__": "test"}, "values": [[120, "1"], [135, "3"], [150, "4"], [165, "4"], [180, "4"], [195, "5"], [210, "8"]]}]}',
|
|
[
|
|
[
|
|
"[('__name__','test')]",
|
|
"[('1970-01-01 00:02:00.000',1),('1970-01-01 00:02:15.000',3),('1970-01-01 00:02:30.000',4),('1970-01-01 00:02:45.000',4),('1970-01-01 00:03:00.000',4),('1970-01-01 00:03:15.000',5),('1970-01-01 00:03:30.000',8)]",
|
|
]
|
|
],
|
|
)
|
|
|
|
|
|
def test_multiple_instant_vectors():
|
|
do_query_test(
|
|
"http_errors",
|
|
200,
|
|
'{"resultType": "vector", "result": [{"metric": {"__name__": "http_errors", "http_code": "401"}, "value": [200, "4"]}, {"metric": {"__name__": "http_errors", "http_code": "404"}, "value": [200, "5"]}]}',
|
|
[
|
|
[
|
|
"[('__name__','http_errors'),('http_code','401')]",
|
|
"1970-01-01 00:03:20.000",
|
|
"4",
|
|
],
|
|
[
|
|
"[('__name__','http_errors'),('http_code','404')]",
|
|
"1970-01-01 00:03:20.000",
|
|
"5",
|
|
],
|
|
],
|
|
)
|
|
|
|
|
|
def test_multiblock_instant_vector_json():
|
|
"""When the pipeline executor produces multiple blocks (one row per block due to max_block_size=1),
|
|
the JSON response for instant vector queries must still be valid.
|
|
Before the fix, each block would re-emit "resultType":"vector","result":[...] producing malformed JSON like:
|
|
{"status":"success","data":{"resultType":"vector","result":[e1]"resultType":"vector","result":[e2]}}
|
|
"""
|
|
import urllib
|
|
|
|
query = "http_errors"
|
|
timestamp = 200
|
|
escaped_query = urllib.parse.quote_plus(query, safe="")
|
|
url = f"http://{node.ip_address}:9093/api/v1/query?query={escaped_query}&time={timestamp}&max_block_size=1"
|
|
response = requests.get(url)
|
|
assert response.status_code == 200, f"Unexpected status code: {response.status_code}, body: {response.text}"
|
|
|
|
# The critical check: response must be valid JSON.
|
|
# Before the fix, response.json() would raise json.JSONDecodeError.
|
|
data = response.json()
|
|
assert data["status"] == "success"
|
|
assert data["data"]["resultType"] == "vector"
|
|
assert len(data["data"]["result"]) == 2
|
|
|
|
|
|
def test_multiblock_range_query_json():
|
|
"""When the pipeline executor produces multiple blocks (one row per block due to max_block_size=1),
|
|
the JSON response for range queries must still be valid.
|
|
Before the fix, entries from different blocks had no comma between them, producing malformed JSON like:
|
|
{"status":"success","data":{"resultType":"matrix","result":[{...}{...}]}}
|
|
"""
|
|
import urllib
|
|
|
|
query = "http_errors"
|
|
start_time = 100
|
|
end_time = 210
|
|
step = 10
|
|
escaped_query = urllib.parse.quote_plus(query, safe="")
|
|
url = (
|
|
f"http://{node.ip_address}:9093/api/v1/query_range"
|
|
f"?query={escaped_query}&start={start_time}&end={end_time}&step={step}&max_block_size=1"
|
|
)
|
|
response = requests.get(url)
|
|
assert response.status_code == 200, f"Unexpected status code: {response.status_code}, body: {response.text}"
|
|
|
|
# The critical check: response must be valid JSON.
|
|
# Before the fix, response.json() would raise json.JSONDecodeError.
|
|
data = response.json()
|
|
assert data["status"] == "success"
|
|
assert data["data"]["resultType"] == "matrix"
|
|
assert len(data["data"]["result"]) == 2
|
|
|
|
|
|
def test_multiple_series_in_same_resultset():
|
|
do_query_test(
|
|
"rate(http_errors[100])[1:1]",
|
|
200,
|
|
'{"resultType": "matrix", "result": [{"metric": {"http_code": "401"}, "values": [[200, "0.04"]]}, {"metric": {"http_code": "404"}, "values": [[200, "0.07"]]}]}',
|
|
[
|
|
[
|
|
"[('http_code','401')]",
|
|
"[('1970-01-01 00:03:20.000',0.04)]",
|
|
],
|
|
[
|
|
"[('http_code','404')]",
|
|
"[('1970-01-01 00:03:20.000',0.07)]",
|
|
],
|
|
],
|
|
)
|
|
|
|
# FIXME: Function sort_by_label() is not implemented yet.
|
|
# do_query_test(
|
|
# "sort_by_label(rate(http_errors[100]), 'http_code')",
|
|
# 200,
|
|
# '{"resultType": "vector", "result": [{"metric": {"http_code": "401"}, "value": [200, "0.04"]}, {"metric": {"http_code": "404"}, "value": [200, "0.07"]}]}',
|
|
# [
|
|
# [
|
|
# "[('http_code','401')]",
|
|
# "1970-01-01 00:03:20.000",
|
|
# "0.04",
|
|
# ],
|
|
# [
|
|
# "[('http_code','404')]",
|
|
# "1970-01-01 00:03:20.000",
|
|
# "0.07",
|
|
# ],
|
|
# ]
|
|
# )
|
|
|
|
do_query_test_expect_error(
|
|
"rate({http_code='404'}[100])",
|
|
200,
|
|
"vector cannot contain metrics with the same labelset",
|
|
"Multiple series have the same tags {'http_code': '404'}",
|
|
)
|
|
|
|
# FIXME: Function count_over_time() is not implemented yet.
|
|
# do_query_test_expect_error(
|
|
# "count_over_time({http_code='404'}[10])[100:10]",
|
|
# 200,
|
|
# "vector cannot contain metrics with the same labelset",
|
|
# "Multiple series have the same tags {'http_code': '404'}",
|
|
# )
|
|
|
|
|
|
def test_alignment_with_subquery_step():
|
|
do_query_test(
|
|
"vector(1)[100:20]",
|
|
10000,
|
|
'{"resultType": "matrix", "result": [{"metric": {}, "values": [[9920, "1"], [9940, "1"], [9960, "1"], [9980, "1"], [10000, "1"]]}]}',
|
|
[
|
|
[
|
|
"[]",
|
|
"[('1970-01-01 02:45:20.000',1),('1970-01-01 02:45:40.000',1),('1970-01-01 02:46:00.000',1),('1970-01-01 02:46:20.000',1),('1970-01-01 02:46:40.000',1)]",
|
|
]
|
|
],
|
|
)
|
|
|
|
do_query_test(
|
|
"vector(1)[100:20]",
|
|
9999.999,
|
|
'{"resultType": "matrix", "result": [{"metric": {}, "values": [[9900, "1"], [9920, "1"], [9940, "1"], [9960, "1"], [9980, "1"]]}]}',
|
|
[
|
|
[
|
|
"[]",
|
|
"[('1970-01-01 02:45:00.000',1),('1970-01-01 02:45:20.000',1),('1970-01-01 02:45:40.000',1),('1970-01-01 02:46:00.000',1),('1970-01-01 02:46:20.000',1)]",
|
|
]
|
|
],
|
|
)
|
|
|
|
do_query_test(
|
|
"vector(1)[100:20]",
|
|
9980,
|
|
'{"resultType": "matrix", "result": [{"metric": {}, "values": [[9900, "1"], [9920, "1"], [9940, "1"], [9960, "1"], [9980, "1"]]}]}',
|
|
[
|
|
[
|
|
"[]",
|
|
"[('1970-01-01 02:45:00.000',1),('1970-01-01 02:45:20.000',1),('1970-01-01 02:45:40.000',1),('1970-01-01 02:46:00.000',1),('1970-01-01 02:46:20.000',1)]",
|
|
]
|
|
],
|
|
)
|
|
|
|
do_query_test(
|
|
"vector(1)[100:20]",
|
|
9979.999,
|
|
'{"resultType": "matrix", "result": [{"metric": {}, "values": [[9880, "1"], [9900, "1"], [9920, "1"], [9940, "1"], [9960, "1"]]}]}',
|
|
[
|
|
[
|
|
"[]",
|
|
"[('1970-01-01 02:44:40.000',1),('1970-01-01 02:45:00.000',1),('1970-01-01 02:45:20.000',1),('1970-01-01 02:45:40.000',1),('1970-01-01 02:46:00.000',1)]",
|
|
]
|
|
],
|
|
)
|
|
|
|
do_query_test(
|
|
"vector(1)[40.001:7.5]",
|
|
10000,
|
|
'{"resultType": "matrix", "result": [{"metric": {}, "values": [[9960, "1"], [9967.5, "1"], [9975, "1"], [9982.5, "1"], [9990, "1"], [9997.5, "1"]]}]}',
|
|
[
|
|
[
|
|
"[]",
|
|
"[('1970-01-01 02:46:00.000',1),('1970-01-01 02:46:07.500',1),('1970-01-01 02:46:15.000',1),('1970-01-01 02:46:22.500',1),('1970-01-01 02:46:30.000',1),('1970-01-01 02:46:37.500',1)]",
|
|
]
|
|
],
|
|
)
|
|
|
|
do_query_test(
|
|
"vector(1)[40:7.5]",
|
|
10000,
|
|
'{"resultType": "matrix", "result": [{"metric": {}, "values": [[9967.5, "1"], [9975, "1"], [9982.5, "1"], [9990, "1"], [9997.5, "1"]]}]}',
|
|
[
|
|
[
|
|
"[]",
|
|
"[('1970-01-01 02:46:07.500',1),('1970-01-01 02:46:15.000',1),('1970-01-01 02:46:22.500',1),('1970-01-01 02:46:30.000',1),('1970-01-01 02:46:37.500',1)]",
|
|
]
|
|
],
|
|
)
|
|
|
|
do_query_test(
|
|
"vector(1)[20:20]",
|
|
9999,
|
|
'{"resultType": "matrix", "result": [{"metric": {}, "values": [[9980, "1"]]}]}',
|
|
[["[]", "[('1970-01-01 02:46:20.000',1)]"]],
|
|
)
|
|
|
|
do_query_test(
|
|
"vector(1)[19.001:20]",
|
|
9999,
|
|
'{"resultType": "matrix", "result": [{"metric": {}, "values": [[9980, "1"]]}]}',
|
|
[["[]", "[('1970-01-01 02:46:20.000',1)]"]],
|
|
)
|
|
|
|
do_query_test(
|
|
"vector(1)[19:20]", 9999, '{"resultType": "matrix", "result": []}', ""
|
|
)
|
|
|
|
|
|
def test_math_binary_operators():
|
|
do_query_test(
|
|
"5 + 7",
|
|
100,
|
|
'{"resultType": "scalar", "result": [100, "12"]}',
|
|
[["1970-01-01 00:01:40.000", 12]],
|
|
)
|
|
|
|
do_query_test(
|
|
"5 - 7",
|
|
100,
|
|
'{"resultType": "scalar", "result": [100, "-2"]}',
|
|
[["1970-01-01 00:01:40.000", -2]],
|
|
)
|
|
|
|
do_query_test(
|
|
"5 * 7",
|
|
100,
|
|
'{"resultType": "scalar", "result": [100, "35"]}',
|
|
[["1970-01-01 00:01:40.000", 35]],
|
|
)
|
|
|
|
do_query_test(
|
|
"25 / 3",
|
|
100,
|
|
'{"resultType": "scalar", "result": [100, "8.333333333333334"]}',
|
|
[["1970-01-01 00:01:40.000", 8.333333333333334]],
|
|
)
|
|
|
|
do_query_test(
|
|
"25 % 3",
|
|
100,
|
|
'{"resultType": "scalar", "result": [100, "1"]}',
|
|
[["1970-01-01 00:01:40.000", 1]],
|
|
)
|
|
|
|
do_query_test(
|
|
"25 ^ 0.5",
|
|
100,
|
|
'{"resultType": "scalar", "result": [100, "5"]}',
|
|
[["1970-01-01 00:01:40.000", 5]],
|
|
)
|
|
|
|
do_query_test(
|
|
"-1 atan2 3",
|
|
100,
|
|
'{"resultType": "scalar", "result": [100, "-0.3217505543966422"]}',
|
|
[["1970-01-01 00:01:40.000", -0.3217505543966422]],
|
|
)
|
|
|
|
do_query_test(
|
|
"vector(4) + 7",
|
|
100,
|
|
'{"resultType": "vector", "result": [{"metric": {}, "value": [100, "11"]}]}',
|
|
[["[]", "1970-01-01 00:01:40.000", 11]],
|
|
)
|
|
|
|
do_query_test(
|
|
"vector(time()) + 7",
|
|
100,
|
|
'{"resultType": "vector", "result": [{"metric": {}, "value": [100, "107"]}]}',
|
|
[["[]", "1970-01-01 00:01:40.000", 107]],
|
|
)
|
|
|
|
do_query_test(
|
|
"deltas + 1",
|
|
700,
|
|
'{"resultType": "vector", "result": [{"metric": {"job": "test"}, "value": [700, "3"]}]}',
|
|
[["[('job','test')]", "1970-01-01 00:11:40.000", 3]],
|
|
)
|
|
|
|
do_query_test(
|
|
"(deltas + 1)[700:100]",
|
|
700,
|
|
'{"resultType": "matrix", "result": [{"metric": {"job": "test"}, "values": [[100, "-1"], [200, "0"], [300, "0.5"], [400, "1"], [500, "1.5"], [600, "2"], [700, "3"]]}]}',
|
|
[
|
|
[
|
|
"[('job','test')]",
|
|
"[('1970-01-01 00:01:40.000',-1),('1970-01-01 00:03:20.000',0),('1970-01-01 00:05:00.000',0.5),('1970-01-01 00:06:40.000',1),('1970-01-01 00:08:20.000',1.5),('1970-01-01 00:10:00.000',2),('1970-01-01 00:11:40.000',3)]",
|
|
]
|
|
],
|
|
)
|
|
|
|
do_query_test(
|
|
"(2 * deltas)[700:100]",
|
|
700,
|
|
'{"resultType": "matrix", "result": [{"metric": {"job": "test"}, "values": [[100, "-4"], [200, "-2"], [300, "-1"], [400, "0"], [500, "1"], [600, "2"], [700, "4"]]}]}',
|
|
[
|
|
[
|
|
"[('job','test')]",
|
|
"[('1970-01-01 00:01:40.000',-4),('1970-01-01 00:03:20.000',-2),('1970-01-01 00:05:00.000',-1),('1970-01-01 00:06:40.000',0),('1970-01-01 00:08:20.000',1),('1970-01-01 00:10:00.000',2),('1970-01-01 00:11:40.000',4)]",
|
|
]
|
|
],
|
|
)
|
|
|
|
do_query_test(
|
|
"(deltas / 2)[700:100]",
|
|
700,
|
|
'{"resultType": "matrix", "result": [{"metric": {"job": "test"}, "values": [[100, "-1"], [200, "-0.5"], [300, "-0.25"], [400, "0"], [500, "0.25"], [600, "0.5"], [700, "1"]]}]}',
|
|
[
|
|
[
|
|
"[('job','test')]",
|
|
"[('1970-01-01 00:01:40.000',-1),('1970-01-01 00:03:20.000',-0.5),('1970-01-01 00:05:00.000',-0.25),('1970-01-01 00:06:40.000',0),('1970-01-01 00:08:20.000',0.25),('1970-01-01 00:10:00.000',0.5),('1970-01-01 00:11:40.000',1)]",
|
|
]
|
|
],
|
|
)
|
|
|
|
do_query_test(
|
|
"deltas + deltas",
|
|
700,
|
|
'{"resultType": "vector", "result": [{"metric": {"job": "test"}, "value": [700, "4"]}]}',
|
|
[["[('job','test')]", "1970-01-01 00:11:40.000", 4]],
|
|
)
|
|
|
|
do_query_test(
|
|
"(deltas + deltas)[700:100]",
|
|
700,
|
|
'{"resultType": "matrix", "result": [{"metric": {"job": "test"}, "values": [[100, "-4"], [200, "-2"], [300, "-1"], [400, "0"], [500, "1"], [600, "2"], [700, "4"]]}]}',
|
|
[
|
|
[
|
|
"[('job','test')]",
|
|
"[('1970-01-01 00:01:40.000',-4),('1970-01-01 00:03:20.000',-2),('1970-01-01 00:05:00.000',-1),('1970-01-01 00:06:40.000',0),('1970-01-01 00:08:20.000',1),('1970-01-01 00:10:00.000',2),('1970-01-01 00:11:40.000',4)]",
|
|
]
|
|
],
|
|
)
|
|
|
|
# FIXME: Function sort_by_label() is not implemented yet.
|
|
# do_query_test(
|
|
# "foo + bar",
|
|
# 150,
|
|
# '{"resultType": "vector", "result": [{"metric": {"shape": "square", "size": "s"}, "value": [150, "740"]}, {"metric": {"shape": "circle", "size": "l"}, "value": [150, "1016"]}]}',
|
|
# [
|
|
# ["[('shape','square'),('size','s')]", "1970-01-01 00:02:30.000", 740],
|
|
# ["[('shape','circle'),('size','l')]", "1970-01-01 00:02:30.000", 1016],
|
|
# ],
|
|
# )
|
|
|
|
do_query_test(
|
|
"(foo + bar)[50:10]",
|
|
150,
|
|
'{"resultType": "matrix", "result": [{"metric": {"shape": "circle", "size": "l"}, "values": [[110, "26"], [120, "32"], [130, "66"], [140, "66"], [150, "1016"]]}, {"metric": {"shape": "square", "size": "s"}, "values": [[110, "7"], [120, "44"], [130, "80"], [140, "740"], [150, "740"]]}]}',
|
|
[
|
|
[
|
|
"[('shape','circle'),('size','l')]",
|
|
"[('1970-01-01 00:01:50.000',26),('1970-01-01 00:02:00.000',32),('1970-01-01 00:02:10.000',66),('1970-01-01 00:02:20.000',66),('1970-01-01 00:02:30.000',1016)]",
|
|
],
|
|
[
|
|
"[('shape','square'),('size','s')]",
|
|
"[('1970-01-01 00:01:50.000',7),('1970-01-01 00:02:00.000',44),('1970-01-01 00:02:10.000',80),('1970-01-01 00:02:20.000',740),('1970-01-01 00:02:30.000',740)]",
|
|
],
|
|
],
|
|
)
|
|
|
|
do_query_test(
|
|
"(foo + ignoring() bar)[50:10]",
|
|
150,
|
|
'{"resultType": "matrix", "result": [{"metric": {"shape": "circle", "size": "l"}, "values": [[110, "26"], [120, "32"], [130, "66"], [140, "66"], [150, "1016"]]}, {"metric": {"shape": "square", "size": "s"}, "values": [[110, "7"], [120, "44"], [130, "80"], [140, "740"], [150, "740"]]}]}',
|
|
[
|
|
[
|
|
"[('shape','circle'),('size','l')]",
|
|
"[('1970-01-01 00:01:50.000',26),('1970-01-01 00:02:00.000',32),('1970-01-01 00:02:10.000',66),('1970-01-01 00:02:20.000',66),('1970-01-01 00:02:30.000',1016)]",
|
|
],
|
|
[
|
|
"[('shape','square'),('size','s')]",
|
|
"[('1970-01-01 00:01:50.000',7),('1970-01-01 00:02:00.000',44),('1970-01-01 00:02:10.000',80),('1970-01-01 00:02:20.000',740),('1970-01-01 00:02:30.000',740)]",
|
|
],
|
|
],
|
|
)
|
|
|
|
do_query_test(
|
|
"(last_over_time(foo[10]) + last_over_time(bar[10]))[50:10]",
|
|
150,
|
|
'{"resultType": "matrix", "result": [{"metric": {"shape": "circle", "size": "l"}, "values": [[110, "26"], [130, "66"], [150, "1016"]]}, {"metric": {"shape": "square", "size": "s"}, "values": [[110, "7"]]}]}',
|
|
[
|
|
[
|
|
"[('shape','circle'),('size','l')]",
|
|
"[('1970-01-01 00:01:50.000',26),('1970-01-01 00:02:10.000',66),('1970-01-01 00:02:30.000',1016)]",
|
|
],
|
|
["[('shape','square'),('size','s')]", "[('1970-01-01 00:01:50.000',7)]"],
|
|
],
|
|
)
|
|
|
|
# FIXME: Function sort_by_label() is not implemented yet.
|
|
# do_query_test(
|
|
# "foo + on(shape) bar",
|
|
# 150,
|
|
# '{"resultType": "vector", "result": [{"metric": {"shape": "square"}, "value": [150, "740"]}, {"metric": {"shape": "triangle"}, "value": [150, "110"]}, {"metric": {"shape": "circle"}, "value": [150, "1016"]}]}',
|
|
# ''
|
|
# [
|
|
# ["[('shape','triangle')]", "1970-01-01 00:02:30.000", 110],
|
|
# ["[('shape','square')]", "1970-01-01 00:02:30.000", 740],
|
|
# ["[('shape','circle')]", "1970-01-01 00:02:30.000", 1016]
|
|
# ],
|
|
# )
|
|
|
|
do_query_test(
|
|
"(foo + on(shape) bar)[50:10]",
|
|
150,
|
|
'{"resultType": "matrix", "result": [{"metric": {"shape": "circle"}, "values": [[110, "26"], [120, "32"], [130, "66"], [140, "66"], [150, "1016"]]}, {"metric": {"shape": "square"}, "values": [[110, "7"], [120, "44"], [130, "80"], [140, "740"], [150, "740"]]}, {"metric": {"shape": "triangle"}, "values": [[110, "16"], [120, "88"], [130, "88"], [140, "88"], [150, "110"]]}]}',
|
|
[
|
|
[
|
|
"[('shape','circle')]",
|
|
"[('1970-01-01 00:01:50.000',26),('1970-01-01 00:02:00.000',32),('1970-01-01 00:02:10.000',66),('1970-01-01 00:02:20.000',66),('1970-01-01 00:02:30.000',1016)]",
|
|
],
|
|
[
|
|
"[('shape','square')]",
|
|
"[('1970-01-01 00:01:50.000',7),('1970-01-01 00:02:00.000',44),('1970-01-01 00:02:10.000',80),('1970-01-01 00:02:20.000',740),('1970-01-01 00:02:30.000',740)]",
|
|
],
|
|
[
|
|
"[('shape','triangle')]",
|
|
"[('1970-01-01 00:01:50.000',16),('1970-01-01 00:02:00.000',88),('1970-01-01 00:02:10.000',88),('1970-01-01 00:02:20.000',88),('1970-01-01 00:02:30.000',110)]",
|
|
],
|
|
],
|
|
)
|
|
|
|
do_query_test(
|
|
"(last_over_time(foo[10]) + on(shape) last_over_time(bar[10]))[50:10]",
|
|
150,
|
|
'{"resultType": "matrix", "result": [{"metric": {"shape": "circle"}, "values": [[110, "26"], [130, "66"], [150, "1016"]]}, {"metric": {"shape": "square"}, "values": [[110, "7"]]}, {"metric": {"shape": "triangle"}, "values": [[110, "16"]]}]}',
|
|
[
|
|
[
|
|
"[('shape','circle')]",
|
|
"[('1970-01-01 00:01:50.000',26),('1970-01-01 00:02:10.000',66),('1970-01-01 00:02:30.000',1016)]",
|
|
],
|
|
["[('shape','square')]", "[('1970-01-01 00:01:50.000',7)]"],
|
|
["[('shape','triangle')]", "[('1970-01-01 00:01:50.000',16)]"],
|
|
],
|
|
)
|
|
|
|
do_query_test(
|
|
"(last_over_time(foo[10]) + ignoring(size) last_over_time(bar[10]))[50:10]",
|
|
150,
|
|
'{"resultType": "matrix", "result": [{"metric": {"shape": "circle"}, "values": [[110, "26"], [130, "66"], [150, "1016"]]}, {"metric": {"shape": "square"}, "values": [[110, "7"]]}, {"metric": {"shape": "triangle"}, "values": [[110, "16"]]}]}',
|
|
[
|
|
[
|
|
"[('shape','circle')]",
|
|
"[('1970-01-01 00:01:50.000',26),('1970-01-01 00:02:10.000',66),('1970-01-01 00:02:30.000',1016)]",
|
|
],
|
|
["[('shape','square')]", "[('1970-01-01 00:01:50.000',7)]"],
|
|
["[('shape','triangle')]", "[('1970-01-01 00:01:50.000',16)]"],
|
|
],
|
|
)
|
|
|
|
do_query_test(
|
|
"(foo + on(shape, size) bar)[50:10]",
|
|
150,
|
|
'{"resultType": "matrix", "result": [{"metric": {"shape": "circle", "size": "l"}, "values": [[110, "26"], [120, "32"], [130, "66"], [140, "66"], [150, "1016"]]}, {"metric": {"shape": "square", "size": "s"}, "values": [[110, "7"], [120, "44"], [130, "80"], [140, "740"], [150, "740"]]}]}',
|
|
[
|
|
[
|
|
"[('shape','circle'),('size','l')]",
|
|
"[('1970-01-01 00:01:50.000',26),('1970-01-01 00:02:00.000',32),('1970-01-01 00:02:10.000',66),('1970-01-01 00:02:20.000',66),('1970-01-01 00:02:30.000',1016)]",
|
|
],
|
|
[
|
|
"[('shape','square'),('size','s')]",
|
|
"[('1970-01-01 00:01:50.000',7),('1970-01-01 00:02:00.000',44),('1970-01-01 00:02:10.000',80),('1970-01-01 00:02:20.000',740),('1970-01-01 00:02:30.000',740)]",
|
|
],
|
|
],
|
|
)
|
|
|
|
do_query_test_expect_error(
|
|
"(foo + on(size) bar)[50:10]",
|
|
150,
|
|
"matching labels must be unique on one side",
|
|
"Multiple series have the same tags",
|
|
)
|
|
|
|
do_query_test(
|
|
"(foo + on(size) group_right bar)[50:10]",
|
|
150,
|
|
'{"resultType": "matrix", "result": [{"metric": {"shape": "circle", "size": "l"}, "values": [[110, "26"], [120, "32"], [130, "66"], [140, "66"], [150, "1016"]]}, {"metric": {"shape": "rectangle", "size": "l"}, "values": [[110, "25"], [120, "25"], [130, "106"], [140, "106"], [150, "106"]]}, {"metric": {"shape": "square", "size": "s"}, "values": [[110, "7"], [120, "44"], [130, "80"], [140, "740"], [150, "740"]]}]}',
|
|
[
|
|
[
|
|
"[('shape','circle'),('size','l')]",
|
|
"[('1970-01-01 00:01:50.000',26),('1970-01-01 00:02:00.000',32),('1970-01-01 00:02:10.000',66),('1970-01-01 00:02:20.000',66),('1970-01-01 00:02:30.000',1016)]",
|
|
],
|
|
[
|
|
"[('shape','rectangle'),('size','l')]",
|
|
"[('1970-01-01 00:01:50.000',25),('1970-01-01 00:02:00.000',25),('1970-01-01 00:02:10.000',106),('1970-01-01 00:02:20.000',106),('1970-01-01 00:02:30.000',106)]",
|
|
],
|
|
[
|
|
"[('shape','square'),('size','s')]",
|
|
"[('1970-01-01 00:01:50.000',7),('1970-01-01 00:02:00.000',44),('1970-01-01 00:02:10.000',80),('1970-01-01 00:02:20.000',740),('1970-01-01 00:02:30.000',740)]",
|
|
],
|
|
],
|
|
)
|
|
|
|
do_query_test(
|
|
"(bar + on(size) group_left foo)[50:10]",
|
|
150,
|
|
'{"resultType": "matrix", "result": [{"metric": {"shape": "circle", "size": "l"}, "values": [[110, "26"], [120, "32"], [130, "66"], [140, "66"], [150, "1016"]]}, {"metric": {"shape": "rectangle", "size": "l"}, "values": [[110, "25"], [120, "25"], [130, "106"], [140, "106"], [150, "106"]]}, {"metric": {"shape": "square", "size": "s"}, "values": [[110, "7"], [120, "44"], [130, "80"], [140, "740"], [150, "740"]]}]}',
|
|
[
|
|
[
|
|
"[('shape','circle'),('size','l')]",
|
|
"[('1970-01-01 00:01:50.000',26),('1970-01-01 00:02:00.000',32),('1970-01-01 00:02:10.000',66),('1970-01-01 00:02:20.000',66),('1970-01-01 00:02:30.000',1016)]",
|
|
],
|
|
[
|
|
"[('shape','rectangle'),('size','l')]",
|
|
"[('1970-01-01 00:01:50.000',25),('1970-01-01 00:02:00.000',25),('1970-01-01 00:02:10.000',106),('1970-01-01 00:02:20.000',106),('1970-01-01 00:02:30.000',106)]",
|
|
],
|
|
[
|
|
"[('shape','square'),('size','s')]",
|
|
"[('1970-01-01 00:01:50.000',7),('1970-01-01 00:02:00.000',44),('1970-01-01 00:02:10.000',80),('1970-01-01 00:02:20.000',740),('1970-01-01 00:02:30.000',740)]",
|
|
],
|
|
],
|
|
)
|
|
|
|
do_query_test(
|
|
"(foo + on(size) group_right(__name__) bar)[50:10]",
|
|
150,
|
|
'{"resultType": "matrix", "result": [{"metric": {"__name__": "foo", "shape": "circle", "size": "l"}, "values": [[110, "26"], [120, "32"], [130, "66"], [140, "66"], [150, "1016"]]}, {"metric": {"__name__": "foo", "shape": "rectangle", "size": "l"}, "values": [[110, "25"], [120, "25"], [130, "106"], [140, "106"], [150, "106"]]}, {"metric": {"__name__": "foo", "shape": "square", "size": "s"}, "values": [[110, "7"], [120, "44"], [130, "80"], [140, "740"], [150, "740"]]}]}',
|
|
[
|
|
[
|
|
"[('__name__','foo'),('shape','circle'),('size','l')]",
|
|
"[('1970-01-01 00:01:50.000',26),('1970-01-01 00:02:00.000',32),('1970-01-01 00:02:10.000',66),('1970-01-01 00:02:20.000',66),('1970-01-01 00:02:30.000',1016)]",
|
|
],
|
|
[
|
|
"[('__name__','foo'),('shape','rectangle'),('size','l')]",
|
|
"[('1970-01-01 00:01:50.000',25),('1970-01-01 00:02:00.000',25),('1970-01-01 00:02:10.000',106),('1970-01-01 00:02:20.000',106),('1970-01-01 00:02:30.000',106)]",
|
|
],
|
|
[
|
|
"[('__name__','foo'),('shape','square'),('size','s')]",
|
|
"[('1970-01-01 00:01:50.000',7),('1970-01-01 00:02:00.000',44),('1970-01-01 00:02:10.000',80),('1970-01-01 00:02:20.000',740),('1970-01-01 00:02:30.000',740)]",
|
|
],
|
|
],
|
|
)
|
|
|
|
do_query_test(
|
|
"(bar + on(size) group_left(__name__) foo)[50:10]",
|
|
150,
|
|
'{"resultType": "matrix", "result": [{"metric": {"__name__": "foo", "shape": "circle", "size": "l"}, "values": [[110, "26"], [120, "32"], [130, "66"], [140, "66"], [150, "1016"]]}, {"metric": {"__name__": "foo", "shape": "rectangle", "size": "l"}, "values": [[110, "25"], [120, "25"], [130, "106"], [140, "106"], [150, "106"]]}, {"metric": {"__name__": "foo", "shape": "square", "size": "s"}, "values": [[110, "7"], [120, "44"], [130, "80"], [140, "740"], [150, "740"]]}]}',
|
|
[
|
|
[
|
|
"[('__name__','foo'),('shape','circle'),('size','l')]",
|
|
"[('1970-01-01 00:01:50.000',26),('1970-01-01 00:02:00.000',32),('1970-01-01 00:02:10.000',66),('1970-01-01 00:02:20.000',66),('1970-01-01 00:02:30.000',1016)]",
|
|
],
|
|
[
|
|
"[('__name__','foo'),('shape','rectangle'),('size','l')]",
|
|
"[('1970-01-01 00:01:50.000',25),('1970-01-01 00:02:00.000',25),('1970-01-01 00:02:10.000',106),('1970-01-01 00:02:20.000',106),('1970-01-01 00:02:30.000',106)]",
|
|
],
|
|
[
|
|
"[('__name__','foo'),('shape','square'),('size','s')]",
|
|
"[('1970-01-01 00:01:50.000',7),('1970-01-01 00:02:00.000',44),('1970-01-01 00:02:10.000',80),('1970-01-01 00:02:20.000',740),('1970-01-01 00:02:30.000',740)]",
|
|
],
|
|
],
|
|
)
|
|
|
|
do_query_test(
|
|
'({__name__=~"foo|bar"} + on(__name__, shape) bar)[50:10]',
|
|
150,
|
|
'{"resultType": "matrix", "result": [{"metric": {"shape": "circle"}, "values": [[110, "20"], [120, "32"], [130, "100"], [140, "100"], [150, "2000"]]}, {"metric": {"shape": "rectangle"}, "values": [[110, "18"], [120, "18"], [130, "180"], [140, "180"], [150, "180"]]}, {"metric": {"shape": "square"}, "values": [[110, "6"], [120, "80"], [130, "80"], [140, "1400"], [150, "1400"]]}, {"metric": {"shape": "triangle"}, "values": [[110, "16"], [120, "16"], [130, "16"], [140, "16"], [150, "60"]]}]}',
|
|
[
|
|
[
|
|
"[('shape','circle')]",
|
|
"[('1970-01-01 00:01:50.000',20),('1970-01-01 00:02:00.000',32),('1970-01-01 00:02:10.000',100),('1970-01-01 00:02:20.000',100),('1970-01-01 00:02:30.000',2000)]",
|
|
],
|
|
[
|
|
"[('shape','rectangle')]",
|
|
"[('1970-01-01 00:01:50.000',18),('1970-01-01 00:02:00.000',18),('1970-01-01 00:02:10.000',180),('1970-01-01 00:02:20.000',180),('1970-01-01 00:02:30.000',180)]",
|
|
],
|
|
[
|
|
"[('shape','square')]",
|
|
"[('1970-01-01 00:01:50.000',6),('1970-01-01 00:02:00.000',80),('1970-01-01 00:02:10.000',80),('1970-01-01 00:02:20.000',1400),('1970-01-01 00:02:30.000',1400)]",
|
|
],
|
|
[
|
|
"[('shape','triangle')]",
|
|
"[('1970-01-01 00:01:50.000',16),('1970-01-01 00:02:00.000',16),('1970-01-01 00:02:10.000',16),('1970-01-01 00:02:20.000',16),('1970-01-01 00:02:30.000',60)]",
|
|
],
|
|
],
|
|
)
|
|
|
|
|
|
def test_comparison_operators_with_bool_modifier():
|
|
# Compare scalars.
|
|
do_query_test("5 == bool 7", 100, '{"resultType": "scalar", "result": [100, "0"]}', [["1970-01-01 00:01:40.000", 0]])
|
|
do_query_test("5 == bool 5", 100, '{"resultType": "scalar", "result": [100, "1"]}', [["1970-01-01 00:01:40.000", 1]])
|
|
do_query_test("5 != bool 7", 100, '{"resultType": "scalar", "result": [100, "1"]}', [["1970-01-01 00:01:40.000", 1]])
|
|
do_query_test("5 != bool 5", 100, '{"resultType": "scalar", "result": [100, "0"]}', [["1970-01-01 00:01:40.000", 0]])
|
|
do_query_test("5 > bool 3", 100, '{"resultType": "scalar", "result": [100, "1"]}', [["1970-01-01 00:01:40.000", 1]])
|
|
do_query_test("5 > bool 7", 100, '{"resultType": "scalar", "result": [100, "0"]}', [["1970-01-01 00:01:40.000", 0]])
|
|
do_query_test("5 >= bool 5", 100, '{"resultType": "scalar", "result": [100, "1"]}', [["1970-01-01 00:01:40.000", 1]])
|
|
do_query_test("5 >= bool 7", 100, '{"resultType": "scalar", "result": [100, "0"]}', [["1970-01-01 00:01:40.000", 0]])
|
|
do_query_test("5 < bool 7", 100, '{"resultType": "scalar", "result": [100, "1"]}', [["1970-01-01 00:01:40.000", 1]])
|
|
do_query_test("5 < bool 3", 100, '{"resultType": "scalar", "result": [100, "0"]}', [["1970-01-01 00:01:40.000", 0]])
|
|
do_query_test("5 <= bool 5", 100, '{"resultType": "scalar", "result": [100, "1"]}', [["1970-01-01 00:01:40.000", 1]])
|
|
do_query_test("5 <= bool 3", 100, '{"resultType": "scalar", "result": [100, "0"]}', [["1970-01-01 00:01:40.000", 0]])
|
|
|
|
# Compare instant vector with scalar.
|
|
do_query_test(
|
|
"vector(5) == bool 5",
|
|
100,
|
|
'{"resultType": "vector", "result": [{"metric": {}, "value": [100, "1"]}]}',
|
|
[["[]", "1970-01-01 00:01:40.000", 1]],
|
|
)
|
|
|
|
do_query_test(
|
|
"vector(5) == bool 7",
|
|
100,
|
|
'{"resultType": "vector", "result": [{"metric": {}, "value": [100, "0"]}]}',
|
|
[["[]", "1970-01-01 00:01:40.000", 0]],
|
|
)
|
|
|
|
# Compare two instant vectors.
|
|
do_query_test(
|
|
"(foo == bool bar)[50:10]",
|
|
150,
|
|
'{"resultType": "matrix", "result": [{"metric": {"shape": "circle", "size": "l"}, "values": [[110, "0"], [120, "1"], [130, "0"], [140, "0"], [150, "0"]]}, {"metric": {"shape": "square", "size": "s"}, "values": [[110, "0"], [120, "0"], [130, "1"], [140, "0"], [150, "0"]]}]}',
|
|
[
|
|
[
|
|
"[('shape','circle'),('size','l')]",
|
|
"[('1970-01-01 00:01:50.000',0),('1970-01-01 00:02:00.000',1),('1970-01-01 00:02:10.000',0),('1970-01-01 00:02:20.000',0),('1970-01-01 00:02:30.000',0)]",
|
|
],
|
|
[
|
|
"[('shape','square'),('size','s')]",
|
|
"[('1970-01-01 00:01:50.000',0),('1970-01-01 00:02:00.000',0),('1970-01-01 00:02:10.000',1),('1970-01-01 00:02:20.000',0),('1970-01-01 00:02:30.000',0)]",
|
|
],
|
|
],
|
|
)
|
|
|
|
do_query_test(
|
|
"(foo != bool bar)[50:10]",
|
|
150,
|
|
'{"resultType": "matrix", "result": [{"metric": {"shape": "circle", "size": "l"}, "values": [[110, "1"], [120, "0"], [130, "1"], [140, "1"], [150, "1"]]}, {"metric": {"shape": "square", "size": "s"}, "values": [[110, "1"], [120, "1"], [130, "0"], [140, "1"], [150, "1"]]}]}',
|
|
[
|
|
[
|
|
"[('shape','circle'),('size','l')]",
|
|
"[('1970-01-01 00:01:50.000',1),('1970-01-01 00:02:00.000',0),('1970-01-01 00:02:10.000',1),('1970-01-01 00:02:20.000',1),('1970-01-01 00:02:30.000',1)]",
|
|
],
|
|
[
|
|
"[('shape','square'),('size','s')]",
|
|
"[('1970-01-01 00:01:50.000',1),('1970-01-01 00:02:00.000',1),('1970-01-01 00:02:10.000',0),('1970-01-01 00:02:20.000',1),('1970-01-01 00:02:30.000',1)]",
|
|
],
|
|
],
|
|
)
|
|
|
|
do_query_test(
|
|
"(foo > bool bar)[50:10]",
|
|
150,
|
|
'{"resultType": "matrix", "result": [{"metric": {"shape": "circle", "size": "l"}, "values": [[110, "1"], [120, "0"], [130, "0"], [140, "0"], [150, "0"]]}, {"metric": {"shape": "square", "size": "s"}, "values": [[110, "1"], [120, "0"], [130, "0"], [140, "0"], [150, "0"]]}]}',
|
|
[
|
|
[
|
|
"[('shape','circle'),('size','l')]",
|
|
"[('1970-01-01 00:01:50.000',1),('1970-01-01 00:02:00.000',0),('1970-01-01 00:02:10.000',0),('1970-01-01 00:02:20.000',0),('1970-01-01 00:02:30.000',0)]",
|
|
],
|
|
[
|
|
"[('shape','square'),('size','s')]",
|
|
"[('1970-01-01 00:01:50.000',1),('1970-01-01 00:02:00.000',0),('1970-01-01 00:02:10.000',0),('1970-01-01 00:02:20.000',0),('1970-01-01 00:02:30.000',0)]",
|
|
],
|
|
],
|
|
)
|
|
|
|
do_query_test(
|
|
"(foo >= bool bar)[50:10]",
|
|
150,
|
|
'{"resultType": "matrix", "result": [{"metric": {"shape": "circle", "size": "l"}, "values": [[110, "1"], [120, "1"], [130, "0"], [140, "0"], [150, "0"]]}, {"metric": {"shape": "square", "size": "s"}, "values": [[110, "1"], [120, "0"], [130, "1"], [140, "0"], [150, "0"]]}]}',
|
|
[
|
|
[
|
|
"[('shape','circle'),('size','l')]",
|
|
"[('1970-01-01 00:01:50.000',1),('1970-01-01 00:02:00.000',1),('1970-01-01 00:02:10.000',0),('1970-01-01 00:02:20.000',0),('1970-01-01 00:02:30.000',0)]",
|
|
],
|
|
[
|
|
"[('shape','square'),('size','s')]",
|
|
"[('1970-01-01 00:01:50.000',1),('1970-01-01 00:02:00.000',0),('1970-01-01 00:02:10.000',1),('1970-01-01 00:02:20.000',0),('1970-01-01 00:02:30.000',0)]",
|
|
],
|
|
],
|
|
)
|
|
|
|
do_query_test(
|
|
"(foo < bool bar)[50:10]",
|
|
150,
|
|
'{"resultType": "matrix", "result": [{"metric": {"shape": "circle", "size": "l"}, "values": [[110, "0"], [120, "0"], [130, "1"], [140, "1"], [150, "1"]]}, {"metric": {"shape": "square", "size": "s"}, "values": [[110, "0"], [120, "1"], [130, "0"], [140, "1"], [150, "1"]]}]}',
|
|
[
|
|
[
|
|
"[('shape','circle'),('size','l')]",
|
|
"[('1970-01-01 00:01:50.000',0),('1970-01-01 00:02:00.000',0),('1970-01-01 00:02:10.000',1),('1970-01-01 00:02:20.000',1),('1970-01-01 00:02:30.000',1)]",
|
|
],
|
|
[
|
|
"[('shape','square'),('size','s')]",
|
|
"[('1970-01-01 00:01:50.000',0),('1970-01-01 00:02:00.000',1),('1970-01-01 00:02:10.000',0),('1970-01-01 00:02:20.000',1),('1970-01-01 00:02:30.000',1)]",
|
|
],
|
|
],
|
|
)
|
|
|
|
do_query_test(
|
|
"(foo <= bool bar)[50:10]",
|
|
150,
|
|
'{"resultType": "matrix", "result": [{"metric": {"shape": "circle", "size": "l"}, "values": [[110, "0"], [120, "1"], [130, "1"], [140, "1"], [150, "1"]]}, {"metric": {"shape": "square", "size": "s"}, "values": [[110, "0"], [120, "1"], [130, "1"], [140, "1"], [150, "1"]]}]}',
|
|
[
|
|
[
|
|
"[('shape','circle'),('size','l')]",
|
|
"[('1970-01-01 00:01:50.000',0),('1970-01-01 00:02:00.000',1),('1970-01-01 00:02:10.000',1),('1970-01-01 00:02:20.000',1),('1970-01-01 00:02:30.000',1)]",
|
|
],
|
|
[
|
|
"[('shape','square'),('size','s')]",
|
|
"[('1970-01-01 00:01:50.000',0),('1970-01-01 00:02:00.000',1),('1970-01-01 00:02:10.000',1),('1970-01-01 00:02:20.000',1),('1970-01-01 00:02:30.000',1)]",
|
|
],
|
|
],
|
|
)
|
|
|
|
# Use on(shape) to match foo and bar by shape only, ignoring size.
|
|
# This lets foo{shape="triangle",size="m"} match bar{shape="triangle",size="xl"},
|
|
# which don't match by default (different size).
|
|
do_query_test(
|
|
"(foo > bool on(shape) bar)[50:10]",
|
|
150,
|
|
'{"resultType": "matrix", "result": [{"metric": {"shape": "circle"}, "values": [[110, "1"], [120, "0"], [130, "0"], [140, "0"], [150, "0"]]}, {"metric": {"shape": "square"}, "values": [[110, "1"], [120, "0"], [130, "0"], [140, "0"], [150, "0"]]}, {"metric": {"shape": "triangle"}, "values": [[110, "0"], [120, "1"], [130, "1"], [140, "1"], [150, "1"]]}]}',
|
|
[
|
|
[
|
|
"[('shape','circle')]",
|
|
"[('1970-01-01 00:01:50.000',1),('1970-01-01 00:02:00.000',0),('1970-01-01 00:02:10.000',0),('1970-01-01 00:02:20.000',0),('1970-01-01 00:02:30.000',0)]",
|
|
],
|
|
[
|
|
"[('shape','square')]",
|
|
"[('1970-01-01 00:01:50.000',1),('1970-01-01 00:02:00.000',0),('1970-01-01 00:02:10.000',0),('1970-01-01 00:02:20.000',0),('1970-01-01 00:02:30.000',0)]",
|
|
],
|
|
[
|
|
"[('shape','triangle')]",
|
|
"[('1970-01-01 00:01:50.000',0),('1970-01-01 00:02:00.000',1),('1970-01-01 00:02:10.000',1),('1970-01-01 00:02:20.000',1),('1970-01-01 00:02:30.000',1)]",
|
|
],
|
|
],
|
|
)
|
|
|
|
do_query_test(
|
|
"(foo > bool ignoring(size) bar)[50:10]",
|
|
150,
|
|
'{"resultType": "matrix", "result": [{"metric": {"shape": "circle"}, "values": [[110, "1"], [120, "0"], [130, "0"], [140, "0"], [150, "0"]]}, {"metric": {"shape": "square"}, "values": [[110, "1"], [120, "0"], [130, "0"], [140, "0"], [150, "0"]]}, {"metric": {"shape": "triangle"}, "values": [[110, "0"], [120, "1"], [130, "1"], [140, "1"], [150, "1"]]}]}',
|
|
[
|
|
["[('shape','circle')]", "[('1970-01-01 00:01:50.000',1),('1970-01-01 00:02:00.000',0),('1970-01-01 00:02:10.000',0),('1970-01-01 00:02:20.000',0),('1970-01-01 00:02:30.000',0)]"],
|
|
["[('shape','square')]", "[('1970-01-01 00:01:50.000',1),('1970-01-01 00:02:00.000',0),('1970-01-01 00:02:10.000',0),('1970-01-01 00:02:20.000',0),('1970-01-01 00:02:30.000',0)]"],
|
|
["[('shape','triangle')]", "[('1970-01-01 00:01:50.000',0),('1970-01-01 00:02:00.000',1),('1970-01-01 00:02:10.000',1),('1970-01-01 00:02:20.000',1),('1970-01-01 00:02:30.000',1)]"],
|
|
],
|
|
)
|
|
|
|
# Use on(size) group_right to allow 1:many matching: size="l" has one foo (circle) but two bars
|
|
# (circle and rectangle), which requires group_right.
|
|
do_query_test(
|
|
"(foo >= bool on(size) group_right bar)[50:10]",
|
|
150,
|
|
'{"resultType": "matrix", "result": [{"metric": {"shape": "circle", "size": "l"}, "values": [[110, "1"], [120, "1"], [130, "0"], [140, "0"], [150, "0"]]}, {"metric": {"shape": "rectangle", "size": "l"}, "values": [[110, "1"], [120, "1"], [130, "0"], [140, "0"], [150, "0"]]}, {"metric": {"shape": "square", "size": "s"}, "values": [[110, "1"], [120, "0"], [130, "1"], [140, "0"], [150, "0"]]}]}',
|
|
[
|
|
[
|
|
"[('shape','circle'),('size','l')]",
|
|
"[('1970-01-01 00:01:50.000',1),('1970-01-01 00:02:00.000',1),('1970-01-01 00:02:10.000',0),('1970-01-01 00:02:20.000',0),('1970-01-01 00:02:30.000',0)]",
|
|
],
|
|
[
|
|
"[('shape','rectangle'),('size','l')]",
|
|
"[('1970-01-01 00:01:50.000',1),('1970-01-01 00:02:00.000',1),('1970-01-01 00:02:10.000',0),('1970-01-01 00:02:20.000',0),('1970-01-01 00:02:30.000',0)]",
|
|
],
|
|
[
|
|
"[('shape','square'),('size','s')]",
|
|
"[('1970-01-01 00:01:50.000',1),('1970-01-01 00:02:00.000',0),('1970-01-01 00:02:10.000',1),('1970-01-01 00:02:20.000',0),('1970-01-01 00:02:30.000',0)]",
|
|
],
|
|
],
|
|
)
|
|
|
|
# group_right(__name__) with bool: bool always drops __name__ unconditionally,
|
|
# so __name__ in group_right(__name__) is ignored.
|
|
do_query_test(
|
|
"(foo >= bool on(size) group_right(__name__) bar)[50:10]",
|
|
150,
|
|
'{"resultType": "matrix", "result": [{"metric": {"shape": "circle", "size": "l"}, "values": [[110, "1"], [120, "1"], [130, "0"], [140, "0"], [150, "0"]]}, {"metric": {"shape": "rectangle", "size": "l"}, "values": [[110, "1"], [120, "1"], [130, "0"], [140, "0"], [150, "0"]]}, {"metric": {"shape": "square", "size": "s"}, "values": [[110, "1"], [120, "0"], [130, "1"], [140, "0"], [150, "0"]]}]}',
|
|
[
|
|
[
|
|
"[('shape','circle'),('size','l')]",
|
|
"[('1970-01-01 00:01:50.000',1),('1970-01-01 00:02:00.000',1),('1970-01-01 00:02:10.000',0),('1970-01-01 00:02:20.000',0),('1970-01-01 00:02:30.000',0)]",
|
|
],
|
|
[
|
|
"[('shape','rectangle'),('size','l')]",
|
|
"[('1970-01-01 00:01:50.000',1),('1970-01-01 00:02:00.000',1),('1970-01-01 00:02:10.000',0),('1970-01-01 00:02:20.000',0),('1970-01-01 00:02:30.000',0)]",
|
|
],
|
|
[
|
|
"[('shape','square'),('size','s')]",
|
|
"[('1970-01-01 00:01:50.000',1),('1970-01-01 00:02:00.000',0),('1970-01-01 00:02:10.000',1),('1970-01-01 00:02:20.000',0),('1970-01-01 00:02:30.000',0)]",
|
|
],
|
|
],
|
|
)
|
|
|
|
# on(__name__, shape) uses __name__ as part of the join key.
|
|
# With bool modifier __name__ is dropped from the result, so the result group is just {shape}.
|
|
do_query_test(
|
|
'({__name__=~"foo|bar"} == bool on(__name__, shape) bar)[50:10]',
|
|
150,
|
|
'{"resultType": "matrix", "result": [{"metric": {"shape": "circle"}, "values": [[110, "1"], [120, "1"], [130, "1"], [140, "1"], [150, "1"]]}, {"metric": {"shape": "rectangle"}, "values": [[110, "1"], [120, "1"], [130, "1"], [140, "1"], [150, "1"]]}, {"metric": {"shape": "square"}, "values": [[110, "1"], [120, "1"], [130, "1"], [140, "1"], [150, "1"]]}, {"metric": {"shape": "triangle"}, "values": [[110, "1"], [120, "1"], [130, "1"], [140, "1"], [150, "1"]]}]}',
|
|
[
|
|
["[('shape','circle')]", "[('1970-01-01 00:01:50.000',1),('1970-01-01 00:02:00.000',1),('1970-01-01 00:02:10.000',1),('1970-01-01 00:02:20.000',1),('1970-01-01 00:02:30.000',1)]"],
|
|
["[('shape','rectangle')]", "[('1970-01-01 00:01:50.000',1),('1970-01-01 00:02:00.000',1),('1970-01-01 00:02:10.000',1),('1970-01-01 00:02:20.000',1),('1970-01-01 00:02:30.000',1)]"],
|
|
["[('shape','square')]", "[('1970-01-01 00:01:50.000',1),('1970-01-01 00:02:00.000',1),('1970-01-01 00:02:10.000',1),('1970-01-01 00:02:20.000',1),('1970-01-01 00:02:30.000',1)]"],
|
|
["[('shape','triangle')]", "[('1970-01-01 00:01:50.000',1),('1970-01-01 00:02:00.000',1),('1970-01-01 00:02:10.000',1),('1970-01-01 00:02:20.000',1),('1970-01-01 00:02:30.000',1)]"],
|
|
],
|
|
)
|
|
|
|
|
|
def test_comparison_operators():
|
|
# Compare instant vector with scalar (filter mode): keeps left values where condition is true.
|
|
do_query_test(
|
|
"(foo == 4)[50:10]",
|
|
150,
|
|
'{"resultType": "matrix", "result": [{"metric": {"__name__": "foo", "shape": "square", "size": "s"}, "values": [[110, "4"], [120, "4"]]}]}',
|
|
[["[('__name__','foo'),('shape','square'),('size','s')]", "[('1970-01-01 00:01:50.000',4),('1970-01-01 00:02:00.000',4)]"]],
|
|
)
|
|
|
|
do_query_test(
|
|
"(foo < 10)[50:10]",
|
|
150,
|
|
'{"resultType": "matrix", "result": [{"metric": {"__name__": "foo", "shape": "square", "size": "s"}, "values": [[110, "4"], [120, "4"]]}, {"metric": {"__name__": "foo", "shape": "triangle", "size": "m"}, "values": [[110, "8"]]}]}',
|
|
[
|
|
[
|
|
"[('__name__','foo'),('shape','square'),('size','s')]",
|
|
"[('1970-01-01 00:01:50.000',4),('1970-01-01 00:02:00.000',4)]",
|
|
],
|
|
[
|
|
"[('__name__','foo'),('shape','triangle'),('size','m')]",
|
|
"[('1970-01-01 00:01:50.000',8)]",
|
|
],
|
|
],
|
|
)
|
|
|
|
# Compare scalar with instant vector (filter mode): keeps right values where condition is true.
|
|
do_query_test(
|
|
"(8 >= bar)[50:10]",
|
|
150,
|
|
'{"resultType": "matrix", "result": [{"metric": {"__name__": "bar", "shape": "square", "size": "s"}, "values": [[110, "3"]]}, {"metric": {"__name__": "bar", "shape": "triangle", "size": "xl"}, "values": [[110, "8"], [120, "8"], [130, "8"], [140, "8"]]}]}',
|
|
[
|
|
[
|
|
"[('__name__','bar'),('shape','square'),('size','s')]",
|
|
"[('1970-01-01 00:01:50.000',3)]",
|
|
],
|
|
[
|
|
"[('__name__','bar'),('shape','triangle'),('size','xl')]",
|
|
"[('1970-01-01 00:01:50.000',8),('1970-01-01 00:02:00.000',8),('1970-01-01 00:02:10.000',8),('1970-01-01 00:02:20.000',8)]",
|
|
],
|
|
],
|
|
)
|
|
|
|
# Compare two instant vectors.
|
|
do_query_test(
|
|
"(foo == bar)[50:10]",
|
|
150,
|
|
'{"resultType": "matrix", "result": [{"metric": {"__name__": "foo", "shape": "circle", "size": "l"}, "values": [[120, "16"]]}, {"metric": {"__name__": "foo", "shape": "square", "size": "s"}, "values": [[130, "40"]]}]}',
|
|
[
|
|
[
|
|
"[('__name__','foo'),('shape','circle'),('size','l')]",
|
|
"[('1970-01-01 00:02:00.000',16)]",
|
|
],
|
|
[
|
|
"[('__name__','foo'),('shape','square'),('size','s')]",
|
|
"[('1970-01-01 00:02:10.000',40)]",
|
|
],
|
|
],
|
|
)
|
|
|
|
do_query_test(
|
|
"(foo != bar)[50:10]",
|
|
150,
|
|
'{"resultType": "matrix", "result": [{"metric": {"__name__": "foo", "shape": "circle", "size": "l"}, "values": [[110, "16"], [130, "16"], [140, "16"], [150, "16"]]}, {"metric": {"__name__": "foo", "shape": "square", "size": "s"}, "values": [[110, "4"], [120, "4"], [140, "40"], [150, "40"]]}]}',
|
|
[
|
|
[
|
|
"[('__name__','foo'),('shape','circle'),('size','l')]",
|
|
"[('1970-01-01 00:01:50.000',16),('1970-01-01 00:02:10.000',16),('1970-01-01 00:02:20.000',16),('1970-01-01 00:02:30.000',16)]",
|
|
],
|
|
[
|
|
"[('__name__','foo'),('shape','square'),('size','s')]",
|
|
"[('1970-01-01 00:01:50.000',4),('1970-01-01 00:02:00.000',4),('1970-01-01 00:02:20.000',40),('1970-01-01 00:02:30.000',40)]",
|
|
],
|
|
],
|
|
)
|
|
|
|
do_query_test(
|
|
"(foo > bar)[50:10]",
|
|
150,
|
|
'{"resultType": "matrix", "result": [{"metric": {"__name__": "foo", "shape": "circle", "size": "l"}, "values": [[110, "16"]]}, {"metric": {"__name__": "foo", "shape": "square", "size": "s"}, "values": [[110, "4"]]}]}',
|
|
[
|
|
[
|
|
"[('__name__','foo'),('shape','circle'),('size','l')]",
|
|
"[('1970-01-01 00:01:50.000',16)]",
|
|
],
|
|
[
|
|
"[('__name__','foo'),('shape','square'),('size','s')]",
|
|
"[('1970-01-01 00:01:50.000',4)]",
|
|
],
|
|
],
|
|
)
|
|
|
|
do_query_test(
|
|
"(foo >= bar)[50:10]",
|
|
150,
|
|
'{"resultType": "matrix", "result": [{"metric": {"__name__": "foo", "shape": "circle", "size": "l"}, "values": [[110, "16"], [120, "16"]]}, {"metric": {"__name__": "foo", "shape": "square", "size": "s"}, "values": [[110, "4"], [130, "40"]]}]}',
|
|
[
|
|
[
|
|
"[('__name__','foo'),('shape','circle'),('size','l')]",
|
|
"[('1970-01-01 00:01:50.000',16),('1970-01-01 00:02:00.000',16)]",
|
|
],
|
|
[
|
|
"[('__name__','foo'),('shape','square'),('size','s')]",
|
|
"[('1970-01-01 00:01:50.000',4),('1970-01-01 00:02:10.000',40)]",
|
|
],
|
|
],
|
|
)
|
|
|
|
do_query_test(
|
|
"(foo < bar)[50:10]",
|
|
150,
|
|
'{"resultType": "matrix", "result": [{"metric": {"__name__": "foo", "shape": "circle", "size": "l"}, "values": [[130, "16"], [140, "16"], [150, "16"]]}, {"metric": {"__name__": "foo", "shape": "square", "size": "s"}, "values": [[120, "4"], [140, "40"], [150, "40"]]}]}',
|
|
[
|
|
[
|
|
"[('__name__','foo'),('shape','circle'),('size','l')]",
|
|
"[('1970-01-01 00:02:10.000',16),('1970-01-01 00:02:20.000',16),('1970-01-01 00:02:30.000',16)]",
|
|
],
|
|
[
|
|
"[('__name__','foo'),('shape','square'),('size','s')]",
|
|
"[('1970-01-01 00:02:00.000',4),('1970-01-01 00:02:20.000',40),('1970-01-01 00:02:30.000',40)]",
|
|
],
|
|
],
|
|
)
|
|
|
|
do_query_test(
|
|
"(foo <= bar)[50:10]",
|
|
150,
|
|
'{"resultType": "matrix", "result": [{"metric": {"__name__": "foo", "shape": "circle", "size": "l"}, "values": [[120, "16"], [130, "16"], [140, "16"], [150, "16"]]}, {"metric": {"__name__": "foo", "shape": "square", "size": "s"}, "values": [[120, "4"], [130, "40"], [140, "40"], [150, "40"]]}]}',
|
|
[
|
|
[
|
|
"[('__name__','foo'),('shape','circle'),('size','l')]",
|
|
"[('1970-01-01 00:02:00.000',16),('1970-01-01 00:02:10.000',16),('1970-01-01 00:02:20.000',16),('1970-01-01 00:02:30.000',16)]",
|
|
],
|
|
[
|
|
"[('__name__','foo'),('shape','square'),('size','s')]",
|
|
"[('1970-01-01 00:02:00.000',4),('1970-01-01 00:02:10.000',40),('1970-01-01 00:02:20.000',40),('1970-01-01 00:02:30.000',40)]",
|
|
],
|
|
],
|
|
)
|
|
|
|
# Use on(shape) to match foo and bar by shape only, ignoring size.
|
|
# This lets foo{shape="triangle",size="m"} match bar{shape="triangle",size="xl"},
|
|
# which don't match by default.
|
|
do_query_test(
|
|
"(foo > on(shape) bar)[50:10]",
|
|
150,
|
|
'{"resultType": "matrix", "result": [{"metric": {"shape": "circle"}, "values": [[110, "16"]]}, {"metric": {"shape": "square"}, "values": [[110, "4"]]}, {"metric": {"shape": "triangle"}, "values": [[120, "80"], [130, "80"], [140, "80"], [150, "80"]]}]}',
|
|
[
|
|
["[('shape','circle')]", "[('1970-01-01 00:01:50.000',16)]"],
|
|
["[('shape','square')]", "[('1970-01-01 00:01:50.000',4)]"],
|
|
["[('shape','triangle')]", "[('1970-01-01 00:02:00.000',80),('1970-01-01 00:02:10.000',80),('1970-01-01 00:02:20.000',80),('1970-01-01 00:02:30.000',80)]"],
|
|
],
|
|
)
|
|
|
|
do_query_test(
|
|
"(foo > ignoring(size) bar)[50:10]",
|
|
150,
|
|
'{"resultType": "matrix", "result": [{"metric": {"__name__": "foo", "shape": "circle"}, "values": [[110, "16"]]}, {"metric": {"__name__": "foo", "shape": "square"}, "values": [[110, "4"]]}, {"metric": {"__name__": "foo", "shape": "triangle"}, "values": [[120, "80"], [130, "80"], [140, "80"], [150, "80"]]}]}',
|
|
[
|
|
["[('__name__','foo'),('shape','circle')]", "[('1970-01-01 00:01:50.000',16)]"],
|
|
["[('__name__','foo'),('shape','square')]", "[('1970-01-01 00:01:50.000',4)]"],
|
|
["[('__name__','foo'),('shape','triangle')]", "[('1970-01-01 00:02:00.000',80),('1970-01-01 00:02:10.000',80),('1970-01-01 00:02:20.000',80),('1970-01-01 00:02:30.000',80)]"],
|
|
],
|
|
)
|
|
|
|
# Use on(size) group_right: size="l" has one foo (circle) but two bars (circle and rectangle).
|
|
do_query_test(
|
|
"(foo >= on(size) group_right bar)[50:10]",
|
|
150,
|
|
'{"resultType": "matrix", "result": [{"metric": {"__name__": "bar", "shape": "circle", "size": "l"}, "values": [[110, "16"], [120, "16"]]}, {"metric": {"__name__": "bar", "shape": "rectangle", "size": "l"}, "values": [[110, "16"], [120, "16"]]}, {"metric": {"__name__": "bar", "shape": "square", "size": "s"}, "values": [[110, "4"], [130, "40"]]}]}',
|
|
[
|
|
[
|
|
"[('__name__','bar'),('shape','circle'),('size','l')]",
|
|
"[('1970-01-01 00:01:50.000',16),('1970-01-01 00:02:00.000',16)]",
|
|
],
|
|
[
|
|
"[('__name__','bar'),('shape','rectangle'),('size','l')]",
|
|
"[('1970-01-01 00:01:50.000',16),('1970-01-01 00:02:00.000',16)]",
|
|
],
|
|
[
|
|
"[('__name__','bar'),('shape','square'),('size','s')]",
|
|
"[('1970-01-01 00:01:50.000',4),('1970-01-01 00:02:10.000',40)]",
|
|
],
|
|
],
|
|
)
|
|
|
|
# group_right(__name__) copies __name__ from the one side (foo) into the result group,
|
|
# replacing bar's __name__
|
|
do_query_test(
|
|
"(foo >= on(size) group_right(__name__) bar)[50:10]",
|
|
150,
|
|
'{"resultType": "matrix", "result": [{"metric": {"__name__": "foo", "shape": "circle", "size": "l"}, "values": [[110, "16"], [120, "16"]]}, {"metric": {"__name__": "foo", "shape": "rectangle", "size": "l"}, "values": [[110, "16"], [120, "16"]]}, {"metric": {"__name__": "foo", "shape": "square", "size": "s"}, "values": [[110, "4"], [130, "40"]]}]}',
|
|
[
|
|
[
|
|
"[('__name__','foo'),('shape','circle'),('size','l')]",
|
|
"[('1970-01-01 00:01:50.000',16),('1970-01-01 00:02:00.000',16)]",
|
|
],
|
|
[
|
|
"[('__name__','foo'),('shape','rectangle'),('size','l')]",
|
|
"[('1970-01-01 00:01:50.000',16),('1970-01-01 00:02:00.000',16)]",
|
|
],
|
|
[
|
|
"[('__name__','foo'),('shape','square'),('size','s')]",
|
|
"[('1970-01-01 00:01:50.000',4),('1970-01-01 00:02:10.000',40)]",
|
|
],
|
|
],
|
|
)
|
|
|
|
# on(__name__, shape) uses __name__ as part of the join key.
|
|
# In filter mode __name__ is preserved in the result, so the result group is {__name__, shape}.
|
|
do_query_test(
|
|
'({__name__=~"foo|bar"} == on(__name__, shape) bar)[50:10]',
|
|
150,
|
|
'{"resultType": "matrix", "result": [{"metric": {"__name__": "bar", "shape": "circle"}, "values": [[110, "10"], [120, "16"], [130, "50"], [140, "50"], [150, "1000"]]}, {"metric": {"__name__": "bar", "shape": "rectangle"}, "values": [[110, "9"], [120, "9"], [130, "90"], [140, "90"], [150, "90"]]}, {"metric": {"__name__": "bar", "shape": "square"}, "values": [[110, "3"], [120, "40"], [130, "40"], [140, "700"], [150, "700"]]}, {"metric": {"__name__": "bar", "shape": "triangle"}, "values": [[110, "8"], [120, "8"], [130, "8"], [140, "8"], [150, "30"]]}]}',
|
|
[
|
|
["[('__name__','bar'),('shape','circle')]", "[('1970-01-01 00:01:50.000',10),('1970-01-01 00:02:00.000',16),('1970-01-01 00:02:10.000',50),('1970-01-01 00:02:20.000',50),('1970-01-01 00:02:30.000',1000)]"],
|
|
["[('__name__','bar'),('shape','rectangle')]", "[('1970-01-01 00:01:50.000',9),('1970-01-01 00:02:00.000',9),('1970-01-01 00:02:10.000',90),('1970-01-01 00:02:20.000',90),('1970-01-01 00:02:30.000',90)]"],
|
|
["[('__name__','bar'),('shape','square')]", "[('1970-01-01 00:01:50.000',3),('1970-01-01 00:02:00.000',40),('1970-01-01 00:02:10.000',40),('1970-01-01 00:02:20.000',700),('1970-01-01 00:02:30.000',700)]"],
|
|
["[('__name__','bar'),('shape','triangle')]", "[('1970-01-01 00:01:50.000',8),('1970-01-01 00:02:00.000',8),('1970-01-01 00:02:10.000',8),('1970-01-01 00:02:20.000',8),('1970-01-01 00:02:30.000',30)]"],
|
|
],
|
|
)
|
|
|
|
|
|
def test_set_binary_operators():
|
|
do_query_test(
|
|
"(last_over_time(foo[10]) and last_over_time(bar[10]))[50:10]",
|
|
150,
|
|
'{"resultType": "matrix", "result": [{"metric": {"__name__": "foo", "shape": "circle", "size": "l"}, "values": [[110, "16"], [130, "16"], [150, "16"]]}, {"metric": {"__name__": "foo", "shape": "square", "size": "s"}, "values": [[110, "4"]]}]}',
|
|
[
|
|
[
|
|
"[('__name__','foo'),('shape','circle'),('size','l')]",
|
|
"[('1970-01-01 00:01:50.000',16),('1970-01-01 00:02:10.000',16),('1970-01-01 00:02:30.000',16)]",
|
|
],
|
|
[
|
|
"[('__name__','foo'),('shape','square'),('size','s')]",
|
|
"[('1970-01-01 00:01:50.000',4)]",
|
|
],
|
|
],
|
|
)
|
|
|
|
do_query_test(
|
|
"(last_over_time(foo[10]) unless last_over_time(bar[10]))[50:10]",
|
|
150,
|
|
'{"resultType": "matrix", "result": [{"metric": {"__name__": "foo", "shape": "square", "size": "s"}, "values": [[130, "40"]]}, {"metric": {"__name__": "foo", "shape": "triangle", "size": "m"}, "values": [[110, "8"], [120, "80"]]}]}',
|
|
[
|
|
[
|
|
"[('__name__','foo'),('shape','square'),('size','s')]",
|
|
"[('1970-01-01 00:02:10.000',40)]",
|
|
],
|
|
[
|
|
"[('__name__','foo'),('shape','triangle'),('size','m')]",
|
|
"[('1970-01-01 00:01:50.000',8),('1970-01-01 00:02:00.000',80)]",
|
|
],
|
|
],
|
|
)
|
|
|
|
do_query_test(
|
|
"(last_over_time(foo[10]) or last_over_time(bar[10]))[50:10]",
|
|
150,
|
|
'{"resultType": "matrix", "result": [{"metric": {"__name__": "bar", "shape": "circle", "size": "l"}, "values": [[120, "16"]]}, {"metric": {"__name__": "bar", "shape": "rectangle", "size": "l"}, "values": [[110, "9"], [130, "90"]]}, {"metric": {"__name__": "bar", "shape": "square", "size": "s"}, "values": [[120, "40"], [140, "700"]]}, {"metric": {"__name__": "bar", "shape": "triangle", "size": "xl"}, "values": [[110, "8"], [150, "30"]]}, {"metric": {"__name__": "foo", "shape": "circle", "size": "l"}, "values": [[110, "16"], [130, "16"], [150, "16"]]}, {"metric": {"__name__": "foo", "shape": "square", "size": "s"}, "values": [[110, "4"], [130, "40"]]}, {"metric": {"__name__": "foo", "shape": "triangle", "size": "m"}, "values": [[110, "8"], [120, "80"]]}]}',
|
|
[
|
|
[
|
|
"[('__name__','bar'),('shape','circle'),('size','l')]",
|
|
"[('1970-01-01 00:02:00.000',16)]",
|
|
],
|
|
[
|
|
"[('__name__','bar'),('shape','rectangle'),('size','l')]",
|
|
"[('1970-01-01 00:01:50.000',9),('1970-01-01 00:02:10.000',90)]",
|
|
],
|
|
[
|
|
"[('__name__','bar'),('shape','square'),('size','s')]",
|
|
"[('1970-01-01 00:02:00.000',40),('1970-01-01 00:02:20.000',700)]",
|
|
],
|
|
[
|
|
"[('__name__','bar'),('shape','triangle'),('size','xl')]",
|
|
"[('1970-01-01 00:01:50.000',8),('1970-01-01 00:02:30.000',30)]",
|
|
],
|
|
[
|
|
"[('__name__','foo'),('shape','circle'),('size','l')]",
|
|
"[('1970-01-01 00:01:50.000',16),('1970-01-01 00:02:10.000',16),('1970-01-01 00:02:30.000',16)]",
|
|
],
|
|
[
|
|
"[('__name__','foo'),('shape','square'),('size','s')]",
|
|
"[('1970-01-01 00:01:50.000',4),('1970-01-01 00:02:10.000',40)]",
|
|
],
|
|
[
|
|
"[('__name__','foo'),('shape','triangle'),('size','m')]",
|
|
"[('1970-01-01 00:01:50.000',8),('1970-01-01 00:02:00.000',80)]",
|
|
],
|
|
],
|
|
)
|
|
|
|
do_query_test(
|
|
"(last_over_time(foo[10]) and on(shape) last_over_time(bar[10]))[50:10]",
|
|
150,
|
|
'{"resultType": "matrix", "result": [{"metric": {"__name__": "foo", "shape": "circle", "size": "l"}, "values": [[110, "16"], [130, "16"], [150, "16"]]}, {"metric": {"__name__": "foo", "shape": "square", "size": "s"}, "values": [[110, "4"]]}, {"metric": {"__name__": "foo", "shape": "triangle", "size": "m"}, "values": [[110, "8"]]}]}',
|
|
[
|
|
[
|
|
"[('__name__','foo'),('shape','circle'),('size','l')]",
|
|
"[('1970-01-01 00:01:50.000',16),('1970-01-01 00:02:10.000',16),('1970-01-01 00:02:30.000',16)]",
|
|
],
|
|
[
|
|
"[('__name__','foo'),('shape','square'),('size','s')]",
|
|
"[('1970-01-01 00:01:50.000',4)]",
|
|
],
|
|
[
|
|
"[('__name__','foo'),('shape','triangle'),('size','m')]",
|
|
"[('1970-01-01 00:01:50.000',8)]",
|
|
],
|
|
],
|
|
)
|
|
|
|
do_query_test(
|
|
"(last_over_time(foo[10]) unless ignoring(size) last_over_time(bar[10]))[50:10]",
|
|
150,
|
|
'{"resultType": "matrix", "result": [{"metric": {"__name__": "foo", "shape": "square", "size": "s"}, "values": [[130, "40"]]}, {"metric": {"__name__": "foo", "shape": "triangle", "size": "m"}, "values": [[120, "80"]]}]}',
|
|
[
|
|
[
|
|
"[('__name__','foo'),('shape','square'),('size','s')]",
|
|
"[('1970-01-01 00:02:10.000',40)]",
|
|
],
|
|
[
|
|
"[('__name__','foo'),('shape','triangle'),('size','m')]",
|
|
"[('1970-01-01 00:02:00.000',80)]",
|
|
],
|
|
],
|
|
)
|
|
|
|
do_query_test(
|
|
"(last_over_time(foo[10]) or on(shape) last_over_time(bar[10]))[50:10]",
|
|
150,
|
|
'{"resultType": "matrix", "result": [{"metric": {"__name__": "bar", "shape": "circle", "size": "l"}, "values": [[120, "16"]]}, {"metric": {"__name__": "bar", "shape": "rectangle", "size": "l"}, "values": [[110, "9"], [130, "90"]]}, {"metric": {"__name__": "bar", "shape": "square", "size": "s"}, "values": [[120, "40"], [140, "700"]]}, {"metric": {"__name__": "bar", "shape": "triangle", "size": "xl"}, "values": [[150, "30"]]}, {"metric": {"__name__": "foo", "shape": "circle", "size": "l"}, "values": [[110, "16"], [130, "16"], [150, "16"]]}, {"metric": {"__name__": "foo", "shape": "square", "size": "s"}, "values": [[110, "4"], [130, "40"]]}, {"metric": {"__name__": "foo", "shape": "triangle", "size": "m"}, "values": [[110, "8"], [120, "80"]]}]}',
|
|
[
|
|
[
|
|
"[('__name__','bar'),('shape','circle'),('size','l')]",
|
|
"[('1970-01-01 00:02:00.000',16)]",
|
|
],
|
|
[
|
|
"[('__name__','bar'),('shape','rectangle'),('size','l')]",
|
|
"[('1970-01-01 00:01:50.000',9),('1970-01-01 00:02:10.000',90)]",
|
|
],
|
|
[
|
|
"[('__name__','bar'),('shape','square'),('size','s')]",
|
|
"[('1970-01-01 00:02:00.000',40),('1970-01-01 00:02:20.000',700)]",
|
|
],
|
|
[
|
|
"[('__name__','bar'),('shape','triangle'),('size','xl')]",
|
|
"[('1970-01-01 00:02:30.000',30)]",
|
|
],
|
|
[
|
|
"[('__name__','foo'),('shape','circle'),('size','l')]",
|
|
"[('1970-01-01 00:01:50.000',16),('1970-01-01 00:02:10.000',16),('1970-01-01 00:02:30.000',16)]",
|
|
],
|
|
[
|
|
"[('__name__','foo'),('shape','square'),('size','s')]",
|
|
"[('1970-01-01 00:01:50.000',4),('1970-01-01 00:02:10.000',40)]",
|
|
],
|
|
[
|
|
"[('__name__','foo'),('shape','triangle'),('size','m')]",
|
|
"[('1970-01-01 00:01:50.000',8),('1970-01-01 00:02:00.000',80)]",
|
|
],
|
|
],
|
|
)
|
|
|
|
# The result of `(foo > 10) or foo` must be exactly `foo`.
|
|
do_query_test(
|
|
"((last_over_time(foo[10]) > 10) or last_over_time(foo[10]))[50:10]",
|
|
150,
|
|
'{"resultType": "matrix", "result": [{"metric": {"__name__": "foo", "shape": "circle", "size": "l"}, "values": [[110, "16"], [130, "16"], [150, "16"]]}, {"metric": {"__name__": "foo", "shape": "square", "size": "s"}, "values": [[110, "4"], [130, "40"]]}, {"metric": {"__name__": "foo", "shape": "triangle", "size": "m"}, "values": [[110, "8"], [120, "80"]]}]}',
|
|
[
|
|
[
|
|
"[('__name__','foo'),('shape','circle'),('size','l')]",
|
|
"[('1970-01-01 00:01:50.000',16),('1970-01-01 00:02:10.000',16),('1970-01-01 00:02:30.000',16)]",
|
|
],
|
|
[
|
|
"[('__name__','foo'),('shape','square'),('size','s')]",
|
|
"[('1970-01-01 00:01:50.000',4),('1970-01-01 00:02:10.000',40)]",
|
|
],
|
|
[
|
|
"[('__name__','foo'),('shape','triangle'),('size','m')]",
|
|
"[('1970-01-01 00:01:50.000',8),('1970-01-01 00:02:00.000',80)]",
|
|
],
|
|
],
|
|
)
|
|
|
|
# Here bar(rectangle,l) shares {size=l} with the foo(circle,l) / bar(circle,l) pair and
|
|
# must still appear at the steps where the original foo(circle,l) was filtered to NULL.
|
|
# And "+ 0" is used here to drop the metric name.
|
|
do_query_test(
|
|
"((last_over_time(foo[10]) > 20) + 0 or on(size) (last_over_time(bar[10]) + 0))[50:10]",
|
|
150,
|
|
'{"resultType": "matrix", "result": [{"metric": {"shape": "circle", "size": "l"}, "values": [[110, "10"], [120, "16"], [130, "50"], [150, "1000"]]}, {"metric": {"shape": "rectangle", "size": "l"}, "values": [[110, "9"], [130, "90"]]}, {"metric": {"shape": "square", "size": "s"}, "values": [[110, "3"], [120, "40"], [130, "40"], [140, "700"]]}, {"metric": {"shape": "triangle", "size": "m"}, "values": [[120, "80"]]}, {"metric": {"shape": "triangle", "size": "xl"}, "values": [[110, "8"], [150, "30"]]}]}',
|
|
[
|
|
[
|
|
"[('shape','circle'),('size','l')]",
|
|
"[('1970-01-01 00:01:50.000',10),('1970-01-01 00:02:00.000',16),('1970-01-01 00:02:10.000',50),('1970-01-01 00:02:30.000',1000)]",
|
|
],
|
|
[
|
|
"[('shape','rectangle'),('size','l')]",
|
|
"[('1970-01-01 00:01:50.000',9),('1970-01-01 00:02:10.000',90)]",
|
|
],
|
|
[
|
|
"[('shape','square'),('size','s')]",
|
|
"[('1970-01-01 00:01:50.000',3),('1970-01-01 00:02:00.000',40),('1970-01-01 00:02:10.000',40),('1970-01-01 00:02:20.000',700)]",
|
|
],
|
|
[
|
|
"[('shape','triangle'),('size','m')]",
|
|
"[('1970-01-01 00:02:00.000',80)]",
|
|
],
|
|
[
|
|
"[('shape','triangle'),('size','xl')]",
|
|
"[('1970-01-01 00:01:50.000',8),('1970-01-01 00:02:30.000',30)]",
|
|
],
|
|
],
|
|
)
|
|
|
|
# Here bar(rectangle,l) on the left at t=130 covers {size=l},
|
|
# so right "(circle,l)=50" at t=130 must be suppressed even though left (circle,l) is NULL there.
|
|
# And "+ 0" is used here to drop the metric name.
|
|
do_query_test(
|
|
"((last_over_time(bar[10]) > 50) + 0 or on(size) (last_over_time(bar[10]) + 0))[50:10]",
|
|
150,
|
|
'{"resultType": "matrix", "result": [{"metric": {"shape": "circle", "size": "l"}, "values": [[110, "10"], [120, "16"], [150, "1000"]]}, {"metric": {"shape": "rectangle", "size": "l"}, "values": [[110, "9"], [130, "90"]]}, {"metric": {"shape": "square", "size": "s"}, "values": [[110, "3"], [120, "40"], [140, "700"]]}, {"metric": {"shape": "triangle", "size": "xl"}, "values": [[110, "8"], [150, "30"]]}]}',
|
|
[
|
|
[
|
|
"[('shape','circle'),('size','l')]",
|
|
"[('1970-01-01 00:01:50.000',10),('1970-01-01 00:02:00.000',16),('1970-01-01 00:02:30.000',1000)]",
|
|
],
|
|
[
|
|
"[('shape','rectangle'),('size','l')]",
|
|
"[('1970-01-01 00:01:50.000',9),('1970-01-01 00:02:10.000',90)]",
|
|
],
|
|
[
|
|
"[('shape','square'),('size','s')]",
|
|
"[('1970-01-01 00:01:50.000',3),('1970-01-01 00:02:00.000',40),('1970-01-01 00:02:20.000',700)]",
|
|
],
|
|
[
|
|
"[('shape','triangle'),('size','xl')]",
|
|
"[('1970-01-01 00:01:50.000',8),('1970-01-01 00:02:30.000',30)]",
|
|
],
|
|
],
|
|
)
|
|
|
|
do_query_test_expect_error(
|
|
"last_over_time(foo[10]) and on(shape) group_left last_over_time(bar[10])",
|
|
150,
|
|
"no grouping allowed",
|
|
"Binary operator 'and' doesn't allow group_left",
|
|
)
|
|
|
|
do_query_test_expect_error(
|
|
"last_over_time(foo[10]) or ignoring(size) group_right last_over_time(bar[10])",
|
|
150,
|
|
"no grouping allowed",
|
|
"Binary operator 'or' doesn't allow group_right",
|
|
)
|
|
|
|
|
|
def test_aggregation_operators():
|
|
do_query_test(
|
|
"sum(bar)",
|
|
120,
|
|
'{"resultType": "vector", "result": [{"metric": {}, "value": [120, "73"]}]}',
|
|
[["[]", "1970-01-01 00:02:00.000", 73]],
|
|
)
|
|
|
|
do_query_test(
|
|
"sum(last_over_time(bar[10]))[50:10]",
|
|
150,
|
|
'{"resultType": "matrix", "result": [{"metric": {}, "values": [[110, "30"], [120, "56"], [130, "140"], [140, "700"], [150, "1030"]]}]}',
|
|
[["[]", "[('1970-01-01 00:01:50.000',30),('1970-01-01 00:02:00.000',56),('1970-01-01 00:02:10.000',140),('1970-01-01 00:02:20.000',700),('1970-01-01 00:02:30.000',1030)]"]],
|
|
)
|
|
|
|
do_query_test(
|
|
"sum(nonexistent_metric_name)[50:10]",
|
|
150,
|
|
'{"resultType": "matrix", "result": []}',
|
|
[],
|
|
)
|
|
|
|
# FIXME: Not deterministic without sort_by_label(), and function sort_by_label() is not implemented yet.
|
|
# do_query_test(
|
|
# "sum(bar) without (shape)",
|
|
# 120,
|
|
# '{"resultType": "vector", "result": [{"metric": {"size": "l"}, "value": [120, "25"]}, {"metric": {"size": "s"}, "value": [120, "40"]}, {"metric": {"size": "xl"}, "value": [120, "8"]}]}',
|
|
# [
|
|
# ["[('size','l')]", "1970-01-01 00:02:00.000", 25],
|
|
# ["[('size','s')]", "1970-01-01 00:02:00.000", 40],
|
|
# ["[('size','xl')]", "1970-01-01 00:02:00.000", 8],
|
|
# ],
|
|
# )
|
|
|
|
do_query_test(
|
|
"(sum(last_over_time(bar[10])) without (shape))[50:10]",
|
|
150,
|
|
'{"resultType": "matrix", "result": [{"metric": {"size": "l"}, "values": [[110, "19"], [120, "16"], [130, "140"], [150, "1000"]]}, {"metric": {"size": "s"}, "values": [[110, "3"], [120, "40"], [140, "700"]]}, {"metric": {"size": "xl"}, "values": [[110, "8"], [150, "30"]]}]}',
|
|
[
|
|
["[('size','l')]", "[('1970-01-01 00:01:50.000',19),('1970-01-01 00:02:00.000',16),('1970-01-01 00:02:10.000',140),('1970-01-01 00:02:30.000',1000)]"],
|
|
["[('size','s')]", "[('1970-01-01 00:01:50.000',3),('1970-01-01 00:02:00.000',40),('1970-01-01 00:02:20.000',700)]"],
|
|
["[('size','xl')]", "[('1970-01-01 00:01:50.000',8),('1970-01-01 00:02:30.000',30)]"],
|
|
],
|
|
)
|
|
|
|
do_query_test(
|
|
"(count(last_over_time(bar[10])) by (size))[50:10]",
|
|
150,
|
|
'{"resultType": "matrix", "result": [{"metric": {"size": "l"}, "values": [[110, "2"], [120, "1"], [130, "2"], [150, "1"]]}, {"metric": {"size": "s"}, "values": [[110, "1"], [120, "1"], [140, "1"]]}, {"metric": {"size": "xl"}, "values": [[110, "1"], [150, "1"]]}]}',
|
|
[
|
|
["[('size','l')]", "[('1970-01-01 00:01:50.000',2),('1970-01-01 00:02:00.000',1),('1970-01-01 00:02:10.000',2),('1970-01-01 00:02:30.000',1)]"],
|
|
["[('size','s')]", "[('1970-01-01 00:01:50.000',1),('1970-01-01 00:02:00.000',1),('1970-01-01 00:02:20.000',1)]"],
|
|
["[('size','xl')]", "[('1970-01-01 00:01:50.000',1),('1970-01-01 00:02:30.000',1)]"],
|
|
],
|
|
)
|
|
|
|
do_query_test(
|
|
"count(nonexistent_metric_name)[50:10]",
|
|
150,
|
|
'{"resultType": "matrix", "result": []}',
|
|
[],
|
|
)
|
|
|
|
do_query_test(
|
|
"(avg(last_over_time(bar[10])) by (size))[50:10]",
|
|
150,
|
|
'{"resultType": "matrix", "result": [{"metric": {"size": "l"}, "values": [[110, "9.5"], [120, "16"], [130, "70"], [150, "1000"]]}, {"metric": {"size": "s"}, "values": [[110, "3"], [120, "40"], [140, "700"]]}, {"metric": {"size": "xl"}, "values": [[110, "8"], [150, "30"]]}]}',
|
|
[
|
|
["[('size','l')]", "[('1970-01-01 00:01:50.000',9.5),('1970-01-01 00:02:00.000',16),('1970-01-01 00:02:10.000',70),('1970-01-01 00:02:30.000',1000)]"],
|
|
["[('size','s')]", "[('1970-01-01 00:01:50.000',3),('1970-01-01 00:02:00.000',40),('1970-01-01 00:02:20.000',700)]"],
|
|
["[('size','xl')]", "[('1970-01-01 00:01:50.000',8),('1970-01-01 00:02:30.000',30)]"],
|
|
],
|
|
)
|
|
|
|
do_query_test(
|
|
"min(last_over_time(bar[10]))[50:10]",
|
|
150,
|
|
'{"resultType": "matrix", "result": [{"metric": {}, "values": [[110, "3"], [120, "16"], [130, "50"], [140, "700"], [150, "30"]]}]}',
|
|
[["[]", "[('1970-01-01 00:01:50.000',3),('1970-01-01 00:02:00.000',16),('1970-01-01 00:02:10.000',50),('1970-01-01 00:02:20.000',700),('1970-01-01 00:02:30.000',30)]"]],
|
|
)
|
|
|
|
do_query_test(
|
|
"max(last_over_time(bar[10]))[50:10]",
|
|
150,
|
|
'{"resultType": "matrix", "result": [{"metric": {}, "values": [[110, "10"], [120, "40"], [130, "90"], [140, "700"], [150, "1000"]]}]}',
|
|
[["[]", "[('1970-01-01 00:01:50.000',10),('1970-01-01 00:02:00.000',40),('1970-01-01 00:02:10.000',90),('1970-01-01 00:02:20.000',700),('1970-01-01 00:02:30.000',1000)]"]],
|
|
)
|
|
|
|
do_query_test(
|
|
"stddev(last_over_time(bar[10]))[50:10]",
|
|
150,
|
|
'{"resultType": "matrix", "result": [{"metric": {}, "values": [[110, "2.692582403567252"], [120, "12"], [130, "20"], [140, "0"], [150, "485"]]}]}',
|
|
[["[]", "[('1970-01-01 00:01:50.000',2.692582403567252),('1970-01-01 00:02:00.000',12),('1970-01-01 00:02:10.000',20),('1970-01-01 00:02:20.000',0),('1970-01-01 00:02:30.000',485)]"]],
|
|
eps=1e-9,
|
|
)
|
|
|
|
do_query_test(
|
|
"stdvar(last_over_time(bar[10]))[50:10]",
|
|
150,
|
|
'{"resultType": "matrix", "result": [{"metric": {}, "values": [[110, "7.25"], [120, "144"], [130, "400"], [140, "0"], [150, "235225"]]}]}',
|
|
[["[]", "[('1970-01-01 00:01:50.000',7.25),('1970-01-01 00:02:00.000',144),('1970-01-01 00:02:10.000',400),('1970-01-01 00:02:20.000',0),('1970-01-01 00:02:30.000',235225)]"]],
|
|
eps=1e-9,
|
|
)
|
|
|
|
# FIXME: Not deterministic without sort_by_label(), and function sort_by_label() is not implemented yet.
|
|
# group replaces all values with 1.
|
|
# {shape="circle", size="l"} and {shape="rectangle", size="l"} are merged to one group.
|
|
# do_query_test(
|
|
# "group(bar) without (shape)",
|
|
# 120,
|
|
# '{"resultType": "vector", "result": [{"metric": {"size": "l"}, "value": [120, "1"]}, {"metric": {"size": "s"}, "value": [120, "1"]}, {"metric": {"size": "xl"}, "value": [120, "1"]}]}',
|
|
# [
|
|
# ["[('size','l')]", "1970-01-01 00:02:00.000", 1],
|
|
# ["[('size','s')]", "1970-01-01 00:02:00.000", 1],
|
|
# ["[('size','xl')]", "1970-01-01 00:02:00.000", 1],
|
|
# ],
|
|
# )
|
|
|
|
do_query_test(
|
|
"(group(last_over_time(bar[10])) without (shape))[50:10]",
|
|
150,
|
|
'{"resultType": "matrix", "result": [{"metric": {"size": "l"}, "values": [[110, "1"], [120, "1"], [130, "1"], [150, "1"]]}, {"metric": {"size": "s"}, "values": [[110, "1"], [120, "1"], [140, "1"]]}, {"metric": {"size": "xl"}, "values": [[110, "1"], [150, "1"]]}]}',
|
|
[
|
|
["[('size','l')]", "[('1970-01-01 00:01:50.000',1),('1970-01-01 00:02:00.000',1),('1970-01-01 00:02:10.000',1),('1970-01-01 00:02:30.000',1)]"],
|
|
["[('size','s')]", "[('1970-01-01 00:01:50.000',1),('1970-01-01 00:02:00.000',1),('1970-01-01 00:02:20.000',1)]"],
|
|
["[('size','xl')]", "[('1970-01-01 00:01:50.000',1),('1970-01-01 00:02:30.000',1)]"],
|
|
],
|
|
)
|
|
|
|
do_query_test(
|
|
"quantile(0.5, last_over_time(bar[10]))[50:10]",
|
|
150,
|
|
'{"resultType": "matrix", "result": [{"metric": {}, "values": [[110, "8.5"], [120, "28"], [130, "70"], [140, "700"], [150, "515"]]}]}',
|
|
[["[]", "[('1970-01-01 00:01:50.000',8.5),('1970-01-01 00:02:00.000',28),('1970-01-01 00:02:10.000',70),('1970-01-01 00:02:20.000',700),('1970-01-01 00:02:30.000',515)]"]],
|
|
)
|
|
|
|
do_query_test(
|
|
"quantile(0.5, nonexistent_metric_name)[50:10]",
|
|
150,
|
|
'{"resultType": "matrix", "result": []}',
|
|
[],
|
|
)
|
|
|
|
# FIXME: quantile with phi depending on timestamp is not implemented yet.
|
|
# phi = scalar(time()) / 200 varies per subquery step: 0.55, 0.60, 0.65, 0.70, 0.75.
|
|
# do_query_test(
|
|
# "quantile(time() / 200, last_over_time(bar[10]))[50:10]",
|
|
# 150,
|
|
# '{"resultType": "matrix", "result": [{"metric": {}, "values": [[110, "8.65"], [120, "30.4"], [130, "76"], [140, "700"], [150, "757.5"]]}]}',
|
|
# [["[]", "[('1970-01-01 00:01:50.000',8.65),('1970-01-01 00:02:00.000',30.4),('1970-01-01 00:02:10.000',76),('1970-01-01 00:02:20.000',700),('1970-01-01 00:02:30.000',757.5)]"]],
|
|
# )
|
|
|
|
# FIXME: Not deterministic without sort_by_label(), and function sort_by_label() is not implemented yet.
|
|
# topk keeps all tags.
|
|
# do_query_test(
|
|
# "topk(2, bar)",
|
|
# 140,
|
|
# '{"resultType": "vector", "result": [{"metric": {"__name__": "bar", "shape": "rectangle", "size": "l"}, "value": [140, "90"]}, {"metric": {"__name__": "bar", "shape": "square", "size": "s"}, "value": [140, "700"]}]}',
|
|
# [
|
|
# ["[('__name__','bar'),('shape','rectangle'),('size','l')]", "1970-01-01 00:02:20.000", 90],
|
|
# ["[('__name__','bar'),('shape','square'),('size','s')]", "1970-01-01 00:02:20.000", 700],
|
|
# ],
|
|
# )
|
|
|
|
do_query_test(
|
|
"topk(2, last_over_time(bar[10]))[50:10]",
|
|
150,
|
|
'{"resultType": "matrix", "result": [{"metric": {"__name__": "bar", "shape": "circle", "size": "l"}, "values": [[110, "10"], [120, "16"], [130, "50"], [150, "1000"]]}, {"metric": {"__name__": "bar", "shape": "rectangle", "size": "l"}, "values": [[110, "9"], [130, "90"]]}, {"metric": {"__name__": "bar", "shape": "square", "size": "s"}, "values": [[120, "40"], [140, "700"]]}, {"metric": {"__name__": "bar", "shape": "triangle", "size": "xl"}, "values": [[150, "30"]]}]}',
|
|
[
|
|
["[('__name__','bar'),('shape','circle'),('size','l')]", "[('1970-01-01 00:01:50.000',10),('1970-01-01 00:02:00.000',16),('1970-01-01 00:02:10.000',50),('1970-01-01 00:02:30.000',1000)]"],
|
|
["[('__name__','bar'),('shape','rectangle'),('size','l')]", "[('1970-01-01 00:01:50.000',9),('1970-01-01 00:02:10.000',90)]"],
|
|
["[('__name__','bar'),('shape','square'),('size','s')]", "[('1970-01-01 00:02:00.000',40),('1970-01-01 00:02:20.000',700)]"],
|
|
["[('__name__','bar'),('shape','triangle'),('size','xl')]", "[('1970-01-01 00:02:30.000',30)]"],
|
|
],
|
|
)
|
|
|
|
do_query_test(
|
|
"(topk(1, last_over_time(bar[10])) by (size))[50:10]",
|
|
150,
|
|
'{"resultType": "matrix", "result": [{"metric": {"__name__": "bar", "shape": "circle", "size": "l"}, "values": [[110, "10"], [120, "16"], [150, "1000"]]}, {"metric": {"__name__": "bar", "shape": "rectangle", "size": "l"}, "values": [[130, "90"]]}, {"metric": {"__name__": "bar", "shape": "square", "size": "s"}, "values": [[110, "3"], [120, "40"], [140, "700"]]}, {"metric": {"__name__": "bar", "shape": "triangle", "size": "xl"}, "values": [[110, "8"], [150, "30"]]}]}',
|
|
[
|
|
["[('__name__','bar'),('shape','circle'),('size','l')]", "[('1970-01-01 00:01:50.000',10),('1970-01-01 00:02:00.000',16),('1970-01-01 00:02:30.000',1000)]"],
|
|
["[('__name__','bar'),('shape','rectangle'),('size','l')]", "[('1970-01-01 00:02:10.000',90)]"],
|
|
["[('__name__','bar'),('shape','square'),('size','s')]", "[('1970-01-01 00:01:50.000',3),('1970-01-01 00:02:00.000',40),('1970-01-01 00:02:20.000',700)]"],
|
|
["[('__name__','bar'),('shape','triangle'),('size','xl')]", "[('1970-01-01 00:01:50.000',8),('1970-01-01 00:02:30.000',30)]"],
|
|
],
|
|
)
|
|
|
|
# We test topk(1) only at timestamps 140, 150 to avoid ties.
|
|
do_query_test(
|
|
'(topk(1, {__name__=~"foo|bar"}) by (size))[20:10]',
|
|
150,
|
|
'{"resultType": "matrix", "result": [{"metric": {"__name__": "bar", "shape": "circle", "size": "l"}, "values": [[150, "1000"]]}, {"metric": {"__name__": "bar", "shape": "rectangle", "size": "l"}, "values": [[140, "90"]]}, {"metric": {"__name__": "bar", "shape": "square", "size": "s"}, "values": [[140, "700"], [150, "700"]]}, {"metric": {"__name__": "bar", "shape": "triangle", "size": "xl"}, "values": [[140, "8"], [150, "30"]]}, {"metric": {"__name__": "foo", "shape": "triangle", "size": "m"}, "values": [[140, "80"], [150, "80"]]}]}',
|
|
[
|
|
["[('__name__','bar'),('shape','circle'),('size','l')]", "[('1970-01-01 00:02:30.000',1000)]"],
|
|
["[('__name__','bar'),('shape','rectangle'),('size','l')]", "[('1970-01-01 00:02:20.000',90)]"],
|
|
["[('__name__','bar'),('shape','square'),('size','s')]", "[('1970-01-01 00:02:20.000',700),('1970-01-01 00:02:30.000',700)]"],
|
|
["[('__name__','bar'),('shape','triangle'),('size','xl')]", "[('1970-01-01 00:02:20.000',8),('1970-01-01 00:02:30.000',30)]"],
|
|
["[('__name__','foo'),('shape','triangle'),('size','m')]", "[('1970-01-01 00:02:20.000',80),('1970-01-01 00:02:30.000',80)]"],
|
|
],
|
|
)
|
|
|
|
do_query_test(
|
|
'(topk(1, {__name__=~"foo|bar"}) by (__name__))[50:10]',
|
|
150,
|
|
'{"resultType": "matrix", "result": [{"metric": {"__name__": "bar", "shape": "circle", "size": "l"}, "values": [[110, "10"], [150, "1000"]]}, {"metric": {"__name__": "bar", "shape": "rectangle", "size": "l"}, "values": [[130, "90"]]}, {"metric": {"__name__": "bar", "shape": "square", "size": "s"}, "values": [[120, "40"], [140, "700"]]}, {"metric": {"__name__": "foo", "shape": "circle", "size": "l"}, "values": [[110, "16"]]}, {"metric": {"__name__": "foo", "shape": "triangle", "size": "m"}, "values": [[120, "80"], [130, "80"], [140, "80"], [150, "80"]]}]}',
|
|
[
|
|
["[('__name__','bar'),('shape','circle'),('size','l')]", "[('1970-01-01 00:01:50.000',10),('1970-01-01 00:02:30.000',1000)]"],
|
|
["[('__name__','bar'),('shape','rectangle'),('size','l')]", "[('1970-01-01 00:02:10.000',90)]"],
|
|
["[('__name__','bar'),('shape','square'),('size','s')]", "[('1970-01-01 00:02:00.000',40),('1970-01-01 00:02:20.000',700)]"],
|
|
["[('__name__','foo'),('shape','circle'),('size','l')]", "[('1970-01-01 00:01:50.000',16)]"],
|
|
["[('__name__','foo'),('shape','triangle'),('size','m')]", "[('1970-01-01 00:02:00.000',80),('1970-01-01 00:02:10.000',80),('1970-01-01 00:02:20.000',80),('1970-01-01 00:02:30.000',80)]"],
|
|
],
|
|
)
|
|
|
|
# topk(-1): k<0 is clamped to 0, returns no series.
|
|
do_query_test(
|
|
"topk(-1, last_over_time(foo[10]))[50:10]",
|
|
150,
|
|
'{"resultType": "matrix", "result": []}',
|
|
[],
|
|
)
|
|
|
|
# topk(+Inf): k=+Inf causes an error because it cannot be converted to an integer.
|
|
do_query_test_expect_error(
|
|
"topk(+Inf, last_over_time(foo[10]))[50:10]",
|
|
150,
|
|
"Scalar value +Inf overflows int64",
|
|
"Argument k of aggregation operator is too large",
|
|
)
|
|
|
|
do_query_test(
|
|
'topk(time() / 10 - 10, last_over_time({__name__=~"foo|bar"}[10]))[50:10]',
|
|
150,
|
|
'{"resultType": "matrix", "result": [{"metric": {"__name__": "bar", "shape": "circle", "size": "l"}, "values": [[130, "50"], [150, "1000"]]}, {"metric": {"__name__": "bar", "shape": "rectangle", "size": "l"}, "values": [[130, "90"]]}, {"metric": {"__name__": "bar", "shape": "square", "size": "s"}, "values": [[120, "40"], [140, "700"]]}, {"metric": {"__name__": "bar", "shape": "triangle", "size": "xl"}, "values": [[150, "30"]]}, {"metric": {"__name__": "foo", "shape": "circle", "size": "l"}, "values": [[110, "16"], [150, "16"]]}, {"metric": {"__name__": "foo", "shape": "square", "size": "s"}, "values": [[130, "40"]]}, {"metric": {"__name__": "foo", "shape": "triangle", "size": "m"}, "values": [[120, "80"]]}]}',
|
|
[
|
|
["[('__name__','bar'),('shape','circle'),('size','l')]", "[('1970-01-01 00:02:10.000',50),('1970-01-01 00:02:30.000',1000)]"],
|
|
["[('__name__','bar'),('shape','rectangle'),('size','l')]", "[('1970-01-01 00:02:10.000',90)]"],
|
|
["[('__name__','bar'),('shape','square'),('size','s')]", "[('1970-01-01 00:02:00.000',40),('1970-01-01 00:02:20.000',700)]"],
|
|
["[('__name__','bar'),('shape','triangle'),('size','xl')]", "[('1970-01-01 00:02:30.000',30)]"],
|
|
["[('__name__','foo'),('shape','circle'),('size','l')]", "[('1970-01-01 00:01:50.000',16),('1970-01-01 00:02:30.000',16)]"],
|
|
["[('__name__','foo'),('shape','square'),('size','s')]", "[('1970-01-01 00:02:10.000',40)]"],
|
|
["[('__name__','foo'),('shape','triangle'),('size','m')]", "[('1970-01-01 00:02:00.000',80)]"],
|
|
],
|
|
)
|
|
|
|
do_query_test(
|
|
"topk(2, nonexistent_metric_name)[50:10]",
|
|
150,
|
|
'{"resultType": "matrix", "result": []}',
|
|
[],
|
|
)
|
|
|
|
# FIXME: Not deterministic without sort_by_label(), and function sort_by_label() is not implemented yet.
|
|
# do_query_test(
|
|
# "bottomk(2, bar)",
|
|
# 140,
|
|
# '{"resultType": "vector", "result": [{"metric": {"__name__": "bar", "shape": "circle", "size": "l"}, "value": [140, "50"]}, {"metric": {"__name__": "bar", "shape": "triangle", "size": "xl"}, "value": [140, "8"]}]}',
|
|
# [
|
|
# ["[('__name__','bar'),('shape','circle'),('size','l')]", "1970-01-01 00:02:20.000", 50],
|
|
# ["[('__name__','bar'),('shape','triangle'),('size','xl')]", "1970-01-01 00:02:20.000", 8],
|
|
# ],
|
|
# )
|
|
|
|
do_query_test(
|
|
"bottomk(2, last_over_time(bar[10]))[50:10]",
|
|
150,
|
|
'{"resultType": "matrix", "result": [{"metric": {"__name__": "bar", "shape": "circle", "size": "l"}, "values": [[120, "16"], [130, "50"], [150, "1000"]]}, {"metric": {"__name__": "bar", "shape": "rectangle", "size": "l"}, "values": [[130, "90"]]}, {"metric": {"__name__": "bar", "shape": "square", "size": "s"}, "values": [[110, "3"], [120, "40"], [140, "700"]]}, {"metric": {"__name__": "bar", "shape": "triangle", "size": "xl"}, "values": [[110, "8"], [150, "30"]]}]}',
|
|
[
|
|
["[('__name__','bar'),('shape','circle'),('size','l')]", "[('1970-01-01 00:02:00.000',16),('1970-01-01 00:02:10.000',50),('1970-01-01 00:02:30.000',1000)]"],
|
|
["[('__name__','bar'),('shape','rectangle'),('size','l')]", "[('1970-01-01 00:02:10.000',90)]"],
|
|
["[('__name__','bar'),('shape','square'),('size','s')]", "[('1970-01-01 00:01:50.000',3),('1970-01-01 00:02:00.000',40),('1970-01-01 00:02:20.000',700)]"],
|
|
["[('__name__','bar'),('shape','triangle'),('size','xl')]", "[('1970-01-01 00:01:50.000',8),('1970-01-01 00:02:30.000',30)]"],
|
|
],
|
|
)
|
|
|
|
do_query_test(
|
|
"(bottomk(1, last_over_time(bar[10])) by (size))[50:10]",
|
|
150,
|
|
'{"resultType": "matrix", "result": [{"metric": {"__name__": "bar", "shape": "circle", "size": "l"}, "values": [[120, "16"], [130, "50"], [150, "1000"]]}, {"metric": {"__name__": "bar", "shape": "rectangle", "size": "l"}, "values": [[110, "9"]]}, {"metric": {"__name__": "bar", "shape": "square", "size": "s"}, "values": [[110, "3"], [120, "40"], [140, "700"]]}, {"metric": {"__name__": "bar", "shape": "triangle", "size": "xl"}, "values": [[110, "8"], [150, "30"]]}]}',
|
|
[
|
|
["[('__name__','bar'),('shape','circle'),('size','l')]", "[('1970-01-01 00:02:00.000',16),('1970-01-01 00:02:10.000',50),('1970-01-01 00:02:30.000',1000)]"],
|
|
["[('__name__','bar'),('shape','rectangle'),('size','l')]", "[('1970-01-01 00:01:50.000',9)]"],
|
|
["[('__name__','bar'),('shape','square'),('size','s')]", "[('1970-01-01 00:01:50.000',3),('1970-01-01 00:02:00.000',40),('1970-01-01 00:02:20.000',700)]"],
|
|
["[('__name__','bar'),('shape','triangle'),('size','xl')]", "[('1970-01-01 00:01:50.000',8),('1970-01-01 00:02:30.000',30)]"],
|
|
],
|
|
)
|
|
|
|
# We test bottomk(1) only at timestamps 140, 150 to avoid ties.
|
|
do_query_test(
|
|
'(bottomk(1, {__name__=~"foo|bar"}) by (size))[20:10]',
|
|
150,
|
|
'{"resultType": "matrix", "result": [{"metric": {"__name__": "bar", "shape": "triangle", "size": "xl"}, "values": [[140, "8"], [150, "30"]]}, {"metric": {"__name__": "foo", "shape": "circle", "size": "l"}, "values": [[140, "16"], [150, "16"]]}, {"metric": {"__name__": "foo", "shape": "square", "size": "s"}, "values": [[140, "40"], [150, "40"]]}, {"metric": {"__name__": "foo", "shape": "triangle", "size": "m"}, "values": [[140, "80"], [150, "80"]]}]}',
|
|
[
|
|
["[('__name__','bar'),('shape','triangle'),('size','xl')]", "[('1970-01-01 00:02:20.000',8),('1970-01-01 00:02:30.000',30)]"],
|
|
["[('__name__','foo'),('shape','circle'),('size','l')]", "[('1970-01-01 00:02:20.000',16),('1970-01-01 00:02:30.000',16)]"],
|
|
["[('__name__','foo'),('shape','square'),('size','s')]", "[('1970-01-01 00:02:20.000',40),('1970-01-01 00:02:30.000',40)]"],
|
|
["[('__name__','foo'),('shape','triangle'),('size','m')]", "[('1970-01-01 00:02:20.000',80),('1970-01-01 00:02:30.000',80)]"],
|
|
],
|
|
)
|
|
|
|
do_query_test(
|
|
'(bottomk(1, {__name__=~"foo|bar"}) by (__name__))[50:10]',
|
|
150,
|
|
'{"resultType": "matrix", "result": [{"metric": {"__name__": "bar", "shape": "square", "size": "s"}, "values": [[110, "3"]]}, {"metric": {"__name__": "bar", "shape": "triangle", "size": "xl"}, "values": [[120, "8"], [130, "8"], [140, "8"], [150, "30"]]}, {"metric": {"__name__": "foo", "shape": "circle", "size": "l"}, "values": [[130, "16"], [140, "16"], [150, "16"]]}, {"metric": {"__name__": "foo", "shape": "square", "size": "s"}, "values": [[110, "4"], [120, "4"]]}]}',
|
|
[
|
|
["[('__name__','bar'),('shape','square'),('size','s')]", "[('1970-01-01 00:01:50.000',3)]"],
|
|
["[('__name__','bar'),('shape','triangle'),('size','xl')]", "[('1970-01-01 00:02:00.000',8),('1970-01-01 00:02:10.000',8),('1970-01-01 00:02:20.000',8),('1970-01-01 00:02:30.000',30)]"],
|
|
["[('__name__','foo'),('shape','circle'),('size','l')]", "[('1970-01-01 00:02:10.000',16),('1970-01-01 00:02:20.000',16),('1970-01-01 00:02:30.000',16)]"],
|
|
["[('__name__','foo'),('shape','square'),('size','s')]", "[('1970-01-01 00:01:50.000',4),('1970-01-01 00:02:00.000',4)]"],
|
|
],
|
|
)
|
|
|
|
# limitk(0): returns no series.
|
|
do_query_test(
|
|
"limitk(0, last_over_time(foo[10]))[50:10]",
|
|
150,
|
|
'{"resultType": "matrix", "result": []}',
|
|
[],
|
|
)
|
|
|
|
# Our implementation of limitk() picks k time series deterministically after sorting them by CityHash64(tags).
|
|
# Prometheus uses its own fingerprint (xxhash.Sum64), so limitk() in Prometheus picks different time series.
|
|
# That's why these tests check only ClickHouse results, and don't compare with Prometheus.
|
|
do_clickhouse_only_query_test(
|
|
"limitk(1, last_over_time(foo[10]))[50:10]",
|
|
150,
|
|
'{"resultType": "matrix", "result": [{"metric": {"__name__": "foo", "shape": "circle", "size": "l"}, "values": [[150, "16"]]}, {"metric": {"__name__": "foo", "shape": "square", "size": "s"}, "values": [[110, "4"], [130, "40"]]}, {"metric": {"__name__": "foo", "shape": "triangle", "size": "m"}, "values": [[120, "80"]]}]}',
|
|
[
|
|
["[('__name__','foo'),('shape','circle'),('size','l')]", "[('1970-01-01 00:02:30.000',16)]"],
|
|
["[('__name__','foo'),('shape','square'),('size','s')]", "[('1970-01-01 00:01:50.000',4),('1970-01-01 00:02:10.000',40)]"],
|
|
["[('__name__','foo'),('shape','triangle'),('size','m')]", "[('1970-01-01 00:02:00.000',80)]"],
|
|
],
|
|
)
|
|
|
|
do_clickhouse_only_query_test(
|
|
"limitk(2, last_over_time(foo[10]))[50:10]",
|
|
150,
|
|
'{"resultType": "matrix", "result": [{"metric": {"__name__": "foo", "shape": "circle", "size": "l"}, "values": [[130, "16"], [150, "16"]]}, {"metric": {"__name__": "foo", "shape": "square", "size": "s"}, "values": [[110, "4"], [130, "40"]]}, {"metric": {"__name__": "foo", "shape": "triangle", "size": "m"}, "values": [[110, "8"], [120, "80"]]}]}',
|
|
[
|
|
["[('__name__','foo'),('shape','circle'),('size','l')]", "[('1970-01-01 00:02:10.000',16),('1970-01-01 00:02:30.000',16)]"],
|
|
["[('__name__','foo'),('shape','square'),('size','s')]", "[('1970-01-01 00:01:50.000',4),('1970-01-01 00:02:10.000',40)]"],
|
|
["[('__name__','foo'),('shape','triangle'),('size','m')]", "[('1970-01-01 00:01:50.000',8),('1970-01-01 00:02:00.000',80)]"],
|
|
],
|
|
)
|
|
|
|
# count(limitk(2)): returns min(k, n) where k=2 and n is the number of series at each timestamp.
|
|
do_query_test(
|
|
"(count(limitk(2, last_over_time(foo[10]))))[50:10]",
|
|
150,
|
|
'{"resultType": "matrix", "result": [{"metric": {}, "values": [[110, "2"], [120, "1"], [130, "2"], [150, "1"]]}]}',
|
|
[["[]", "[('1970-01-01 00:01:50.000',2),('1970-01-01 00:02:00.000',1),('1970-01-01 00:02:10.000',2),('1970-01-01 00:02:30.000',1)]"]],
|
|
)
|
|
|
|
# limitk(3): returns all 3 series.
|
|
do_query_test(
|
|
"limitk(3, last_over_time(foo[10]))[50:10]",
|
|
150,
|
|
'{"resultType": "matrix", "result": [{"metric": {"__name__": "foo", "shape": "circle", "size": "l"}, "values": [[110, "16"], [130, "16"], [150, "16"]]}, {"metric": {"__name__": "foo", "shape": "square", "size": "s"}, "values": [[110, "4"], [130, "40"]]}, {"metric": {"__name__": "foo", "shape": "triangle", "size": "m"}, "values": [[110, "8"], [120, "80"]]}]}',
|
|
[
|
|
["[('__name__','foo'),('shape','circle'),('size','l')]", "[('1970-01-01 00:01:50.000',16),('1970-01-01 00:02:10.000',16),('1970-01-01 00:02:30.000',16)]"],
|
|
["[('__name__','foo'),('shape','square'),('size','s')]", "[('1970-01-01 00:01:50.000',4),('1970-01-01 00:02:10.000',40)]"],
|
|
["[('__name__','foo'),('shape','triangle'),('size','m')]", "[('1970-01-01 00:01:50.000',8),('1970-01-01 00:02:00.000',80)]"],
|
|
],
|
|
)
|
|
|
|
# limitk(4): also returns all 3 series.
|
|
do_query_test(
|
|
"limitk(4, last_over_time(foo[10]))[50:10]",
|
|
150,
|
|
'{"resultType": "matrix", "result": [{"metric": {"__name__": "foo", "shape": "circle", "size": "l"}, "values": [[110, "16"], [130, "16"], [150, "16"]]}, {"metric": {"__name__": "foo", "shape": "square", "size": "s"}, "values": [[110, "4"], [130, "40"]]}, {"metric": {"__name__": "foo", "shape": "triangle", "size": "m"}, "values": [[110, "8"], [120, "80"]]}]}',
|
|
[
|
|
["[('__name__','foo'),('shape','circle'),('size','l')]", "[('1970-01-01 00:01:50.000',16),('1970-01-01 00:02:10.000',16),('1970-01-01 00:02:30.000',16)]"],
|
|
["[('__name__','foo'),('shape','square'),('size','s')]", "[('1970-01-01 00:01:50.000',4),('1970-01-01 00:02:10.000',40)]"],
|
|
["[('__name__','foo'),('shape','triangle'),('size','m')]", "[('1970-01-01 00:01:50.000',8),('1970-01-01 00:02:00.000',80)]"],
|
|
],
|
|
)
|
|
|
|
# limitk(-2): k<0 is clamped to 0, returns no series.
|
|
do_query_test(
|
|
"limitk(-2, last_over_time(foo[10]))[50:10]",
|
|
150,
|
|
'{"resultType": "matrix", "result": []}',
|
|
[],
|
|
)
|
|
|
|
# limitk with non-constant k=time()/10 - 10 (values 0,1,2,3,4,5 at steps 100..150).
|
|
# ClickHouse-only because limitk picks series via CityHash64(tags) which differs from Prometheus's xxhash.Sum64.
|
|
do_clickhouse_only_query_test(
|
|
"limitk(time() / 10 - 10, last_over_time(foo[10]))[50:10]",
|
|
150,
|
|
'{"resultType": "matrix", "result": [{"metric": {"__name__": "foo", "shape": "circle", "size": "l"}, "values": [[130, "16"], [150, "16"]]}, {"metric": {"__name__": "foo", "shape": "square", "size": "s"}, "values": [[110, "4"], [130, "40"]]}, {"metric": {"__name__": "foo", "shape": "triangle", "size": "m"}, "values": [[120, "80"]]}]}',
|
|
[
|
|
["[('__name__','foo'),('shape','circle'),('size','l')]", "[('1970-01-01 00:02:10.000',16),('1970-01-01 00:02:30.000',16)]"],
|
|
["[('__name__','foo'),('shape','square'),('size','s')]", "[('1970-01-01 00:01:50.000',4),('1970-01-01 00:02:10.000',40)]"],
|
|
["[('__name__','foo'),('shape','triangle'),('size','m')]", "[('1970-01-01 00:02:00.000',80)]"],
|
|
],
|
|
)
|
|
|
|
|
|
def test_histogram_quantile():
|
|
# The classic histogram `http_request_duration_seconds_bucket` has cumulative counts at t=300:
|
|
# le=0.1 -> 10 (10 observations in (-Inf, 0.1])
|
|
# le=0.5 -> 30 (20 more observations in (0.1, 0.5])
|
|
# le=1.0 -> 50 (20 more observations in (0.5, 1.0])
|
|
# le=+Inf -> 60 (10 more observations in (1.0, +Inf))
|
|
|
|
# phi=0.5 -> target rank = 0.5 * 60 = 30, which lands exactly on the le=0.5 bucket edge.
|
|
do_query_test(
|
|
"histogram_quantile(0.5, http_request_duration_seconds_bucket)",
|
|
300,
|
|
'{"resultType": "vector", "result": [{"metric": {"job": "api"}, "value": [300, "0.5"]}]}',
|
|
[["[('job','api')]", "1970-01-01 00:05:00.000", "0.5"]],
|
|
)
|
|
|
|
# phi=0.25 -> target rank = 15, falls inside bucket (0.1, 0.5]. Linear interpolation:
|
|
# 0.1 + (0.5 - 0.1) * (15 - 10) / (30 - 10) = 0.1 + 0.4 * 0.25 = 0.2.
|
|
do_query_test(
|
|
"histogram_quantile(0.25, http_request_duration_seconds_bucket)",
|
|
300,
|
|
'{"resultType": "vector", "result": [{"metric": {"job": "api"}, "value": [300, "0.2"]}]}',
|
|
[["[('job','api')]", "1970-01-01 00:05:00.000", "0.2"]],
|
|
eps=1e-12,
|
|
)
|
|
|
|
# phi=0.9 -> target rank = 54, falls inside the +Inf bucket. Prometheus returns the
|
|
# upper bound of the last finite bucket (1.0) rather than extrapolating to infinity.
|
|
do_query_test(
|
|
"histogram_quantile(0.9, http_request_duration_seconds_bucket)",
|
|
300,
|
|
'{"resultType": "vector", "result": [{"metric": {"job": "api"}, "value": [300, "1"]}]}',
|
|
[["[('job','api')]", "1970-01-01 00:05:00.000", "1"]],
|
|
)
|
|
|
|
# phi=0.1 -> target rank = 6, falls inside the first bucket (0, 0.1] whose upper
|
|
# bound is positive. Prometheus interpolates from 0 as if the first bucket's lower
|
|
# bound were 0: 0.1 * (6 / 10) = 0.06.
|
|
do_query_test(
|
|
"histogram_quantile(0.1, http_request_duration_seconds_bucket)",
|
|
300,
|
|
'{"resultType": "vector", "result": [{"metric": {"job": "api"}, "value": [300, "0.06"]}]}',
|
|
[["[('job','api')]", "1970-01-01 00:05:00.000", "0.06"]],
|
|
eps=1e-12,
|
|
)
|
|
|
|
# Multiple series (two `job` values) -> the aggregate must produce one quantile per
|
|
# group. Also verifies that `le` and `__name__` are removed from the output labels
|
|
# while other labels (`job`) are preserved. Expressed as a range query so both sides
|
|
# sort deterministically by labels (Prometheus's instant-vector output is unordered
|
|
# per the HTTP API docs), mirroring the `topk`/`bottomk` precedent.
|
|
do_range_query_test(
|
|
"histogram_quantile(0.5, cache_lookup_duration_seconds_bucket)",
|
|
300,
|
|
300,
|
|
10,
|
|
'{"resultType": "matrix", "result": [{"metric": {"job": "reader"}, "values": [[300, "2.5"]]}, {"metric": {"job": "writer"}, "values": [[300, "1.75"]]}]}',
|
|
[
|
|
["[('job','reader')]", "[('1970-01-01 00:05:00.000',2.5)]"],
|
|
["[('job','writer')]", "[('1970-01-01 00:05:00.000',1.75)]"],
|
|
],
|
|
eps=1e-12,
|
|
)
|
|
|
|
# Two distinct histograms (`two_hist_a_bucket` / `two_hist_b_bucket`) selected
|
|
# together by a name regex. Quantiles must be computed per histogram and
|
|
# `__name__` then dropped from the output; merging buckets across histograms
|
|
# would yield a single, incorrect result. Output ordering is by labelset.
|
|
# two_hist_a_bucket{env="prod",kind="a"}: cumulative 10/50/60 -> rank 30 -> 0.55
|
|
# two_hist_b_bucket{env="prod",kind="b"}: cumulative 5/ 8/10 -> rank 5 -> 0.1
|
|
do_range_query_test(
|
|
'histogram_quantile(0.5, {__name__=~"two_hist_a_bucket|two_hist_b_bucket"})',
|
|
300,
|
|
300,
|
|
10,
|
|
'{"resultType": "matrix", "result": [{"metric": {"env": "prod", "kind": "a"}, "values": [[300, "0.55"]]}, {"metric": {"env": "prod", "kind": "b"}, "values": [[300, "0.1"]]}]}',
|
|
[
|
|
["[('env','prod'),('kind','a')]", "[('1970-01-01 00:05:00.000',0.55)]"],
|
|
["[('env','prod'),('kind','b')]", "[('1970-01-01 00:05:00.000',0.1)]"],
|
|
],
|
|
eps=1e-12,
|
|
)
|
|
|
|
# Range-query form: evaluate histogram_quantile over a step range that covers t=300.
|
|
# Since all histogram samples are at t=300, phi=0.5 returns 0.5 for every step where the
|
|
# 5m lookback window still contains the samples.
|
|
do_range_query_test(
|
|
"histogram_quantile(0.5, http_request_duration_seconds_bucket)",
|
|
300,
|
|
320,
|
|
10,
|
|
'{"resultType": "matrix", "result": [{"metric": {"job": "api"}, "values": [[300, "0.5"], [310, "0.5"], [320, "0.5"]]}]}',
|
|
[
|
|
[
|
|
"[('job','api')]",
|
|
"[('1970-01-01 00:05:00.000',0.5),('1970-01-01 00:05:10.000',0.5),('1970-01-01 00:05:20.000',0.5)]",
|
|
]
|
|
],
|
|
)
|
|
|
|
# Degenerate inputs: Prometheus returns NaN for histograms with <2 buckets,
|
|
# no `+Inf` bucket, or zero observations.
|
|
do_query_test(
|
|
"histogram_quantile(0.5, only_inf_bucket)",
|
|
300,
|
|
'{"resultType": "vector", "result": [{"metric": {}, "value": [300, "NaN"]}]}',
|
|
[["[]", "1970-01-01 00:05:00.000", "nan"]],
|
|
)
|
|
|
|
do_query_test(
|
|
"histogram_quantile(0.5, no_inf_bucket)",
|
|
300,
|
|
'{"resultType": "vector", "result": [{"metric": {}, "value": [300, "NaN"]}]}',
|
|
[["[]", "1970-01-01 00:05:00.000", "nan"]],
|
|
)
|
|
|
|
do_query_test(
|
|
"histogram_quantile(0.5, zero_count_bucket)",
|
|
300,
|
|
'{"resultType": "vector", "result": [{"metric": {}, "value": [300, "NaN"]}]}',
|
|
[["[]", "1970-01-01 00:05:00.000", "nan"]],
|
|
)
|
|
|
|
# Negative `le` upper bounds: interpolation still works across the zero boundary.
|
|
do_query_test(
|
|
"histogram_quantile(0.5, negative_le_bucket)",
|
|
300,
|
|
'{"resultType": "vector", "result": [{"metric": {}, "value": [300, "-0.5"]}]}',
|
|
[["[]", "1970-01-01 00:05:00.000", "-0.5"]],
|
|
eps=1e-12,
|
|
)
|
|
|
|
# Empty input short-circuits in `applyHistogramQuantile` via `StoreMethod::EMPTY`
|
|
# without invoking the aggregate.
|
|
do_query_test(
|
|
"histogram_quantile(0.5, nonexistent_metric_bucket)",
|
|
300,
|
|
'{"resultType": "vector", "result": []}',
|
|
[],
|
|
)
|
|
|
|
# A bucket with an `le` label that does not parse as a float must be silently
|
|
# dropped (matching Prometheus), not abort the whole query. With the `le="abc"`
|
|
# bucket excluded, the remaining well-formed buckets are le=0.1 -> 10, le=1.0 -> 50,
|
|
# le=+Inf -> 60, so phi=0.5 -> rank 30, interpolated within (0.1, 1.0] to 0.55.
|
|
do_query_test(
|
|
"histogram_quantile(0.5, bad_le_bucket)",
|
|
300,
|
|
'{"resultType": "vector", "result": [{"metric": {}, "value": [300, "0.55"]}]}',
|
|
[["[]", "1970-01-01 00:05:00.000", "0.55"]],
|
|
eps=1e-12,
|
|
)
|
|
|
|
# Idiomatic `histogram_quantile(phi, rate(bucket[window]))` pattern.
|
|
do_query_test(
|
|
"histogram_quantile(0.5, rate(rate_bucket[60s]))",
|
|
360,
|
|
'{"resultType": "vector", "result": [{"metric": {}, "value": [360, "0.5"]}]}',
|
|
[["[]", "1970-01-01 00:06:00.000", "0.5"]],
|
|
eps=1e-12,
|
|
)
|
|
|
|
# Out-of-range phi: PromQL short-circuits before looking at the histogram.
|
|
# phi < 0 -> -Inf at every time step.
|
|
do_query_test(
|
|
"histogram_quantile(-0.5, http_request_duration_seconds_bucket)",
|
|
300,
|
|
'{"resultType": "vector", "result": [{"metric": {"job": "api"}, "value": [300, "-Inf"]}]}',
|
|
[["[('job','api')]", "1970-01-01 00:05:00.000", "-inf"]],
|
|
)
|
|
|
|
# phi > 1 -> +Inf at every time step.
|
|
do_query_test(
|
|
"histogram_quantile(1.5, http_request_duration_seconds_bucket)",
|
|
300,
|
|
'{"resultType": "vector", "result": [{"metric": {"job": "api"}, "value": [300, "+Inf"]}]}',
|
|
[["[('job','api')]", "1970-01-01 00:05:00.000", "inf"]],
|
|
)
|
|
|
|
# phi NaN -> NaN at every time step.
|
|
do_query_test(
|
|
"histogram_quantile(NaN, http_request_duration_seconds_bucket)",
|
|
300,
|
|
'{"resultType": "vector", "result": [{"metric": {"job": "api"}, "value": [300, "NaN"]}]}',
|
|
[["[('job','api')]", "1970-01-01 00:05:00.000", "nan"]],
|
|
)
|
|
|
|
# Type validation: second argument must be an instant vector.
|
|
do_query_test_expect_error(
|
|
"histogram_quantile(0.9, 1)",
|
|
300,
|
|
"expected type instant vector",
|
|
"expects second argument of type",
|
|
)
|
|
|
|
# Type validation: first argument must be a scalar.
|
|
do_query_test_expect_error(
|
|
"histogram_quantile(http_request_duration_seconds_bucket, http_request_duration_seconds_bucket)",
|
|
300,
|
|
"expected type scalar",
|
|
"expects first argument of type",
|
|
)
|
|
|
|
|
|
def test_label_manipulation_functions():
|
|
# Add a new label using a regex capture from an existing label.
|
|
do_query_test(
|
|
'label_replace(up, "new_job", "renamed-$1", "job", "(.*)")',
|
|
1753176757.89,
|
|
'{"resultType": "vector", "result": [{"metric": {"__name__": "up", "job": "prometheus", "new_job": "renamed-prometheus"}, "value": [1753176757.89, "1"]}]}',
|
|
[["[('__name__','up'),('job','prometheus'),('new_job','renamed-prometheus')]", "2025-07-22 09:32:37.890", "1"]],
|
|
)
|
|
|
|
# Overwrite an existing label with a constant replacement.
|
|
do_query_test(
|
|
'label_replace(up, "job", "static", "job", ".*")',
|
|
1753176757.89,
|
|
'{"resultType": "vector", "result": [{"metric": {"__name__": "up", "job": "static"}, "value": [1753176757.89, "1"]}]}',
|
|
[["[('__name__','up'),('job','static')]", "2025-07-22 09:32:37.890", "1"]],
|
|
)
|
|
|
|
# When the regex does not match, the series is returned unchanged.
|
|
do_query_test(
|
|
'label_replace(up, "new_label", "x", "job", "nomatch")',
|
|
1753176757.89,
|
|
'{"resultType": "vector", "result": [{"metric": {"__name__": "up", "job": "prometheus"}, "value": [1753176757.89, "1"]}]}',
|
|
[["[('__name__','up'),('job','prometheus')]", "2025-07-22 09:32:37.890", "1"]],
|
|
)
|
|
|
|
# Set __name__ to a constant: there is no tag "", so its value is treated as "" which always matches regex "",
|
|
# so the following will always set the metric name to "service_up".
|
|
do_query_test(
|
|
'label_replace(up, "__name__", "service_up", "", "")',
|
|
1753176757.89,
|
|
'{"resultType": "vector", "result": [{"metric": {"__name__": "service_up", "job": "prometheus"}, "value": [1753176757.89, "1"]}]}',
|
|
[["[('__name__','service_up'),('job','prometheus')]", "2025-07-22 09:32:37.890", "1"]],
|
|
)
|
|
|
|
# Multi-series: derive a new label per series; original labelsets remain distinct.
|
|
do_query_test(
|
|
'label_replace(http_errors, "code_class", "${1}xx", "http_code", "(.).+")[10:10]',
|
|
200,
|
|
'{"resultType": "matrix", "result": [{"metric": {"__name__": "http_errors", "code_class": "4xx", "http_code": "401"}, "values": [[200, "4"]]}, {"metric": {"__name__": "http_errors", "code_class": "4xx", "http_code": "404"}, "values": [[200, "5"]]}]}',
|
|
[
|
|
[
|
|
"[('__name__','http_errors'),('code_class','4xx'),('http_code','401')]",
|
|
"[('1970-01-01 00:03:20.000',4)]",
|
|
],
|
|
[
|
|
"[('__name__','http_errors'),('code_class','4xx'),('http_code','404')]",
|
|
"[('1970-01-01 00:03:20.000',5)]",
|
|
],
|
|
],
|
|
)
|
|
|
|
# Named capture group: reference it as ${name} in the replacement.
|
|
do_query_test(
|
|
'label_replace(http_errors, "code_class", "${digit}xx", "http_code", "(?P<digit>.).+")[10:10]',
|
|
200,
|
|
'{"resultType": "matrix", "result": [{"metric": {"__name__": "http_errors", "code_class": "4xx", "http_code": "401"}, "values": [[200, "4"]]}, {"metric": {"__name__": "http_errors", "code_class": "4xx", "http_code": "404"}, "values": [[200, "5"]]}]}',
|
|
[
|
|
[
|
|
"[('__name__','http_errors'),('code_class','4xx'),('http_code','401')]",
|
|
"[('1970-01-01 00:03:20.000',4)]",
|
|
],
|
|
[
|
|
"[('__name__','http_errors'),('code_class','4xx'),('http_code','404')]",
|
|
"[('1970-01-01 00:03:20.000',5)]",
|
|
],
|
|
],
|
|
)
|
|
|
|
# Collapsing two series into the same labelset must throw.
|
|
do_query_test_expect_error(
|
|
'label_replace(http_errors, "http_code", "same", "", "")',
|
|
200,
|
|
"vector cannot contain metrics with the same labelset",
|
|
"Multiple series have the same tags",
|
|
)
|
|
|
|
# Wrong number of arguments.
|
|
do_query_test_expect_error(
|
|
'label_replace(up, "x", "y")',
|
|
1753176757.89,
|
|
'expected 5 argument(s) in call to "label_replace", got 3',
|
|
"Function 'label_replace' expects 5 arguments, but was called with 3 arguments",
|
|
)
|
|
|
|
# Invalid regular expression.
|
|
do_query_test_expect_error(
|
|
'label_replace(up, "x", "y", "job", "((")',
|
|
1753176757.89,
|
|
"invalid regular expression",
|
|
"Invalid regular expression '(('",
|
|
)
|
|
|
|
# Join two source labels with a separator.
|
|
do_query_test(
|
|
'label_join(up, "combined", "-", "__name__", "job")',
|
|
1753176757.89,
|
|
'{"resultType": "vector", "result": [{"metric": {"__name__": "up", "combined": "up-prometheus", "job": "prometheus"}, "value": [1753176757.89, "1"]}]}',
|
|
[["[('__name__','up'),('combined','up-prometheus'),('job','prometheus')]", "2025-07-22 09:32:37.890", "1"]],
|
|
)
|
|
|
|
# Join into __name__.
|
|
do_query_test(
|
|
'label_join(up, "__name__", "_", "__name__", "job")',
|
|
1753176757.89,
|
|
'{"resultType": "vector", "result": [{"metric": {"__name__": "up_prometheus", "job": "prometheus"}, "value": [1753176757.89, "1"]}]}',
|
|
[["[('__name__','up_prometheus'),('job','prometheus')]", "2025-07-22 09:32:37.890", "1"]],
|
|
)
|
|
|
|
# A single source label effectively copies its value into the destination label.
|
|
do_query_test(
|
|
'label_join(up, "alias", "", "job")',
|
|
1753176757.89,
|
|
'{"resultType": "vector", "result": [{"metric": {"__name__": "up", "alias": "prometheus", "job": "prometheus"}, "value": [1753176757.89, "1"]}]}',
|
|
[["[('__name__','up'),('alias','prometheus'),('job','prometheus')]", "2025-07-22 09:32:37.890", "1"]],
|
|
)
|
|
|
|
# Zero source labels: dst is set to "" which removes the label from each series.
|
|
do_query_test(
|
|
'label_join(up, "job", "_")',
|
|
1753176757.89,
|
|
'{"resultType": "vector", "result": [{"metric": {"__name__": "up"}, "value": [1753176757.89, "1"]}]}',
|
|
[["[('__name__','up')]", "2025-07-22 09:32:37.890", "1"]],
|
|
)
|
|
|
|
# Multi-series: derive a unique destination value per series from existing labels.
|
|
do_query_test(
|
|
'label_join(http_errors, "tag", "/", "__name__", "http_code")[10:10]',
|
|
200,
|
|
'{"resultType": "matrix", "result": [{"metric": {"__name__": "http_errors", "http_code": "401", "tag": "http_errors/401"}, "values": [[200, "4"]]}, {"metric": {"__name__": "http_errors", "http_code": "404", "tag": "http_errors/404"}, "values": [[200, "5"]]}]}',
|
|
[
|
|
[
|
|
"[('__name__','http_errors'),('http_code','401'),('tag','http_errors/401')]",
|
|
"[('1970-01-01 00:03:20.000',4)]",
|
|
],
|
|
[
|
|
"[('__name__','http_errors'),('http_code','404'),('tag','http_errors/404')]",
|
|
"[('1970-01-01 00:03:20.000',5)]",
|
|
],
|
|
],
|
|
)
|
|
|
|
# Collapsing two series into the same labelset must throw.
|
|
do_query_test_expect_error(
|
|
'label_join(http_errors, "http_code", "_", "__name__")',
|
|
200,
|
|
"vector cannot contain metrics with the same labelset",
|
|
"Multiple series have the same tags",
|
|
)
|
|
|
|
# Too few arguments.
|
|
do_query_test_expect_error(
|
|
'label_join(up, "x")',
|
|
1753176757.89,
|
|
'expected at least 3 argument(s) in call to "label_join", got 2',
|
|
"Function 'label_join' expects 3 or more arguments, but was called with 2 arguments",
|
|
)
|