blob: 0b65c55cb4e9b079cfe3341cd2135e232ca171b4 [file] [log] [blame]
Mike Frysingerf1ba7ad2022-09-12 05:42:57 -04001# Copyright 2021 The ChromiumOS Authors
Michael Mortensen7335e302021-02-23 10:42:56 -07002# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
Mike Frysingera2527f82023-02-03 04:32:15 -05004
Michael Mortensen7335e302021-02-23 10:42:56 -07005"""Unittests for Firmware operations."""
6
Michael Mortensen7335e302021-02-23 10:42:56 -07007import os
Mike Frysinger166fea02021-02-12 05:30:33 -05008from unittest import mock
Michael Mortensen7335e302021-02-23 10:42:56 -07009
Mike Frysinger2c024062021-05-22 15:43:22 -040010from chromite.third_party.google.protobuf import json_format
Michael Mortensen7335e302021-02-23 10:42:56 -070011
12from chromite.api import api_config
13from chromite.api.controller import firmware
14from chromite.api.gen.chromite.api import firmware_pb2
Andrew Luod08045d2021-06-17 12:06:44 -070015from chromite.api.gen.chromiumos import common_pb2
Michael Mortensen7335e302021-02-23 10:42:56 -070016from chromite.lib import constants
17from chromite.lib import cros_build_lib
18from chromite.lib import cros_test_lib
19
20
Alex Klein1699fab2022-09-08 08:46:06 -060021class BuildAllFirmwareTestCase(
22 cros_test_lib.MockTempDirTestCase, api_config.ApiConfigMixin
23):
24 """BuildAllFirmware tests."""
Michael Mortensen7335e302021-02-23 10:42:56 -070025
Alex Klein1699fab2022-09-08 08:46:06 -060026 def setUp(self):
27 self.chroot_path = "/path/to/chroot"
28 self.cros_build_run_patch = self.PatchObject(
29 cros_build_lib,
30 "run",
31 return_value=cros_build_lib.CompletedProcess(returncode=0),
32 )
Michael Mortensen7335e302021-02-23 10:42:56 -070033
Alex Klein1699fab2022-09-08 08:46:06 -060034 def _GetInput(
35 self,
36 chroot_path=None,
37 fw_location=common_pb2.PLATFORM_EC,
38 code_coverage=False,
39 ):
40 """Helper for creating input message."""
41 proto = firmware_pb2.BuildAllFirmwareRequest(
42 firmware_location=fw_location,
43 chroot={"path": chroot_path},
44 code_coverage=code_coverage,
45 )
46 return proto
Michael Mortensen7335e302021-02-23 10:42:56 -070047
Alex Klein1699fab2022-09-08 08:46:06 -060048 def testBuildAllFirmware(self):
Alex Kleinab87ceb2023-01-24 12:00:51 -070049 """Test endpoint by verifying call to cros_build_lib.run."""
Alex Klein1699fab2022-09-08 08:46:06 -060050 for fw_loc in common_pb2.FwLocation.values():
51 fw_path = firmware.get_fw_loc(fw_loc)
52 if not fw_path:
53 continue
54 request = self._GetInput(
55 chroot_path=self.chroot_path,
56 fw_location=fw_loc,
57 code_coverage=True,
58 )
59 # TODO(mmortensen): Consider refactoring firmware._call_entry code
Alex Kleinab87ceb2023-01-24 12:00:51 -070060 # (putting the parsing of the output file in a function) so that we
61 # don't have to mock something as generic as 'json_format.Parse' to
62 # avoid an error on parsing an empty(due to mock call) file.
Alex Klein1699fab2022-09-08 08:46:06 -060063 json_format_patch = self.PatchObject(json_format, "Parse")
64 response = firmware_pb2.BuildAllFirmwareResponse()
65 # Call the method under test.
66 firmware.BuildAllFirmware(request, response, self.api_config)
Alex Kleinab87ceb2023-01-24 12:00:51 -070067 # Because we mock out the function, we verify that it is called as
68 # we expect it to be called.
Alex Klein1699fab2022-09-08 08:46:06 -060069 called_function = os.path.join(
70 constants.SOURCE_ROOT, fw_path, "firmware_builder.py"
71 )
72 self.cros_build_run_patch.assert_called_with(
73 [
74 called_function,
75 "--metrics",
76 mock.ANY,
77 "--code-coverage",
78 "build",
79 ],
80 check=False,
81 )
82 # Verify that we try to parse the metrics file.
83 json_format_patch.assert_called()
Michael Mortensen7335e302021-02-23 10:42:56 -070084
Alex Klein1699fab2022-09-08 08:46:06 -060085 def testValidateOnly(self):
Alex Kleinab87ceb2023-01-24 12:00:51 -070086 """Verify a validate-only call does not execute any logic."""
Alex Klein1699fab2022-09-08 08:46:06 -060087 for fw_loc in common_pb2.FwLocation.values():
88 if not firmware.get_fw_loc(fw_loc):
89 continue
90 request = self._GetInput(
91 chroot_path=self.chroot_path,
92 fw_location=fw_loc,
93 code_coverage=True,
94 )
95 response = firmware_pb2.BuildAllFirmwareResponse()
96 firmware.BuildAllFirmware(
97 request, response, self.validate_only_config
98 )
99 self.cros_build_run_patch.assert_not_called()
Michael Mortensen515c8892021-02-26 15:37:59 -0700100
Alex Klein1699fab2022-09-08 08:46:06 -0600101 def testMockCall(self):
Alex Kleinab87ceb2023-01-24 12:00:51 -0700102 """Test a mock call does not execute logic, returns mocked value."""
Alex Klein1699fab2022-09-08 08:46:06 -0600103 for fw_loc in common_pb2.FwLocation.values():
104 if not firmware.get_fw_loc(fw_loc):
105 continue
106 request = self._GetInput(
107 chroot_path=self.chroot_path,
108 fw_location=fw_loc,
109 code_coverage=True,
110 )
111 response = firmware_pb2.BuildAllFirmwareResponse()
112 firmware.BuildAllFirmware(request, response, self.mock_call_config)
113 self.cros_build_run_patch.assert_not_called()
114 self.assertEqual(len(response.metrics.value), 1)
115 self.assertEqual(response.metrics.value[0].target_name, "foo")
116 self.assertEqual(response.metrics.value[0].platform_name, "bar")
117 self.assertEqual(len(response.metrics.value[0].fw_section), 1)
118 self.assertEqual(
119 response.metrics.value[0].fw_section[0].region, "EC_RO"
120 )
121 self.assertEqual(response.metrics.value[0].fw_section[0].used, 100)
122 self.assertEqual(response.metrics.value[0].fw_section[0].total, 150)