[tests] kill empty build_integration_tests.py

Reviewed By: jberdine

Differential Revision: D4329664

fbshipit-source-id: dc59abc
master
Jules Villard 8 years ago committed by Facebook Github Bot
parent c6ed7ad489
commit a9d5b5afdb

@ -157,8 +157,7 @@ $(BUILD_SYSTEMS_TESTS:%=build_%_clean):
$(MAKE) -C $(INFER_DIR)/tests/build_systems/$(patsubst build_%_clean,%,$@) clean)
.PHONY: build_systems_tests
build_systems_tests: infer $(BUILD_SYSTEMS_TESTS:%=build_%_test)
NO_BUCKD=1 $(INFER_DIR)/tests/build_systems/build_integration_tests.py
build_systems_tests: $(BUILD_SYSTEMS_TESTS:%=build_%_test)
.PHONY: print_build_systems_tests
print_build_systems_tests: $(BUILD_SYSTEMS_TESTS:%=build_%_print)
@ -220,8 +219,6 @@ test-replace:
mv -f $$file $$(dirname $$file)/$$(basename -s .exp.test $$file).exp; done
@for file in $$(find $(INFER_DIR)/tests -name "*.test.dot"); do \
mv -f $$file $$(dirname $$file)/$$(basename -s .test.dot $$file).dot; done
INFER_RECORD_INTEGRATION_TESTS=1 NO_BUCKD=1 \
$(INFER_DIR)/tests/build_systems/build_integration_tests.py
.PHONY: uninstall
uninstall:

