pub struct Report { /* private fields */ }Expand description
Result of a full allocation-failure check.
Implementations§
Source§impl Report
impl Report
Sourcepub fn stability_baselines(&self) -> &[Baseline]
pub fn stability_baselines(&self) -> &[Baseline]
Returns extra baseline runs used to validate allocation-count stability.
Sourcepub fn baseline_is_stable(&self) -> bool
pub fn baseline_is_stable(&self) -> bool
Returns whether every baseline run completed with the same allocation count as the primary baseline run.
Examples found in repository?
119fn unstable_baseline_diagnostic() {
120 let runs = AtomicUsize::new(0);
121
122 let report = alloc_chaos::Check::new().stability_runs(2).run(|| {
123 if runs.fetch_add(1, Ordering::SeqCst) == 0 {
124 checked_packet_builder();
125 }
126 });
127
128 print_report("unstable baseline", &report);
129 assert!(!report.baseline_is_stable());
130 assert!(report.attempts().is_empty());
131 assert!(!report.is_success());
132}Sourcepub fn baseline_allocations(&self) -> usize
pub fn baseline_allocations(&self) -> usize
Returns the number of allocation attempts observed during the primary baseline run.
Sourcepub fn attempts(&self) -> &[Attempt]
pub fn attempts(&self) -> &[Attempt]
Returns all injected-failure runs.
Examples found in repository?
96fn reproduce_one_failure_and_show_metadata() {
97 let full_report = alloc_chaos::check(checked_packet_builder);
98 full_report.assert_success();
99
100 let target = full_report
101 .attempts()
102 .first()
103 .map(alloc_chaos::Attempt::target_allocation)
104 .expect("packet builder should allocate during the baseline run");
105
106 let report = alloc_chaos::Check::new()
107 .only_failure(target)
108 .run(checked_packet_builder);
109
110 print_report("single-target reproduction", &report);
111 print_allocation_metadata(&report);
112
113 assert!(report.is_truncated());
114 assert_eq!(report.tested_failures(), 1);
115 assert!(report.attempts()[0].is_success());
116 assert!(!report.is_success());
117}
118
119fn unstable_baseline_diagnostic() {
120 let runs = AtomicUsize::new(0);
121
122 let report = alloc_chaos::Check::new().stability_runs(2).run(|| {
123 if runs.fetch_add(1, Ordering::SeqCst) == 0 {
124 checked_packet_builder();
125 }
126 });
127
128 print_report("unstable baseline", &report);
129 assert!(!report.baseline_is_stable());
130 assert!(report.attempts().is_empty());
131 assert!(!report.is_success());
132}
133
134fn mishandled_oom_diagnostic() {
135 with_quiet_expected_panics(|| {
136 let report = alloc_chaos::Check::new()
137 .max_failures(1)
138 .run(|| match build_packet() {
139 Ok(packet) => assert_eq!(packet.body.len(), 256),
140 Err(BuildError::OutOfMemory) => panic!("allocation failure was not handled"),
141 });
142
143 print_report("mishandled OOM path", &report);
144 assert!(report.first_failure().is_some());
145 assert!(!report.is_success());
146 });
147}
148
149fn print_report(title: &str, report: &alloc_chaos::Report) {
150 println!("\n=== {title} ===");
151 println!("{report}");
152}
153
154fn print_allocation_metadata(report: &alloc_chaos::Report) {
155 for attempt in report.attempts() {
156 if let Some(allocation) = attempt.injected_allocation() {
157 println!(
158 "metadata: target #{} -> {} size={} align={} new_size={:?}",
159 allocation.index(),
160 allocation.operation(),
161 allocation.size(),
162 allocation.align(),
163 allocation.new_size(),
164 );
165 }
166 }
167}Sourcepub fn failed_attempts(&self) -> impl Iterator<Item = &Attempt>
pub fn failed_attempts(&self) -> impl Iterator<Item = &Attempt>
Returns all injected-failure runs that did not complete successfully.
Sourcepub fn first_failure(&self) -> Option<&Attempt>
pub fn first_failure(&self) -> Option<&Attempt>
Returns the first injected-failure run that did not complete successfully.
Examples found in repository?
134fn mishandled_oom_diagnostic() {
135 with_quiet_expected_panics(|| {
136 let report = alloc_chaos::Check::new()
137 .max_failures(1)
138 .run(|| match build_packet() {
139 Ok(packet) => assert_eq!(packet.body.len(), 256),
140 Err(BuildError::OutOfMemory) => panic!("allocation failure was not handled"),
141 });
142
143 print_report("mishandled OOM path", &report);
144 assert!(report.first_failure().is_some());
145 assert!(!report.is_success());
146 });
147}Sourcepub fn tested_failures(&self) -> usize
pub fn tested_failures(&self) -> usize
Returns the number of selected failure targets that were executed.
Examples found in repository?
85fn range_diagnostic_run() {
86 let report = alloc_chaos::Check::new()
87 .failure_range(1..2)
88 .run(checked_packet_builder);
89
90 print_report("selected failure range", &report);
91 assert!(report.is_truncated());
92 assert_eq!(report.tested_failures(), 1);
93 assert!(!report.is_success());
94}
95
96fn reproduce_one_failure_and_show_metadata() {
97 let full_report = alloc_chaos::check(checked_packet_builder);
98 full_report.assert_success();
99
100 let target = full_report
101 .attempts()
102 .first()
103 .map(alloc_chaos::Attempt::target_allocation)
104 .expect("packet builder should allocate during the baseline run");
105
106 let report = alloc_chaos::Check::new()
107 .only_failure(target)
108 .run(checked_packet_builder);
109
110 print_report("single-target reproduction", &report);
111 print_allocation_metadata(&report);
112
113 assert!(report.is_truncated());
114 assert_eq!(report.tested_failures(), 1);
115 assert!(report.attempts()[0].is_success());
116 assert!(!report.is_success());
117}Sourcepub fn injected_failures(&self) -> usize
pub fn injected_failures(&self) -> usize
Returns the number of executed runs that actually reached and failed the selected allocation attempt.
Sourcepub fn untested_failures(&self) -> usize
pub fn untested_failures(&self) -> usize
Returns the number of observed baseline allocation attempts that did not have a corresponding injected failure.
Sourcepub fn is_truncated(&self) -> bool
pub fn is_truncated(&self) -> bool
Returns true if not every observed baseline allocation was tested.
This can happen when the baseline run panics, when the baseline is
unstable, when Check::max_failures limits the run count, when
Check::only_failure or Check::failure_range selects a subset, or
when Check::stop_on_failure stops the check early.
Examples found in repository?
74fn bounded_diagnostic_run() {
75 let report = alloc_chaos::Check::new()
76 .max_failures(1)
77 .stop_on_failure(true)
78 .run(checked_packet_builder);
79
80 print_report("bounded diagnostic run", &report);
81 assert!(report.is_truncated());
82 assert!(!report.is_success());
83}
84
85fn range_diagnostic_run() {
86 let report = alloc_chaos::Check::new()
87 .failure_range(1..2)
88 .run(checked_packet_builder);
89
90 print_report("selected failure range", &report);
91 assert!(report.is_truncated());
92 assert_eq!(report.tested_failures(), 1);
93 assert!(!report.is_success());
94}
95
96fn reproduce_one_failure_and_show_metadata() {
97 let full_report = alloc_chaos::check(checked_packet_builder);
98 full_report.assert_success();
99
100 let target = full_report
101 .attempts()
102 .first()
103 .map(alloc_chaos::Attempt::target_allocation)
104 .expect("packet builder should allocate during the baseline run");
105
106 let report = alloc_chaos::Check::new()
107 .only_failure(target)
108 .run(checked_packet_builder);
109
110 print_report("single-target reproduction", &report);
111 print_allocation_metadata(&report);
112
113 assert!(report.is_truncated());
114 assert_eq!(report.tested_failures(), 1);
115 assert!(report.attempts()[0].is_success());
116 assert!(!report.is_success());
117}Sourcepub fn allocator_installed(&self) -> bool
pub fn allocator_installed(&self) -> bool
Returns whether the ChaosAllocator was observed during an explicit
allocator-installation probe at the start of the check.
false usually means the global allocator wrapper was not installed.
Sourcepub fn is_success(&self) -> bool
pub fn is_success(&self) -> bool
Returns true only for an exhaustive, valid, fully successful check.
Success requires all of the following:
- the global allocator wrapper was installed;
- the primary baseline completed;
- all configured stability baseline runs matched the primary baseline;
- the report is not truncated;
- every observed baseline allocation was tested; and
- every injected run reached its target allocation and completed without panic.
Examples found in repository?
74fn bounded_diagnostic_run() {
75 let report = alloc_chaos::Check::new()
76 .max_failures(1)
77 .stop_on_failure(true)
78 .run(checked_packet_builder);
79
80 print_report("bounded diagnostic run", &report);
81 assert!(report.is_truncated());
82 assert!(!report.is_success());
83}
84
85fn range_diagnostic_run() {
86 let report = alloc_chaos::Check::new()
87 .failure_range(1..2)
88 .run(checked_packet_builder);
89
90 print_report("selected failure range", &report);
91 assert!(report.is_truncated());
92 assert_eq!(report.tested_failures(), 1);
93 assert!(!report.is_success());
94}
95
96fn reproduce_one_failure_and_show_metadata() {
97 let full_report = alloc_chaos::check(checked_packet_builder);
98 full_report.assert_success();
99
100 let target = full_report
101 .attempts()
102 .first()
103 .map(alloc_chaos::Attempt::target_allocation)
104 .expect("packet builder should allocate during the baseline run");
105
106 let report = alloc_chaos::Check::new()
107 .only_failure(target)
108 .run(checked_packet_builder);
109
110 print_report("single-target reproduction", &report);
111 print_allocation_metadata(&report);
112
113 assert!(report.is_truncated());
114 assert_eq!(report.tested_failures(), 1);
115 assert!(report.attempts()[0].is_success());
116 assert!(!report.is_success());
117}
118
119fn unstable_baseline_diagnostic() {
120 let runs = AtomicUsize::new(0);
121
122 let report = alloc_chaos::Check::new().stability_runs(2).run(|| {
123 if runs.fetch_add(1, Ordering::SeqCst) == 0 {
124 checked_packet_builder();
125 }
126 });
127
128 print_report("unstable baseline", &report);
129 assert!(!report.baseline_is_stable());
130 assert!(report.attempts().is_empty());
131 assert!(!report.is_success());
132}
133
134fn mishandled_oom_diagnostic() {
135 with_quiet_expected_panics(|| {
136 let report = alloc_chaos::Check::new()
137 .max_failures(1)
138 .run(|| match build_packet() {
139 Ok(packet) => assert_eq!(packet.body.len(), 256),
140 Err(BuildError::OutOfMemory) => panic!("allocation failure was not handled"),
141 });
142
143 print_report("mishandled OOM path", &report);
144 assert!(report.first_failure().is_some());
145 assert!(!report.is_success());
146 });
147}Sourcepub fn assert_success(&self)
pub fn assert_success(&self)
Panics with a human-readable report if Report::is_success is false.
Examples found in repository?
67fn strict_success() {
68 let report = alloc_chaos::check(checked_packet_builder);
69
70 print_report("strict exhaustive check", &report);
71 report.assert_success();
72}
73
74fn bounded_diagnostic_run() {
75 let report = alloc_chaos::Check::new()
76 .max_failures(1)
77 .stop_on_failure(true)
78 .run(checked_packet_builder);
79
80 print_report("bounded diagnostic run", &report);
81 assert!(report.is_truncated());
82 assert!(!report.is_success());
83}
84
85fn range_diagnostic_run() {
86 let report = alloc_chaos::Check::new()
87 .failure_range(1..2)
88 .run(checked_packet_builder);
89
90 print_report("selected failure range", &report);
91 assert!(report.is_truncated());
92 assert_eq!(report.tested_failures(), 1);
93 assert!(!report.is_success());
94}
95
96fn reproduce_one_failure_and_show_metadata() {
97 let full_report = alloc_chaos::check(checked_packet_builder);
98 full_report.assert_success();
99
100 let target = full_report
101 .attempts()
102 .first()
103 .map(alloc_chaos::Attempt::target_allocation)
104 .expect("packet builder should allocate during the baseline run");
105
106 let report = alloc_chaos::Check::new()
107 .only_failure(target)
108 .run(checked_packet_builder);
109
110 print_report("single-target reproduction", &report);
111 print_allocation_metadata(&report);
112
113 assert!(report.is_truncated());
114 assert_eq!(report.tested_failures(), 1);
115 assert!(report.attempts()[0].is_success());
116 assert!(!report.is_success());
117}