2020-01-21 14:27:39 +01:00
#!/usr/bin/env python3
2019-10-23 09:12:15 +02:00
# Run this script from your branch with proposed Cppcheck patch to verify your
2020-06-15 20:04:43 +02:00
# patch against current main. It will compare output of testing a bunch of
2019-10-23 09:12:15 +02:00
# opensource packages
import donate_cpu_lib as lib
import argparse
import os
import sys
import random
import subprocess
2020-05-14 19:45:53 +02:00
def format_float ( a , b = 1 ) :
if a > 0 and b > 0 :
return ' {:.2f} ' . format ( a / b )
return ' N/A '
2019-10-23 09:12:15 +02:00
if __name__ == " __main__ " :
2020-06-15 20:04:43 +02:00
parser = argparse . ArgumentParser ( description = ' Run this script from your branch with proposed Cppcheck patch to verify your patch against current main. It will compare output of testing bunch of opensource packages ' )
2019-10-23 09:12:15 +02:00
parser . add_argument ( ' -j ' , default = 1 , type = int , help = ' Concurency execution threads ' )
2019-10-24 21:54:22 +02:00
parser . add_argument ( ' -p ' , default = 256 , type = int , help = ' Count of packages to check ' )
2019-10-23 09:12:15 +02:00
parser . add_argument ( ' -o ' , default = ' my_check_diff.log ' , help = ' Filename of result inside a working path dir ' )
parser . add_argument ( ' --work-path ' , ' --work-path= ' , default = lib . work_path , type = str , help = ' Working directory for reference repo ' )
args = parser . parse_args ( )
print ( args )
2019-12-12 16:43:40 +01:00
work_path = os . path . abspath ( args . work_path )
2019-10-23 09:12:15 +02:00
if not os . path . exists ( work_path ) :
os . makedirs ( work_path )
2020-06-15 20:04:43 +02:00
main_dir = os . path . join ( work_path , ' cppcheck ' )
2019-10-23 09:12:15 +02:00
jobs = ' -j ' + str ( args . j )
result_file = os . path . join ( work_path , args . o )
2020-05-14 19:45:53 +02:00
( f , ext ) = os . path . splitext ( result_file )
timing_file = f + ' _timing ' + ext
2019-10-23 09:12:15 +02:00
your_repo_dir = os . path . dirname ( os . path . dirname ( os . path . abspath ( sys . argv [ 0 ] ) ) )
if os . path . exists ( result_file ) :
os . remove ( result_file )
2020-05-14 19:45:53 +02:00
if os . path . exists ( timing_file ) :
os . remove ( timing_file )
2019-10-23 09:12:15 +02:00
2020-06-15 20:04:43 +02:00
if not lib . get_cppcheck ( main_dir , work_path ) :
print ( ' Failed to clone main of Cppcheck, retry later ' )
2019-10-23 09:12:15 +02:00
sys . exit ( 1 )
try :
os . chdir ( your_repo_dir )
2020-06-15 20:04:43 +02:00
commit_id = ( subprocess . check_output ( [ ' git ' , ' merge-base ' , ' origin/main ' , ' HEAD ' ] ) ) . strip ( ) . decode ( ' ascii ' )
2019-10-23 09:12:15 +02:00
with open ( result_file , ' a ' ) as myfile :
myfile . write ( ' Common ancestor: ' + commit_id + ' \n \n ' )
2020-05-14 19:45:53 +02:00
package_width = ' 140 '
timing_width = ' >7 '
with open ( timing_file , ' a ' ) as myfile :
myfile . write ( ' { : {package_width} } { : {timing_width} } { : {timing_width} } { : {timing_width} } \n ' . format (
2020-06-15 20:04:43 +02:00
' Package ' , ' main ' , ' your ' , ' Factor ' , package_width = package_width , timing_width = timing_width ) )
2019-10-23 09:12:15 +02:00
2020-06-15 20:04:43 +02:00
os . chdir ( main_dir )
2019-10-23 09:12:15 +02:00
subprocess . check_call ( [ ' git ' , ' checkout ' , ' -f ' , commit_id ] )
except :
2020-06-15 20:04:43 +02:00
print ( ' Failed to switch to common ancestor of your branch and main ' )
2019-10-23 09:12:15 +02:00
sys . exit ( 1 )
2020-06-15 20:04:43 +02:00
if not lib . compile_cppcheck ( main_dir , jobs ) :
print ( ' Failed to compile main of Cppcheck ' )
2019-10-23 09:12:15 +02:00
sys . exit ( 1 )
print ( ' Testing your PR from directory: ' + your_repo_dir )
2020-01-21 14:27:39 +01:00
if not lib . compile_cppcheck ( your_repo_dir , jobs ) :
2019-10-23 09:12:15 +02:00
print ( ' Failed to compile your version of Cppcheck ' )
sys . exit ( 1 )
packages_count = lib . get_packages_count ( lib . server_address )
if not packages_count :
print ( " network or server might be temporarily down.. " )
sys . exit ( 1 )
packages_idxs = list ( range ( packages_count ) )
random . shuffle ( packages_idxs )
packages_processed = 0
crashes = [ ]
2020-01-24 12:33:51 +01:00
timeouts = [ ]
2019-10-23 09:12:15 +02:00
while packages_processed < args . p and len ( packages_idxs ) > 0 :
package = lib . get_package ( lib . server_address , packages_idxs . pop ( ) )
tgz = lib . download_package ( work_path , package , None )
if tgz is None :
print ( " No package downloaded " )
continue
if not lib . unpack_package ( work_path , tgz ) :
print ( " No files to process " )
continue
results_to_diff = [ ]
2020-06-15 20:04:43 +02:00
main_crashed = False
2019-10-23 09:12:15 +02:00
your_crashed = False
2020-06-15 20:04:43 +02:00
main_timeout = False
2020-01-24 12:33:51 +01:00
your_timeout = False
2019-10-23 09:12:15 +02:00
libraries = lib . get_libraries ( )
2020-06-15 20:04:43 +02:00
c , errout , info , time_main , cppcheck_options , timing_info = lib . scan_package ( work_path , main_dir , jobs , libraries )
2019-10-23 09:12:15 +02:00
if c < 0 :
if c == - 101 and ' error: could not find or open any of the paths given. ' in errout :
# No sourcefile found (for example only headers present)
print ( ' Error: 101 ' )
2020-01-24 12:33:51 +01:00
elif c == lib . RETURN_CODE_TIMEOUT :
2020-06-15 20:04:43 +02:00
print ( ' Main timed out! ' )
main_timeout = True
2019-10-23 09:12:15 +02:00
else :
2020-06-15 20:04:43 +02:00
print ( ' Main crashed! ' )
main_crashed = True
2019-10-23 09:12:15 +02:00
results_to_diff . append ( errout )
2020-05-14 19:45:53 +02:00
c , errout , info , time_your , cppcheck_options , timing_info = lib . scan_package ( work_path , your_repo_dir , jobs , libraries )
2019-10-23 09:12:15 +02:00
if c < 0 :
if c == - 101 and ' error: could not find or open any of the paths given. ' in errout :
# No sourcefile found (for example only headers present)
print ( ' Error: 101 ' )
2020-01-24 12:33:51 +01:00
elif c == lib . RETURN_CODE_TIMEOUT :
print ( ' Your code timed out! ' )
your_timeout = True
2019-10-23 09:12:15 +02:00
else :
print ( ' Your code crashed! ' )
your_crashed = True
results_to_diff . append ( errout )
2020-06-15 20:04:43 +02:00
if main_crashed or your_crashed :
2019-10-23 09:12:15 +02:00
who = None
2020-06-15 20:04:43 +02:00
if main_crashed and your_crashed :
2019-10-23 09:12:15 +02:00
who = ' Both '
2020-06-15 20:04:43 +02:00
elif main_crashed :
who = ' Main '
2019-10-23 09:12:15 +02:00
else :
who = ' Your '
2020-01-21 14:27:39 +01:00
crashes . append ( package + ' ' + who )
2019-11-05 21:05:43 +01:00
2020-06-15 20:04:43 +02:00
if main_timeout or your_timeout :
2020-01-24 12:33:51 +01:00
who = None
2020-06-15 20:04:43 +02:00
if main_timeout and your_timeout :
2020-01-24 12:33:51 +01:00
who = ' Both '
2020-06-15 20:04:43 +02:00
elif main_timeout :
who = ' Main '
2020-01-24 12:33:51 +01:00
else :
who = ' Your '
timeouts . append ( package + ' ' + who )
2019-10-23 09:12:15 +02:00
with open ( result_file , ' a ' ) as myfile :
myfile . write ( package + ' \n ' )
2020-06-15 20:04:43 +02:00
diff = lib . diff_results ( work_path , ' main ' , results_to_diff [ 0 ] , ' your ' , results_to_diff [ 1 ] )
2019-10-24 21:54:22 +02:00
if diff != ' ' :
myfile . write ( ' diff: \n ' + diff + ' \n ' )
2019-10-23 09:12:15 +02:00
2020-05-14 19:45:53 +02:00
with open ( timing_file , ' a ' ) as myfile :
myfile . write ( ' { : {package_width} } { : {timing_width} } { : {timing_width} } { : {timing_width} } \n ' . format (
2020-06-15 20:04:43 +02:00
package , format_float ( time_main ) ,
format_float ( time_your ) , format_float ( time_your , time_main ) ,
2020-05-14 19:45:53 +02:00
package_width = package_width , timing_width = timing_width ) )
2019-10-23 09:12:15 +02:00
packages_processed + = 1
print ( str ( packages_processed ) + ' of ' + str ( args . p ) + ' packages processed \n ' )
with open ( result_file , ' a ' ) as myfile :
myfile . write ( ' \n \n crashes \n ' )
myfile . write ( ' \n ' . join ( crashes ) )
2020-01-24 12:33:51 +01:00
with open ( result_file , ' a ' ) as myfile :
myfile . write ( ' \n \n timeouts \n ' )
2020-05-14 19:45:53 +02:00
myfile . write ( ' \n ' . join ( timeouts ) + ' \n ' )
2020-01-24 12:33:51 +01:00
2019-10-23 09:12:15 +02:00
print ( ' Result saved to: ' + result_file )