Skip to content

Commit bd572d5

Browse files
authored
Fix max_scale validation of exponential histogram configuration (#1452)
`metrics::Aggregation::validate()` has a bug that limits `max_scale` of a `Base2ExponentialHistogram` to the interval `[10, 20]` instead of the expected `[-10, 20]`.
1 parent 7f77ec6 commit bd572d5

File tree

2 files changed

+88
-1
lines changed

2 files changed

+88
-1
lines changed

opentelemetry-sdk/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
### Fixed
3333

3434
- Fix delta aggregation metric reuse. (#1434)
35+
- Fix `max_scale` validation of exponential histogram configuration. (#1452)
3536

3637
## v0.21.1
3738

opentelemetry-sdk/src/metrics/aggregation.rs

Lines changed: 87 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ impl Aggregation {
134134
max_scale,
135135
)));
136136
}
137-
if *max_scale < -EXPO_MIN_SCALE {
137+
if *max_scale < EXPO_MIN_SCALE {
138138
return Err(MetricsError::Config(format!(
139139
"aggregation: exponential histogram: max scale ({}) is less than -10",
140140
max_scale,
@@ -146,3 +146,89 @@ impl Aggregation {
146146
}
147147
}
148148
}
149+
150+
#[cfg(test)]
151+
mod tests {
152+
use crate::metrics::{
153+
internal::{EXPO_MAX_SCALE, EXPO_MIN_SCALE},
154+
Aggregation,
155+
};
156+
use opentelemetry::metrics::{MetricsError, Result};
157+
158+
#[test]
159+
fn validate_aggregation() {
160+
struct TestCase {
161+
name: &'static str,
162+
input: Aggregation,
163+
check: Box<dyn Fn(Result<()>) -> bool>,
164+
}
165+
let ok = Box::new(|result: Result<()>| result.is_ok());
166+
let config_error = Box::new(|result| matches!(result, Err(MetricsError::Config(_))));
167+
168+
let test_cases: Vec<TestCase> = vec![
169+
TestCase {
170+
name: "base2 histogram with maximum max_scale",
171+
input: Aggregation::Base2ExponentialHistogram {
172+
max_size: 160,
173+
max_scale: EXPO_MAX_SCALE,
174+
record_min_max: true,
175+
},
176+
check: ok.clone(),
177+
},
178+
TestCase {
179+
name: "base2 histogram with minimum max_scale",
180+
input: Aggregation::Base2ExponentialHistogram {
181+
max_size: 160,
182+
max_scale: EXPO_MIN_SCALE,
183+
record_min_max: true,
184+
},
185+
check: ok.clone(),
186+
},
187+
TestCase {
188+
name: "base2 histogram with max_scale too small",
189+
input: Aggregation::Base2ExponentialHistogram {
190+
max_size: 160,
191+
max_scale: EXPO_MIN_SCALE - 1,
192+
record_min_max: true,
193+
},
194+
check: config_error.clone(),
195+
},
196+
TestCase {
197+
name: "base2 histogram with max_scale too big",
198+
input: Aggregation::Base2ExponentialHistogram {
199+
max_size: 160,
200+
max_scale: EXPO_MAX_SCALE + 1,
201+
record_min_max: true,
202+
},
203+
check: config_error.clone(),
204+
},
205+
TestCase {
206+
name: "explicit histogram with one boundary",
207+
input: Aggregation::ExplicitBucketHistogram {
208+
boundaries: vec![0.0],
209+
record_min_max: true,
210+
},
211+
check: ok.clone(),
212+
},
213+
TestCase {
214+
name: "explicit histogram with monotonic boundaries",
215+
input: Aggregation::ExplicitBucketHistogram {
216+
boundaries: vec![0.0, 2.0, 4.0, 8.0],
217+
record_min_max: true,
218+
},
219+
check: ok.clone(),
220+
},
221+
TestCase {
222+
name: "explicit histogram with non-monotonic boundaries",
223+
input: Aggregation::ExplicitBucketHistogram {
224+
boundaries: vec![2.0, 0.0, 4.0, 8.0],
225+
record_min_max: true,
226+
},
227+
check: config_error.clone(),
228+
},
229+
];
230+
for test in test_cases {
231+
assert!((test.check)(test.input.validate()), "{}", test.name)
232+
}
233+
}
234+
}

0 commit comments

Comments
 (0)