load 5m
	http_requests{job="api-server", instance="0", group="production"}	0+10x10
	http_requests{job="api-server", instance="1", group="production"}	0+20x10
	http_requests{job="api-server", instance="0", group="canary"}		0+30x10
	http_requests{job="api-server", instance="1", group="canary"}		0+40x10
	http_requests{job="app-server", instance="0", group="production"}	0+50x10
	http_requests{job="app-server", instance="1", group="production"}	0+60x10
	http_requests{job="app-server", instance="0", group="canary"}		0+70x10
	http_requests{job="app-server", instance="1", group="canary"}		0+80x10

load 5m
	x{y="testvalue"} 0+10x10

load 5m
	testcounter_reset_middle	0+10x4 0+10x5
	testcounter_reset_end    	0+10x9 0 10

load 4m
	testcounter_zero_cutoff{start="0m"}	0+240x10
	testcounter_zero_cutoff{start="1m"}	60+240x10
	testcounter_zero_cutoff{start="2m"}	120+240x10
	testcounter_zero_cutoff{start="3m"}	180+240x10
	testcounter_zero_cutoff{start="4m"}	240+240x10
	testcounter_zero_cutoff{start="5m"}	300+240x10

load 5m
	label_grouping_test{a="aa", b="bb"}	0+10x10
	label_grouping_test{a="a", b="abb"}	0+20x10

load 5m
	vector_matching_a{l="x"} 0+1x100
	vector_matching_a{l="y"} 0+2x50
	vector_matching_b{l="x"} 0+4x25

load 5m
	cpu_count{instance="0", type="numa"}	0+30x10
	cpu_count{instance="0", type="smp"} 	0+10x20
	cpu_count{instance="1", type="smp"} 	0+20x10


eval instant at 50m SUM(http_requests)
	{} 3600

eval instant at 50m SUM(http_requests{instance="0"}) BY(job)
	{job="api-server"} 400
	{job="app-server"} 1200

eval instant at 50m SUM(http_requests{instance="0"}) BY(job) KEEP_COMMON
	{instance="0", job="api-server"} 400
	{instance="0", job="app-server"} 1200

eval instant at 50m SUM(http_requests) BY (job)
	{job="api-server"} 1000
	{job="app-server"} 2600

# Non-existent labels mentioned in BY-clauses shouldn't propagate to output.
eval instant at 50m SUM(http_requests) BY (job, nonexistent)
	{job="api-server"} 1000
	{job="app-server"} 2600


eval instant at 50m COUNT(http_requests) BY (job)
	{job="api-server"} 4
	{job="app-server"} 4


eval instant at 50m SUM(http_requests) BY (job, group)
	{group="canary", job="api-server"} 700
	{group="canary", job="app-server"} 1500
	{group="production", job="api-server"} 300
	{group="production", job="app-server"} 1100


eval instant at 50m AVG(http_requests) BY (job)
	{job="api-server"} 250
	{job="app-server"} 650


eval instant at 50m MIN(http_requests) BY (job)
	{job="api-server"} 100
	{job="app-server"} 500


eval instant at 50m MAX(http_requests) BY (job)
	{job="api-server"} 400
	{job="app-server"} 800


# Single-letter label names and values.
eval instant at 50m x{y="testvalue"}
	x{y="testvalue"} 100


# Rates should calculate per-second rates.
eval instant at 50m rate(http_requests{group="canary", instance="1", job="app-server"}[50m])
	{group="canary", instance="1", job="app-server"} 0.26666666666666666


# Counter resets at in the middle of range are handled correctly by rate().
eval instant at 50m rate(testcounter_reset_middle[50m])
	{} 0.03


# Counter resets at end of range are ignored by rate().
eval instant at 50m rate(testcounter_reset_end[5m])
	{} 0


