Files
hassio-addons-avm/hassio-google-drive-backup/tests/test_data_cache.py

211 lines
7.4 KiB
Python

import pytest
import os
import json
from injector import Injector
from datetime import timedelta
from backup.config import Config, Setting, VERSION, Version
from backup.util import DataCache, UpgradeFlags, KEY_CREATED, KEY_LAST_SEEN, CACHE_EXPIRATION_DAYS
from backup.time import Time
from os.path import join
@pytest.mark.asyncio
async def test_read_and_write(config: Config, time: Time) -> None:
cache = DataCache(config, time)
assert len(cache.backups) == 0
cache.backup("test")[KEY_CREATED] = time.now().isoformat()
assert not cache._dirty
cache.makeDirty()
assert cache._dirty
cache.saveIfDirty()
assert not cache._dirty
cache = DataCache(config, time)
assert cache.backup("test")[KEY_CREATED] == time.now().isoformat()
assert not cache._dirty
@pytest.mark.asyncio
async def test_backup_expiration(config: Config, time: Time) -> None:
cache = DataCache(config, time)
assert len(cache.backups) == 0
cache.backup("new")[KEY_LAST_SEEN] = time.now().isoformat()
cache.backup("old")[KEY_LAST_SEEN] = (
time.now() - timedelta(days=CACHE_EXPIRATION_DAYS + 1)) .isoformat()
cache.makeDirty()
cache.saveIfDirty()
assert len(cache.backups) == 1
assert "new" in cache.backups
assert "old" not in cache.backups
@pytest.mark.asyncio
async def test_version_upgrades(time: Time, injector: Injector, config: Config) -> None:
# Simluate upgrading from an un-tracked version
assert not os.path.exists(config.get(Setting.DATA_CACHE_FILE_PATH))
cache = injector.get(DataCache)
upgrade_time = time.now()
assert cache.previousVersion == Version.default()
assert cache.currentVersion == Version.parse(VERSION)
assert os.path.exists(config.get(Setting.DATA_CACHE_FILE_PATH))
with open(config.get(Setting.DATA_CACHE_FILE_PATH)) as f:
data = json.load(f)
assert data["upgrades"] == [{
"prev_version": str(Version.default()),
"new_version": VERSION,
"date": upgrade_time.isoformat()
}]
# Reload the data cache, verify there is no upgrade.
time.advance(days=1)
cache = DataCache(config, time)
assert cache.previousVersion == Version.parse(VERSION)
assert cache.currentVersion == Version.parse(VERSION)
assert os.path.exists(config.get(Setting.DATA_CACHE_FILE_PATH))
with open(config.get(Setting.DATA_CACHE_FILE_PATH)) as f:
data = json.load(f)
assert data["upgrades"] == [{
"prev_version": str(Version.default()),
"new_version": VERSION,
"date": upgrade_time.isoformat()
}]
# simulate upgrading to a new version, verify an upgrade gets identified.
upgrade_version = Version.parse("200")
class UpgradeCache(DataCache):
def __init__(self):
super().__init__(config, time)
@property
def currentVersion(self):
return upgrade_version
cache = UpgradeCache()
assert cache.previousVersion == Version.parse(VERSION)
assert cache.currentVersion == upgrade_version
assert os.path.exists(config.get(Setting.DATA_CACHE_FILE_PATH))
with open(config.get(Setting.DATA_CACHE_FILE_PATH)) as f:
data = json.load(f)
assert data["upgrades"] == [
{
"prev_version": str(Version.default()),
"new_version": VERSION,
"date": upgrade_time.isoformat()
},
{
"prev_version": VERSION,
"new_version": str(upgrade_version),
"date": time.now().isoformat()
}
]
next_upgrade_time = time.now()
time.advance(days=1)
# Verify version upgrade time queries work as expected
assert cache.getUpgradeTime(Version.parse(VERSION)) == upgrade_time
assert cache.getUpgradeTime(Version.default()) == upgrade_time
assert cache.getUpgradeTime(upgrade_version) == next_upgrade_time
# degenerate case, should never happen but a sensible value needs to be returned
assert cache.getUpgradeTime(Version.parse("201")) == time.now()
@pytest.mark.asyncio
async def test_flag(config: Config, time: Time):
cache = DataCache(config, time)
assert not cache.checkFlag(UpgradeFlags.TESTING_FLAG)
assert not cache.dirty
cache.addFlag(UpgradeFlags.TESTING_FLAG)
assert cache.dirty
assert cache.checkFlag(UpgradeFlags.TESTING_FLAG)
cache.saveIfDirty()
cache = DataCache(config, time)
assert cache.checkFlag(UpgradeFlags.TESTING_FLAG)
@pytest.mark.asyncio
async def test_warn_upgrade_new_install(config: Config, time: Time):
"""A fresh install of the addon should never warn about upgrade snapshots"""
cache = DataCache(config, time)
assert not cache.notifyForIgnoreUpgrades
assert cache._config.get(Setting.IGNORE_UPGRADE_BACKUPS)
@pytest.mark.asyncio
async def test_warn_upgrade_old_install(config: Config, time: Time):
"""An old install of the addon warn about upgrade snapshots"""
with open(config.get(Setting.DATA_CACHE_FILE_PATH), "w") as f:
data = {
"upgrades": [
{
"prev_version": str(Version.default()),
"new_version": "0.108.1",
"date": time.now().isoformat()
}
]
}
json.dump(data, f)
cache = DataCache(config, time)
assert cache.notifyForIgnoreUpgrades
assert not cache._config.get(Setting.IGNORE_UPGRADE_BACKUPS)
@pytest.mark.asyncio
async def test_warn_upgrade_old_install_explicit_ignore_upgrades(config: Config, time: Time, cleandir: str):
"""An old install of the addon should not warn about upgrade snapshots if it explicitly ignores them"""
with open(config.get(Setting.DATA_CACHE_FILE_PATH), "w") as f:
data = {
"upgrades": [
{
"prev_version": str(Version.default()),
"new_version": "0.108.1",
"date": time.now().isoformat()
}
]
}
json.dump(data, f)
config_path = join(cleandir, "config.json")
with open(config_path, "w") as f:
data = {
Setting.IGNORE_UPGRADE_BACKUPS.value: True,
Setting.DATA_CACHE_FILE_PATH.value: config.get(Setting.DATA_CACHE_FILE_PATH)
}
json.dump(data, f)
cache = DataCache(Config.fromFile(config_path), time)
assert not cache.notifyForIgnoreUpgrades
assert cache._config.get(Setting.IGNORE_UPGRADE_BACKUPS)
@pytest.mark.asyncio
async def test_warn_upgrade_old_install_explicit_ignore_others(config: Config, time: Time, cleandir: str):
"""An old install of the addon should not warn about upgrade snapshots if it explicitly ignores them"""
with open(config.get(Setting.DATA_CACHE_FILE_PATH), "w") as f:
data = {
"upgrades": [
{
"prev_version": str(Version.default()),
"new_version": "0.108.1",
"date": time.now().isoformat()
}
]
}
json.dump(data, f)
config_path = join(cleandir, "config.json")
with open(config_path, "w") as f:
data = {
Setting.IGNORE_OTHER_BACKUPS.value: True,
Setting.DATA_CACHE_FILE_PATH.value: config.get(Setting.DATA_CACHE_FILE_PATH)
}
json.dump(data, f)
cache = DataCache(Config.fromFile(config_path), time)
assert not cache.notifyForIgnoreUpgrades