@@ -1251,6 +1251,140 @@ mod tests {
1251
1251
counter_multithreaded_aggregation_helper ( Temporality :: Cumulative ) ;
1252
1252
}
1253
1253
1254
+ #[ tokio:: test( flavor = "multi_thread" , worker_threads = 1 ) ]
1255
+ async fn synchronous_instruments_cumulative_with_gap_in_measurements ( ) {
1256
+ // Run this test with stdout enabled to see output.
1257
+ // cargo test synchronous_instruments_cumulative_with_gap_in_measurements --features=testing -- --nocapture
1258
+
1259
+ synchronous_instruments_cumulative_with_gap_in_measurements_helper ( "counter" ) ;
1260
+ synchronous_instruments_cumulative_with_gap_in_measurements_helper ( "updown_counter" ) ;
1261
+ synchronous_instruments_cumulative_with_gap_in_measurements_helper ( "histogram" ) ;
1262
+
1263
+ /* Synchronous Gauge has an aggregation bug. Uncomment the code below to run the test for gauge
1264
+ once this issue is fixed: https://github.com/open-telemetry/opentelemetry-rust/issues/1975
1265
+ */
1266
+
1267
+ // synchronous_instruments_cumulative_with_gap_in_measurements_helper("gauge");
1268
+ }
1269
+
1270
+ fn synchronous_instruments_cumulative_with_gap_in_measurements_helper (
1271
+ instrument_name : & ' static str ,
1272
+ ) {
1273
+ let mut test_context = TestContext :: new ( Temporality :: Cumulative ) ;
1274
+ let attributes = & [ KeyValue :: new ( "key1" , "value1" ) ] ;
1275
+
1276
+ // Create instrument and emit measurements
1277
+ match instrument_name {
1278
+ "counter" => {
1279
+ let counter = test_context. meter ( ) . u64_counter ( "test_counter" ) . init ( ) ;
1280
+ counter. add ( 5 , & [ ] ) ;
1281
+ counter. add ( 10 , attributes) ;
1282
+ }
1283
+ "updown_counter" => {
1284
+ let updown_counter = test_context
1285
+ . meter ( )
1286
+ . i64_up_down_counter ( "test_updowncounter" )
1287
+ . init ( ) ;
1288
+ updown_counter. add ( 15 , & [ ] ) ;
1289
+ updown_counter. add ( 20 , attributes) ;
1290
+ }
1291
+ "histogram" => {
1292
+ let histogram = test_context. meter ( ) . u64_histogram ( "test_histogram" ) . init ( ) ;
1293
+ histogram. record ( 25 , & [ ] ) ;
1294
+ histogram. record ( 30 , attributes) ;
1295
+ }
1296
+ "gauge" => {
1297
+ let gauge = test_context. meter ( ) . u64_gauge ( "test_gauge" ) . init ( ) ;
1298
+ gauge. record ( 35 , & [ ] ) ;
1299
+ gauge. record ( 40 , attributes) ;
1300
+ }
1301
+ _ => panic ! ( "Incorrect instrument kind provided" ) ,
1302
+ } ;
1303
+
1304
+ test_context. flush_metrics ( ) ;
1305
+
1306
+ // Test the first export
1307
+ assert_correct_export ( & mut test_context, instrument_name) ;
1308
+
1309
+ // Reset and export again without making any measurements
1310
+ test_context. reset_metrics ( ) ;
1311
+
1312
+ test_context. flush_metrics ( ) ;
1313
+
1314
+ // Test that latest export has the same data as the previous one
1315
+ assert_correct_export ( & mut test_context, instrument_name) ;
1316
+
1317
+ fn assert_correct_export ( test_context : & mut TestContext , instrument_name : & ' static str ) {
1318
+ match instrument_name {
1319
+ "counter" => {
1320
+ let counter_data =
1321
+ test_context. get_aggregation :: < data:: Sum < u64 > > ( "test_counter" , None ) ;
1322
+ assert_eq ! ( counter_data. data_points. len( ) , 2 ) ;
1323
+ let zero_attribute_datapoint =
1324
+ find_datapoint_with_no_attributes ( & counter_data. data_points )
1325
+ . expect ( "datapoint with no attributes expected" ) ;
1326
+ assert_eq ! ( zero_attribute_datapoint. value, 5 ) ;
1327
+ let data_point1 =
1328
+ find_datapoint_with_key_value ( & counter_data. data_points , "key1" , "value1" )
1329
+ . expect ( "datapoint with key1=value1 expected" ) ;
1330
+ assert_eq ! ( data_point1. value, 10 ) ;
1331
+ }
1332
+ "updown_counter" => {
1333
+ let updown_counter_data =
1334
+ test_context. get_aggregation :: < data:: Sum < i64 > > ( "test_updowncounter" , None ) ;
1335
+ assert_eq ! ( updown_counter_data. data_points. len( ) , 2 ) ;
1336
+ let zero_attribute_datapoint =
1337
+ find_datapoint_with_no_attributes ( & updown_counter_data. data_points )
1338
+ . expect ( "datapoint with no attributes expected" ) ;
1339
+ assert_eq ! ( zero_attribute_datapoint. value, 15 ) ;
1340
+ let data_point1 = find_datapoint_with_key_value (
1341
+ & updown_counter_data. data_points ,
1342
+ "key1" ,
1343
+ "value1" ,
1344
+ )
1345
+ . expect ( "datapoint with key1=value1 expected" ) ;
1346
+ assert_eq ! ( data_point1. value, 20 ) ;
1347
+ }
1348
+ "histogram" => {
1349
+ let histogram_data = test_context
1350
+ . get_aggregation :: < data:: Histogram < u64 > > ( "test_histogram" , None ) ;
1351
+ assert_eq ! ( histogram_data. data_points. len( ) , 2 ) ;
1352
+ let zero_attribute_datapoint =
1353
+ find_histogram_datapoint_with_no_attributes ( & histogram_data. data_points )
1354
+ . expect ( "datapoint with no attributes expected" ) ;
1355
+ assert_eq ! ( zero_attribute_datapoint. count, 1 ) ;
1356
+ assert_eq ! ( zero_attribute_datapoint. sum, 25 ) ;
1357
+ assert_eq ! ( zero_attribute_datapoint. min, Some ( 25 ) ) ;
1358
+ assert_eq ! ( zero_attribute_datapoint. max, Some ( 25 ) ) ;
1359
+ let data_point1 = find_histogram_datapoint_with_key_value (
1360
+ & histogram_data. data_points ,
1361
+ "key1" ,
1362
+ "value1" ,
1363
+ )
1364
+ . expect ( "datapoint with key1=value1 expected" ) ;
1365
+ assert_eq ! ( data_point1. count, 1 ) ;
1366
+ assert_eq ! ( data_point1. sum, 30 ) ;
1367
+ assert_eq ! ( data_point1. min, Some ( 30 ) ) ;
1368
+ assert_eq ! ( data_point1. max, Some ( 30 ) ) ;
1369
+ }
1370
+ "gauge" => {
1371
+ let gauge_data =
1372
+ test_context. get_aggregation :: < data:: Gauge < u64 > > ( "test_gauge" , None ) ;
1373
+ assert_eq ! ( gauge_data. data_points. len( ) , 2 ) ;
1374
+ let zero_attribute_datapoint =
1375
+ find_datapoint_with_no_attributes ( & gauge_data. data_points )
1376
+ . expect ( "datapoint with no attributes expected" ) ;
1377
+ assert_eq ! ( zero_attribute_datapoint. value, 35 ) ;
1378
+ let data_point1 =
1379
+ find_datapoint_with_key_value ( & gauge_data. data_points , "key1" , "value1" )
1380
+ . expect ( "datapoint with key1=value1 expected" ) ;
1381
+ assert_eq ! ( data_point1. value, 40 ) ;
1382
+ }
1383
+ _ => panic ! ( "Incorrect instrument kind provided" ) ,
1384
+ }
1385
+ }
1386
+ }
1387
+
1254
1388
fn counter_multithreaded_aggregation_helper ( temporality : Temporality ) {
1255
1389
// Arrange
1256
1390
let mut test_context = TestContext :: new ( temporality) ;
@@ -1716,6 +1850,14 @@ mod tests {
1716
1850
} )
1717
1851
}
1718
1852
1853
+ fn find_histogram_datapoint_with_no_attributes < T > (
1854
+ data_points : & [ HistogramDataPoint < T > ] ,
1855
+ ) -> Option < & HistogramDataPoint < T > > {
1856
+ data_points
1857
+ . iter ( )
1858
+ . find ( |& datapoint| datapoint. attributes . is_empty ( ) )
1859
+ }
1860
+
1719
1861
fn find_scope_metric < ' a > (
1720
1862
metrics : & ' a [ ScopeMetrics ] ,
1721
1863
name : & ' a str ,
0 commit comments