6969 "Output_mismatch" : "C Compiler and Wasm Output mismatch" ,
7070 "Fail_native_succeeded" : "Fail Test: Native Succeeded (Should Fail)" ,
7171 "Fail_wasm_succeeded" : "Fail Test: Wasm Succeeded (Should Fail)" ,
72- "Fail_both_succeeded" : "Fail Test: Both Native and Wasm Succeeded (Should Fail)"
72+ "Fail_both_succeeded" : "Fail Test: Both Native and Wasm Succeeded (Should Fail)" ,
73+ "Fail_native_compiling" : "Fail Test: Native Compilation Failure (Should Succeed)" ,
74+ "Fail_wasm_compiling" : "Fail Test: Wasm Compilation Failure (Should Succeed)"
7375 }
7476
7577# ----------------------------------------------------------------------
@@ -453,15 +455,30 @@ def test_single_file_unified(source_file, result, timeout_sec=DEFAULT_TIMEOUT, t
453455 # Run native version
454456 native_success , native_output , native_retcode , native_error = compile_and_run_native (source_file , timeout_sec )
455457
456- # If native compile failed, report and return
458+ # NOTE: We explicitly early-abort here and report the native compilation failure
459+ # rather than treating it as a successful "fail-test".
457460 if native_error == "Failure_native_compiling" :
458- handler .add_compile_failure (native_output , is_native = True )
461+ # Record this specifically as a fail-test native-compilation error so it is
462+ # counted alongside other `Fail_*` test categories instead of the generic
463+ # compilation error bucket used elsewhere.
464+ failure_info = (
465+ "=== FAILURE: Native compilation failed during fail-test (expected runtime failure) ===\n "
466+ f"Native output:\n { native_output } "
467+ )
468+ add_test_result (result , str (source_file ), "Failure" , "Fail_native_compiling" , failure_info )
459469 return
460470
461471 # Compile and run WASM
462- wasm_file , compile_err = compile_c_to_wasm (source_file )
472+ wasm_file , wasm_compile_error = compile_c_to_wasm (source_file )
463473 if wasm_file is None :
464- handler .add_compile_failure (compile_err , is_native = False )
474+ # Record this specifically as a fail-test WASM-compilation error so it is
475+ # counted alongside other `Fail_*` test categories instead of the generic
476+ # Lind_wasm_compiling bucket used elsewhere.
477+ failure_info = (
478+ "=== FAILURE: Wasm compilation failed during fail-test (expected runtime failure) ===\n "
479+ f"Wasm compile output:\n { wasm_compile_error } "
480+ )
481+ add_test_result (result , str (source_file ), "Failure" , "Fail_wasm_compiling" , failure_info )
465482 return
466483
467484 try :
@@ -472,7 +489,7 @@ def test_single_file_unified(source_file, result, timeout_sec=DEFAULT_TIMEOUT, t
472489
473490 # Check if wasm_retcode is an integer or string
474491 if isinstance (wasm_retcode , str ):
475- wasm_failed = True # timeout or unknown_error means it failed
492+ wasm_failed = wasm_retcode in [ " timeout" , " unknown_error" ] # Explicitly check for failure strings
476493 else :
477494 wasm_failed = wasm_retcode != 0
478495
@@ -487,27 +504,15 @@ def test_single_file_unified(source_file, result, timeout_sec=DEFAULT_TIMEOUT, t
487504 handler .add_success (output_info )
488505 elif not native_failed and not wasm_failed :
489506 # Both succeeded when they should have failed
490- failure_info = (
491- "=== FAILURE: Both Native and Wasm succeeded when they should fail ===\n "
492- f"Native output:\n { native_output } \n \n "
493- f"Wasm output:\n { wasm_output } "
494- )
507+ failure_info = build_fail_message ("both" , native_output , wasm_output , native_retcode , wasm_retcode )
495508 add_test_result (result , str (source_file ), "Failure" , "Fail_both_succeeded" , failure_info )
496509 elif not native_failed :
497510 # Only native succeeded
498- failure_info = (
499- "=== FAILURE: Native succeeded when it should fail ===\n "
500- f"Native output:\n { native_output } \n \n "
501- f"Wasm failed with exit code { wasm_retcode } :\n { wasm_output } "
502- )
511+ failure_info = build_fail_message ("native_only" , native_output , wasm_output , native_retcode , wasm_retcode )
503512 add_test_result (result , str (source_file ), "Failure" , "Fail_native_succeeded" , failure_info )
504513 else :
505514 # Only wasm succeeded
506- failure_info = (
507- "=== FAILURE: Wasm succeeded when it should fail ===\n "
508- f"Wasm output:\n { wasm_output } \n \n "
509- f"Native failed with exit code { native_retcode } :\n { native_output } "
510- )
515+ failure_info = build_fail_message ("wasm_only" , native_output , wasm_output , native_retcode , wasm_retcode )
511516 add_test_result (result , str (source_file ), "Failure" , "Fail_wasm_succeeded" , failure_info )
512517
513518 finally :
@@ -526,9 +531,9 @@ def test_single_file_unified(source_file, result, timeout_sec=DEFAULT_TIMEOUT, t
526531 return
527532
528533 # Compile and run WASM
529- wasm_file , compile_err = compile_c_to_wasm (source_file )
534+ wasm_file , wasm_compile_error = compile_c_to_wasm (source_file )
530535 if wasm_file is None :
531- handler .add_compile_failure (compile_err )
536+ handler .add_compile_failure (wasm_compile_error )
532537 return
533538
534539 try :
@@ -1222,6 +1227,46 @@ def run_tests(config, artifacts_root, results, timeout_sec):
12221227 else :
12231228 # Log warning for tests not in deterministic/non-deterministic/fail folders
12241229 logger .warning (f"Test file { original_source } is not in a deterministic, non-deterministic, or fail folder - skipping" )
1230+
1231+ def build_fail_message (case : str , native_output : str , wasm_output : str , native_retcode = None , wasm_retcode = None ) -> str :
1232+ """
1233+ Build a consistent failure message for fail-tests.
1234+
1235+ Args:
1236+ case: One of "both", "native_only", "wasm_only" describing which succeeded.
1237+ native_output: Captured native stdout/stderr text.
1238+ wasm_output: Captured wasm stdout/stderr text.
1239+ native_retcode: Native return code (optional, included where helpful).
1240+ wasm_retcode: Wasm return code (optional, included where helpful).
1241+
1242+ Returns:
1243+ A formatted failure string.
1244+ """
1245+ if case == "both" :
1246+ return (
1247+ "=== FAILURE: Both Native and Wasm succeeded when they should fail ===\n "
1248+ f"Native output:\n { native_output } \n \n "
1249+ f"Wasm output:\n { wasm_output } "
1250+ )
1251+ elif case == "native_only" :
1252+ return (
1253+ "=== FAILURE: Native succeeded when it should fail ===\n "
1254+ f"Native output:\n { native_output } \n \n "
1255+ f"Wasm failed with exit code { wasm_retcode } :\n { wasm_output } "
1256+ )
1257+ elif case == "wasm_only" :
1258+ return (
1259+ "=== FAILURE: Wasm succeeded when it should fail ===\n "
1260+ f"Wasm output:\n { wasm_output } \n \n "
1261+ f"Native failed with exit code { native_retcode } :\n { native_output } "
1262+ )
1263+ else :
1264+ return (
1265+ "=== FAILURE: Unexpected fail-test result ===\n "
1266+ f"Native (rc={ native_retcode } ) output:\n { native_output } \n \n "
1267+ f"Wasm (rc={ wasm_retcode } ) output:\n { wasm_output } "
1268+ )
1269+
12251270def main ():
12261271 os .chdir (LIND_WASM_BASE )
12271272 args = parse_arguments ()
0 commit comments