@ -1,320 +0,0 @@
#!/usr/bin/env python2.7
# -*- coding: utf-8 -*-
# Copyright (c) 2015 - present Facebook, Inc.
# All rights reserved.
#
# This source code is licensed under the BSD style license found in the
# LICENSE file in the root directory of this source tree. An additional grant
# of patent rights can be found in the PATENTS file in the same directory.
# example usage:
# # run all the tests
# ./build_integration_test.py
# # run only the ant and gradle tests
# ./build_integration_test.py -- ant gradle
# # run no test
# ./build_integration_test.py --
# # run only the waf tests and record the output
# INFER_RECORD_INTEGRATION_TESTS=1 ./build_integration_test.py -- waf
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from __future__ import unicode_literals
import json
import os
import platform
import shutil
import subprocess
import sys
import tempfile
import unittest
SCRIPT_DIR = os.path.dirname(os.path.realpath(__file__))
sys.path.insert(0,
os.path.join(SCRIPT_DIR,
os.pardir, os.pardir, 'lib', 'python'))
from inferlib import config, issues, utils
ROOT_DIR = os.path.join(SCRIPT_DIR, os.pardir, os.pardir, os.pardir)
INFER_BIN = os.path.join(ROOT_DIR, 'infer', 'bin', 'infer')
INFERPRINT_BIN = os.path.join(ROOT_DIR, 'infer', 'bin', 'InferPrint')
CLANG_BIN = os.path.join(ROOT_DIR, 'facebook-clang-plugins', 'clang',
'install', 'bin', 'clang')
REPORT_JSON = 'report.json'
RECORD_ENV = 'INFER_RECORD_INTEGRATION_TESTS'
REPORT_FIELDS = [
issues.JSON_INDEX_FILENAME,
issues.JSON_INDEX_PROCEDURE,
issues.JSON_INDEX_TYPE,
]
CODETOANALYZE_DIR = os.path.join(SCRIPT_DIR, 'codetoanalyze')
EXPECTED_OUTPUTS_DIR = os.path.join(SCRIPT_DIR, 'expected_outputs')
ALL_TESTS = [
'waf',
]
to_test = ALL_TESTS
def should_record_tests():
return RECORD_ENV in os.environ and os.environ[RECORD_ENV] == '1'
def quote(s):
return '\"%s\"' % s
def string_of_error(e):
line = ''
if issues.JSON_INDEX_LINE in e:
line = ' on line %s ' % e[issues.JSON_INDEX_LINE]
msg = '%s in file %s, procedure %s%s' % (
e[issues.JSON_INDEX_TYPE],
quote(e[issues.JSON_INDEX_FILENAME]),
quote(e[issues.JSON_INDEX_PROCEDURE]),
line,
)
return msg
def save_report(reports, filename):
# sorting to avoid spurious differences between two lists of reports
reports.sort()
def filter_report(report):
return dict((k, v) for (k, v) in report.items() if k in REPORT_FIELDS)
def should_report(report):
return len(report) > 0
filtered = filter(should_report, map(filter_report, reports))
utils.dump_json_to_path(filtered, filename,
separators=(',', ': '), sort_keys=True)
def run_analysis(clean_cmds, build_cmds, extra_check, should_fail, env=None):
for clean_cmd in clean_cmds:
subprocess.check_call(clean_cmd, env=env)
temp_out_dir = tempfile.mkdtemp(suffix='_out', prefix='infer_')
for build_cmd in build_cmds:
extra_args = (build_cmd['infer_args']
if 'infer_args' in build_cmd
else [])
infer_cmd = ([INFER_BIN, '-o', temp_out_dir] +
extra_args +
['--'] +
build_cmd['compile'])
# Only record the output of the last build command. We record
# all of them but each command overwrites the output of the
# previous one.
with tempfile.TemporaryFile(
mode='w',
suffix='.out',
prefix='analysis_') as analysis_output:
try:
subprocess.check_call(infer_cmd,
stdout=analysis_output, env=env)
if should_fail is not None:
# hacky since we should clean up infer-out, etc. as below
# if you made the test fails, this is your punishment
assert False
except subprocess.CalledProcessError, exn:
if exn.returncode != should_fail:
raise
# Set this to True to create an issues.exp file using the
# results of the test. This is a temporary hack to aid
# migrating the tests from this file to Makefiles. It can be
# useful to compare the result of your migrated test with the
# issues.exp that this gives you.
if False:
inferprint_cmd = (
[INFERPRINT_BIN, '-q', '--issues-tests', 'issues.exp',
'--from-json-report',
os.path.join(temp_out_dir, 'report.json')] +
extra_args)
subprocess.check_call(inferprint_cmd, env=env)
json_path = os.path.join(temp_out_dir, REPORT_JSON)
found_errors = utils.load_json_from_path(json_path)
extra_check(temp_out_dir)
shutil.rmtree(temp_out_dir)
os.chdir(SCRIPT_DIR)
return found_errors
def match_pattern(f, p):
for key in p.keys():
if f[key] != p[key]:
return False
return True
def is_expected(e, patterns):
for p in patterns:
if match_pattern(e, p):
return True
return False
def is_missing(p, errors):
for e in errors:
if match_pattern(e, p):
return False
return True
def unexpected_errors(errors, patterns):
return [e for e in errors if not is_expected(e, patterns)]
def missing_errors(errors, patterns):
return [p for p in patterns if is_missing(p, errors)]
def check_results(errors, patterns):
unexpected = unexpected_errors(errors, patterns)
if unexpected != []:
utils.stderr('\nInfer found the following unexpected errors:')
for e in unexpected:
utils.stderr('\t{}\n'.format(string_of_error(e)))
missing = missing_errors(errors, patterns)
if missing != []:
utils.stderr('\nInfer did not find the following errors:')
for p in missing:
utils.stderr('\t{}\n'.format(string_of_error(p)))
assert unexpected == []
assert missing == []
def is_tool_available(cmd):
try:
with open(os.devnull, 'w') as devnull:
subprocess.call(cmd, stdout=devnull)
except OSError as e:
if e.errno == os.errno.ENOENT:
return False
else:
raise
return True
def do_test(errors, expected_errors_filename):
if should_record_tests():
save_report(errors, expected_errors_filename)
return
else:
patterns = utils.load_json_from_path(expected_errors_filename)
check_results(errors, patterns)
def make_paths_relative_in_report(root, errors):
for error in errors:
# remove "root/" from each file name
rel_fname = error[issues.JSON_INDEX_FILENAME][len(root) + 1:]
error[issues.JSON_INDEX_FILENAME] = rel_fname
return errors
def test(name,
readable_name,
root,
compile_commands,
clean_commands=[],
env=None,
available=lambda: True,
enabled=None,
report_fname=None,
extra_check=lambda x: None,
should_fail=None,
preprocess=lambda: None,
postprocess=lambda errors: errors):
"""Run a test.
Arguments:
- [name] is used to test if the test is enabled by default (but
see [enabled])
- [root] the directory from which to run the test
- [compile_commands] the commands to be captured by Infer
- [clean_commands] commands to setup the build directory prior to
running Infer
- [env] the environment in which to run all the commands
- [available] a test to determine whether the test can be run
- [enabled] whether the test should attempt to run. By default it
is enabled if [[name] in [to_test]]
- [report_fname] where to find the expected Infer results
- [extra_check] some function that will be given the temporary
results directory as argument
- [should_fail] if not None then running infer is expected to fail
with [should_fail] error code
- [preprocess] a function to run before the clean and compile
commands. If the function returns something non-None, use that as
the compile commands.
- [postprocess] a function that takes in an Infer report and can
modify them. It must return an Infer report.
Returns [True] if the test ran, [False] otherwise.
"""
# python can't into using values of arguments in the default
# values of other arguments
if enabled is None:
enabled = name in to_test
if report_fname is None:
report_fname = '%s_report.json' % name
if not (enabled and available()):
print('Skipping %s integration test' % readable_name)
return False
print('\nRunning %s integration test' % readable_name)
if not os.path.exists(root):
os.makedirs(root)
os.chdir(root)
pre = preprocess()
if pre is not None:
compile_commands = pre
# rerun this in case preprocess() deleted the current directory
if not os.path.exists(root):
os.makedirs(root)
os.chdir(root)
errors = run_analysis(
clean_commands,
compile_commands,
extra_check=extra_check,
should_fail=should_fail,
env=env)
original = os.path.join(EXPECTED_OUTPUTS_DIR, report_fname)
do_test(postprocess(errors), original)
return True
class BuildIntegrationTest(unittest.TestCase):
pass
if __name__ == '__main__':
# hackish capturing of the arguments after '--'
try:
i = sys.argv.index('--')
to_test = sys.argv[i + 1:]
sys.argv = sys.argv[:i]
except ValueError:
pass
unittest.main() # run all the tests
Loading…
Cancel
Save