firmware: add FIRMWARE_LCOV, add bcs_version

BUG=b:156895937, b:180008611
TEST=compile

Cq-Depend: chromium:2749421
Change-Id: I94a6a326803d9e44dc1d3d7cf48a2a77928c0c84
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/chromite/+/2770602
Reviewed-by: Paul Fagerburg <pfagerburg@chromium.org>
Reviewed-by: Alex Klein <saklein@chromium.org>
Tested-by: LaMont Jones <lamontjones@chromium.org>
Commit-Queue: Paul Fagerburg <pfagerburg@chromium.org>
diff --git a/api/controller/firmware.py b/api/controller/firmware.py
index b8ea777..75d1c04 100644
--- a/api/controller/firmware.py
+++ b/api/controller/firmware.py
@@ -161,7 +161,7 @@
   """Runs all of the firmware tests at the specified location."""
 
   if len(input_proto.artifacts.output_artifacts) > 1:
-    raise ValueError('Must have exactly one output_artifact')
+    raise ValueError('Must have exactly one output_artifact entry')
 
   with osutils.TempDir(delete=False) as tmpdir:
     info = input_proto.artifacts.output_artifacts[0]
@@ -176,27 +176,34 @@
         *args,
         output_dir=tmpdir,
         metadata=metadata_path)
-    tarball_paths = []
-    if (input_proto.artifacts.FIRMWARE_TARBALL_INFO in info.artifact_types and
-        os.path.exists(metadata_path)):
+    file_paths = []
+    if os.path.exists(metadata_path):
       with open(metadata_path, 'r') as f:
         metadata = json_format.Parse(f.read(),
                                      firmware_pb2.FirmwareArtifactInfo())
-      out = output_proto.artifacts.artifacts.add(
+    else:
+      metadata = firmware_pb2.FirmwareArtifactInfo()
+    if input_proto.artifacts.FIRMWARE_TARBALL_INFO in info.artifact_types:
+      output_proto.artifacts.artifacts.add(
           artifact_type=input_proto.artifacts.FIRMWARE_TARBALL_INFO,
-          paths=[
+          location=info.location, paths=[
               common_pb2.Path(
                   path=metadata_path, location=common_pb2.Path.INSIDE)
           ])
-      tarball_paths = [
-          common_pb2.Path(
-              path=os.path.join(tmpdir, x.file_name),
-              location=common_pb2.Path.INSIDE) for x in metadata.objects
+
+    full_path = lambda x: common_pb2.Path(
+        path=os.path.join(tmpdir, x.file_name),
+        location=common_pb2.Path.INSIDE)
+
+    for typ, name in (
+        (input_proto.artifacts.FIRMWARE_TARBALL, 'tarball_info'),
+        (input_proto.artifacts.FIRMWARE_LCOV, 'lcov_info')):
+      file_paths = [
+          full_path(x) for x in metadata.objects
+          if x.WhichOneof('firmware_object_info') == name
       ]
-    if (tarball_paths and
-        input_proto.artifacts.FIRMWARE_TARBALL in info.artifact_types):
-      out = output_proto.artifacts.artifacts.add(
-          artifact_type=input_proto.artifacts.FIRMWARE_TARBALL,
-          paths=tarball_paths)
-      out.location = info.location
+      if (file_paths and typ in info.artifact_types):
+        output_proto.artifacts.artifacts.add(
+            artifact_type=typ, paths=file_paths, location=info.location)
+
     return resp