| #!/usr/bin/env python3 |
| # Copyright 2018 The Fuchsia Authors. All rights reserved. |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| """Checks that the output of the config parser is stable across runs.""" |
| |
| import os |
| import subprocess |
| import sys |
| import tempfile |
| |
| THIS_DIR = os.path.abspath(os.path.dirname(__file__)) |
| SRC_ROOT_DIR = os.path.abspath( |
| os.path.join(THIS_DIR, os.pardir, os.pardir, os.pardir)) |
| |
| sys.path += [os.path.join(SRC_ROOT_DIR, 'third_party', 'pyyaml', 'lib3')] |
| import yaml |
| |
| OUT_DIR = os.path.abspath(os.path.join(SRC_ROOT_DIR, 'out')) |
| CONFIG_PARSER_BIN = os.path.join(OUT_DIR, 'config_parser') |
| CONFIG_DIR = os.path.join(SRC_ROOT_DIR, 'third_party', 'cobalt_config') |
| PRIVACY_ENCODING_PARAMS_FILE = os.path.join(SRC_ROOT_DIR, 'src', 'algorithms', |
| 'privacy', 'data', |
| 'privacy_encoding_params') |
| |
| SYSROOT_BIN = os.path.join(SRC_ROOT_DIR, 'sysroot', 'bin') |
| CLANG = os.path.join(SYSROOT_BIN, 'clang++') |
| RUSTC = os.path.join(SYSROOT_BIN, 'rustc') |
| GO_BIN = os.path.join(SRC_ROOT_DIR, 'sysroot', 'golang', 'bin', 'go') |
| DART = os.path.join(SYSROOT_BIN, 'dart') |
| |
| |
| def main(): |
| customers = [] |
| with open(os.path.join(CONFIG_DIR, 'projects.yaml'), 'r') as stream: |
| customers = yaml.safe_load(stream) |
| |
| running_compiles = [] |
| for customer in customers: |
| customer_id = customer['customer_id'] |
| for project in customer['projects']: |
| project_id = project['project_id'] |
| for format in ['cpp', 'rust', 'go', 'dart', 'json']: |
| cmd = [ |
| CONFIG_PARSER_BIN, |
| '-config_dir', |
| CONFIG_DIR, |
| '-out_format', |
| format, |
| '-privacy_encoding_params_file', |
| PRIVACY_ENCODING_PARAMS_FILE, |
| '-features', |
| 'generate-dimension-name-maps', |
| ] |
| cmd.extend(['-customer_id', str(customer_id)]) |
| cmd.extend(['-project_id', str(project_id)]) |
| if format == 'go': |
| cmd.append('-go_package') |
| cmd.append('%s_%s' % |
| (customer['customer_name'], project['project_name'])) |
| out1 = subprocess.run(cmd, capture_output=True, check=True).stdout |
| compile = None |
| src = None |
| tmpdir = None |
| if format == 'cpp': |
| src = tempfile.NamedTemporaryFile(suffix='.hpp') |
| src.write(out1) |
| src.flush() |
| compile = subprocess.Popen([CLANG, '-std=c++17', src.name]) |
| elif format == 'rust': |
| src = tempfile.NamedTemporaryFile( |
| prefix=project['project_name'], suffix='.rs') |
| src.write(out1) |
| src.flush() |
| tmpdir = tempfile.TemporaryDirectory() |
| subprocess.run([ |
| RUSTC, '--out-dir', tmpdir.name, '--edition=2018', |
| '--crate-type=lib', '--crate-name=cobalt_client', |
| os.path.join(SRC_ROOT_DIR, 'src', 'lib', 'client', 'rust', 'src', |
| 'lib.rs') |
| ], |
| check=True) |
| compile = subprocess.Popen([ |
| RUSTC, '--out-dir', tmpdir.name, '--edition=2018', '--extern', |
| 'cobalt_client=%s/libcobalt_client.rlib' % tmpdir.name, |
| '--crate-type=lib', src.name |
| ], |
| stderr=subprocess.STDOUT, |
| stdout=subprocess.PIPE) |
| elif format == 'go': |
| src = tempfile.NamedTemporaryFile(suffix='.go') |
| src.write(out1) |
| src.flush() |
| compile = subprocess.Popen([GO_BIN, 'build', '-a', src.name]) |
| elif format == 'dart': |
| src = tempfile.NamedTemporaryFile(suffix='.dart') |
| src.write(out1) |
| src.flush() |
| compile = subprocess.Popen([DART, 'analyze', src.name], |
| stdout=subprocess.DEVNULL) |
| if compile: |
| running_compiles.append( |
| (customer['customer_name'], project['project_name'], format, src, |
| tmpdir, compile)) |
| |
| failures = [] |
| for running_compile in running_compiles: |
| customer_name, project_name, format, src, tmpdir, compile = running_compile |
| compile.wait() |
| if compile.returncode != 0: |
| stdout, _ = compile.communicate() |
| print(stdout) |
| failures.append( |
| 'Failed to compile generated source for project: %s/%s (language: %s)' |
| % (customer_name, project_name, format)) |
| |
| return failures |
| |
| |
| if __name__ == '__main__': |
| errors = main() |
| for error in errors: |
| print(error) |
| sys.exit(len(errors)) |