Skip to content

Commit 069d04a

Browse files
oss-fuzz: make python-base for testing (#298)
* oss-fuzz: make python-base for testing This adds python-based testing which will soon substitute the bash scripts used for testing many projects. * Add python testing infra * nit
1 parent 273c238 commit 069d04a

File tree

4 files changed

+160
-3
lines changed

4 files changed

+160
-3
lines changed

oss_fuzz_integration/__init__.py

Whitespace-only changes.

oss_fuzz_integration/project-checker.py renamed to oss_fuzz_integration/project_checker.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,15 @@
1717
import sys
1818
import argparse
1919

20+
class ProjectCheckError(Exception):
21+
def __init__(self, message):
22+
self.message = message
23+
24+
def __str__(self):
25+
return self.message
26+
2027
def err_exit(msg):
21-
print(f"Error {msg}")
22-
exit(0)
28+
raise ProjectCheckError(f"Error {msg}")
2329

2430
def guide_exit(msg):
2531
msg += (

oss_fuzz_integration/test_projects.py

Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
#!/usr/bin/python3
2+
# Copyright 2022 Fuzz Introspector Authors
3+
#
4+
# Licensed under the Apache License, Version 2.0 (the "License");
5+
# you may not use this file except in compliance with the License.
6+
# You may obtain a copy of the License at
7+
#
8+
# http://www.apache.org/licenses/LICENSE-2.0
9+
#
10+
# Unless required by applicable law or agreed to in writing, software
11+
# distributed under the License is distributed on an "AS IS" BASIS,
12+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
# See the License for the specific language governing permissions and
14+
# limitations under the License.
15+
"""Module for testing OSS-Fuzz projects"""
16+
17+
import os
18+
import sys
19+
import shutil
20+
import subprocess
21+
22+
import project_checker
23+
24+
SCRIPT_DIR = os.path.realpath(os.path.dirname(os.path.realpath(__file__)))
25+
26+
OSS_FUZZ_HELPER = os.path.realpath(os.getcwd()) + "/infra/helper.py"
27+
COV_HELPER = SCRIPT_DIR + "/get_full_coverage.py"
28+
PROJ_CHECK = SCRIPT_DIR + "/project-checker.py"
29+
30+
# find next test dir
31+
def get_latest_dir(dirname):
32+
curr_index = -1
33+
for l in os.listdir(os.getcwd()):
34+
if dirname in l:
35+
curr_index = max(int(l.replace(dirname, "")), curr_index)
36+
return curr_index
37+
38+
39+
def run_full_cov(project):
40+
cmd = []
41+
cmd.append("python3")
42+
cmd.append(COV_HELPER)
43+
cmd.append(project)
44+
cmd.append("10") # seconds to run
45+
46+
covlog = open("get_coverage.log", "wb")
47+
subprocess.check_call(
48+
" ".join(cmd),
49+
stdout=covlog,
50+
stderr=covlog,
51+
shell=True
52+
)
53+
54+
55+
def run_fuzz_introspector(project):
56+
cmd = []
57+
cmd.append("python3")
58+
cmd.append(OSS_FUZZ_HELPER)
59+
cmd.append("build_fuzzers")
60+
cmd.append("--sanitizer=introspector")
61+
cmd.append(project)
62+
63+
build_log = open("build_introspector.log", "wb")
64+
try:
65+
subprocess.check_call(
66+
" ".join(cmd),
67+
stdout = build_log,
68+
stderr = build_log,
69+
shell=True
70+
)
71+
except:
72+
return False
73+
return True
74+
75+
76+
def main_loop():
77+
testdir = "test-report-" + str((get_latest_dir("test-report-") + 1))
78+
print("Test directory: %s"%(testdir))
79+
os.mkdir(testdir)
80+
81+
projects_to_test = [
82+
"leveldb",
83+
"htslib",
84+
"jsoncpp",
85+
"unrar",
86+
"tarantool",
87+
"fio",
88+
"wuffs"
89+
]
90+
91+
build_results = []
92+
project_check_results = []
93+
for project in projects_to_test:
94+
print("Testing %s"%(project))
95+
96+
# Building and running
97+
run_full_cov(project)
98+
latest_corp = "corpus-" + str(get_latest_dir("corpus-"))
99+
100+
shutil.move("get_coverage.log", latest_corp + "/get_coverage.log")
101+
with open(os.path.join(latest_corp, "project_name"), "w") as pn:
102+
pn.write(project+"\n")
103+
104+
fuzz_intro_success = run_fuzz_introspector(project)
105+
build_results.append((project, fuzz_intro_success))
106+
shutil.move(
107+
"build_introspector.log",
108+
latest_corp + "/build_introspector.log"
109+
)
110+
111+
if fuzz_intro_success:
112+
# Copy fuzz-introspector related files over
113+
shutil.copytree(
114+
"build/out/%s/inspector/"%(project),
115+
os.path.join(latest_corp, "inspector-report")
116+
)
117+
shutil.copytree(
118+
os.path.join(latest_corp, "report"),
119+
os.path.join(latest_corp, "inspector-report/covreport")
120+
)
121+
122+
for d in os.listdir(os.path.join(latest_corp, "report_target")):
123+
full_path = os.path.join(latest_corp, "report_target", d)
124+
shutil.copytree(
125+
full_path,
126+
os.path.join(latest_corp, "inspector-report/covreport/", d)
127+
)
128+
129+
# Copy the entire corpus-X directory into the test directory
130+
target_dir = os.path.join(testdir, latest_corp)
131+
shutil.copytree(latest_corp, target_dir)
132+
133+
# Check project checker
134+
try:
135+
project_checker.check_project_dir(target_dir)
136+
project_check_results.append((project, True, ""))
137+
except project_checker.ProjectCheckError as e:
138+
project_check_results.append((project, False, str(e)))
139+
140+
141+
print("Summary of building with fuzz-introspector:")
142+
for p, s in build_results:
143+
print("\t%s: %s"%(p, "success" if s else "failed"))
144+
145+
print("Summary of data checker:")
146+
for p, s, m in project_check_results:
147+
print("\t%s: %s %s"%(p, "success" if s else "failed", m))
148+
149+
150+
if __name__ == "__main__":
151+
main_loop()

oss_fuzz_integration/test_projects.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,4 +59,4 @@ for fuzzname in leveldb htslib unrar jsoncpp tarantool fio wuffs; do
5959
cp -rf ./corpus-$LATEST_CORPUS_DIR $NEW_TEST_DIR/
6060
done
6161

62-
python3 $SCRIPT_DIR/project-checker.py --test-dir=$NEW_TEST_DIR/
62+
python3 $SCRIPT_DIR/project_checker.py --test-dir=$NEW_TEST_DIR/

0 commit comments

Comments
 (0)