Fix GHA and GMSCore version not shown in test report
PiperOrigin-RevId: 604087771
diff --git a/ui_automator/test_reporter.py b/ui_automator/test_reporter.py
index eae676d..d5d0852 100644
--- a/ui_automator/test_reporter.py
+++ b/ui_automator/test_reporter.py
@@ -37,7 +37,7 @@
'Removing from GHA': 'test_decommission',
})
_NA = 'n/a'
-_SUMMARY_COL_INDENTS = 25
+_MINIMUM_SUMMARY_COL_INDENTS = 25
_TEST_CASE_TITLE_INDENTS = 25
_TEST_RESULT_INDENTS = 8
@@ -54,11 +54,11 @@
class ReportInfo(TypedDict):
"""Type guard for summary of running unit tests."""
- gha_version: NotRequired[str | None]
- gms_core_version: NotRequired[str | None]
- hub_version: NotRequired[str | None]
- device_firmware: NotRequired[str | None]
- dut: NotRequired[str | None]
+ gha_version: NotRequired[str]
+ gms_core_version: NotRequired[str]
+ hub_version: NotRequired[str]
+ device_firmware: NotRequired[str]
+ dut: NotRequired[str]
# pylint: disable=protected-access
@@ -283,7 +283,12 @@
100.0 * float(total_successful_runs) / float(total_runs)
)
report_info = report_info or {}
- # TODO(b/317837867): Replace all placeholders with real values.
+ data_indents = _MINIMUM_SUMMARY_COL_INDENTS
+ for value in report_info.values():
+ # Set indents to the maximum length of values in report info.
+ # Add 2 extra spaces to separate data and next header.
+ # If the value is less than minimum column indents, use the minimum.
+ data_indents = max(data_indents, len(value) + 2)
rows: list[list[str]] = []
rows.append(['Summary', '', 'Version Info', ''])
rows.append([
@@ -316,19 +321,11 @@
])
f = open(summary_file_path, 'w', encoding='utf-8')
- data_indents = (
- # Set indents to the maximum length of values in report info if any.
- # Add 2 extra spaces to separate data and next header.
- # If the value is less than default column indents, use the default.
- max(max(map(len, report_info.values())) + 2, _SUMMARY_COL_INDENTS)
- if report_info
- else _SUMMARY_COL_INDENTS
- )
for row in rows:
for i, element in enumerate(row):
if i % 2 == 0:
# Writes header.
- f.write(element.ljust(_SUMMARY_COL_INDENTS))
+ f.write(element.ljust(_MINIMUM_SUMMARY_COL_INDENTS))
else:
f.write(element.ljust(data_indents))
f.write('\n')
diff --git a/ui_automator/ui_automator.py b/ui_automator/ui_automator.py
index edb17ca..380ab31 100644
--- a/ui_automator/ui_automator.py
+++ b/ui_automator/ui_automator.py
@@ -407,6 +407,7 @@
self._is_reg_test_finished = True
executor.shutdown(wait=False)
+ @get_android_device_ready
def get_report_info(self) -> test_reporter.ReportInfo:
"""Gets report info for regression tests.
@@ -417,12 +418,16 @@
"""
temp_info = collections.defaultdict()
if self._connected_device:
- temp_info['gha_version'] = ad.get_apk_version(
+ gha_version = ad.get_apk_version(
self._connected_device, 'com.google.android.apps.chromecast.app'
)
- temp_info['gms_core_version'] = ad.get_apk_version(
+ if gha_version:
+ temp_info['gha_version'] = gha_version
+ gms_core_version = ad.get_apk_version(
self._connected_device, 'com.google.android.gms'
)
+ if gms_core_version:
+ temp_info['gms_core_version'] = gms_core_version
if _DUT.value:
temp_info['dut'] = f"<{', '.join(_DUT.value)}>"
diff --git a/ui_automator/ui_automator_test.py b/ui_automator/ui_automator_test.py
index d8813ba..2b2a191 100644
--- a/ui_automator/ui_automator_test.py
+++ b/ui_automator/ui_automator_test.py
@@ -1000,29 +1000,35 @@
mock_exit.assert_called_once()
@mock.patch.object(android_device, 'get_all_instances', autospec=True)
+ @mock.patch.object(ui_automator.UIAutomator, 'load_snippet', autospec=True)
def test_get_report_info_includes_apk_versions_with_device_connected(
self,
+ mock_load_snippet,
mock_get_all_instances,
):
+ mock_get_all_instances.return_value = [self.mock_android_device]
self.mock_android_device.adb.shell.side_effect = [
b'versionName=0.0.0\n',
b'versionName=0.0.1\n',
]
- mock_get_all_instances.return_value = [self.mock_android_device]
- self.ui_automator.load_device()
report_info = self.ui_automator.get_report_info()
- self.assertEqual(len(report_info), 2)
- self.assertEqual(report_info.get('gha_version'), '0.0.0')
- self.assertEqual(report_info.get('gms_core_version'), '0.0.1')
+ mock_load_snippet.assert_called_once()
+ self.assertDictEqual(
+ report_info, {'gha_version': '0.0.0', 'gms_core_version': '0.0.1'}
+ )
- def test_get_report_info_returns_empty_dict_when_no_device_connected(
- self,
+ @mock.patch.object(android_device, 'get_all_instances', autospec=True)
+ def test_get_report_info_raises_an_error_when_no_device_connected(
+ self, mock_get_all_instances
):
- report_info = self.ui_automator.get_report_info()
+ mock_get_all_instances.return_value = []
- self.assertDictEqual(report_info, {})
+ with self.assertRaisesRegex(
+ errors.AndroidDeviceNotReadyError, 'get_report_info failed.'
+ ):
+ self.ui_automator.get_report_info()
@mock.patch.object(time, 'sleep', autospec=True)
@mock.patch('builtins.open', autospec=True)
@@ -1064,48 +1070,95 @@
mock_open.assert_called_once()
@flagsaver.flagsaver((ui_automator._DUT, ['model', 'type', 'protocol']))
- def test_get_report_info_includes_dut_value_from_flag_input(self):
- report_info = self.ui_automator.get_report_info()
-
- self.assertEqual(len(report_info), 1)
- self.assertEqual(report_info.get('dut'), '<model, type, protocol>')
-
- @flagsaver.flagsaver((ui_automator._DUT, None))
- def test_get_report_info_returns_empty_dict_without_dut_flag_input(
- self,
+ @mock.patch.object(ui_automator.UIAutomator, 'load_device', autospec=True)
+ @mock.patch.object(ui_automator.UIAutomator, 'load_snippet', autospec=True)
+ def test_get_report_info_includes_dut_value_from_flag_input(
+ self, mock_load_snippet, mock_load_device
):
report_info = self.ui_automator.get_report_info()
+ mock_load_device.assert_called_once()
+ mock_load_snippet.assert_called_once()
+ self.assertDictEqual(report_info, {'dut': '<model, type, protocol>'})
+
+ @flagsaver.flagsaver((ui_automator._DUT, None))
+ @mock.patch.object(ui_automator.UIAutomator, 'load_device', autospec=True)
+ @mock.patch.object(ui_automator.UIAutomator, 'load_snippet', autospec=True)
+ def test_get_report_info_returns_empty_dict_without_dut_flag_input(
+ self, mock_load_snippet, mock_load_device
+ ):
+ report_info = self.ui_automator.get_report_info()
+
+ mock_load_device.assert_called_once()
+ mock_load_snippet.assert_called_once()
self.assertDictEqual(report_info, {})
@flagsaver.flagsaver((ui_automator._HUB, '10.1.3'))
- def test_get_report_info_includes_hub_value_from_flag_input(self):
- report_info = self.ui_automator.get_report_info()
-
- self.assertEqual(len(report_info), 1)
- self.assertEqual(report_info.get('hub_version'), '10.1.3')
-
- @flagsaver.flagsaver((ui_automator._HUB, None))
- def test_get_report_info_returns_empty_dict_without_hub_flag_input(
- self,
+ @mock.patch.object(ui_automator.UIAutomator, 'load_device', autospec=True)
+ @mock.patch.object(ui_automator.UIAutomator, 'load_snippet', autospec=True)
+ def test_get_report_info_includes_hub_value_from_flag_input(
+ self, mock_load_snippet, mock_load_device
):
report_info = self.ui_automator.get_report_info()
+ mock_load_device.assert_called_once()
+ mock_load_snippet.assert_called_once()
+ self.assertDictEqual(report_info, {'hub_version': '10.1.3'})
+
+ @flagsaver.flagsaver((ui_automator._HUB, None))
+ @mock.patch.object(ui_automator.UIAutomator, 'load_device', autospec=True)
+ @mock.patch.object(ui_automator.UIAutomator, 'load_snippet', autospec=True)
+ def test_get_report_info_returns_empty_dict_without_hub_flag_input(
+ self, mock_load_snippet, mock_load_device
+ ):
+ report_info = self.ui_automator.get_report_info()
+
+ mock_load_device.assert_called_once()
+ mock_load_snippet.assert_called_once()
self.assertDictEqual(report_info, {})
@flagsaver.flagsaver((ui_automator._DEVICE_FIRMWARE, '10.20.12'))
- def test_get_report_info_includes_device_firmware_from_flag_input(self):
- report_info = self.ui_automator.get_report_info()
-
- self.assertEqual(len(report_info), 1)
- self.assertEqual(report_info.get('device_firmware'), '10.20.12')
-
- @flagsaver.flagsaver((ui_automator._DEVICE_FIRMWARE, None))
- def test_get_report_info_returns_empty_dict_without_device_firmware_flag(
- self,
+ @mock.patch.object(ui_automator.UIAutomator, 'load_device', autospec=True)
+ @mock.patch.object(ui_automator.UIAutomator, 'load_snippet', autospec=True)
+ def test_get_report_info_includes_device_firmware_from_flag_input(
+ self, mock_load_snippet, mock_load_device
):
report_info = self.ui_automator.get_report_info()
+ mock_load_device.assert_called_once()
+ mock_load_snippet.assert_called_once()
+ self.assertDictEqual(report_info, {'device_firmware': '10.20.12'})
+
+ @flagsaver.flagsaver((ui_automator._DEVICE_FIRMWARE, None))
+ @mock.patch.object(ui_automator.UIAutomator, 'load_device', autospec=True)
+ @mock.patch.object(ui_automator.UIAutomator, 'load_snippet', autospec=True)
+ def test_get_report_info_returns_empty_dict_without_device_firmware_flag(
+ self, mock_load_snippet, mock_load_device
+ ):
+ report_info = self.ui_automator.get_report_info()
+
+ mock_load_device.assert_called_once()
+ mock_load_snippet.assert_called_once()
+ self.assertDictEqual(report_info, {})
+
+ @mock.patch.object(android_device, 'get_all_instances', autospec=True)
+ @mock.patch.object(ui_automator.UIAutomator, 'load_snippet', autospec=True)
+ def test_get_report_info_should_not_write_none_in_report_info(
+ self,
+ mock_load_snippet,
+ mock_get_all_instances,
+ ):
+ mock_get_all_instances.return_value = [self.mock_android_device]
+ self.mock_android_device.adb.shell.side_effect = [
+ # Response for getting gha version.
+ b'Unable to find package\n',
+ # Response for getting gms core version.
+ b'Unable to find package\n',
+ ]
+
+ report_info = self.ui_automator.get_report_info()
+
+ mock_load_snippet.assert_called_once()
self.assertDictEqual(report_info, {})
if __name__ == '__main__':