Skip to content

Commit 2add813

Browse files
authored
migrate tests in pool.rs to use insta (#16145)
fix according to review fix to_string error fix test by stripping backtrace
1 parent d4218fd commit 2add813

File tree

3 files changed

+100
-82
lines changed

3 files changed

+100
-82
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

datafusion/execution/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,3 +52,4 @@ url = { workspace = true }
5252

5353
[dev-dependencies]
5454
chrono = { workspace = true }
55+
insta = { workspace = true }

datafusion/execution/src/memory_pool/pool.rs

Lines changed: 98 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -443,8 +443,18 @@ fn provide_top_memory_consumers_to_error_msg(
443443
#[cfg(test)]
444444
mod tests {
445445
use super::*;
446+
use insta::{allow_duplicates, assert_snapshot, Settings};
446447
use std::sync::Arc;
447448

449+
fn make_settings() -> Settings {
450+
let mut settings = Settings::clone_current();
451+
settings.add_filter(
452+
r"([^\s]+)\#\d+\(can spill: (true|false)\)",
453+
"$1#[ID](can spill: $2)",
454+
);
455+
settings
456+
}
457+
448458
#[test]
449459
fn test_fair() {
450460
let pool = Arc::new(FairSpillPool::new(100)) as _;
@@ -463,10 +473,10 @@ mod tests {
463473
assert_eq!(pool.reserved(), 4000);
464474

465475
let err = r2.try_grow(1).unwrap_err().strip_backtrace();
466-
assert_eq!(err, "Resources exhausted: Failed to allocate additional 1.0 B for r2 with 2000.0 B already allocated for this reservation - 0.0 B remain available for the total pool");
476+
assert_snapshot!(err, @"Resources exhausted: Failed to allocate additional 1.0 B for r2 with 2000.0 B already allocated for this reservation - 0.0 B remain available for the total pool");
467477

468478
let err = r2.try_grow(1).unwrap_err().strip_backtrace();
469-
assert_eq!(err, "Resources exhausted: Failed to allocate additional 1.0 B for r2 with 2000.0 B already allocated for this reservation - 0.0 B remain available for the total pool");
479+
assert_snapshot!(err, @"Resources exhausted: Failed to allocate additional 1.0 B for r2 with 2000.0 B already allocated for this reservation - 0.0 B remain available for the total pool");
470480

471481
r1.shrink(1990);
472482
r2.shrink(2000);
@@ -491,12 +501,12 @@ mod tests {
491501
.register(&pool);
492502

493503
let err = r3.try_grow(70).unwrap_err().strip_backtrace();
494-
assert_eq!(err, "Resources exhausted: Failed to allocate additional 70.0 B for r3 with 0.0 B already allocated for this reservation - 40.0 B remain available for the total pool");
504+
assert_snapshot!(err, @"Resources exhausted: Failed to allocate additional 70.0 B for r3 with 0.0 B already allocated for this reservation - 40.0 B remain available for the total pool");
495505

496506
//Shrinking r2 to zero doesn't allow a3 to allocate more than 45
497507
r2.free();
498508
let err = r3.try_grow(70).unwrap_err().strip_backtrace();
499-
assert_eq!(err, "Resources exhausted: Failed to allocate additional 70.0 B for r3 with 0.0 B already allocated for this reservation - 40.0 B remain available for the total pool");
509+
assert_snapshot!(err, @"Resources exhausted: Failed to allocate additional 70.0 B for r3 with 0.0 B already allocated for this reservation - 40.0 B remain available for the total pool");
500510

501511
// But dropping r2 does
502512
drop(r2);
@@ -509,11 +519,13 @@ mod tests {
509519

510520
let mut r4 = MemoryConsumer::new("s4").register(&pool);
511521
let err = r4.try_grow(30).unwrap_err().strip_backtrace();
512-
assert_eq!(err, "Resources exhausted: Failed to allocate additional 30.0 B for s4 with 0.0 B already allocated for this reservation - 20.0 B remain available for the total pool");
522+
assert_snapshot!(err, @"Resources exhausted: Failed to allocate additional 30.0 B for s4 with 0.0 B already allocated for this reservation - 20.0 B remain available for the total pool");
513523
}
514524

515525
#[test]
516526
fn test_tracked_consumers_pool() {
527+
let setting = make_settings();
528+
let _bound = setting.bind_to_scope();
517529
let pool: Arc<dyn MemoryPool> = Arc::new(TrackConsumersPool::new(
518530
GreedyMemoryPool::new(100),
519531
NonZeroUsize::new(3).unwrap(),
@@ -546,19 +558,22 @@ mod tests {
546558
// Test: reports if new reservation causes error
547559
// using the previously set sizes for other consumers
548560
let mut r5 = MemoryConsumer::new("r5").register(&pool);
549-
let expected = format!("Additional allocation failed with top memory consumers (across reservations) as:\n r1#{}(can spill: false) consumed 50.0 B,\n r3#{}(can spill: false) consumed 20.0 B,\n r2#{}(can spill: false) consumed 15.0 B.\nError: Failed to allocate additional 150.0 B for r5 with 0.0 B already allocated for this reservation - 5.0 B remain available for the total pool", r1.consumer().id(), r3.consumer().id(), r2.consumer().id());
550561
let res = r5.try_grow(150);
551-
assert!(
552-
matches!(
553-
&res,
554-
Err(DataFusionError::ResourcesExhausted(ref e)) if e.to_string().contains(&expected)
555-
),
556-
"should provide list of top memory consumers, instead found {res:?}"
557-
);
562+
assert!(res.is_err());
563+
let error = res.unwrap_err().strip_backtrace();
564+
assert_snapshot!(error, @r"
565+
Resources exhausted: Additional allocation failed with top memory consumers (across reservations) as:
566+
r1#[ID](can spill: false) consumed 50.0 B,
567+
r3#[ID](can spill: false) consumed 20.0 B,
568+
r2#[ID](can spill: false) consumed 15.0 B.
569+
Error: Failed to allocate additional 150.0 B for r5 with 0.0 B already allocated for this reservation - 5.0 B remain available for the total pool
570+
");
558571
}
559572

560573
#[test]
561574
fn test_tracked_consumers_pool_register() {
575+
let setting = make_settings();
576+
let _bound = setting.bind_to_scope();
562577
let pool: Arc<dyn MemoryPool> = Arc::new(TrackConsumersPool::new(
563578
GreedyMemoryPool::new(100),
564579
NonZeroUsize::new(3).unwrap(),
@@ -568,15 +583,14 @@ mod tests {
568583

569584
// Test: see error message when no consumers recorded yet
570585
let mut r0 = MemoryConsumer::new(same_name).register(&pool);
571-
let expected = format!("Additional allocation failed with top memory consumers (across reservations) as:\n foo#{}(can spill: false) consumed 0.0 B.\nError: Failed to allocate additional 150.0 B for foo with 0.0 B already allocated for this reservation - 100.0 B remain available for the total pool", r0.consumer().id());
572586
let res = r0.try_grow(150);
573-
assert!(
574-
matches!(
575-
&res,
576-
Err(DataFusionError::ResourcesExhausted(ref e)) if e.to_string().contains(&expected)
577-
),
578-
"should provide proper error when no reservations have been made yet, instead found {res:?}"
579-
);
587+
assert!(res.is_err());
588+
let error = res.unwrap_err().strip_backtrace();
589+
assert_snapshot!(error, @r"
590+
Resources exhausted: Additional allocation failed with top memory consumers (across reservations) as:
591+
foo#[ID](can spill: false) consumed 0.0 B.
592+
Error: Failed to allocate additional 150.0 B for foo with 0.0 B already allocated for this reservation - 100.0 B remain available for the total pool
593+
");
580594

581595
// API: multiple registrations using the same hashed consumer,
582596
// will be recognized *differently* in the TrackConsumersPool.
@@ -586,100 +600,101 @@ mod tests {
586600
let mut r1 = new_consumer_same_name.register(&pool);
587601
// TODO: the insufficient_capacity_err() message is per reservation, not per consumer.
588602
// a followup PR will clarify this message "0 bytes already allocated for this reservation"
589-
let expected = format!("Additional allocation failed with top memory consumers (across reservations) as:\n foo#{}(can spill: false) consumed 10.0 B,\n foo#{}(can spill: false) consumed 0.0 B.\nError: Failed to allocate additional 150.0 B for foo with 0.0 B already allocated for this reservation - 90.0 B remain available for the total pool", r0.consumer().id(), r1.consumer().id());
590603
let res = r1.try_grow(150);
591-
assert!(
592-
matches!(
593-
&res,
594-
Err(DataFusionError::ResourcesExhausted(ref e)) if e.to_string().contains(&expected)
595-
),
596-
"should provide proper error for 2 consumers, instead found {res:?}"
597-
);
604+
assert!(res.is_err());
605+
let error = res.unwrap_err().strip_backtrace();
606+
assert_snapshot!(error, @r"
607+
Resources exhausted: Additional allocation failed with top memory consumers (across reservations) as:
608+
foo#[ID](can spill: false) consumed 10.0 B,
609+
foo#[ID](can spill: false) consumed 0.0 B.
610+
Error: Failed to allocate additional 150.0 B for foo with 0.0 B already allocated for this reservation - 90.0 B remain available for the total pool
611+
");
598612

599613
// Test: will accumulate size changes per consumer, not per reservation
600614
r1.grow(20);
601-
let expected = format!("Additional allocation failed with top memory consumers (across reservations) as:\n foo#{}(can spill: false) consumed 20.0 B,\n foo#{}(can spill: false) consumed 10.0 B.\nError: Failed to allocate additional 150.0 B for foo with 20.0 B already allocated for this reservation - 70.0 B remain available for the total pool", r1.consumer().id(), r0.consumer().id());
615+
602616
let res = r1.try_grow(150);
603-
assert!(
604-
matches!(
605-
&res,
606-
Err(DataFusionError::ResourcesExhausted(ref e)) if e.to_string().contains(&expected)
607-
),
608-
"should provide proper error for 2 consumers(one foo=20.0 B, another foo=10.0 B, available=70.0 B), instead found {res:?}"
609-
);
617+
assert!(res.is_err());
618+
let error = res.unwrap_err().strip_backtrace();
619+
assert_snapshot!(error, @r"
620+
Resources exhausted: Additional allocation failed with top memory consumers (across reservations) as:
621+
foo#[ID](can spill: false) consumed 20.0 B,
622+
foo#[ID](can spill: false) consumed 10.0 B.
623+
Error: Failed to allocate additional 150.0 B for foo with 20.0 B already allocated for this reservation - 70.0 B remain available for the total pool
624+
");
610625

611626
// Test: different hashed consumer, (even with the same name),
612627
// will be recognized as different in the TrackConsumersPool
613628
let consumer_with_same_name_but_different_hash =
614629
MemoryConsumer::new(same_name).with_can_spill(true);
615630
let mut r2 = consumer_with_same_name_but_different_hash.register(&pool);
616-
let expected = format!("Additional allocation failed with top memory consumers (across reservations) as:\n foo#{}(can spill: false) consumed 20.0 B,\n foo#{}(can spill: false) consumed 10.0 B,\n foo#{}(can spill: true) consumed 0.0 B.\nError: Failed to allocate additional 150.0 B for foo with 0.0 B already allocated for this reservation - 70.0 B remain available for the total pool", r1.consumer().id(), r0.consumer().id(), r2.consumer().id());
617631
let res = r2.try_grow(150);
618-
assert!(
619-
matches!(
620-
&res,
621-
Err(DataFusionError::ResourcesExhausted(ref e)) if e.to_string().contains(&expected)
622-
),
623-
"should provide proper error with 3 separate consumers(1 = 20 bytes, 2 = 10 bytes, 3 = 0 bytes), instead found {res:?}"
624-
);
632+
assert!(res.is_err());
633+
let error = res.unwrap_err().strip_backtrace();
634+
assert_snapshot!(error, @r"
635+
Resources exhausted: Additional allocation failed with top memory consumers (across reservations) as:
636+
foo#[ID](can spill: false) consumed 20.0 B,
637+
foo#[ID](can spill: false) consumed 10.0 B,
638+
foo#[ID](can spill: true) consumed 0.0 B.
639+
Error: Failed to allocate additional 150.0 B for foo with 0.0 B already allocated for this reservation - 70.0 B remain available for the total pool
640+
");
625641
}
626642

627643
#[test]
628644
fn test_tracked_consumers_pool_deregister() {
629645
fn test_per_pool_type(pool: Arc<dyn MemoryPool>) {
630646
// Baseline: see the 2 memory consumers
647+
let setting = make_settings();
648+
let _bound = setting.bind_to_scope();
631649
let mut r0 = MemoryConsumer::new("r0").register(&pool);
632650
r0.grow(10);
633651
let r1_consumer = MemoryConsumer::new("r1");
634652
let mut r1 = r1_consumer.register(&pool);
635653
r1.grow(20);
636654

637-
let expected = format!("Additional allocation failed with top memory consumers (across reservations) as:\n r1#{}(can spill: false) consumed 20.0 B,\n r0#{}(can spill: false) consumed 10.0 B.\nError: Failed to allocate additional 150.0 B for r0 with 10.0 B already allocated for this reservation - 70.0 B remain available for the total pool", r1.consumer().id(), r0.consumer().id());
638655
let res = r0.try_grow(150);
639-
assert!(
640-
matches!(
641-
&res,
642-
Err(DataFusionError::ResourcesExhausted(ref e)) if e.to_string().contains(&expected)
643-
),
644-
"should provide proper error with both consumers, instead found {res:?}"
645-
);
656+
assert!(res.is_err());
657+
let error = res.unwrap_err().strip_backtrace();
658+
allow_duplicates!(assert_snapshot!(error, @r"
659+
Resources exhausted: Additional allocation failed with top memory consumers (across reservations) as:
660+
r1#[ID](can spill: false) consumed 20.0 B,
661+
r0#[ID](can spill: false) consumed 10.0 B.
662+
Error: Failed to allocate additional 150.0 B for r0 with 10.0 B already allocated for this reservation - 70.0 B remain available for the total pool
663+
"));
646664

647665
// Test: unregister one
648666
// only the remaining one should be listed
649667
drop(r1);
650-
let expected_consumers = format!("Additional allocation failed with top memory consumers (across reservations) as:\n r0#{}(can spill: false) consumed 10.0 B", r0.consumer().id());
651668
let res = r0.try_grow(150);
652-
assert!(
653-
matches!(
654-
&res,
655-
Err(DataFusionError::ResourcesExhausted(ref e)) if e.to_string().contains(&expected_consumers)
656-
),
657-
"should provide proper error with only 1 consumer left registered, instead found {res:?}"
658-
);
669+
assert!(res.is_err());
670+
let error = res.unwrap_err().strip_backtrace();
671+
allow_duplicates!(assert_snapshot!(error, @r"
672+
Resources exhausted: Additional allocation failed with top memory consumers (across reservations) as:
673+
r0#[ID](can spill: false) consumed 10.0 B.
674+
Error: Failed to allocate additional 150.0 B for r0 with 10.0 B already allocated for this reservation - 90.0 B remain available for the total pool
675+
"));
659676

660677
// Test: actual message we see is the `available is 70`. When it should be `available is 90`.
661678
// This is because the pool.shrink() does not automatically occur within the inner_pool.deregister().
662-
let expected_90_available = "Failed to allocate additional 150.0 B for r0 with 10.0 B already allocated for this reservation - 90.0 B remain available for the total pool";
663679
let res = r0.try_grow(150);
664-
assert!(
665-
matches!(
666-
&res,
667-
Err(DataFusionError::ResourcesExhausted(ref e)) if e.to_string().contains(expected_90_available)
668-
),
669-
"should find that the inner pool will still count all bytes for the deregistered consumer until the reservation is dropped, instead found {res:?}"
670-
);
680+
assert!(res.is_err());
681+
let error = res.unwrap_err().strip_backtrace();
682+
allow_duplicates!(assert_snapshot!(error, @r"
683+
Resources exhausted: Additional allocation failed with top memory consumers (across reservations) as:
684+
r0#[ID](can spill: false) consumed 10.0 B.
685+
Error: Failed to allocate additional 150.0 B for r0 with 10.0 B already allocated for this reservation - 90.0 B remain available for the total pool
686+
"));
671687

672688
// Test: the registration needs to free itself (or be dropped),
673689
// for the proper error message
674-
let expected_90_available = "Failed to allocate additional 150.0 B for r0 with 10.0 B already allocated for this reservation - 90.0 B remain available for the total pool";
675690
let res = r0.try_grow(150);
676-
assert!(
677-
matches!(
678-
&res,
679-
Err(DataFusionError::ResourcesExhausted(ref e)) if e.to_string().contains(expected_90_available)
680-
),
681-
"should correctly account the total bytes after reservation is free, instead found {res:?}"
682-
);
691+
assert!(res.is_err());
692+
let error = res.unwrap_err().strip_backtrace();
693+
allow_duplicates!(assert_snapshot!(error, @r"
694+
Resources exhausted: Additional allocation failed with top memory consumers (across reservations) as:
695+
r0#[ID](can spill: false) consumed 10.0 B.
696+
Error: Failed to allocate additional 150.0 B for r0 with 10.0 B already allocated for this reservation - 90.0 B remain available for the total pool
697+
"));
683698
}
684699

685700
let tracked_spill_pool: Arc<dyn MemoryPool> = Arc::new(TrackConsumersPool::new(
@@ -697,6 +712,8 @@ mod tests {
697712

698713
#[test]
699714
fn test_tracked_consumers_pool_use_beyond_errors() {
715+
let setting = make_settings();
716+
let _bound = setting.bind_to_scope();
700717
let upcasted: Arc<dyn std::any::Any + Send + Sync> =
701718
Arc::new(TrackConsumersPool::new(
702719
GreedyMemoryPool::new(100),
@@ -720,11 +737,10 @@ mod tests {
720737
.unwrap();
721738

722739
// Test: can get runtime metrics, even without an error thrown
723-
let expected = format!(" r3#{}(can spill: false) consumed 45.0 B,\n r1#{}(can spill: false) consumed 20.0 B.", r3.consumer().id(), r1.consumer().id());
724740
let res = downcasted.report_top(2);
725-
assert_eq!(
726-
res, expected,
727-
"should provide list of top memory consumers, instead found {res:?}"
728-
);
741+
assert_snapshot!(res, @r"
742+
r3#[ID](can spill: false) consumed 45.0 B,
743+
r1#[ID](can spill: false) consumed 20.0 B.
744+
");
729745
}
730746
}

0 commit comments

Comments
 (0)