1515import tempfile
1616import time
1717from enum import Enum
18+ from math import expm1
1819from pathlib import Path
1920from typing import Any , Dict , List , Union , Tuple , Optional
2021from urllib import request
2122
22- SUB_VERSION = 9
23- RELEASE_NOTES = """- Fix FlameGraph converter [#22](https://github.com/jvm-profiling-tools/ap-loader/issues/22)
23+ SUB_VERSION = 10
24+ RELEASE_NOTES = """- Drop support for async-profiler < 4.0 versions, as 4.0 changed how its tested
25+ - Major changes in the usage of the JFR conversion made by async-profiler
26+ which are not hidden
27+ - Clean up the code
2428"""
2529
2630HELP = """
@@ -158,8 +162,11 @@ def get_release_versions(tool: Tool) -> List[str]:
158162
159163
160164def get_most_recent_release (tool : Tool ) -> str :
161- return [version for version in get_release_versions (tool ) if
162- version .startswith ("3." ) or version .startswith ("4." ) or version .startswith ("2." )][0 ]
165+ def check_version (version : str ) -> bool :
166+ if tool == Tool .ASYNC_PROFILER :
167+ return version .startswith ("4." )
168+ return version .startswith ( "2." )
169+ return [version for version in get_release_versions (tool ) if check_version (version )][0 ]
163170
164171
165172def get_release_info (tool : Tool , release : str ) -> str :
@@ -302,22 +309,35 @@ def build_tests(release: str):
302309 release_file = release_target_file (release , "all" )
303310 shutil .copytree (code_folder , TESTS_CODE_DIR )
304311 test_folder = f"{ TESTS_CODE_DIR } /test"
305- for file in os .listdir (test_folder ):
306- if file .endswith (".java" ):
307- execute (f"javac { test_folder } /{ file } " )
308- if file .endswith (".sh" ) and not file .startswith ("fd" ):
309- with open (f"{ test_folder } /{ file } " ) as f :
310- content = f .read ()
311- content = content .replace ("../profiler.sh " ,
312- f"java -jar '{ release_file } ' profiler " ).replace (
313- "../build/bin/asprof" ,
314- f"java -jar '{ release_file } ' profiler" ).replace (
315- "-agentpath:../build/libasyncProfiler.so" ,
316- f"-javaagent:{ release_file } " ).replace (
317- "-agentpath:$(ls ../build/lib/libasyncProfiler.*)" ,
318- f"-javaagent:{ release_file } " )
319- with open (f"{ test_folder } /{ file } " , "w" ) as f :
320- f .write (content )
312+ # walk all files in the folder recursively and replace the paths
313+ # to the release file
314+ for root , dirs , files in os .walk (TESTS_CODE_DIR ):
315+ for file in files :
316+ if file .endswith (".java" ) or file .endswith ("Makefile" ):
317+ with open (f"{ root } /{ file } " ) as f :
318+ content = f .read ()
319+ content = (content
320+ .replace ("-source 7 -target 7" , "-source 8 -target 8" )
321+ .replace ('cmd.add("-agentpath:" + profilerLibPath() + "=" +' ,
322+ f'cmd.add("-javaagent:{ release_file } " + "=" +' )
323+ .replace (
324+ 'cmd.add("build/bin/asprof")' ,
325+ f'cmd.addAll(List.of("java", "-jar", "{ release_file } ", "profiler"))' ))
326+ if file == "AllocTests.java" :
327+ # the startup test doesn't work
328+ # so let's find the @Test annotation in the line before
329+ # 'public void startup(TestProcess p)' and remove it
330+ lines = content .splitlines ()
331+ # find startup line
332+ startup_line = next (i for i , line in enumerate (lines ) if
333+ "public void startup(TestProcess p)" in line )
334+ # find the line before
335+ before_startup_line = startup_line - 1
336+ # find the @Test annotation
337+ lines = lines [:before_startup_line ] + lines [startup_line :]
338+ content = "\n " .join (lines )
339+ with open (f"{ root } /{ file } " , "w" ) as f :
340+ f .write (content )
321341
322342
323343def clear_tests_dir ():
@@ -331,6 +351,7 @@ def test_release_basic_execution(release: str, platform: str,
331351 Tests that the agentpath command returns a usable agent on this platform
332352 """
333353 release_file = release_target_file (release , platform )
354+ cmd = ""
334355 try :
335356 pipe = subprocess .PIPE if not ignore_output else subprocess .DEVNULL
336357 clear_tests_dir ()
@@ -345,23 +366,26 @@ def test_release_basic_execution(release: str, platform: str,
345366 return False
346367 profile_file = f"{ TESTS_DIR } /profile.jfr"
347368 cmd = f"java -javaagent:{ release_file } =start,file={ profile_file } ,jfr " \
348- f"-cp { TESTS_CODE_DIR } /test ThreadsTarget "
369+ f"{ CURRENT_DIR } /misc/TestMain.java "
349370 if not ignore_output :
350- print (f"Execute { cmd } " )
371+ print (f"Execute cd { CURRENT_DIR } ; { cmd } " )
351372 subprocess .check_call (cmd , shell = True , cwd = CURRENT_DIR , stdout = pipe ,
352373 stderr = pipe )
353374 if not os .path .exists (profile_file ):
354375 return False
355376 flamegraph_file = f"{ TESTS_DIR } /flamegraph.html"
356- cmd = f"java -jar '{ release_file } ' converter jfr2flame { profile_file } { flamegraph_file } "
377+ cmd = f"java -jar '{ release_file } ' converter -o html { profile_file } { flamegraph_file } "
357378 if not ignore_output :
358- print (f"Execute { cmd } " )
379+ print (f"Execute cd { CURRENT_DIR } ; { cmd } " )
359380 subprocess .check_call (cmd , shell = True , cwd = CURRENT_DIR , stdout = pipe ,
360381 stderr = pipe )
361382 if not os .path .exists (flamegraph_file ):
383+ print ("no flamegraph file" )
362384 return False
363385 return True
364386 except subprocess .CalledProcessError :
387+ if not ignore_output :
388+ print (f"Error executing command: { cmd } " )
365389 return False
366390
367391
@@ -400,14 +424,10 @@ def run_async_profiler_test(test_script: str) -> bool:
400424
401425def run_async_profiler_tests ():
402426 print ("Run async-profiler tests" )
403- test_folder = f"{ TESTS_CODE_DIR } /test"
404- failed = False
405- for file in os .listdir (test_folder ):
406- if file .endswith (".sh" ) and not file .startswith ("fd" ):
407- if not run_async_profiler_test (file ):
408- failed = True
409- if failed :
410- raise Exception ("Some async-profiler tests failed" )
427+ try :
428+ subprocess .check_call ("make test" , cwd = TESTS_CODE_DIR , shell = True ,)
429+ except subprocess .CalledProcessError as ex :
430+ raise Exception (f"Some async-profiler tests failed { ex } " )
411431
412432
413433def test_release (release : str ):
@@ -529,8 +549,7 @@ def cli():
529549 coms = {"current_version" : lambda : print (
530550 get_most_recent_release (Tool .ASYNC_PROFILER )),
531551 "versions" : lambda : print (" " .join (
532- version for version in get_release_versions (Tool .ASYNC_PROFILER ) if
533- version .startswith ("2." ) or version .startswith ("3." ) or version .startswith ("4." ))),
552+ version for version in get_release_versions (Tool .ASYNC_PROFILER ) if version .startswith ("4." ))),
534553 "download" : lambda : download_release (release ),
535554 "build" : lambda : build_release (release ),
536555 "test" : lambda : test_release (release ),
0 commit comments