@@ -82,7 +82,7 @@ impl Default for Contexts {
8282 attributes_per_resource : ConfRange :: Inclusive { min : 1 , max : 20 } ,
8383 scopes_per_resource : ConfRange :: Inclusive { min : 1 , max : 20 } ,
8484 attributes_per_scope : ConfRange :: Constant ( 0 ) ,
85- metrics_per_scope : ConfRange :: Inclusive { min : 0 , max : 20 } ,
85+ metrics_per_scope : ConfRange :: Inclusive { min : 1 , max : 20 } ,
8686 attributes_per_metric : ConfRange :: Inclusive { min : 0 , max : 10 } ,
8787 }
8888 }
@@ -288,12 +288,13 @@ impl crate::Serialize for OpentelemetryMetrics {
288288 // those in until max_bytes -- but they do set the scopes per request
289289 // etc. All of that is transparent here, handled by the generators
290290 // above.
291- let bytes_remaining = max_bytes. checked_sub ( 5 + max_bytes. div_ceil ( 0b0111_1111 ) ) ;
292- let Some ( mut bytes_remaining) = bytes_remaining else {
293- return Ok ( ( ) ) ;
294- } ;
295-
291+ let mut bytes_remaining = max_bytes
292+ . checked_sub ( 5 + max_bytes. div_ceil ( 0b0111_1111 ) )
293+ . ok_or ( Error :: Serialize ) ?;
296294 let mut acc = Vec :: with_capacity ( 128 ) ; // arbitrary constant
295+
296+ // Generate resources as space allows. We will always generate at least
297+ // one, whether it fits or not.
297298 loop {
298299 let resource: v1:: ResourceMetrics = self . generate ( & mut rng) ?;
299300 let len = resource. encoded_len ( ) + 2 ;
@@ -378,10 +379,22 @@ mod test {
378379 // exceed `max_bytes`.
379380 proptest ! {
380381 #[ test]
381- fn payload_not_exceed_max_bytes( seed: u64 , max_bytes: u16 ) {
382+ fn payload_not_exceed_max_bytes( seed: u64 , max_bytes in 128u16 ..u16 :: MAX ) {
383+ let config = Config {
384+ contexts: Contexts {
385+ total_contexts: ConfRange :: Constant ( 1 ) ,
386+ attributes_per_resource: ConfRange :: Constant ( 0 ) ,
387+ scopes_per_resource: ConfRange :: Constant ( 1 ) ,
388+ attributes_per_scope: ConfRange :: Constant ( 0 ) ,
389+ metrics_per_scope: ConfRange :: Constant ( 1 ) ,
390+ attributes_per_metric: ConfRange :: Constant ( 0 ) ,
391+ } ,
392+ ..Default :: default ( )
393+ } ;
394+
382395 let max_bytes = max_bytes as usize ;
383396 let mut rng = SmallRng :: seed_from_u64( seed) ;
384- let mut metrics = OpentelemetryMetrics :: new( Config :: default ( ) , & mut rng) . expect( "failed to create metrics generator" ) ;
397+ let mut metrics = OpentelemetryMetrics :: new( config , & mut rng) . expect( "failed to create metrics generator" ) ;
385398
386399 let mut bytes = Vec :: with_capacity( max_bytes) ;
387400 metrics. to_bytes( rng, max_bytes, & mut bytes) . expect( "failed to convert to bytes" ) ;
@@ -437,42 +450,6 @@ mod test {
437450 }
438451 }
439452
440- // We want to be sure that the payloads are not being left empty.
441- proptest ! {
442- #[ test]
443- fn payload_is_at_least_half_of_max_bytes(
444- seed: u64 ,
445- total_contexts in 1 ..1_000_u32 ,
446- attributes_per_resource in 0 ..20_u8 ,
447- scopes_per_resource in 0 ..20_u8 ,
448- attributes_per_scope in 0 ..20_u8 ,
449- metrics_per_scope in 0 ..20_u8 ,
450- attributes_per_metric in 0 ..10_u8 ,
451- max_bytes in 16u16 ..u16 :: MAX
452- ) {
453- let config = Config {
454- contexts: Contexts {
455- total_contexts: ConfRange :: Constant ( total_contexts) ,
456- attributes_per_resource: ConfRange :: Constant ( attributes_per_resource) ,
457- scopes_per_resource: ConfRange :: Constant ( scopes_per_resource) ,
458- attributes_per_scope: ConfRange :: Constant ( attributes_per_scope) ,
459- metrics_per_scope: ConfRange :: Constant ( metrics_per_scope) ,
460- attributes_per_metric: ConfRange :: Constant ( attributes_per_metric) ,
461- } ,
462- ..Default :: default ( )
463- } ;
464-
465- let max_bytes = max_bytes as usize ;
466- let mut rng = SmallRng :: seed_from_u64( seed) ;
467- let metrics = OpentelemetryMetrics :: new( config, & mut rng) . expect( "failed to create metrics generator" ) ;
468-
469- let mut bytes = Vec :: with_capacity( max_bytes) ;
470- metrics. to_bytes( rng, max_bytes, & mut bytes) . expect( "failed to convert to bytes" ) ;
471-
472- assert!( !bytes. is_empty( ) ) ;
473- }
474- }
475-
476453 // We want to know that every payload produced by this type actually
477454 // deserializes as a collection of OTEL metrics.
478455 proptest ! {
@@ -485,7 +462,7 @@ mod test {
485462 attributes_per_scope in 0 ..20_u8 ,
486463 metrics_per_scope in 0 ..20_u8 ,
487464 attributes_per_metric in 0 ..10_u8 ,
488- max_bytes: u16
465+ max_bytes in 8u16 .. u16 :: MAX
489466 ) {
490467 let config = Config {
491468 contexts: Contexts {
0 commit comments