15
15
import tempfile
16
16
import time
17
17
from enum import Enum
18
+ from math import expm1
18
19
from pathlib import Path
19
20
from typing import Any , Dict , List , Union , Tuple , Optional
20
21
from urllib import request
21
22
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
24
28
"""
25
29
26
30
HELP = """
@@ -158,8 +162,11 @@ def get_release_versions(tool: Tool) -> List[str]:
158
162
159
163
160
164
def 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 ]
163
170
164
171
165
172
def get_release_info (tool : Tool , release : str ) -> str :
@@ -302,22 +309,35 @@ def build_tests(release: str):
302
309
release_file = release_target_file (release , "all" )
303
310
shutil .copytree (code_folder , TESTS_CODE_DIR )
304
311
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 )
321
341
322
342
323
343
def clear_tests_dir ():
@@ -331,6 +351,7 @@ def test_release_basic_execution(release: str, platform: str,
331
351
Tests that the agentpath command returns a usable agent on this platform
332
352
"""
333
353
release_file = release_target_file (release , platform )
354
+ cmd = ""
334
355
try :
335
356
pipe = subprocess .PIPE if not ignore_output else subprocess .DEVNULL
336
357
clear_tests_dir ()
@@ -345,23 +366,26 @@ def test_release_basic_execution(release: str, platform: str,
345
366
return False
346
367
profile_file = f"{ TESTS_DIR } /profile.jfr"
347
368
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 "
349
370
if not ignore_output :
350
- print (f"Execute { cmd } " )
371
+ print (f"Execute cd { CURRENT_DIR } ; { cmd } " )
351
372
subprocess .check_call (cmd , shell = True , cwd = CURRENT_DIR , stdout = pipe ,
352
373
stderr = pipe )
353
374
if not os .path .exists (profile_file ):
354
375
return False
355
376
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 } "
357
378
if not ignore_output :
358
- print (f"Execute { cmd } " )
379
+ print (f"Execute cd { CURRENT_DIR } ; { cmd } " )
359
380
subprocess .check_call (cmd , shell = True , cwd = CURRENT_DIR , stdout = pipe ,
360
381
stderr = pipe )
361
382
if not os .path .exists (flamegraph_file ):
383
+ print ("no flamegraph file" )
362
384
return False
363
385
return True
364
386
except subprocess .CalledProcessError :
387
+ if not ignore_output :
388
+ print (f"Error executing command: { cmd } " )
365
389
return False
366
390
367
391
@@ -400,14 +424,10 @@ def run_async_profiler_test(test_script: str) -> bool:
400
424
401
425
def run_async_profiler_tests ():
402
426
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 } " )
411
431
412
432
413
433
def test_release (release : str ):
@@ -529,8 +549,7 @@ def cli():
529
549
coms = {"current_version" : lambda : print (
530
550
get_most_recent_release (Tool .ASYNC_PROFILER )),
531
551
"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." ))),
534
553
"download" : lambda : download_release (release ),
535
554
"build" : lambda : build_release (release ),
536
555
"test" : lambda : test_release (release ),
0 commit comments