diff --git a/src/azure-cli/azure/cli/command_modules/resource/_bicep.py b/src/azure-cli/azure/cli/command_modules/resource/_bicep.py index d8e4caef7cc..05ece5183bd 100644 --- a/src/azure-cli/azure/cli/command_modules/resource/_bicep.py +++ b/src/azure-cli/azure/cli/command_modules/resource/_bicep.py @@ -38,6 +38,7 @@ _bicep_installation_dir = os.path.join(_config_dir, "bin") _bicep_version_check_file_path = os.path.join(_config_dir, "bicepVersionCheck.json") _bicep_version_check_cache_ttl = timedelta(minutes=10) +_bicep_version_check_time_format = "%Y-%m-%dT%H:%M:%S.%f" _logger = get_logger(__name__) @@ -149,7 +150,7 @@ def _load_bicep_version_check_result_from_cache(): with open(_bicep_version_check_file_path, "r") as version_check_file: version_check_data = json.load(version_check_file) latest_release_tag = version_check_data["latestReleaseTag"] - last_check_time = datetime.fromisoformat(version_check_data["lastCheckTime"]) + last_check_time = datetime.strptime(version_check_data["lastCheckTime"], _bicep_version_check_time_format) cache_expired = datetime.now() - last_check_time > _bicep_version_check_cache_ttl return latest_release_tag, cache_expired @@ -160,7 +161,7 @@ def _load_bicep_version_check_result_from_cache(): def _refresh_bicep_version_check_cache(lastest_release_tag): with open(_bicep_version_check_file_path, "w+") as version_check_file: version_check_data = { - "lastCheckTime": datetime.now().isoformat(timespec="microseconds"), + "lastCheckTime": datetime.now().strftime(_bicep_version_check_time_format), "latestReleaseTag": lastest_release_tag, } json.dump(version_check_data, version_check_file) diff --git a/src/azure-cli/azure/cli/command_modules/resource/tests/latest/test_resource_bicep.py b/src/azure-cli/azure/cli/command_modules/resource/tests/latest/test_resource_bicep.py index e1fe7209793..bc28fc51344 100644 --- a/src/azure-cli/azure/cli/command_modules/resource/tests/latest/test_resource_bicep.py +++ b/src/azure-cli/azure/cli/command_modules/resource/tests/latest/test_resource_bicep.py @@ -3,6 +3,8 @@ # Licensed under the MIT License. See License.txt in the project root for license information. # -------------------------------------------------------------------------------------------- +import os +import contextlib import unittest import mock @@ -11,6 +13,7 @@ ensure_bicep_installation, run_bicep_command, validate_bicep_target_scope, + _bicep_version_check_file_path, ) from azure.cli.core.azclierror import InvalidTemplateError @@ -49,6 +52,34 @@ def test_run_bicep_command_check_version( "v2.0.0", ) + @mock.patch("azure.cli.command_modules.resource._bicep._logger.warning") + @mock.patch("azure.cli.command_modules.resource._bicep._run_command") + @mock.patch("azure.cli.command_modules.resource._bicep.ensure_bicep_installation") + @mock.patch("azure.cli.command_modules.resource._bicep.get_bicep_latest_release_tag") + @mock.patch("azure.cli.command_modules.resource._bicep._get_bicep_installed_version") + @mock.patch("os.path.isfile") + def test_run_bicep_command_check_version_cache_read_write( + self, + isfile_stub, + _get_bicep_installed_version_stub, + get_bicep_latest_release_tag_stub, + ensure_bicep_installation_mock, + _run_command_mock, + warning_mock, + ): + try: + self._remove_bicep_version_check_file() + + isfile_stub.return_value = True + _get_bicep_installed_version_stub.return_value = "1.0.0" + get_bicep_latest_release_tag_stub.return_value = "v2.0.0" + + run_bicep_command(["--version"], check_version=True) + + self.assertTrue(os.path.isfile(_bicep_version_check_file_path)) + finally: + self._remove_bicep_version_check_file() + @mock.patch("os.path.isfile") @mock.patch("azure.cli.command_modules.resource._bicep._get_bicep_installed_version") @mock.patch("os.path.dirname") @@ -73,8 +104,14 @@ def test_validate_target_scope_raise_error_if_target_scope_does_not_match_deploy def test_validate_target_scope_success_if_target_scope_matches_deployment_scope(self): for template_schema, deployment_scope in [ ("https://schema.management.azure.com/schemas/2019-08-01/deploymentTemplate.json#", "resourceGroup"), - ("https://schema.management.azure.com/schemas/2019-08-01/subscriptionDeploymentTemplate.json#", "subscription"), - ("https://schema.management.azure.com/schemas/2019-08-01/managementGroupDeploymentTemplate.json#", "managementGroup"), + ( + "https://schema.management.azure.com/schemas/2019-08-01/subscriptionDeploymentTemplate.json#", + "subscription", + ), + ( + "https://schema.management.azure.com/schemas/2019-08-01/managementGroupDeploymentTemplate.json#", + "managementGroup", + ), ("https://schema.management.azure.com/schemas/2019-08-01/tenantDeploymentTemplate.json#", "tenant"), ]: with self.subTest(template_schema=template_schema, deployment_scope=deployment_scope): @@ -84,3 +121,7 @@ def test_validate_target_scope_success_if_target_scope_matches_deployment_scope( self.fail(e.error_msg) except: self.fail("Encountered an unexpected exception.") + + def _remove_bicep_version_check_file(self): + with contextlib.suppress(FileNotFoundError): + os.remove(_bicep_version_check_file_path)