# Zero cutoff for left-side extrapolation.
eval instant at 10m rate(testcounter_zero_cutoff[20m])
	{start="0m"} 0.5
	{start="1m"} 0.55
	{start="2m"} 0.6
	{start="3m"} 0.65
	{start="4m"} 0.7
	{start="5m"} 0.6

# Normal half-interval cutoff for left-side extrapolation.
eval instant at 50m rate(testcounter_zero_cutoff[20m])
	{start="0m"} 0.6
	{start="1m"} 0.6
	{start="2m"} 0.6
	{start="3m"} 0.6
	{start="4m"} 0.6
	{start="5m"} 0.6


# count_scalar for a non-empty vector should return scalar element count.
eval instant at 50m count_scalar(http_requests)
	8

# count_scalar for an empty vector should return scalar 0.
eval instant at 50m count_scalar(nonexistent)
	0

eval instant at 50m http_requests{group!="canary"}
	http_requests{group="production", instance="1", job="app-server"} 600
	http_requests{group="production", instance="0", job="app-server"} 500
	http_requests{group="production", instance="1", job="api-server"} 200
	http_requests{group="production", instance="0", job="api-server"} 100

eval instant at 50m http_requests{job=~".+-server",group!="canary"}
	http_requests{group="production", instance="1", job="app-server"} 600
	http_requests{group="production", instance="0", job="app-server"} 500
	http_requests{group="production", instance="1", job="api-server"} 200
	http_requests{group="production", instance="0", job="api-server"} 100

eval instant at 50m http_requests{job!~"api-.+",group!="canary"}
	http_requests{group="production", instance="1", job="app-server"} 600
	http_requests{group="production", instance="0", job="app-server"} 500

eval instant at 50m count_scalar(http_requests{job=~"server"})
	0

eval instant at 50m http_requests{group="production",job=~"api-.+"}
	http_requests{group="production", instance="0", job="api-server"} 100
	http_requests{group="production", instance="1", job="api-server"} 200

eval instant at 50m abs(-1 * http_requests{group="production",job="api-server"})
	{group="production", instance="0", job="api-server"} 100
	{group="production", instance="1", job="api-server"} 200

eval instant at 50m floor(0.004 * http_requests{group="production",job="api-server"})
	{group="production", instance="0", job="api-server"} 0
	{group="production", instance="1", job="api-server"} 0

eval instant at 50m ceil(0.004 * http_requests{group="production",job="api-server"})
	{group="production", instance="0", job="api-server"} 1
	{group="production", instance="1", job="api-server"} 1

eval instant at 50m round(0.004 * http_requests{group="production",job="api-server"})
	{group="production", instance="0", job="api-server"} 0
	{group="production", instance="1", job="api-server"} 1

# Round should correctly handle negative numbers.
eval instant at 50m round(-1 * (0.004 * http_requests{group="production",job="api-server"}))
	{group="production", instance="0", job="api-server"} 0
	{group="production", instance="1", job="api-server"} -1

# Round should round half up.
eval instant at 50m round(0.005 * http_requests{group="production",job="api-server"})
	{group="production", instance="0", job="api-server"} 1
	{group="production", instance="1", job="api-server"} 1

eval instant at 50m round(-1 * (0.005 * http_requests{group="production",job="api-server"}))
	{group="production", instance="0", job="api-server"} 0
	{group="production", instance="1", job="api-server"} -1

eval instant at 50m round(1 + 0.005 * http_requests{group="production",job="api-server"})
	{group="production", instance="0", job="api-server"} 2
	{group="production", instance="1", job="api-server"} 2

eval instant at 50m round(-1 * (1 + 0.005 * http_requests{group="production",job="api-server"}))
	{group="production", instance="0", job="api-server"} -1
	{group="production", instance="1", job="api-server"} -2

# Round should accept the number to round nearest to.
eval instant at 50m round(0.0005 * http_requests{group="production",job="api-server"}, 0.1)
	{group="production", instance="0", job="api-server"} 0.1
	{group="production", instance="1", job="api-server"} 0.1

