Added option to use dx in dexfuzz testing as well.
Rationale:
Moving away from jack, we need all our fuzzing tools
to be able to use alternative compilation paths.
BUG: 19637031
Test: nightly fuzzing (Aart's cron job for now)
Change-Id: I92b13e46ed692d7813c072b576d8a3267ff36dd5
diff --git a/tools/jfuzz/README.md b/tools/jfuzz/README.md
index c87e714..10d175b 100644
--- a/tools/jfuzz/README.md
+++ b/tools/jfuzz/README.md
@@ -48,6 +48,7 @@
[--report_script=SCRIPT]
[--jfuzz_arg=ARG]
[--true_divergence]
+ [--use_dx]
where
@@ -63,6 +64,7 @@
--report_script : path to script called for each divergence
--jfuzz_arg : argument for jfuzz
--true_divergence : don't bisect timeout divergences
+ --use_dx : use dx (rather than jack)
How to start JFuzz nightly testing
==================================
@@ -83,12 +85,14 @@
[--num_tests=NUM_TESTS]
[--num_inputs=NUM_INPUTS]
[--device=DEVICE]
+ [--use_dx]
where
--num_tests : number of tests to run (10000 by default)
--num_inputs: number of JFuzz programs to generate
--device : target device serial number (passed to adb -s)
+ --use_dx : use dx (rather than jack)
Background
==========
diff --git a/tools/jfuzz/run_dex_fuzz_test.py b/tools/jfuzz/run_dex_fuzz_test.py
index c1d2e4f..ca0aec0 100755
--- a/tools/jfuzz/run_dex_fuzz_test.py
+++ b/tools/jfuzz/run_dex_fuzz_test.py
@@ -19,6 +19,7 @@
import shutil
import sys
+from glob import glob
from subprocess import call
from tempfile import mkdtemp
@@ -40,13 +41,14 @@
class DexFuzzTester(object):
"""Tester that feeds JFuzz programs into DexFuzz testing."""
- def __init__(self, num_tests, num_inputs, device):
+ def __init__(self, num_tests, num_inputs, device, use_dx):
"""Constructor for the tester.
Args:
num_tests: int, number of tests to run
num_inputs: int, number of JFuzz programs to generate
device: string, target device serial number (or None)
+ use_dx: boolean, if True use dx rather than jack
"""
self._num_tests = num_tests
self._num_inputs = num_inputs
@@ -56,6 +58,7 @@
self._dexfuzz_dir = None
self._inputs_dir = None
self._dexfuzz_env = None
+ self._use_dx = use_dx
def __enter__(self):
"""On entry, enters new temp directory after saving current directory.
@@ -100,6 +103,35 @@
self.GenerateJFuzzPrograms()
self.RunDexFuzz()
+ def CompileOnHost(self):
+ """Compiles Test.java into classes.dex using either javac/dx or jack.
+
+ Raises:
+ FatalError: error when compilation fails
+ """
+ if self._use_dx:
+ if RunCommand(['javac', 'Test.java'],
+ out=None, err='jerr.txt', timeout=30) != RetCode.SUCCESS:
+ print('Unexpected error while running javac')
+ raise FatalError('Unexpected error while running javac')
+ cfiles = glob('*.class')
+ if RunCommand(['dx', '--dex', '--output=classes.dex'] + cfiles,
+ out=None, err='dxerr.txt', timeout=30) != RetCode.SUCCESS:
+ print('Unexpected error while running dx')
+ raise FatalError('Unexpected error while running dx')
+ # Cleanup on success (nothing to see).
+ for cfile in cfiles:
+ os.unlink(cfile)
+ os.unlink('jerr.txt')
+ os.unlink('dxerr.txt')
+ else:
+ jack_args = ['-cp', GetJackClassPath(), '--output-dex', '.', 'Test.java']
+ if RunCommand(['jack'] + jack_args, out=None, err='jackerr.txt',
+ timeout=30) != RetCode.SUCCESS:
+ print('Unexpected error while running Jack')
+ raise FatalError('Unexpected error while running Jack')
+ # Cleanup on success (nothing to see).
+ os.unlink('jackerr.txt')
def GenerateJFuzzPrograms(self):
"""Generates JFuzz programs.
@@ -109,17 +141,12 @@
"""
os.chdir(self._inputs_dir)
for i in range(1, self._num_inputs + 1):
- jack_args = ['-cp', GetJackClassPath(), '--output-dex', '.', 'Test.java']
if RunCommand(['jfuzz'], out='Test.java', err=None) != RetCode.SUCCESS:
print('Unexpected error while running JFuzz')
raise FatalError('Unexpected error while running JFuzz')
- if RunCommand(['jack'] + jack_args, out=None, err='jackerr.txt',
- timeout=30) != RetCode.SUCCESS:
- print('Unexpected error while running Jack')
- raise FatalError('Unexpected error while running Jack')
+ self.CompileOnHost()
shutil.move('Test.java', '../Test' + str(i) + '.java')
shutil.move('classes.dex', 'classes' + str(i) + '.dex')
- os.unlink('jackerr.txt')
def RunDexFuzz(self):
"""Starts the DexFuzz testing."""
@@ -152,10 +179,12 @@
type=int, help='number of tests to run')
parser.add_argument('--num_inputs', default=10,
type=int, help='number of JFuzz program to generate')
+ parser.add_argument('--use_dx', default=False, action='store_true',
+ help='use dx (rather than jack)')
parser.add_argument('--device', help='target device serial number')
args = parser.parse_args()
# Run the DexFuzz tester.
- with DexFuzzTester(args.num_tests, args.num_inputs, args.device) as fuzzer:
+ with DexFuzzTester(args.num_tests, args.num_inputs, args.device, args.use_dx) as fuzzer:
fuzzer.Run()
if __name__ == '__main__':
diff --git a/tools/jfuzz/run_jfuzz_test.py b/tools/jfuzz/run_jfuzz_test.py
index 58bc737..dac1c79 100755
--- a/tools/jfuzz/run_jfuzz_test.py
+++ b/tools/jfuzz/run_jfuzz_test.py
@@ -606,7 +606,7 @@
parser.add_argument('--true_divergence', default=False, action='store_true',
help='don\'t bisect timeout divergences')
parser.add_argument('--use_dx', default=False, action='store_true',
- help='use old-style dx (rather than jack)')
+ help='use dx (rather than jack)')
args = parser.parse_args()
if args.mode1 == args.mode2:
raise FatalError('Identical execution modes given')