From de8f335e0a4da636fce2ec54099212c5f1689aa7 Mon Sep 17 00:00:00 2001 From: Paul Fagerburg Date: Wed, 10 Mar 2021 14:37:48 -0700 Subject: firmware_builder: bundle code coverage information Add a rule to the makefile to merge code coverage into a single LCOV file, which firmware_builder.py will bundle as a build artifact. BUG=b:156895937 BRANCH=None TEST=Verify code coverage builds: ``` make clobber make coverage ls build/coverage/lcov.info ``` Verify firmware_builder tests (generate code coverage) and bundles the code coverage information with the correct metadata: ``` make clobber firmware_builder.py --code-coverage --metrics metrics.json test firmware_builder.py --code-coverage --metrics metrics.json bundle ls /tmp/artifact_bundles/coverage.tbz2 cat /tmp/artifact_bundle_metadata ``` Cq-Depend: chromium:2770601 Signed-off-by: Paul Fagerburg Change-Id: I355ea76cc774f566bf552741c1a1bdc94cd21bda Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2749421 Reviewed-by: LaMont Jones --- firmware_builder.py | 57 ++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 52 insertions(+), 5 deletions(-) (limited to 'firmware_builder.py') diff --git a/firmware_builder.py b/firmware_builder.py index 0ae9604f34..4fb2ccac71 100755 --- a/firmware_builder.py +++ b/firmware_builder.py @@ -51,11 +51,51 @@ def build(opts): def bundle(opts): - """Bundles the artifacts from each target into its own tarball.""" - info = firmware_pb2.FirmwareArtifactInfo() + if opts.code_coverage: + bundle_coverage(opts) + else: + bundle_firmware(opts) + + +def get_bundle_dir(opts): + """Get the directory for the bundle from opts or use the default. + + Also create the directory if it doesn't exist.""" bundle_dir = opts.output_dir if opts.output_dir else DEFAULT_BUNDLE_DIRECTORY if not os.path.isdir(bundle_dir): os.mkdir(bundle_dir) + return bundle_dir + + +def write_metadata(opts, info): + """Write the metadata about the bundle.""" + bundle_metadata_file = opts.metadata if opts.metadata else DEFAULT_BUNDLE_METADATA_FILE + with open(bundle_metadata_file, 'w') as f: + f.write(json_format.MessageToJson(info)) + + +def bundle_coverage(opts): + """Bundles the artifacts from code coverage into its own tarball.""" + info = firmware_pb2.FirmwareArtifactInfo() + info.bcs_version_info.version_string = opts.bcs_version + bundle_dir = get_bundle_dir(opts) + ec_dir = os.path.dirname(__file__) + tarball_name = 'coverage.tbz2' + tarball_path = os.path.join(bundle_dir, tarball_name) + cmd = ['tar', 'cvfj', tarball_path, 'lcov.info'] + subprocess.run(cmd, cwd=os.path.join(ec_dir, 'build/coverage'), check=True) + meta = info.objects.add() + meta.file_name = tarball_name + meta.lcov_info.type = firmware_pb2.FirmwareArtifactInfo.LcovTarballInfo.LcovType.LCOV + + write_metadata(opts, info) + + +def bundle_firmware(opts): + """Bundles the artifacts from each target into its own tarball.""" + info = firmware_pb2.FirmwareArtifactInfo() + info.bcs_version_info.version_string = opts.bcs_version + bundle_dir = get_bundle_dir(opts) ec_dir = os.path.dirname(__file__) for build_target in sorted(os.listdir(os.path.join(ec_dir, 'build'))): tarball_name = ''.join([build_target, '.firmware.tbz2']) @@ -71,9 +111,7 @@ def bundle(opts): # TODO(kmshelton): Populate the rest of metadata contents as it gets defined in # infra/proto/src/chromite/api/firmware.proto. - bundle_metadata_file = opts.metadata if opts.metadata else DEFAULT_BUNDLE_METADATA_FILE - with open(bundle_metadata_file, 'w') as f: - f.write(json_format.MessageToJson(info)) + write_metadata(opts, info) def test(opts): @@ -158,6 +196,15 @@ def parse_args(args): help='Build host-based unit tests for code coverage.', ) + parser.add_argument( + '--bcs-version', + dest='bcs_version', + default='', + required=False, + # TODO(b/180008931): make this required=True. + help='BCS version to include in metadata.', + ) + # Would make this required=True, but not available until 3.7 sub_cmds = parser.add_subparsers() -- cgit v1.2.1