eval instant at 50m round(2.1 + 0.0005 * http_requests{group="production",job="api-server"}, 0.1)
	{group="production", instance="0", job="api-server"} 2.2
	{group="production", instance="1", job="api-server"} 2.2

eval instant at 50m round(5.2 + 0.0005 * http_requests{group="production",job="api-server"}, 0.1)
	{group="production", instance="0", job="api-server"} 5.3
	{group="production", instance="1", job="api-server"} 5.3

# Round should work correctly with negative numbers and multiple decimal places.
eval instant at 50m round(-1 * (5.2 + 0.0005 * http_requests{group="production",job="api-server"}), 0.1)
	{group="production", instance="0", job="api-server"} -5.2
	{group="production", instance="1", job="api-server"} -5.3

# Round should work correctly with big toNearests.
eval instant at 50m round(0.025 * http_requests{group="production",job="api-server"}, 5)
	{group="production", instance="0", job="api-server"} 5
	{group="production", instance="1", job="api-server"} 5

eval instant at 50m round(0.045 * http_requests{group="production",job="api-server"}, 5)
	{group="production", instance="0", job="api-server"} 5
	{group="production", instance="1", job="api-server"} 10

eval instant at 50m avg_over_time(http_requests{group="production",job="api-server"}[1h])
	{group="production", instance="0", job="api-server"} 50
	{group="production", instance="1", job="api-server"} 100

eval instant at 50m count_over_time(http_requests{group="production",job="api-server"}[1h])
	{group="production", instance="0", job="api-server"} 11
	{group="production", instance="1", job="api-server"} 11

eval instant at 50m max_over_time(http_requests{group="production",job="api-server"}[1h])
	{group="production", instance="0", job="api-server"} 100
	{group="production", instance="1", job="api-server"} 200

eval instant at 50m min_over_time(http_requests{group="production",job="api-server"}[1h])
	{group="production", instance="0", job="api-server"} 0
	{group="production", instance="1", job="api-server"} 0

eval instant at 50m sum_over_time(http_requests{group="production",job="api-server"}[1h])
	{group="production", instance="0", job="api-server"} 550
	{group="production", instance="1", job="api-server"} 1100

eval instant at 50m time()
	3000

eval instant at 50m drop_common_labels(http_requests{group="production",job="api-server"})
	http_requests{instance="0"} 100
	http_requests{instance="1"} 200

eval instant at 50m {__name__=~".+"}
	http_requests{group="canary", instance="0", job="api-server"} 300
	http_requests{group="canary", instance="0", job="app-server"} 700
	http_requests{group="canary", instance="1", job="api-server"} 400
	http_requests{group="canary", instance="1", job="app-server"} 800
	http_requests{group="production", instance="0", job="api-server"} 100
	http_requests{group="production", instance="0", job="app-server"} 500
	http_requests{group="production", instance="1", job="api-server"} 200
	http_requests{group="production", instance="1", job="app-server"} 600
	testcounter_reset_end 0
	testcounter_reset_middle 50
	x{y="testvalue"} 100
	label_grouping_test{a="a", b="abb"} 200
	label_grouping_test{a="aa", b="bb"} 100
	vector_matching_a{l="x"} 10
	vector_matching_a{l="y"} 20
	vector_matching_b{l="x"} 40
	cpu_count{instance="1", type="smp"} 200
	cpu_count{instance="0", type="smp"} 100
	cpu_count{instance="0", type="numa"} 300


eval instant at 50m {job=~".+-server", job!~"api-.+"}
	http_requests{group="canary", instance="0", job="app-server"} 700
	http_requests{group="canary", instance="1", job="app-server"} 800
	http_requests{group="production", instance="0", job="app-server"} 500
	http_requests{group="production", instance="1", job="app-server"} 600

eval instant at 50m absent(nonexistent)
	{} 1


eval instant at 50m absent(nonexistent{job="testjob", instance="testinstance", method=~".x"})
	{instance="testinstance", job="testjob"} 1

