From 99bd483b99a84f05b28696bfcf0339947e847b05 Mon Sep 17 00:00:00 2001 From: Sean Marlow Date: Fri, 12 Jan 2024 12:00:52 -0500 Subject: [PATCH] Attempt to backup archive before saving After saving clean up the backup file if it exists. --- csp_billing_adapter_local/plugin.py | 16 +++++++++++++++- tests/unit/test_plugin.py | 8 +++++--- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/csp_billing_adapter_local/plugin.py b/csp_billing_adapter_local/plugin.py index 34d1f1f..c3f2ed9 100644 --- a/csp_billing_adapter_local/plugin.py +++ b/csp_billing_adapter_local/plugin.py @@ -22,6 +22,7 @@ import logging import urllib.request import urllib.error +import shutil from json.decoder import JSONDecodeError from pathlib import Path @@ -100,9 +101,22 @@ def update_cache(config: Config, cache: dict, replace: bool): @csp_billing_adapter.hookimpl(trylast=True) def save_metering_archive(config: Config, archive_data: list): """Update local storage archive with new content""" - with open(get_local_path(ARCHIVE_FILE), 'w', encoding='utf-8') as f: + archive_path = get_local_path(ARCHIVE_FILE) + archive_bak = Path(str(archive_path) + '.bak') + + try: + shutil.copy(archive_path, archive_bak) + except FileNotFoundError: + pass + + with open(archive_path, 'w', encoding='utf-8') as f: json.dump(archive_data, f) + try: + archive_bak.unlink() + except FileNotFoundError: + pass + @csp_billing_adapter.hookimpl(trylast=True) def get_metering_archive(config: Config): diff --git a/tests/unit/test_plugin.py b/tests/unit/test_plugin.py index dbd11eb..f8e9dde 100644 --- a/tests/unit/test_plugin.py +++ b/tests/unit/test_plugin.py @@ -26,7 +26,7 @@ import json import logging from pathlib import Path -from tempfile import NamedTemporaryFile +from tempfile import NamedTemporaryFile, TemporaryDirectory from unittest.mock import patch from pytest import raises @@ -477,8 +477,10 @@ def test_local_get_metering_archive_file_not_found_exception( def test_local_save_metering_archive(self, mock_get_local_path): """Test save_metering_archive() in local plugin""" - with NamedTemporaryFile() as temp_file: - mock_get_local_path.return_value = Path(temp_file.name) + with TemporaryDirectory() as temp_dir: + mock_get_local_path.return_value = Path( + temp_dir + ).joinpath('archive.json') archive = [{ 'billing_time': '2024-02-09T18:11:59.527064+00:00', 'billing_status': {