diff options
author | Rob Guo <robertguo@me.com> | 2017-10-04 15:41:52 -0400 |
---|---|---|
committer | Rob Guo <robertguo@me.com> | 2017-10-04 15:50:59 -0400 |
commit | 381c7fc06c8f97d83ec5e7681004a2c67e4e1299 (patch) | |
tree | 74cfac2592d37a4b1bd8cff94d4cc52ebc540992 /buildscripts | |
parent | e329bd234dc00535b36a47ae998cf24a40552968 (diff) | |
download | mongo-381c7fc06c8f97d83ec5e7681004a2c67e4e1299.tar.gz |
SERVER-30839 prevent buildscripts/combine_reports.py from overwriting report.json
Diffstat (limited to 'buildscripts')
-rwxr-xr-x | buildscripts/collect_resource_info.py | 29 | ||||
-rwxr-xr-x | buildscripts/combine_reports.py | 42 | ||||
-rwxr-xr-x | buildscripts/resmoke.py | 5 | ||||
-rw-r--r-- | buildscripts/resmokelib/utils/__init__.py | 27 |
4 files changed, 63 insertions, 40 deletions
diff --git a/buildscripts/collect_resource_info.py b/buildscripts/collect_resource_info.py index c6f7b1ac527..5fc6c614afa 100755 --- a/buildscripts/collect_resource_info.py +++ b/buildscripts/collect_resource_info.py @@ -7,7 +7,6 @@ Collect system resource information on processes running in Evergreen on a given from __future__ import absolute_import from __future__ import print_function -import contextlib from datetime import datetime import optparse import os @@ -17,30 +16,13 @@ import time from bson.json_util import dumps import requests -@contextlib.contextmanager -def open_or_use_stdout(filename): - """ - Opens the specified file for writing, or returns sys.stdout if filename is "-". - """ - if filename == "-": - yield sys.stdout - return - - line_buffered = 1 - try: - fp = open(filename, "w", line_buffered) - except IOError: - print("Could not open file {}".format(filename), file=sys.stderr) - sys.exit(1) - - try: - yield fp - finally: - fp.close() +# Get relative imports to work when the package is not installed on the PYTHONPATH. +sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) +from buildscripts.resmokelib import utils + def main(): - usage = "usage: %prog [options]" parser = optparse.OptionParser(description=__doc__, usage=usage) parser.add_option("-i", "--interval", @@ -58,7 +40,7 @@ def main(): (options, _) = parser.parse_args() - with open_or_use_stdout(options.outfile) as fp: + with utils.open_or_use_stdout(options.outfile) as fp: while True: # Requires the Evergreen agent to be running on port 2285. response = requests.get("http://localhost:2285/status") @@ -109,5 +91,6 @@ def main(): os.fsync(fp.fileno()) time.sleep(options.interval) + if __name__ == "__main__": main() diff --git a/buildscripts/combine_reports.py b/buildscripts/combine_reports.py index d7fe0eb5ece..e0e81569a80 100755 --- a/buildscripts/combine_reports.py +++ b/buildscripts/combine_reports.py @@ -14,9 +14,9 @@ import sys from optparse import OptionParser # Get relative imports to work when the package is not installed on the PYTHONPATH. -if __name__ == "__main__" and __package__ is None: - sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) - from buildscripts.resmokelib.testing import report +sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) +from buildscripts.resmokelib.testing import report +from buildscripts.resmokelib import utils def read_json_file(json_file): @@ -37,8 +37,18 @@ def report_exit(combined_test_report): return ret -def main(): +def check_error(input_count, output_count): + """ + Error if both input and output exist, or if neither exist. + """ + if (not input_count) and (not output_count): + raise ValueError("None of the input file(s) or output file exists") + + elif input_count and output_count: + raise ValueError("Both input file and output files exist") + +def main(): usage = "usage: %prog [options] report1.json report2.json ..." parser = OptionParser(description=__doc__, usage=usage) parser.add_option("-o", "--output-file", @@ -47,10 +57,6 @@ def main(): help="If '-', then the combined report file is written to stdout." " Any other value is treated as the output file name. By default," " output is written to stdout.") - parser.add_option("-m", "--ignore-missing-reports", - dest="ignore_missing", - action="store_true", - help="Ignore any input report file that does not exist.") parser.add_option("-x", "--no-report-exit", dest="report_exit", default=True, @@ -63,25 +69,33 @@ def main(): sys.exit("No report files were specified") report_files = args + report_files_count = len(report_files) test_reports = [] + for report_file in report_files: try: report_file_json = read_json_file(report_file) test_reports.append(report.TestReport.from_dict(report_file_json)) except IOError as e: # errno.ENOENT is the error code for "No such file or directory". - if options.ignore_missing and e.errno == errno.ENOENT: - print("Ignoring missing file {}".format(report_file)) + if e.errno == errno.ENOENT: + report_file_count -= 1 continue raise combined_test_report = report.TestReport.combine(*test_reports) combined_report = combined_test_report.as_dict() - if options.outfile != "-": - with open(options.outfile, "w") as fstream: - json.dump(combined_report, fstream) + + if options.outfile == "-": + outfile_exists = False # Nothing will be overridden when writing to stdout. else: - print(json.dumps(combined_report)) + outfile_exists = os.path.exists(options.outfile) + + check_error(report_files_count, outfile_exists) + + if not outfile_exists: + with utils.open_or_use_stdout(options.outfile) as fh: + json.dump(combined_report, fh) if options.report_exit: sys.exit(report_exit(combined_test_report)) diff --git a/buildscripts/resmoke.py b/buildscripts/resmoke.py index 29591ef57a3..aa8d437d815 100755 --- a/buildscripts/resmoke.py +++ b/buildscripts/resmoke.py @@ -12,9 +12,8 @@ import sys import time # Get relative imports to work when the package is not installed on the PYTHONPATH. -if __name__ == "__main__" and __package__ is None: - sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) - from buildscripts import resmokelib +sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) +from buildscripts import resmokelib def _execute_suite(suite): diff --git a/buildscripts/resmokelib/utils/__init__.py b/buildscripts/resmokelib/utils/__init__.py index 77cc6952fb0..fa782f34301 100644 --- a/buildscripts/resmokelib/utils/__init__.py +++ b/buildscripts/resmokelib/utils/__init__.py @@ -3,12 +3,38 @@ Helper functions. """ from __future__ import absolute_import +from __future__ import print_function +import contextlib import os.path +import sys import yaml +@contextlib.contextmanager +def open_or_use_stdout(filename): + """ + Opens the specified file for writing, or returns sys.stdout if filename is "-". + """ + + if filename == "-": + yield sys.stdout + return + + line_buffered = 1 + try: + fp = open(filename, "w", line_buffered) + except IOError: + print("Could not open file {}".format(filename), file=sys.stderr) + sys.exit(1) + + try: + yield fp + finally: + fp.close() + + def default_if_none(value, default): return value if value is not None else default @@ -60,6 +86,7 @@ def dump_yaml(value): # Use block (indented) style for formatting YAML. return yaml.safe_dump(value, default_flow_style=False).rstrip() + def load_yaml(value): """ Attempts to parse 'value' as YAML. |