3535
3636import functools
3737import glob
38+ import gzip
3839import re
3940import os
4041import sys
@@ -598,7 +599,7 @@ def gate_python(tasks):
598599 python_suite .extensions .run_python_unittests (python_svm_image_path )
599600
600601
601- def _svm_truffle_tck (native_image , language_id , language_distribution = None , fail_on_error = True ):
602+ def _svm_truffle_tck (native_image , language_id , language_distribution = None , fail_on_error = True , print_call_tree = False ):
602603 assert language_distribution , 'Language_distribution must be given'
603604 dists = [
604605 mx .distribution ('substratevm:SVM_TRUFFLE_TCK' ),
@@ -619,6 +620,7 @@ def _collect_excludes(suite, suite_import, excludes):
619620 success = False
620621 try :
621622 report_file = join (svmbuild , "language_permissions.log" )
623+ print_call_tree_options = ['-H:+PrintAnalysisCallTree' ] if print_call_tree else []
622624 options = mx .get_runtime_jvm_args (dists , exclude_names = ['substratevm:SVM' ]) + [
623625 '--features=com.oracle.svm.truffle.tck.PermissionsFeature' ,
624626 ] + mx_sdk_vm_impl .svm_experimental_options ([
@@ -629,7 +631,7 @@ def _collect_excludes(suite, suite_import, excludes):
629631 f'-H:TruffleTCKPermissionsReportFile={ report_file } ' ,
630632 f'-H:Path={ svmbuild } ' ,
631633 '--add-exports=org.graalvm.truffle.runtime/com.oracle.truffle.runtime=ALL-UNNAMED'
632- ]) + [
634+ ] + print_call_tree_options ) + [
633635 'com.oracle.svm.truffle.tck.MockMain'
634636 ]
635637 if excludes :
@@ -643,7 +645,8 @@ def _collect_excludes(suite, suite_import, excludes):
643645 if fail_on_error :
644646 mx .abort (message )
645647 else :
646- return message
648+ reports_folder = os .path .join (svmbuild , 'reports' ) if print_call_tree else None
649+ return message , reports_folder
647650 else :
648651 success = True
649652 finally :
@@ -653,15 +656,35 @@ def _collect_excludes(suite, suite_import, excludes):
653656
654657
655658def gate_truffle_native_tck_smoke_test (tasks ):
659+
660+ def _copy_call_tree (source_folder ):
661+ """
662+ Copies native-image call tree from a temporary folder to the current working directory
663+ and compresses it with gzip algorithm. Such a file can be preserved when the build fails.
664+ """
665+ call_tree_file = None
666+ for file in os .listdir (source_folder ):
667+ if file .startswith ("call_tree_" ) and file .endswith (".txt" ):
668+ call_tree_file = os .path .join (source_folder , file )
669+ break
670+ if call_tree_file :
671+ dest_file = "call_tree.txt.gz"
672+ with open (call_tree_file , "rb" ) as f_in :
673+ with gzip .open (dest_file , "wb" ) as f_out :
674+ shutil .copyfileobj (f_in , f_out )
675+
656676 with Task ('Truffle Native TCK Smoke Test' , tasks , tags = [VmGateTasks .truffle_native_tck ]) as t :
657677 if t :
658678 truffle_suite = mx .suite ('truffle' )
659679 test_language_dist = [d for d in truffle_suite .dists if d .name == 'TRUFFLE_TCK_TESTS_LANGUAGE' ][0 ]
660680 native_image_context , svm = graalvm_svm ()
661681 with native_image_context (svm .IMAGE_ASSERTION_FLAGS ) as native_image :
662- result = _svm_truffle_tck (native_image , 'TCKSmokeTestLanguage' , test_language_dist , False )
663- if not 'Failed: Language TCKSmokeTestLanguage performs following privileged calls' in result :
664- mx .abort ("Expected failure, log:\n " + result )
682+ result = _svm_truffle_tck (native_image , 'TCKSmokeTestLanguage' , test_language_dist , False , True )
683+ privileged_calls = result [0 ]
684+ reports_folder = result [1 ]
685+ if not 'Failed: Language TCKSmokeTestLanguage performs following privileged calls' in privileged_calls :
686+ _copy_call_tree (reports_folder )
687+ mx .abort ("Expected failure, log:\n " + privileged_calls )
665688
666689 must_have_methods = [
667690 'PrivilegedCallNode.callConstructorReflectively' ,
@@ -680,11 +703,13 @@ def gate_truffle_native_tck_smoke_test(tasks):
680703 'AllowedURLNode.doURLOf'
681704 ]
682705 for method in must_have_methods :
683- if method not in result :
684- mx .abort (f"Missing { method } call in the log.\n Log content:\n " + result )
706+ if method not in privileged_calls :
707+ _copy_call_tree (reports_folder )
708+ mx .abort (f"Missing { method } call in the log.\n Log content:\n " + privileged_calls )
685709 for method in must_not_have_methods :
686- if method in result :
687- mx .abort (f"Found { method } call in the log.\n Log content:\n " + result )
710+ if method in privileged_calls :
711+ _copy_call_tree (reports_folder )
712+ mx .abort (f"Found { method } call in the log.\n Log content:\n " + privileged_calls )
688713
689714def gate_truffle_native_tck_js (tasks ):
690715 with Task ('JavaScript Truffle Native TCK' , tasks , tags = [VmGateTasks .truffle_native_tck_js ]) as t :
0 commit comments