| #!/usr/bin/env vpython3 |
| # Copyright 2019 The Chromium Authors |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| """ |
| Unit tests for extractor.py. |
| """ |
| |
| from __future__ import print_function |
| |
| import argparse |
| import os |
| import unittest |
| import re |
| import subprocess |
| |
| from glob import glob |
| from pathlib import Path |
| from typing import Tuple |
| |
| # Path to the directory where this script is. |
| SCRIPT_DIR = Path(__file__).resolve().parent |
| |
| |
| def run_extractor(file_path: Path) -> Tuple[bytes, bytes]: |
| script_path = Path('../extractor.py') |
| cmd_line = ('python3', str(script_path), '--no-filter', file_path) |
| return subprocess.Popen( |
| cmd_line, stdout=subprocess.PIPE, stderr=subprocess.PIPE) |
| |
| |
| def get_expected_files(source_file: Path) -> Path: |
| stdout_file = (source_file.with_name('%s-stdout' % |
| source_file.stem).with_suffix('.txt')) |
| stderr_file = (source_file.with_name('%s-stderr' % |
| source_file.stem).with_suffix('.txt')) |
| return (stdout_file, stderr_file) |
| |
| |
| def dos2unix(body: str): |
| """Converts CRLF to LF.""" |
| return body.replace('\r\n', '\n') |
| |
| |
| def remove_tracebacks(body: str): |
| """Removes python tracebacks from the string.""" |
| regex = re.compile( |
| r''' |
| # A line that says "Traceback (...):" |
| ^Traceback[^\n]*:\n |
| # Followed by lines that begin with whitespace. |
| ((\s.*)?\n)*''', |
| re.MULTILINE | re.VERBOSE) |
| return re.sub(regex, '', body) |
| |
| |
| class ExtractorTest(unittest.TestCase): |
| def testExtractor(self): |
| files = list(Path(f) for f in glob('*.cc') + glob('*.java')) |
| for source_file in files: |
| if source_file.stem.startswith('test_'): |
| continue |
| |
| print("Running test on %s..." % source_file) |
| (stdout_file, stderr_file) = get_expected_files(source_file) |
| expected_stdout = dos2unix(stdout_file.read_text()) |
| expected_stderr = dos2unix(stderr_file.read_text()) |
| |
| proc = run_extractor(source_file) |
| (stdout, stderr) = (dos2unix(b.decode()) for b in proc.communicate()) |
| |
| self.assertEqual(expected_stderr, remove_tracebacks(stderr)) |
| expected_returncode = 2 if expected_stderr else 0 |
| self.assertEqual(expected_returncode, proc.returncode) |
| self.assertEqual(expected_stdout, stdout) |
| |
| |
| def generate_expected_files(): |
| files = list(Path(f) |
| for f in glob('*.java')) # glob('*.cc') + glob('*.java')) |
| for source_file in files: |
| proc = run_extractor(source_file) |
| (stdout, stderr) = (b.decode() for b in proc.communicate()) |
| |
| (stdout_file, stderr_file) = get_expected_files(source_file) |
| stdout_file.write_text(stdout) |
| stderr_file.write_text(stderr) |
| |
| |
| if __name__ == '__main__': |
| parser = argparse.ArgumentParser( |
| description="Network Traffic Annotation Extractor Unit Tests") |
| parser.add_argument( |
| '--generate-expected-files', action='store_true', |
| help='Generate "-stdout.txt" and "-stderr.txt" for file in test_data') |
| args = parser.parse_args() |
| |
| # Set directory for both test and gen command to the test_data folder. |
| os.chdir(Path(__file__).resolve().parent / 'test_data') |
| |
| # XXX |
| # # Run the extractor script with --generate-compdb to ensure the |
| # # compile_commands.json file exists in the default output directory. |
| # proc = run_extractor(os.devnull, '--generate-compdb') |
| # proc.communicate() # Wait until extractor finishes running. |
| |
| if args.generate_expected_files: |
| generate_expected_files() |
| else: |
| unittest.main() |