@@ -773,6 +773,115 @@ mod tests {
773
773
) ;
774
774
}
775
775
776
+ // "multi_thread" tokio flavor must be used else flush won't
777
+ // be able to make progress!
778
+ #[ tokio:: test( flavor = "multi_thread" , worker_threads = 1 ) ]
779
+ #[ ignore = "Known bug: https://github.com/open-telemetry/opentelemetry-rust/issues/1598" ]
780
+ async fn delta_memory_efficiency_test ( ) {
781
+ // Run this test with stdout enabled to see output.
782
+ // cargo test delta_memory_efficiency_test --features=metrics,testing -- --nocapture
783
+
784
+ // Arrange
785
+ let exporter = InMemoryMetricsExporterBuilder :: new ( )
786
+ . with_temporality_selector ( DeltaTemporalitySelector ( ) )
787
+ . build ( ) ;
788
+ let reader = PeriodicReader :: builder ( exporter. clone ( ) , runtime:: Tokio ) . build ( ) ;
789
+ let meter_provider = SdkMeterProvider :: builder ( ) . with_reader ( reader) . build ( ) ;
790
+
791
+ // Act
792
+ let meter = meter_provider. meter ( "test" ) ;
793
+ let counter = meter
794
+ . u64_counter ( "my_counter" )
795
+ . with_unit ( Unit :: new ( "my_unit" ) )
796
+ . init ( ) ;
797
+ counter. add ( 1 , & [ KeyValue :: new ( "key1" , "value1" ) ] ) ;
798
+ counter. add ( 1 , & [ KeyValue :: new ( "key1" , "value1" ) ] ) ;
799
+ counter. add ( 1 , & [ KeyValue :: new ( "key1" , "value1" ) ] ) ;
800
+ counter. add ( 1 , & [ KeyValue :: new ( "key1" , "value1" ) ] ) ;
801
+ counter. add ( 1 , & [ KeyValue :: new ( "key1" , "value1" ) ] ) ;
802
+
803
+ counter. add ( 1 , & [ KeyValue :: new ( "key1" , "value2" ) ] ) ;
804
+ counter. add ( 1 , & [ KeyValue :: new ( "key1" , "value2" ) ] ) ;
805
+ counter. add ( 1 , & [ KeyValue :: new ( "key1" , "value2" ) ] ) ;
806
+
807
+ meter_provider. force_flush ( ) . unwrap ( ) ;
808
+
809
+ // Assert
810
+ let resource_metrics = exporter
811
+ . get_finished_metrics ( )
812
+ . expect ( "metrics are expected to be exported." ) ;
813
+ assert ! ( !resource_metrics. is_empty( ) ) ;
814
+ let metric = & resource_metrics[ 0 ] . scope_metrics [ 0 ] . metrics [ 0 ] ;
815
+ assert_eq ! ( metric. name, "my_counter" ) ;
816
+ assert_eq ! ( metric. unit. as_str( ) , "my_unit" ) ;
817
+ let sum = metric
818
+ . data
819
+ . as_any ( )
820
+ . downcast_ref :: < data:: Sum < u64 > > ( )
821
+ . expect ( "Sum aggregation expected for Counter instruments by default" ) ;
822
+
823
+ // Expecting 2 time-series.
824
+ assert_eq ! ( sum. data_points. len( ) , 2 ) ;
825
+ assert ! ( sum. is_monotonic, "Counter should produce monotonic." ) ;
826
+ assert_eq ! (
827
+ sum. temporality,
828
+ data:: Temporality :: Delta ,
829
+ "Should produce Delta as configured"
830
+ ) ;
831
+
832
+ // find and validate key1=value1 datapoint
833
+ let mut data_point1 = None ;
834
+ for datapoint in & sum. data_points {
835
+ if datapoint
836
+ . attributes
837
+ . iter ( )
838
+ . any ( |( k, v) | k. as_str ( ) == "key1" && v. as_str ( ) == "value1" )
839
+ {
840
+ data_point1 = Some ( datapoint) ;
841
+ }
842
+ }
843
+ assert_eq ! (
844
+ data_point1
845
+ . expect( "datapoint with key1=value1 expected" )
846
+ . value,
847
+ 5
848
+ ) ;
849
+
850
+ // find and validate key1=value2 datapoint
851
+ let mut data_point1 = None ;
852
+ for datapoint in & sum. data_points {
853
+ if datapoint
854
+ . attributes
855
+ . iter ( )
856
+ . any ( |( k, v) | k. as_str ( ) == "key1" && v. as_str ( ) == "value2" )
857
+ {
858
+ data_point1 = Some ( datapoint) ;
859
+ }
860
+ }
861
+ assert_eq ! (
862
+ data_point1
863
+ . expect( "datapoint with key1=value2 expected" )
864
+ . value,
865
+ 3
866
+ ) ;
867
+
868
+ // flush again, and validate that nothing is flushed
869
+ // as delta temporality.
870
+ meter_provider. force_flush ( ) . unwrap ( ) ;
871
+ let resource_metrics = exporter
872
+ . get_finished_metrics ( )
873
+ . expect ( "metrics are expected to be exported." ) ;
874
+ println ! ( "resource_metrics: {:?}" , resource_metrics) ;
875
+ assert ! ( resource_metrics. is_empty( ) , "No metrics should be exported as no new measurements were recorded since last collect." ) ;
876
+ }
877
+
878
+ struct DeltaTemporalitySelector ( ) ;
879
+ impl TemporalitySelector for DeltaTemporalitySelector {
880
+ fn temporality ( & self , _kind : InstrumentKind ) -> Temporality {
881
+ Temporality :: Delta
882
+ }
883
+ }
884
+
776
885
struct TestContext {
777
886
exporter : InMemoryMetricsExporter ,
778
887
meter_provider : SdkMeterProvider ,
0 commit comments