Files
fixminer_source/python/patch_validate_introClass.py
2020-04-06 21:30:39 +02:00

126 lines
4.4 KiB
Python
Executable File

import bugzoo
from bugzoo import server, Container
import csv
import os
introClassFile = './data/introClassData.txt'
def patch_validate():
with bugzoo.server.ephemeral(port=8081,verbose=True,timeout_connection=3000) as client:
# url = "http://127.0.0.1:6060"
# client = bugzoo.Client(url)
# bug = client.bugs['introclass:checksum:08c7ea:006']
bugList = []
with open(introClassFile,'r') as file:
for line in file.readlines():
bugList.append(line.strip())
for i in range(0,len(bugList)):
try:
bugName = bugList[i]
# if bugName != 'introclass:digits:070455:000':
# continue
print("bugName: {}".format(bugName),end=' ')
bug = client.bugs[bugName]
if client.bugs.is_installed(bug):
# print("the image is installed! :-)")
pass
else:
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=' ')
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=' ')
# print("patching...")
diff_files = get_diff(bug.name, client, container)
patch_result = patch_application(client, container, diff_files)
if not patch_result:
print("@{}@".format(patch_result))
continue
print("@{}@".format(patch_result), end=' ')
print("Second_test:",end=' ')
post_test_outcomes = {}
post_failure_cases, post_failure, total, post_test_outcomes = test_all(bug, container, client)
print("@fail:{}@total:{}".format(post_failure, total),end=' ')
print("@post_failure_cases:{}".format(post_failure_cases))
except:
print(" ")
continue
pass
from bugzoo import Patch, Client
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 get_diff(bug, client, container):
patch_list = []
path = './data/introclass/' + bug
for root, dirs, files in os.walk(path):
for name in files:
if name.endswith('.patch'):
patch_list.append(os.path.join(root, name))
diff_files = []
for patch_file in patch_list:
unidiff = ''
with open(patch_file,'r') as file:
for line in file.readlines():
if line.startswith('\\'):
continue
elif line.startswith('---'):
unidiff += '--- ' + bug.split(':')[1] + '.c\n'
elif line.startswith('+++'):
unidiff += '+++ ' + bug.split(':')[1] + '.c\n'
else:
unidiff += line
diff_files.append(unidiff.strip())
return diff_files
def patch_application(client: Client, container: Container, diff_files: list) -> None:
result = None
for unidiff in diff_files:
if len(unidiff) < 5:
continue
# first, we build a Patch object using a unified-format diff
patch = Patch.from_unidiff(unidiff)
# we then attempt to apply the patch to the source code
re = client.containers.patch(container, patch)
if not re:
return False
else:
result = True
# finally, we rebuild the program inside the container
client.containers.build(container)
return result
if __name__ == "__main__":
patch_validate()