diff --git a/tools/memap.py b/tools/memap.py index f26e97a819..0b9e91f6a1 100644 --- a/tools/memap.py +++ b/tools/memap.py @@ -9,6 +9,7 @@ import csv import json import argparse from prettytable import PrettyTable +from StringIO import StringIO from utils import argparse_filestring_type, \ argparse_lowercase_hyphen_type, argparse_uppercase_type @@ -396,7 +397,7 @@ class MemapParser(object): export_formats = ["json", "csv-ci", "table"] - def generate_output(self, export_format, file_output=None): + def generate_output(self, export_format, file_output=None, silent=False): """ Generates summary of memory map data Positional arguments: @@ -407,10 +408,13 @@ class MemapParser(object): """ try: - if file_output: - file_desc = open(file_output, 'wb') + if silent: + file_desc = None else: - file_desc = sys.stdout + if file_output: + file_desc = open(file_output, 'wb') + else: + file_desc = sys.stdout except IOError as error: print "I/O error({0}): {1}".format(error.errno, error.strerror) return False @@ -418,19 +422,25 @@ class MemapParser(object): to_call = {'json': self.generate_json, 'csv-ci': self.generate_csv, 'table': self.generate_table}[export_format] - to_call(file_desc) + output_string = to_call(file_desc) - if file_desc is not sys.stdout: + if file_desc is not sys.stdout and file_desc is not None: file_desc.close() + return output_string + def generate_json(self, file_desc): """Generate a json file from a memory map Positional arguments: file_desc - the file to write out the final report to """ - file_desc.write(json.dumps(self.mem_report, indent=4)) - file_desc.write('\n') + output = json.dumps(self.mem_report, indent=4) + if file_desc: + file_desc.write(output) + file_desc.write('\n') + + return output def generate_csv(self, file_desc): """Generate a CSV file from a memoy map @@ -438,7 +448,8 @@ class MemapParser(object): Positional arguments: file_desc - the file to write out the final report to """ - csv_writer = csv.writer(file_desc, delimiter=',', + string_io = StringIO() + csv_writer = csv.writer(string_io, delimiter=',', quoting=csv.QUOTE_MINIMAL) csv_module_section = [] @@ -472,6 +483,11 @@ class MemapParser(object): csv_writer.writerow(csv_module_section) csv_writer.writerow(csv_sizes) + if file_desc: + file_desc.write(string_io.getvalue()) + + return string_io.getvalue() + def generate_table(self, file_desc): """Generate a table from a memoy map @@ -504,28 +520,32 @@ class MemapParser(object): table.add_row(subtotal_row) - file_desc.write(table.get_string()) - file_desc.write('\n') + output = table.get_string() + output += '\n' if self.mem_summary['heap'] == 0: - file_desc.write("Allocated Heap: unknown\n") + output += "Allocated Heap: unknown\n" else: - file_desc.write("Allocated Heap: %s bytes\n" % - str(self.mem_summary['heap'])) + output += "Allocated Heap: %s bytes\n" % \ + str(self.mem_summary['heap']) if self.mem_summary['stack'] == 0: - file_desc.write("Allocated Stack: unknown\n") + output += "Allocated Stack: unknown\n" else: - file_desc.write("Allocated Stack: %s bytes\n" % - str(self.mem_summary['stack'])) + output += "Allocated Stack: %s bytes\n" % \ + str(self.mem_summary['stack']) - file_desc.write("Total Static RAM memory (data + bss): %s bytes\n" % - (str(self.mem_summary['static_ram']))) - file_desc.write( - "Total RAM memory (data + bss + heap + stack): %s bytes\n" - % (str(self.mem_summary['total_ram']))) - file_desc.write("Total Flash memory (text + data + misc): %s bytes\n" % - (str(self.mem_summary['total_flash']))) + output += "Total Static RAM memory (data + bss): %s bytes\n" % \ + str(self.mem_summary['static_ram']) + output += "Total RAM memory (data + bss + heap + stack): %s bytes\n" % \ + str(self.mem_summary['total_ram']) + output += "Total Flash memory (text + data + misc): %s bytes\n" % \ + str(self.mem_summary['total_flash']) + + if file_desc: + file_desc.write(output) + + return output toolchains = ["ARM", "ARM_STD", "ARM_MICRO", "GCC_ARM", "IAR"] diff --git a/tools/test_api.py b/tools/test_api.py index 9b0e01aafc..af503316eb 100644 --- a/tools/test_api.py +++ b/tools/test_api.py @@ -2071,6 +2071,19 @@ def norm_relative_path(path, start): def build_test_worker(*args, **kwargs): + """This is a worker function for the parallel building of tests. The `args` + and `kwargs` are passed directly to `build_project`. It returns a dictionary + with the following structure: + + { + 'result': `True` if no exceptions were thrown, `False` otherwise + 'reason': Instance of exception that was thrown on failure + 'bin_file': Path to the created binary if `build_project` was + successful. Not present otherwise + 'kwargs': The keyword arguments that were passed to `build_project`. + This includes arguments that were modified (ex. report) + } + """ bin_file = None ret = { 'result': False, @@ -2138,7 +2151,8 @@ def build_tests(tests, base_source_paths, build_path, target, toolchain_name, 'properties': properties, 'verbose': verbose, 'app_config': app_config, - 'build_profile': build_profile + 'build_profile': build_profile, + 'silent': True } results.append(p.apply_async(build_test_worker, args, kwargs)) @@ -2161,13 +2175,16 @@ def build_tests(tests, base_source_paths, build_path, target, toolchain_name, worker_result = r.get() results.remove(r) + # Take report from the kwargs and merge it into existing report + report_entry = worker_result['kwargs']['report'][target_name][toolchain_name] + for test_key in report_entry.keys(): + report[target_name][toolchain_name][test_key] = report_entry[test_key] - for test_key in worker_result['kwargs']['report'][target_name][toolchain_name].keys(): - report[target_name][toolchain_name][test_key] = worker_result['kwargs']['report'][target_name][toolchain_name][test_key] - + # Set the overall result to a failure if a build failure occurred if not worker_result['result'] and not isinstance(worker_result['reason'], NotSupportedException): result = False + # Adding binary path to test build result if worker_result['result'] and 'bin_file' in worker_result: bin_file = norm_relative_path(worker_result['bin_file'], execution_directory) @@ -2179,7 +2196,9 @@ def build_tests(tests, base_source_paths, build_path, target, toolchain_name, ] } - # TODO: add 'Image: bin_file' print statement here + test_key = worker_result['kwargs']['project_id'].upper() + print report[target_name][toolchain_name][test_key][0][0]['output'].rstrip() + print 'Image: %s\n' % bin_file except ToolException, err: if p._taskqueue.queue: diff --git a/tools/toolchains/__init__.py b/tools/toolchains/__init__.py index c57dda55e6..595f220769 100644 --- a/tools/toolchains/__init__.py +++ b/tools/toolchains/__init__.py @@ -1076,7 +1076,7 @@ class mbedToolchain: return None # Write output to stdout in text (pretty table) format - memap.generate_output('table') + self.info(memap.generate_output('table', silent=True)) # Write output to file in JSON format map_out = splitext(map)[0] + "_map.json"