def report_failure(opts): # type: (Dict[str, Any]) -> None """ Create report when analyzer failed. The major report is the preprocessor output. The output filename generated randomly. The compiler output also captured into '.stderr.txt' file. And some more execution context also saved into '.info.txt' file. """ def extension(): # type: () -> str """ Generate preprocessor file extension. """ mapping = {'objective-c++': '.mii', 'objective-c': '.mi', 'c++': '.ii'} return mapping.get(opts['language'], '.i') def destination(): # type: () -> str """ Creates failures directory if not exits yet. """ failures_dir = os.path.join(opts['output_dir'], 'failures') if not os.path.isdir(failures_dir): os.makedirs(failures_dir) return failures_dir # Classify error type: when Clang terminated by a signal it's a 'Crash'. # (python subprocess Popen.returncode is negative when child terminated # by signal.) Everything else is 'Other Error'. error = 'crash' if opts['exit_code'] < 0 else 'other_error' # Create preprocessor output file name. (This is blindly following the # Perl implementation.) (fd, name) = tempfile.mkstemp(suffix=extension(), prefix='clang_' + error + '_', dir=destination()) os.close(fd) # Execute Clang again, but run the syntax check only. try: cwd = opts['directory'] cmd = get_arguments([opts['clang'], '-fsyntax-only', '-E'] + opts['prepend-flags'] + opts['flags'] + opts['append-flags'] + [opts['source'], '-o', name], cwd) run_command(cmd, cwd=cwd) # write general information about the crash with open(name + '.info.txt', 'w') as handle: handle.write(opts['source'] + os.linesep) handle.write(error.title().replace('_', ' ') + os.linesep) handle.write(' '.join(cmd) + os.linesep) handle.write(' '.join(platform.uname()) + os.linesep) handle.write(get_version(opts['clang'])) handle.close() # write the captured output too with open(name + '.stderr.txt', 'w') as handle: for line in opts['error_output']: handle.write(line) handle.close() except (OSError, subprocess.CalledProcessError): logging.warning('failed to report failure', exc_info=True)
def report_failure(opts): # type: (Dict[str, Any]) -> None """ Create report when analyzer failed. The major report is the preprocessor output. The output filename generated randomly. The compiler output also captured into '.stderr.txt' file. And some more execution context also saved into '.info.txt' file. """ def extension(): # type: () -> str """ Generate preprocessor file extension. """ mapping = {'objective-c++': '.mii', 'objective-c': '.mi', 'c++': '.ii'} return mapping.get(opts['language'], '.i') def destination(): # type: () -> str """ Creates failures directory if not exits yet. """ failures_dir = os.path.join(opts['output_dir'], 'failures') if not os.path.isdir(failures_dir): os.makedirs(failures_dir) return failures_dir # Classify error type: when Clang terminated by a signal it's a 'Crash'. # (python subprocess Popen.returncode is negative when child terminated # by signal.) Everything else is 'Other Error'. error = 'crash' if opts['exit_code'] < 0 else 'other_error' # Create preprocessor output file name. (This is blindly following the # Perl implementation.) (fd, name) = tempfile.mkstemp(suffix=extension(), prefix='clang_' + error + '_', dir=destination()) os.close(fd) # Execute Clang again, but run the syntax check only. try: cwd = opts['directory'] cmd = get_arguments([opts['clang'], '-fsyntax-only', '-E'] + opts['flags'] + [opts['source'], '-o', name], cwd) run_command(cmd, cwd=cwd) # write general information about the crash with open(name + '.info.txt', 'w') as handle: handle.write(opts['source'] + os.linesep) handle.write(error.title().replace('_', ' ') + os.linesep) handle.write(' '.join(cmd) + os.linesep) handle.write(' '.join(platform.uname()) + os.linesep) handle.write(get_version(opts['clang'])) handle.close() # write the captured output too with open(name + '.stderr.txt', 'w') as handle: for line in opts['error_output']: handle.write(line) handle.close() except (OSError, subprocess.CalledProcessError): logging.warning('failed to report failure', exc_info=True)
def assemble_cover(output_dir, prefix, args, fragments): """ Put together the fragments into a final report. """ import getpass import socket import datetime if args.html_title is None: args.html_title = os.path.basename(prefix) + ' - analyzer results' with open(os.path.join(output_dir, 'index.html'), 'w') as handle: indent = 0 handle.write( reindent( """ |<!DOCTYPE html> |<html> | <head> | <title>{html_title}</title> | <link type="text/css" rel="stylesheet" href="scanview.css"/> | <script type='text/javascript' src="sorttable.js"></script> | <script type='text/javascript' src='selectable.js'></script> | </head>""", indent).format(html_title=args.html_title)) handle.write(comment('SUMMARYENDHEAD')) handle.write( reindent( """ | <body> | <h1>{html_title}</h1> | <table> | <tr><th>User:</th><td>{user_name}@{host_name}</td></tr> | <tr><th>Working Directory:</th><td>{current_dir}</td></tr> | <tr><th>Command Line:</th><td>{cmd_args}</td></tr> | <tr><th>Clang Version:</th><td>{clang_version}</td></tr> | <tr><th>Date:</th><td>{date}</td></tr> | </table>""", indent).format(html_title=args.html_title, user_name=getpass.getuser(), host_name=socket.gethostname(), current_dir=prefix, cmd_args=' '.join(sys.argv), clang_version=get_version(args.clang), date=datetime.datetime.today().strftime('%c'))) for fragment in fragments: # copy the content of fragments with open(fragment, 'r') as input_handle: shutil.copyfileobj(input_handle, handle) handle.write( reindent(""" | </body> |</html>""", indent))
def report_failure(opts): """ Create report when analyzer failed. The major report is the preprocessor output. The output filename generated randomly. The compiler output also captured into '.stderr.txt' file. And some more execution context also saved into '.info.txt' file. """ def extension(opts): """ Generate preprocessor file extension. """ mapping = {'objective-c++': '.mii', 'objective-c': '.mi', 'c++': '.ii'} return mapping.get(opts['language'], '.i') def destination(opts): """ Creates failures directory if not exits yet. """ name = os.path.join(opts['output_dir'], 'failures') if not os.path.isdir(name): os.makedirs(name) return name error = opts['error_type'] (handle, name) = tempfile.mkstemp(suffix=extension(opts), prefix='clang_' + error + '_', dir=destination(opts)) os.close(handle) cwd = opts['directory'] cmd = get_arguments([opts['clang'], '-fsyntax-only', '-E'] + opts['flags'] + [opts['file'], '-o', name], cwd) logging.debug('exec command in %s: %s', cwd, ' '.join(cmd)) subprocess.call(cmd, cwd=cwd) # write general information about the crash with open(name + '.info.txt', 'w') as handle: handle.write(opts['file'] + os.linesep) handle.write(error.title().replace('_', ' ') + os.linesep) handle.write(' '.join(cmd) + os.linesep) handle.write(' '.join(os.uname()) + os.linesep) handle.write(get_version(opts['clang'])) handle.close() # write the captured output too with open(name + '.stderr.txt', 'w') as handle: handle.writelines(opts['error_output']) handle.close() # return with the previous step exit code and output return { 'error_output': opts['error_output'], 'exit_code': opts['exit_code'] }
def assemble_cover(output_dir, prefix, args, fragments): """ Put together the fragments into a final report. """ import getpass import socket import datetime if args.html_title is None: args.html_title = os.path.basename(prefix) + ' - analyzer results' with open(os.path.join(output_dir, 'index.html'), 'w') as handle: indent = 0 handle.write(reindent(""" |<!DOCTYPE html> |<html> | <head> | <title>{html_title}</title> | <link type="text/css" rel="stylesheet" href="scanview.css"/> | <script type='text/javascript' src="sorttable.js"></script> | <script type='text/javascript' src='selectable.js'></script> | </head>""", indent).format(html_title=args.html_title)) handle.write(comment('SUMMARYENDHEAD')) handle.write(reindent( """ | <body> | <h1>{html_title}</h1> | <table> | <tr><th>User:</th><td>{user_name}@{host_name}</td></tr> | <tr><th>Working Directory:</th><td>{current_dir}</td></tr> | <tr><th>Command Line:</th><td>{cmd_args}</td></tr> | <tr><th>Clang Version:</th><td>{clang_version}</td></tr> | <tr><th>Date:</th><td>{date}</td></tr> | </table>""", indent).format(html_title=args.html_title, user_name=getpass.getuser(), host_name=socket.gethostname(), current_dir=prefix, cmd_args=' '.join(sys.argv), clang_version=get_version(args.clang), date=datetime.datetime.today().strftime('%c'))) for fragment in fragments: # copy the content of fragments with open(fragment, 'r') as input_handle: for line in input_handle: handle.write(line) handle.write(reindent(""" | </body> |</html>""", indent))
def report_failure(opts): """ Create report when analyzer failed. The major report is the preprocessor output. The output filename generated randomly. The compiler output also captured into '.stderr.txt' file. And some more execution context also saved into '.info.txt' file. """ def extension(opts): """ Generate preprocessor file extension. """ mapping = {'objective-c++': '.mii', 'objective-c': '.mi', 'c++': '.ii'} return mapping.get(opts['language'], '.i') def destination(opts): """ Creates failures directory if not exits yet. """ name = os.path.join(opts['output_dir'], 'failures') if not os.path.isdir(name): os.makedirs(name) return name error = opts['error_type'] (handle, name) = tempfile.mkstemp(suffix=extension(opts), prefix='clang_' + error + '_', dir=destination(opts)) os.close(handle) cwd = opts['directory'] cmd = get_arguments([opts['clang']] + opts['report'] + ['-o', name], cwd) logging.debug('exec command in %s: %s', cwd, ' '.join(cmd)) subprocess.call(cmd, cwd=cwd) with open(name + '.info.txt', 'w') as handle: handle.write(opts['file'] + os.linesep) handle.write(error.title().replace('_', ' ') + os.linesep) handle.write(' '.join(cmd) + os.linesep) handle.write(' '.join(os.uname()) + os.linesep) handle.write(get_version(cmd[0])) handle.close() with open(name + '.stderr.txt', 'w') as handle: handle.writelines(opts['error_output']) handle.close() return { 'error_output': opts['error_output'], 'exit_code': opts['exit_code'] }
def report_failure(opts): """ Create report when analyzer failed. The major report is the preprocessor output. The output filename generated randomly. The compiler output also captured into '.stderr.txt' file. And some more execution context also saved into '.info.txt' file. """ def extension(opts): """ Generate preprocessor file extension. """ mapping = {"objective-c++": ".mii", "objective-c": ".mi", "c++": ".ii"} return mapping.get(opts["language"], ".i") def destination(opts): """ Creates failures directory if not exits yet. """ name = os.path.join(opts["output_dir"], "failures") if not os.path.isdir(name): os.makedirs(name) return name error = opts["error_type"] (handle, name) = tempfile.mkstemp(suffix=extension(opts), prefix="clang_" + error + "_", dir=destination(opts)) os.close(handle) cwd = opts["directory"] cmd = get_arguments([opts["clang"]] + opts["report"] + ["-o", name], cwd) logging.debug("exec command in %s: %s", cwd, " ".join(cmd)) subprocess.call(cmd, cwd=cwd) with open(name + ".info.txt", "w") as handle: handle.write(opts["file"] + os.linesep) handle.write(error.title().replace("_", " ") + os.linesep) handle.write(" ".join(cmd) + os.linesep) handle.write(" ".join(os.uname()) + os.linesep) handle.write(get_version(cmd[0])) handle.close() with open(name + ".stderr.txt", "w") as handle: handle.writelines(opts["error_output"]) handle.close() return {"error_output": opts["error_output"], "exit_code": opts["exit_code"]}
def test_get_version_throws(self): with self.assertRaises(OSError): sut.get_version('notexists')
def test_get_version_is_not_empty(self): self.assertTrue(sut.get_version('clang'))