eval instant at 50m count_scalar(absent(http_requests))
	0

eval instant at 50m count_scalar(absent(sum(http_requests)))
	0

eval instant at 50m absent(sum(nonexistent{job="testjob", instance="testinstance"}))
	{} 1

eval instant at 50m http_requests{group="production",job="api-server"} offset 5m
	http_requests{group="production", instance="0", job="api-server"} 90
	http_requests{group="production", instance="1", job="api-server"} 180

eval instant at 50m rate(http_requests{group="production",job="api-server"}[10m] offset 5m)
	{group="production", instance="0", job="api-server"} 0.03333333333333333
	{group="production", instance="1", job="api-server"} 0.06666666666666667

eval instant at 50m http_requests{group="canary", instance="0", job="api-server"} / 0
	{group="canary", instance="0", job="api-server"} +Inf

eval instant at 50m -1 * http_requests{group="canary", instance="0", job="api-server"} / 0
	{group="canary", instance="0", job="api-server"} -Inf

eval instant at 50m 0 * http_requests{group="canary", instance="0", job="api-server"} / 0
	{group="canary", instance="0", job="api-server"} NaN

eval instant at 50m 0 * http_requests{group="canary", instance="0", job="api-server"} % 0
	{group="canary", instance="0", job="api-server"} NaN

eval instant at 50m exp(vector_matching_a)
	{l="x"} 22026.465794806718
	{l="y"} 485165195.4097903

eval instant at 50m exp(vector_matching_a - 10)
	{l="y"} 22026.465794806718
	{l="x"} 1

eval instant at 50m exp(vector_matching_a - 20)
	{l="x"} 4.5399929762484854e-05
	{l="y"} 1

eval instant at 50m ln(vector_matching_a)
	{l="x"} 2.302585092994046
	{l="y"} 2.995732273553991

eval instant at 50m ln(vector_matching_a - 10)
	{l="y"} 2.302585092994046
	{l="x"} -Inf

eval instant at 50m ln(vector_matching_a - 20)
	{l="y"} -Inf
	{l="x"} NaN

eval instant at 50m exp(ln(vector_matching_a))
	{l="y"} 20
	{l="x"} 10

eval instant at 50m sqrt(vector_matching_a)
	{l="x"} 3.1622776601683795
	{l="y"} 4.47213595499958

eval instant at 50m log2(vector_matching_a)
	{l="x"} 3.3219280948873626
	{l="y"} 4.321928094887363

eval instant at 50m log2(vector_matching_a - 10)
	{l="y"} 3.3219280948873626
	{l="x"} -Inf

eval instant at 50m log2(vector_matching_a - 20)
	{l="x"} NaN
	{l="y"} -Inf

eval instant at 50m log10(vector_matching_a)
	{l="x"} 1
	{l="y"} 1.301029995663981

eval instant at 50m log10(vector_matching_a - 10)
	{l="y"} 1
	{l="x"} -Inf

eval instant at 50m log10(vector_matching_a - 20)
	{l="x"} NaN
	{l="y"} -Inf


# Matrix tests.

clear
load 1h
	testmetric{testlabel="1"} 1 1
	testmetric{testlabel="2"} _ 2

eval instant at 0h drop_common_labels(testmetric)
	testmetric 1

eval instant at 1h drop_common_labels(testmetric)
	testmetric{testlabel="1"} 1
	testmetric{testlabel="2"} 2

clear
load 1h
	testmetric{testlabel="1"} 1 1
	testmetric{testlabel="2"} 2 _

eval instant at 0h sum(testmetric) keep_common
	{} 3

eval instant at 1h sum(testmetric) keep_common
	{testlabel="1"} 1

clear
load 1h
	testmetric{aa="bb"} 1
	testmetric{a="abb"} 2

eval instant at 0h testmetric
	testmetric{aa="bb"} 1
	testmetric{a="abb"} 2