@@ -534,4 +534,132 @@ mod tests {
534534 "Expected valid Stream to be built successfully"
535535 ) ;
536536 }
537+
538+ #[ cfg( feature = "spec_unstable_metrics_views" ) ]
539+ #[ test]
540+ fn stream_histogram_bucket_validation ( ) {
541+ use super :: Aggregation ;
542+
543+ // Test with valid bucket boundaries
544+ let valid_boundaries = vec ! [ 1.0 , 2.0 , 5.0 , 10.0 , 20.0 , 50.0 , 100.0 ] ;
545+ let builder = StreamBuilder :: new ( )
546+ . with_name ( "valid_histogram" )
547+ . with_aggregation ( Aggregation :: ExplicitBucketHistogram {
548+ boundaries : valid_boundaries. clone ( ) ,
549+ record_min_max : true ,
550+ } ) ;
551+
552+ let result = builder. build ( ) ;
553+ assert ! (
554+ result. is_ok( ) ,
555+ "Expected successful build with valid bucket boundaries"
556+ ) ;
557+
558+ // Test with invalid bucket boundaries (NaN and Infinity)
559+
560+ // Test with NaN
561+ let invalid_nan_boundaries = vec ! [ 1.0 , 2.0 , f64 :: NAN , 10.0 ] ;
562+
563+ let builder = StreamBuilder :: new ( )
564+ . with_name ( "invalid_histogram_nan" )
565+ . with_aggregation ( Aggregation :: ExplicitBucketHistogram {
566+ boundaries : invalid_nan_boundaries,
567+ record_min_max : true ,
568+ } ) ;
569+
570+ let result = builder. build ( ) ;
571+ assert ! (
572+ result. is_err( ) ,
573+ "Expected error for NaN in bucket boundaries"
574+ ) ;
575+ assert_eq ! (
576+ result. err( ) . unwrap( ) . to_string( ) ,
577+ "Bucket boundaries must not contain NaN, Infinity, or -Infinity" ,
578+ "Expected correct validation error for NaN"
579+ ) ;
580+
581+ // Test with infinity
582+ let invalid_inf_boundaries = vec ! [ 1.0 , 5.0 , f64 :: INFINITY , 100.0 ] ;
583+
584+ let builder = StreamBuilder :: new ( )
585+ . with_name ( "invalid_histogram_inf" )
586+ . with_aggregation ( Aggregation :: ExplicitBucketHistogram {
587+ boundaries : invalid_inf_boundaries,
588+ record_min_max : true ,
589+ } ) ;
590+
591+ let result = builder. build ( ) ;
592+ assert ! (
593+ result. is_err( ) ,
594+ "Expected error for Infinity in bucket boundaries"
595+ ) ;
596+ assert_eq ! (
597+ result. err( ) . unwrap( ) . to_string( ) ,
598+ "Bucket boundaries must not contain NaN, Infinity, or -Infinity" ,
599+ "Expected correct validation error for Infinity"
600+ ) ;
601+
602+ // Test with negative infinity
603+ let invalid_neg_inf_boundaries = vec ! [ f64 :: NEG_INFINITY , 5.0 , 10.0 , 100.0 ] ;
604+
605+ let builder = StreamBuilder :: new ( )
606+ . with_name ( "invalid_histogram_neg_inf" )
607+ . with_aggregation ( Aggregation :: ExplicitBucketHistogram {
608+ boundaries : invalid_neg_inf_boundaries,
609+ record_min_max : true ,
610+ } ) ;
611+
612+ let result = builder. build ( ) ;
613+ assert ! (
614+ result. is_err( ) ,
615+ "Expected error for negative Infinity in bucket boundaries"
616+ ) ;
617+ assert_eq ! (
618+ result. err( ) . unwrap( ) . to_string( ) ,
619+ "Bucket boundaries must not contain NaN, Infinity, or -Infinity" ,
620+ "Expected correct validation error for negative Infinity"
621+ ) ;
622+
623+ // Test with unsorted bucket boundaries
624+ let unsorted_boundaries = vec ! [ 1.0 , 5.0 , 2.0 , 10.0 ] ; // 2.0 comes after 5.0, which is incorrect
625+
626+ let builder = StreamBuilder :: new ( )
627+ . with_name ( "unsorted_histogram" )
628+ . with_aggregation ( Aggregation :: ExplicitBucketHistogram {
629+ boundaries : unsorted_boundaries,
630+ record_min_max : true ,
631+ } ) ;
632+
633+ let result = builder. build ( ) ;
634+ assert ! (
635+ result. is_err( ) ,
636+ "Expected error for unsorted bucket boundaries"
637+ ) ;
638+ assert_eq ! (
639+ result. err( ) . unwrap( ) . to_string( ) ,
640+ "Bucket boundaries must be sorted and not contain any duplicates" ,
641+ "Expected correct validation error for unsorted boundaries"
642+ ) ;
643+
644+ // Test with duplicate bucket boundaries
645+ let duplicate_boundaries = vec ! [ 1.0 , 2.0 , 5.0 , 5.0 , 10.0 ] ; // 5.0 appears twice
646+
647+ let builder = StreamBuilder :: new ( )
648+ . with_name ( "duplicate_histogram" )
649+ . with_aggregation ( Aggregation :: ExplicitBucketHistogram {
650+ boundaries : duplicate_boundaries,
651+ record_min_max : true ,
652+ } ) ;
653+
654+ let result = builder. build ( ) ;
655+ assert ! (
656+ result. is_err( ) ,
657+ "Expected error for duplicate bucket boundaries"
658+ ) ;
659+ assert_eq ! (
660+ result. err( ) . unwrap( ) . to_string( ) ,
661+ "Bucket boundaries must be sorted and not contain any duplicates" ,
662+ "Expected correct validation error for duplicate boundaries"
663+ ) ;
664+ }
537665}
0 commit comments