11// SPDX-License-Identifier: PMPL-1.0-or-later
22
3- //! Tests for the PanLL event-chain export module
3+ //! Tests for the PanLL event-chain export module.
4+ //!
5+ //! All tests are panic-free: they return `Result` and propagate errors with
6+ //! `?`. JSON value access uses `.ok_or(...)` rather than `.as_array().unwrap()`.
47
58use panic_attack:: panll;
69use panic_attack:: types:: * ;
@@ -12,17 +15,15 @@ fn make_assault_report(
1215 weak_points : Vec < WeakPoint > ,
1316 attack_results : Vec < AttackResult > ,
1417) -> AssaultReport {
15- let _critical_count = weak_points
16- . iter ( )
17- . filter ( |wp| wp. severity == Severity :: Critical )
18- . count ( ) ;
1918 let unsafe_count = weak_points
2019 . iter ( )
2120 . filter ( |wp| wp. category == WeakPointCategory :: UnsafeCode )
2221 . count ( ) ;
2322
2423 AssaultReport {
24+ schema_version : "2.5" . to_string ( ) ,
2525 assail_report : AssailReport {
26+ schema_version : "2.5" . to_string ( ) ,
2627 program_path : PathBuf :: from ( "/tmp/test-target" ) ,
2728 language : Language :: Rust ,
2829 frameworks : vec ! [ ] ,
@@ -32,6 +33,7 @@ fn make_assault_report(
3233 unsafe_blocks : unsafe_count,
3334 panic_sites : 0 ,
3435 unwrap_calls : 3 ,
36+ safe_unwrap_calls : 0 ,
3537 allocation_sites : 5 ,
3638 io_operations : 1 ,
3739 threading_constructs : 0 ,
@@ -56,21 +58,22 @@ fn make_assault_report(
5658}
5759
5860#[ test]
59- fn test_panll_export_writes_valid_json ( ) {
61+ fn test_panll_export_writes_valid_json ( ) -> Result < ( ) , Box < dyn std :: error :: Error > > {
6062 let report = make_assault_report ( vec ! [ ] , vec ! [ ] ) ;
61- let dir = TempDir :: new ( ) . unwrap ( ) ;
63+ let dir = TempDir :: new ( ) ? ;
6264 let output = dir. path ( ) . join ( "panll-out.json" ) ;
6365
64- panll:: write_export ( & report, None , & output) . unwrap ( ) ;
66+ panll:: write_export ( & report, None , & output) ? ;
6567
66- let content = std:: fs:: read_to_string ( & output) . unwrap ( ) ;
67- let parsed: serde_json:: Value = serde_json:: from_str ( & content) . unwrap ( ) ;
68+ let content = std:: fs:: read_to_string ( & output) ? ;
69+ let parsed: serde_json:: Value = serde_json:: from_str ( & content) ? ;
6870 assert_eq ! ( parsed[ "format" ] , "panll.event-chain.v0" ) ;
6971 assert_eq ! ( parsed[ "source" ] [ "tool" ] , "panic-attack" ) ;
72+ Ok ( ( ) )
7073}
7174
7275#[ test]
73- fn test_panll_export_summary_reflects_report ( ) {
76+ fn test_panll_export_summary_reflects_report ( ) -> Result < ( ) , Box < dyn std :: error :: Error > > {
7477 let report = make_assault_report (
7578 vec ! [ WeakPoint {
7679 category: WeakPointCategory :: UnsafeCode ,
@@ -84,20 +87,21 @@ fn test_panll_export_summary_reflects_report() {
8487 } ] ,
8588 vec ! [ ] ,
8689 ) ;
87- let dir = TempDir :: new ( ) . unwrap ( ) ;
90+ let dir = TempDir :: new ( ) ? ;
8891 let output = dir. path ( ) . join ( "panll-out.json" ) ;
8992
90- panll:: write_export ( & report, None , & output) . unwrap ( ) ;
93+ panll:: write_export ( & report, None , & output) ? ;
9194
92- let content = std:: fs:: read_to_string ( & output) . unwrap ( ) ;
93- let parsed: serde_json:: Value = serde_json:: from_str ( & content) . unwrap ( ) ;
95+ let content = std:: fs:: read_to_string ( & output) ? ;
96+ let parsed: serde_json:: Value = serde_json:: from_str ( & content) ? ;
9497 assert_eq ! ( parsed[ "summary" ] [ "weak_points" ] , 1 ) ;
9598 assert_eq ! ( parsed[ "summary" ] [ "critical_weak_points" ] , 1 ) ;
9699 assert_eq ! ( parsed[ "summary" ] [ "robustness_score" ] , 75.0 ) ;
100+ Ok ( ( ) )
97101}
98102
99103#[ test]
100- fn test_panll_export_constraints_from_critical_wp ( ) {
104+ fn test_panll_export_constraints_from_critical_wp ( ) -> Result < ( ) , Box < dyn std :: error :: Error > > {
101105 let report = make_assault_report (
102106 vec ! [
103107 WeakPoint {
@@ -123,29 +127,37 @@ fn test_panll_export_constraints_from_critical_wp() {
123127 ] ,
124128 vec ! [ ] ,
125129 ) ;
126- let dir = TempDir :: new ( ) . unwrap ( ) ;
130+ let dir = TempDir :: new ( ) ? ;
127131 let output = dir. path ( ) . join ( "panll-out.json" ) ;
128132
129- panll:: write_export ( & report, None , & output) . unwrap ( ) ;
133+ panll:: write_export ( & report, None , & output) ? ;
130134
131- let content = std:: fs:: read_to_string ( & output) . unwrap ( ) ;
132- let parsed: serde_json:: Value = serde_json:: from_str ( & content) . unwrap ( ) ;
133- let constraints = parsed[ "constraints" ] . as_array ( ) . unwrap ( ) ;
135+ let content = std:: fs:: read_to_string ( & output) ?;
136+ let parsed: serde_json:: Value = serde_json:: from_str ( & content) ?;
137+ let constraints = parsed[ "constraints" ]
138+ . as_array ( )
139+ . ok_or ( "constraints must be an array" ) ?;
134140
135- // Only the critical WP should generate a constraint, not the medium one
136141 assert_eq ! ( constraints. len( ) , 1 , "only critical WPs become constraints" ) ;
137- assert ! ( constraints[ 0 ] [ "id" ]
138- . as_str( )
139- . unwrap( )
140- . starts_with( "wp-crit-" ) ) ;
141- assert ! ( constraints[ 0 ] [ "description" ]
142- . as_str( )
143- . unwrap( )
144- . contains( "transmute" ) ) ;
142+ assert ! (
143+ constraints[ 0 ] [ "id" ]
144+ . as_str( )
145+ . ok_or( "constraint id must be a string" ) ?
146+ . starts_with( "wp-crit-" ) ,
147+ "constraint id should start with wp-crit-"
148+ ) ;
149+ assert ! (
150+ constraints[ 0 ] [ "description" ]
151+ . as_str( )
152+ . ok_or( "constraint description must be a string" ) ?
153+ . contains( "transmute" ) ,
154+ "constraint should mention the detected issue"
155+ ) ;
156+ Ok ( ( ) )
145157}
146158
147159#[ test]
148- fn test_panll_export_event_chain_from_attacks ( ) {
160+ fn test_panll_export_event_chain_from_attacks ( ) -> Result < ( ) , Box < dyn std :: error :: Error > > {
149161 let report = make_assault_report (
150162 vec ! [ ] ,
151163 vec ! [
@@ -175,24 +187,27 @@ fn test_panll_export_event_chain_from_attacks() {
175187 } ,
176188 ] ,
177189 ) ;
178- let dir = TempDir :: new ( ) . unwrap ( ) ;
190+ let dir = TempDir :: new ( ) ? ;
179191 let output = dir. path ( ) . join ( "panll-out.json" ) ;
180192
181- panll:: write_export ( & report, None , & output) . unwrap ( ) ;
193+ panll:: write_export ( & report, None , & output) ? ;
182194
183- let content = std:: fs:: read_to_string ( & output) . unwrap ( ) ;
184- let parsed: serde_json:: Value = serde_json:: from_str ( & content) . unwrap ( ) ;
185- let events = parsed[ "event_chain" ] . as_array ( ) . unwrap ( ) ;
195+ let content = std:: fs:: read_to_string ( & output) ?;
196+ let parsed: serde_json:: Value = serde_json:: from_str ( & content) ?;
197+ let events = parsed[ "event_chain" ]
198+ . as_array ( )
199+ . ok_or ( "event_chain must be an array" ) ?;
186200
187201 assert_eq ! ( events. len( ) , 2 ) ;
188202 assert_eq ! ( events[ 0 ] [ "axis" ] , "cpu" ) ;
189203 assert_eq ! ( events[ 0 ] [ "status" ] , "passed" ) ;
190204 assert_eq ! ( events[ 1 ] [ "axis" ] , "memory" ) ;
191205 assert_eq ! ( events[ 1 ] [ "status" ] , "failed" ) ;
206+ Ok ( ( ) )
192207}
193208
194209#[ test]
195- fn test_panll_export_constraints_from_failed_attacks ( ) {
210+ fn test_panll_export_constraints_from_failed_attacks ( ) -> Result < ( ) , Box < dyn std :: error :: Error > > {
196211 let mut report = make_assault_report (
197212 vec ! [ ] ,
198213 vec ! [ AttackResult {
@@ -216,25 +231,28 @@ fn test_panll_export_constraints_from_failed_attacks() {
216231 ) ;
217232 report. total_crashes = 1 ;
218233
219- let dir = TempDir :: new ( ) . unwrap ( ) ;
234+ let dir = TempDir :: new ( ) ? ;
220235 let output = dir. path ( ) . join ( "panll-out.json" ) ;
221236
222- panll:: write_export ( & report, None , & output) . unwrap ( ) ;
237+ panll:: write_export ( & report, None , & output) ? ;
223238
224- let content = std:: fs:: read_to_string ( & output) . unwrap ( ) ;
225- let parsed: serde_json:: Value = serde_json:: from_str ( & content) . unwrap ( ) ;
226- let constraints = parsed[ "constraints" ] . as_array ( ) . unwrap ( ) ;
239+ let content = std:: fs:: read_to_string ( & output) ?;
240+ let parsed: serde_json:: Value = serde_json:: from_str ( & content) ?;
241+ let constraints = parsed[ "constraints" ]
242+ . as_array ( )
243+ . ok_or ( "constraints must be an array" ) ?;
227244
228245 assert ! (
229246 constraints
230247 . iter( )
231- . any( |c| c[ "id" ] . as_str( ) . unwrap ( ) . starts_with( "attack-fail-" ) ) ,
248+ . any( |c| c[ "id" ] . as_str( ) . map_or ( false , |id| id . starts_with( "attack-fail-" ) ) ) ,
232249 "failed attack should generate a constraint"
233250 ) ;
251+ Ok ( ( ) )
234252}
235253
236254#[ test]
237- fn test_panll_export_skipped_attacks_not_in_constraints ( ) {
255+ fn test_panll_export_skipped_attacks_not_in_constraints ( ) -> Result < ( ) , Box < dyn std :: error :: Error > > {
238256 let report = make_assault_report (
239257 vec ! [ ] ,
240258 vec ! [ AttackResult {
@@ -251,34 +269,40 @@ fn test_panll_export_skipped_attacks_not_in_constraints() {
251269 } ] ,
252270 ) ;
253271
254- let dir = TempDir :: new ( ) . unwrap ( ) ;
272+ let dir = TempDir :: new ( ) ? ;
255273 let output = dir. path ( ) . join ( "panll-out.json" ) ;
256274
257- panll:: write_export ( & report, None , & output) . unwrap ( ) ;
275+ panll:: write_export ( & report, None , & output) ? ;
258276
259- let content = std:: fs:: read_to_string ( & output) . unwrap ( ) ;
260- let parsed: serde_json:: Value = serde_json:: from_str ( & content) . unwrap ( ) ;
261- let constraints = parsed[ "constraints" ] . as_array ( ) . unwrap ( ) ;
277+ let content = std:: fs:: read_to_string ( & output) ?;
278+ let parsed: serde_json:: Value = serde_json:: from_str ( & content) ?;
279+ let constraints = parsed[ "constraints" ]
280+ . as_array ( )
281+ . ok_or ( "constraints must be an array" ) ?;
262282
263283 assert ! (
264284 constraints. is_empty( ) ,
265285 "skipped attacks should not generate constraints"
266286 ) ;
267287
268- let events = parsed[ "event_chain" ] . as_array ( ) . unwrap ( ) ;
288+ let events = parsed[ "event_chain" ]
289+ . as_array ( )
290+ . ok_or ( "event_chain must be an array" ) ?;
269291 assert_eq ! ( events[ 0 ] [ "status" ] , "skipped" ) ;
292+ Ok ( ( ) )
270293}
271294
272295#[ test]
273- fn test_panll_export_report_path_recorded ( ) {
296+ fn test_panll_export_report_path_recorded ( ) -> Result < ( ) , Box < dyn std :: error :: Error > > {
274297 let report = make_assault_report ( vec ! [ ] , vec ! [ ] ) ;
275- let dir = TempDir :: new ( ) . unwrap ( ) ;
298+ let dir = TempDir :: new ( ) ? ;
276299 let output = dir. path ( ) . join ( "panll-out.json" ) ;
277300 let source_path = std:: path:: Path :: new ( "/tmp/my-report.json" ) ;
278301
279- panll:: write_export ( & report, Some ( source_path) , & output) . unwrap ( ) ;
302+ panll:: write_export ( & report, Some ( source_path) , & output) ? ;
280303
281- let content = std:: fs:: read_to_string ( & output) . unwrap ( ) ;
282- let parsed: serde_json:: Value = serde_json:: from_str ( & content) . unwrap ( ) ;
304+ let content = std:: fs:: read_to_string ( & output) ? ;
305+ let parsed: serde_json:: Value = serde_json:: from_str ( & content) ? ;
283306 assert_eq ! ( parsed[ "source" ] [ "report_path" ] , "/tmp/my-report.json" ) ;
307+ Ok ( ( ) )
284308}
0 commit comments