Skip to content

Commit

Permalink
core: sample-count is now stable (#1625)
Browse files Browse the repository at this point in the history
Update `:sample-count` operator to be considered stable. It
has been around for a few months and usage seems to match
user expectations.
  • Loading branch information
brharrington authored Mar 11, 2024
1 parent e689860 commit a422f5e
Show file tree
Hide file tree
Showing 2 changed files with 10 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1249,8 +1249,6 @@ object MathVocabulary extends Vocabulary {

override def name: String = "sample-count"

override def isStable: Boolean = false

override def matches(stack: List[Any]): Boolean = {
stack match {
case DoubleType(_) :: DoubleType(_) :: (_: Query) :: _ => true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ package com.netflix.atlas.core.model
import java.util.concurrent.TimeUnit
import java.util.stream.Collectors
import com.netflix.atlas.core.stacklang.Interpreter
import com.netflix.atlas.core.util.Features
import com.netflix.spectator.api.Counter
import com.netflix.spectator.api.DefaultRegistry
import com.netflix.spectator.api.histogram.PercentileBuckets
Expand Down Expand Up @@ -50,14 +49,6 @@ class PercentilesSuite extends FunSuite {
expr.eval(context, input).data
}

def evalUnstable(str: String, input: List[TimeSeries]): List[TimeSeries] = {
val expr = interpreter.execute(str, Map.empty[String, Any], Features.UNSTABLE).stack match {
case (v: TimeSeriesExpr) :: _ => v
case _ => throw new IllegalArgumentException("invalid expr")
}
expr.eval(context, input).data
}

private val input100 = {
(0 until 100).map { i =>
val bucket = f"D${PercentileBuckets.indexOf(i)}%04X"
Expand Down Expand Up @@ -361,72 +352,72 @@ class PercentilesSuite extends FunSuite {
}

test("sample-count: distribution summary, range") {
val data = evalUnstable("name,test,:eq,50,100,:sample-count", input100)
val data = eval("name,test,:eq,50,100,:sample-count", input100)
assertEquals(data.size, 1)
val t = data.head
assertEqualsDouble(t.data(0L), 0.9, 1e-6)
}

test("sample-count: distribution summary, 0 - N") {
val data = evalUnstable("name,test,:eq,0,50,:sample-count", input100)
val data = eval("name,test,:eq,0,50,:sample-count", input100)
assertEquals(data.size, 1)
val t = data.head
assertEqualsDouble(t.data(0L), 0.85, 1e-6)
}

test("sample-count: distribution summary, N - Max") {
val data = evalUnstable("name,test,:eq,50,Infinity,:sample-count", input100)
val data = eval("name,test,:eq,50,Infinity,:sample-count", input100)
assertEquals(data.size, 1)
val t = data.head
assertEqualsDouble(t.data(0L), 0.9, 1e-6)
}

test("sample-count: distribution summary, Min >= Max") {
val e = intercept[IllegalArgumentException] {
evalUnstable("name,test,:eq,5,5,:sample-count", input100)
eval("name,test,:eq,5,5,:sample-count", input100)
}
assertEquals(e.getMessage, "requirement failed: min >= max (min=5.0, max=5.0)")
}

test("sample-count: distribution summary, Min < 0") {
val e = intercept[IllegalArgumentException] {
evalUnstable("name,test,:eq,-5,5,:sample-count", input100)
eval("name,test,:eq,-5,5,:sample-count", input100)
}
assertEquals(e.getMessage, "requirement failed: min < 0 (min=-5.0)")
}

test("sample-count: distribution summary, NaN - 100") {
val e = intercept[IllegalArgumentException] {
evalUnstable("name,test,:eq,NaN,100,:sample-count", input100)
eval("name,test,:eq,NaN,100,:sample-count", input100)
}
assertEquals(e.getMessage, "requirement failed: min >= max (min=NaN, max=100.0)")
}

test("sample-count: distribution summary, 0 - NaN") {
val e = intercept[IllegalArgumentException] {
evalUnstable("name,test,:eq,0,NaN,:sample-count", input100)
eval("name,test,:eq,0,NaN,:sample-count", input100)
}
assertEquals(e.getMessage, "requirement failed: min >= max (min=0.0, max=NaN)")
}

test("sample-count: distribution summary, NaN - NaN") {
val e = intercept[IllegalArgumentException] {
evalUnstable("name,test,:eq,NaN,NaN,:sample-count", input100)
eval("name,test,:eq,NaN,NaN,:sample-count", input100)
}
assertEquals(e.getMessage, "requirement failed: min >= max (min=NaN, max=NaN)")
}

test("sample-count: timer, range too high") {
// Timer range is in seconds, sample data is 0-100 ns
val data = evalUnstable("name,test,:eq,50,100,:sample-count", inputTimer100)
val data = eval("name,test,:eq,50,100,:sample-count", inputTimer100)
assertEquals(data.size, 1)
val t = data.head
assert(t.data(0L).isNaN)
}

test("sample-count: timer, range") {
// Timer range is in seconds, sample data is 0-100 ns
val data = evalUnstable("name,test,:eq,50e-9,100e-9,:sample-count", inputTimer100)
val data = eval("name,test,:eq,50e-9,100e-9,:sample-count", inputTimer100)
assertEquals(data.size, 1)
val t = data.head
assertEqualsDouble(t.data(0L), 0.9, 1e-6)
Expand Down

0 comments on commit a422f5e

Please sign in to comment.