Index: tests/abi_corpus/validator_regression_test.py |
diff --git a/tests/abi_corpus/validator_regression_test.py b/tests/abi_corpus/validator_regression_test.py |
new file mode 100755 |
index 0000000000000000000000000000000000000000..0850d4063eb3a01c3e1de43a2e600d14b989b93d |
--- /dev/null |
+++ b/tests/abi_corpus/validator_regression_test.py |
@@ -0,0 +1,137 @@ |
+#!/usr/bin/python |
+# Copyright (c) 2012 The Native Client Authors. All rights reserved. |
+# Use of this source code is governed by a BSD-style license that can be |
+# found in the LICENSE file. |
+ |
+import optparse |
+import os |
+import subprocess |
+import tempfile |
+ |
+import corpus_errors |
+import corpus_utils |
+ |
+ |
+class UnexpectedValidateResult(Exception): |
+ pass |
+ |
+ |
+def ValidateNexe(options, path, src_path, expect_pass): |
+ """Run the validator on a nexe, check if the result is expected. |
+ |
+ Args: |
+ options: bag of options. |
+ path: path to the nexe. |
+ src_path: path to nexe on server. |
+ expect_pass: boolean indicating if the nexe is expected to validate. |
+ Returns: |
+ True if validation matches expectations. |
+ """ |
+ process = subprocess.Popen( |
+ [options.validator, path], |
+ stdout=subprocess.PIPE, |
+ stderr=subprocess.PIPE) |
+ process_stdout, process_stderr = process.communicate() |
+ # Check if result is what we expect. |
+ did_pass = (process.returncode == 0) |
+ if expect_pass != did_pass: |
+ if options.verbose: |
+ print '-' * 70 |
+ print 'Validating: %s' % path |
+ print 'From: %s' % src_path |
+ print 'Size: %d' % os.path.getsize(path) |
+ print 'SHA1: %s' % corpus_utils.Sha1FromFilename(path) |
+ print 'Validator: %s' % options.validator |
+ print 'Unexpected return code: %s' % process.returncode |
+ print '>>> STDOUT' |
+ print process_stdout |
+ print '>>> STDERR' |
+ print process_stderr |
+ print '-' * 70 |
+ else: |
+ print 'Unexpected return code %d on sha1: %s' % ( |
+ process.returncode, corpus_utils.Sha1FromFilename(path)) |
+ return False |
+ return True |
+ |
+ |
+def TestValidators(options, work_dir): |
+ """Test x86 validators on current snapshot. |
+ |
+ Args: |
+ options: bag of options. |
+ work_dir: directory to operate in. |
+ """ |
+ nexe_filename = os.path.join(work_dir, 'test.nexe') |
+ list_filename = os.path.join(work_dir, 'naclapps.list') |
+ filenames = corpus_utils.DownloadNexeList(list_filename) |
+ progress = corpus_utils.Progress(len(filenames)) |
+ for filename in filenames: |
+ progress.Tally() |
+ corpus_utils.PrimeCache(options.cache_dir, filename) |
+ # Stop here if downloading only. |
+ if options.download_only: |
+ continue |
+ # Skip if not the right architecture. |
+ architecture = corpus_utils.NexeArchitecture( |
+ corpus_utils.CachedPath(options.cache_dir, filename)) |
+ if architecture != options.architecture: |
+ continue |
+ # Validate a copy in case validator is mutating. |
+ corpus_utils.CopyFromCache(options.cache_dir, filename, nexe_filename) |
+ try: |
+ result = ValidateNexe( |
+ options, nexe_filename, filename, |
+ corpus_errors.NexeShouldValidate(filename)) |
+ progress.Result(result) |
+ if not result and not options.keep_going: |
+ break |
+ finally: |
+ try: |
+ os.remove(nexe_filename) |
+ except OSError: |
+ print 'ERROR - unable to remove %s' % nexe_filename |
+ progress.Summary(warn_only=True) |
+ |
+ |
+def Main(): |
+ parser = optparse.OptionParser() |
+ parser.add_option( |
+ '--download-only', dest='download_only', |
+ default=False, action='store_true', |
+ help='download to cache without running the tests') |
+ parser.add_option( |
+ '-k', '--keep-going', dest='keep_going', |
+ default=False, action='store_true', |
+ help='keep going on failure') |
+ parser.add_option( |
+ '--validator', dest='validator', |
+ help='location of validator executable') |
+ parser.add_option( |
+ '--arch', dest='architecture', |
+ help='architecture of validator') |
+ parser.add_option( |
+ '-v', '--verbose', dest='verbose', default=False, action='store_true', |
+ help='run in verbose mode') |
+ parser.add_option( |
+ '--cache-dir', dest='cache_dir', |
+ default=corpus_utils.DefaultCacheDirectory(), |
+ help='directory to cache downloads in') |
+ options, args = parser.parse_args() |
+ if args: |
+ parser.error('unused arguments') |
+ if not options.download_only: |
+ if not options.validator: |
+ parser.error('no validator specified') |
+ if not options.architecture: |
+ parser.error('no architecture specified') |
+ |
+ work_dir = tempfile.mkdtemp(suffix='validate_nexes', prefix='tmp') |
+ try: |
+ TestValidators(options, work_dir) |
+ finally: |
+ corpus_utils.RemoveDir(work_dir) |
+ |
+ |
+if __name__ == '__main__': |
+ Main() |