Files
fixminer_source/python/test_patched_file.py
T
2020-09-03 10:11:15 +02:00

369 lines
16 KiB
Python
Executable File

import bugzoo
from bugzoo import server, Container
from common.commons import *
import signal
# from common.commons import shellGitCheckout
DATA_PATH = os.environ["DATA_PATH"]
ROOT_DIR = os.environ["ROOT_DIR"]
DATASET = os.environ["dataset"]
introClassFile = join(DATA_PATH,'introClassData.txt')
COCCI_PATH = join(os.environ["coccinelle"],'spatch')
def patchSourceFile(bugPath,spfile,bugName):
# print(bugPath)
srcName = bugPath.split('/')[-1].split(':')[1]
srcPath = join(bugPath,srcName + '.c')
patchName = srcName+'.c'
if(isfile(join(DATA_PATH,"introclass",bugName,'patched',patchName+spfile+'.c'))):
return join(DATA_PATH,"introclass",bugName,'patched',patchName+spfile+'.c')
if not (isfile(join(DATA_PATH,"introclass",bugName,'patches',patchName+spfile+'.txt'))):
cmd = COCCI_PATH + ' --sp-file ' + join(DATASET, 'cocci', spfile) + ' ' + srcPath + ' --patch -o' + join(
DATA_PATH, "introclass", bugName, 'patches', patchName) + ' > ' + join(DATA_PATH, "introclass", bugName,
'patches',
patchName + spfile + '.txt')
output, e = shellGitCheckout(cmd)
# logging.info(output)
patchSize = os.path.getsize(join(DATA_PATH,"introclass",bugName,'patches',patchName+spfile+'.txt'))
if patchSize == 0 :
# os.remove(join(DATA_PATH,"introclass",bugName,'patches',patchName+spfile+'.txt'))
return None
else:
cmd = 'patch -d '+join(DATA_PATH, "introclass", bugName)+' -i '+join(DATA_PATH,"introclass",bugName,'patches',patchName+spfile+'.txt')+' -o '+join(DATA_PATH,"introclass",bugName,'patched',patchName+spfile+'.c')
o,e = shellGitCheckout(cmd)
return join(DATA_PATH, "introclass", bugName, 'patched', patchName + spfile + '.c')
def testCore(t):
bugName, port = t
container = None
# with bugzoo.server.ephemeral(port=port, verbose=False,bugzooPath="/Users/anil.koyuncu/anaconda3/envs/python36/bin/bugzood", timeout_connection=3000) as client:
cmd = 'bash {} {}'.format(join(ROOT_DIR,'data','startBugzoo.sh'),port)
with Popen(cmd, stdout=PIPE, stderr=PIPE, shell=True) as myProcess:
# o,e = shellGitCheckout(cmd)
url = "http://127.0.0.1:{}".format(port)
timeout_connection = 3000
client = Client(url, timeout_connection=timeout_connection)
# with bugzoo.server.ephemeral(port=port, verbose=False, timeout_connection=3000) as client:
try:
# port = 6060
# url = "http://127.0.0.1:{}".format(port)
# client = Client(url, timeout_connection=300)
# bugName = bugList[i]
# if bugName != 'introclass:digits:070455:000':
# continue
fix = 'failure'
output = ''
# print("bugName: {}".format(bugName), end=' ')
output += 'bugName:' + bugName + ', '
bug = client.bugs[bugName]
if not client.bugs.is_installed(bug):
output += ' building'
client.bugs.build(bug)
# client.bugs.download(bug)
# print("the image is not installed :'(")
# print("creating container...")
container = client.containers.provision(bug)
# print("container is ready")
# print("First_test:", end=' ')
# output += 'First_test:'
# pre_test_outcomes = {}
# pre_failure_cases, pre_failure, total, pre_test_outcomes = test_all(bug, container, client)
# # print("@fail:{}@total:{}".format(pre_failure, total), end=' ')
# # print("@pre_failure_cases:{}".format(pre_failure_cases), end=' ')
# if pre_failure == 0:
# logging.error(bugName + ' no failed test initially')
# return ''
# output += '@fail:' + str(pre_failure) + '@total:' + str(total) + ', '
# spfiles = listdir(join(DATASET, 'cocci'))
spfiles = load_zipped_pickle(join(DATA_PATH, 'uniquePatternsMod.pickle'))
spfiles.sort_values(by='uProject', inplace=True, ascending=False)
spfiles = spfiles[['uid']]
#['uid', 'uFreq', 'uFunction', 'uFilenames', 'uPatch', 'uProject']
# spfiles = spfiles[spfiles.uFreq > 2]
spfiles = spfiles[['uid']]
# print("patching... " + bugName)
for idx,spfile in enumerate(spfiles.uid.values.tolist()):
if spfile == '.DS_Store':
continue
# spfile ='if_8_102.cocci0-cocci_patches'
path = join(DATA_PATH,'introclass',bugName)
patch = patchSourceFile(path,spfile,bugName)
if patch is None:
continue
# print(patch)
# print(str(idx) + '..'+str(len(spfiles)))
# patch_path = join(path ,'patched')
# # avaliable_patch = os.path.abspath('data') + '/introclass2/' + bugName + '/' + 'patches'
# patch_names = os.listdir(patch_path)
#
times = 0
# for patch_name in patch_names:
# if patch_name not in os.listdir(avaliable_patch):
# continue
# patch = join(patch_path,patch_name)
patch_result = patched_application(path, bug.name, patch, client, container)
if patch_result == -1 or patch_result.code != 0:
# print("@{}@".format('False'), end='')
# print("{}".format('F'), end=' ')
# output += '@False@F '
output += '@False:' + str(idx) + ':' + patch.split('/')[-1] + '@'
continue
# print("@{}@".format('True'), end='')
# output += '@True@'
output += '@True:' + str(idx) + ':' + patch.split('/')[-1] + '@'
# print("Second_test:", end=' ')
#black
# post_test_outcomes = {}
# post_failure_cases, post_failure, total, post_test_outcomes = test_all(bug, container, client)
validTests = readTestSuite(join(path, 'whitebox_test.sh'))
post_failure_cases, post_failure, total = test_all_white(bug, container, client,validTests)
# print("{}".format(post_failure), end=' ')
output += str(post_failure) + ' '
if post_failure == 0:
times += 1
fix = 'success'
# print("fix {} by {}".format(bugName, patch_name))
output += 'fix {} by {} '.format(bugName, patch)
break
# print("@fail:{}@total:{}".format(post_failure, total),end=' ')
# print("@post_failure_cases:{}".format(post_failure_cases))
# cmd = 'docker rm -fv {}'.format(container.id)
# out, e = shellGitCheckout(cmd)
output += 'times:{}, '.format(times) + fix
print(output)
return output
except Exception as e:
logging.error(e)
finally:
# ''
cmd = 'docker stop {}'.format(container.id)
out, e = shellGitCheckout(cmd)
try:
client.shutdown()
except Exception as e:
logging.debug(e)
# print(myProcess.pid)
# os.killpg(myProcess.pid, signal.SIGTERM)
# docker stop $(docker ps -q)
def patch_validate():
logger = logging.getLogger()
for k,v in logger.manager.loggerDict.items():
if(k.startswith('bugzoo')):
if isinstance(v,logging.Logger):
v.setLevel(logging.ERROR)
# url = "http://127.0.0.1:6060"
# client = bugzoo.Client(url)
# bug = client.bugs['introclass:checksum:08c7ea:006']
bugList = []
nonFail = ['introclass:syllables:93f87b:005','introclass:smallest:f94e26:004','introclass:smallest:d25c71:001','introclass:median:d25c71:002','introclass:smallest:d25c71:000'
,'introclass:median:d6364e:007','introclass:median:489253:007','introclass:syllables:d12048:004','introclass:smallest:d9e7ea:002','introclass:syllables:035fe9:000'
,'introclass:syllables:c9d718:002','introclass:syllables:ea67b8:007','introclass:median:48b829:000','introclass:syllables:d9e7ea:001']
black = load_zipped_pickle(join(DATA_PATH,'blackBugs'))
white = load_zipped_pickle(join(DATA_PATH,'whiteBugs'))
# nonFail.append('introclass:grade-b1924d-001')
# nonFail.append('introclass:smallest-b1924d-002')
# allFixed = list(set(white).union(black)) #288
allFixed = white
# cmd = 'bash ' + join(DATA_PATH,'startBugzoo.sh')
# cmd = "/Users/anil.koyuncu/anaconda3/envs/python36/bin/bugzood --debug -p " + str(port)
# output, errors = shellGitCheckout(cmd)
# with bugzoo.server.ephemeral(port=8082, verbose=True, timeout_connection=3000) as client:
port = 6000
bugs2test= listdir(join(DATA_PATH, "introclass"))
for b in bugs2test:
if b == '.DS_Store':
continue
if b in nonFail:
continue
if b not in allFixed:
continue
t = b, port
bugList.append(t)
if port == 6300:
port = 6000
port += 1
# with open(introClassFile, 'r') as file:
# for line in file.readlines():
#
# t =line.strip(),port
# bugList.append(t)
# if port == 6300:
# port = 6000
# port +=1
# for i in range(0,len(bugList)):
# t = 'introclass:syllables:93f87b:005',6000
# t = 'introclass:syllables:99cbb4:000',6000
# testCore(t)
# results = parallelRunMerge(testCore, bugList,max_workers=10)
results = parallelRunMerge(testCore, bugList , max_workers=12)
print('\n'.join(results))
with open(join(DATA_PATH, 'introTestResultsWhiteuProject'), 'w',
encoding='utf-8') as writeFile:
# if levelPatch == 0:
writeFile.write('\n'.join(results))
# for i in bugList:
# testCore(i)
# pass
from bugzoo import Patch, Client
def readTestSuite(testPath):
regex = r"([p|n0-9]+)\)"
with open(testPath,mode='r') as testFile:
test_str = testFile.read()
matches = re.finditer(regex, test_str, re.MULTILINE)
testList = []
for matchNum, match in enumerate(matches, start=1):
for groupNum in range(0, len(match.groups())):
groupNum = groupNum + 1
testList.append(match.group(groupNum))
return testList
def test_all_white(bug, container, client,validTests):
test_outcomes = {} # type: Dict[TestCase, TestOutcome]
failure_cases = []
failure = 0
total = len(validTests)
for test in validTests:
# if test.name in validTests:
cmd = './whitebox_test.sh {}'.format(test)
out = client.containers.exec(container=container, command=cmd, context='/experiment/')
if 'passed' not in out.output or out.code != 0:
failure += 1
failure_cases.append(test)
# test_outcomes.append(out.output)
break
# test_outcomes[test] = client.containers.test(container, test)
# if test.expected_outcome != test_outcomes[test].passed:
# if test_outcomes[test].passed != True:
# failure.append(test.name)
# failure_cases.append(test.command)
# break
return failure_cases, failure, total
def test_all(bug, container, client):
test_outcomes = {} # type: Dict[TestCase, TestOutcome]
failure_cases = []
failure = 0
total = len(bug.tests._tests)
for test in bug.tests:
test_outcomes[test] = client.containers.test(container, test)
# if test.expected_outcome != test_outcomes[test].passed:
if test_outcomes[test].passed != True:
failure += 1
failure_cases.append(test.command)
break
return failure_cases, failure, total, test_outcomes
def patched_application(path, bugName, patched, client: Client, container: Container):
buggroup = bugName.split(":")[1]
# path = join(BUGDIR,bug)
program = path + '/' + buggroup + '.c'
fixedFile = patched.split('/')[-1]
cmd = 'docker cp ' + patched + ' ' + container.id + ':/experiment/'
output, e = shellGitCheckout(cmd)
cmd = 'sudo chown $(whoami):$(whoami) "{}"'
cmd = cmd.format(fixedFile)
output = client.containers.exec(container=container, command=cmd, context='/experiment/')
# cmd = 'rm .genprog_test_cache.json & mv {} {}.c & gcc -o {} {}'.format(fixedFile,fixedFile, buggroup, fixedFile+'.c')
cmd = 'rm {} & rm .genprog_test_cache.json'.format(buggroup)
output = client.containers.exec(container=container, command=cmd, context='/experiment/')
cmd = 'setarch `uname -m` -R gcc -o {} {}'.format(buggroup, fixedFile)
output = client.containers.exec(container=container, command=cmd, context='/experiment/')
return output
def checkCorrect():
regex = r"fix (.*) by (.*)\.c"
if not os.path.exists(join(DATA_PATH, 'introclass_eval')):
os.makedirs(join(DATA_PATH, 'introclass_eval'))
with open(join(DATA_PATH, 'introTestResults'), 'r',
encoding='utf-8') as readFile:
res = readFile.readlines()
results = []
for line in res:
if line.strip().endswith('success'):
line = '\n'.join(line.split('@'))
matches = re.finditer(regex, line, re.MULTILINE)
for matchNum, match in enumerate(matches, start=1):
bug, patch = match.groups()
print(bug,patch)
t = bug,patch
results.append(t)
# for groupNum in range(0, len(match.groups())):
# groupNum = groupNum + 1
#
# print("Group {groupNum} found at {start}-{end}: {group}".format(groupNum=groupNum,
# start=match.start(groupNum),
# end=match.end(groupNum),
# group=match.group(groupNum)))
# line
for t in results:
bug, patch = t
if not os.path.exists(join(DATA_PATH, 'introclass_eval',bug)):
os.makedirs(join(DATA_PATH, 'introclass_eval',bug))
buggyFile = join(DATA_PATH,'introclass',bug,patch.split('.')[0]+'.c')
spinferFix = join(DATA_PATH,'introclass_patched',bug,'patches',patch + '.c')
spinferPatch = join(DATA_PATH,'introclass_eval',bug,patch +'.patch')
oracle = join(DATA_PATH,'introclass',bug,'oracle.c.patch')
oracleEval = join(DATA_PATH,'introclass_eval',bug,'oracle.patch')
cmd = 'diff -u ' +buggyFile + ' ' + spinferFix + ' > ' + spinferPatch
o,e= shellGitCheckout(cmd)
shutil.copy(oracle,oracleEval)
if __name__ == "__main__":
patch_validate()